xref: /netbsd-src/games/hunt/README.protocol (revision 9a53db37056d25ef22e0e366240e39e4b08cf80a)
1*9a53db37Sdholland
2*9a53db37SdhollandTHE HUNT PROTOCOL
3*9a53db37Sdholland=================
4*9a53db37Sdholland
5*9a53db37SdhollandThese are some notes on the traditional INET protocol between hunt(6) and
6*9a53db37Sdhollandhuntd(6) as divined from the source code.
7*9a53db37Sdholland
8*9a53db37Sdholland(In the original hunt, AF_UNIX sockets were used, but they are not
9*9a53db37Sdhollandconsidered here.)
10*9a53db37Sdholland
11*9a53db37SdhollandThe game of hunt is played with one server and several clients. The clients
12*9a53db37Sdhollandact as dumb 'graphics' clients in that they mostly only ever relay the
13*9a53db37Sdhollanduser's keystrokes to the server, and the server usually only ever sends
14*9a53db37Sdhollandscreen-drawing commands to the client. ie, the server does all the work.
15*9a53db37Sdholland
16*9a53db37SdhollandThe game server (huntd) listens on three different network ports which
17*9a53db37SdhollandI'll refer to as W, S and P, described as follows:
18*9a53db37Sdholland
19*9a53db37Sdholland	W	well known UDP port (26740, or 'udp/hunt' in netdb)
20*9a53db37Sdholland	S	statistics TCP port
21*9a53db37Sdholland	P	game play TCP port
22*9a53db37Sdholland
23*9a53db37SdhollandThe protocol on each port is different and are described separately in
24*9a53db37Sdhollandthe following sections.
25*9a53db37Sdholland
26*9a53db37SdhollandLines starting with "C:" and "S:" will indicate messages sent from the
27*9a53db37Sdhollandclient (hunt) or server (huntd) respectively.
28*9a53db37Sdholland
29*9a53db37SdhollandW - well known port
30*9a53db37Sdholland-------------------
31*9a53db37Sdholland	This server port is used only to query simple information about the
32*9a53db37Sdholland	game such as the port numbers of the other two ports (S and P),
33*9a53db37Sdholland	and to find out how many players are still in the game.
34*9a53db37Sdholland
35*9a53db37Sdholland	All datagrams sent to (and possibly from) this UDP port consist of
36*9a53db37Sdholland	a single unsigned 16-bit integer, encoded in network byte order.
37*9a53db37Sdholland
38*9a53db37Sdholland	Server response datagrams should be sent to the source address
39*9a53db37Sdholland	of the client request datagrams.
40*9a53db37Sdholland
41*9a53db37Sdholland	It is not useful to run multiple hunt servers on the one host
42*9a53db37Sdholland	interface, each of which perhaps listen to the well known port and
43*9a53db37Sdholland	respond appropriately. This is because clients will not be able to
44*9a53db37Sdholland	disambiguate which game is which.
45*9a53db37Sdholland
46*9a53db37Sdholland	It is reasonable (and expected) to have servers listen to a
47*9a53db37Sdholland	broadcast or multicast network address and respond, since the
48*9a53db37Sdholland	clients can extract a particular server's network address from
49*9a53db37Sdholland	the reply packet's source field.
50*9a53db37Sdholland
51*9a53db37Sdholland    Player port request
52*9a53db37Sdholland
53*9a53db37Sdholland	A client requests the game play port P with the C_PLAYER message.
54*9a53db37Sdholland	This is useful for clients broadcasting for any available games. eg:
55*9a53db37Sdholland
56*9a53db37Sdholland		C: {uint16: 0 (C_PLAYER)}
57*9a53db37Sdholland		S: {uint16: P (TCP port number for the game play port)}
58*9a53db37Sdholland
59*9a53db37Sdholland	The TCP address of the game play port should be formed from the
60*9a53db37Sdholland	transmitted port number and the source address as received by
61*9a53db37Sdholland	the client.
62*9a53db37Sdholland
63*9a53db37Sdholland    Monitor port request
64*9a53db37Sdholland
65*9a53db37Sdholland	A client can request the game play port P with the C_MONITOR message.
66*9a53db37Sdholland	However, the server will NOT reply if there are no players in
67*9a53db37Sdholland	the game. This is useful for broadcasting for 'active' games. eg:
68*9a53db37Sdholland
69*9a53db37Sdholland		C: {uint16: 1 (C_MONITOR)}
70*9a53db37Sdholland		S: {uint16: P (TCP port number for the game play port)}
71*9a53db37Sdholland
72*9a53db37Sdholland    Message port request
73*9a53db37Sdholland
74*9a53db37Sdholland	If the server receives the C_MESSAGE message it will
75*9a53db37Sdholland	respond with the number of players currently in its game, unless
76*9a53db37Sdholland	there are 0 players, in which case it remains silent. This
77*9a53db37Sdholland	is used when a player wishes to send a text message to all other
78*9a53db37Sdholland	players, but doesn't want to connect if the game is over. eg:
79*9a53db37Sdholland
80*9a53db37Sdholland		C: {uint16: 2 (C_MESSAGE)}
81*9a53db37Sdholland		S: {uint16: n (positive number of players)}
82*9a53db37Sdholland
83*9a53db37Sdholland    Statistics port request
84*9a53db37Sdholland
85*9a53db37Sdholland	The server's statistics port is queried with the C_SCORES message.
86*9a53db37Sdholland	eg:
87*9a53db37Sdholland
88*9a53db37Sdholland		C: {uint16: 3 (C_SCORES)}
89*9a53db37Sdholland		S: {uint16: S (TCP port number for the statistics port)}
90*9a53db37Sdholland
91*9a53db37Sdholland
92*9a53db37SdhollandS - statistics port
93*9a53db37Sdholland-------------------
94*9a53db37Sdholland	The statistics port accepts a TCP connection, and keeps
95*9a53db37Sdholland	it alive for long enough to send a text stream to the client.
96*9a53db37Sdholland	This text consists of the game statistics. Lines in the
97*9a53db37Sdholland	text message are terminated with the \n (LF) character.
98*9a53db37Sdholland
99*9a53db37Sdholland		C: <connect>
100*9a53db37Sdholland		S: <accept>
101*9a53db37Sdholland		S: {char[]: lines of text, each terminated with <LF>}
102*9a53db37Sdholland		S: <close>
103*9a53db37Sdholland
104*9a53db37Sdholland	The client is not to send any data to the server with this
105*9a53db37Sdholland	connection.
106*9a53db37Sdholland
107*9a53db37SdhollandP - game play port
108*9a53db37Sdholland------------------
109*9a53db37Sdholland	This port provides the TCP channel for the main game play between
110*9a53db37Sdholland	the client and the server.
111*9a53db37Sdholland
112*9a53db37Sdholland	All integers are unsigned, 32-bit and in network byte order.
113*9a53db37Sdholland	All fixed sized octet strings are ASCII encoded, NUL terminated.
114*9a53db37Sdholland
115*9a53db37Sdholland    Initial connection
116*9a53db37Sdholland
117*9a53db37Sdholland	The initial setup protocol between the client and server is as follows.
118*9a53db37Sdholland	The client sends some of its own details, and then the server replies
119*9a53db37Sdholland	with the version number of the server (currently (uint32)-1).
120*9a53db37Sdholland
121*9a53db37Sdholland		C: <connect>
122*9a53db37Sdholland		S: <accept>
123*9a53db37Sdholland		C: {uint32:   uid}
124*9a53db37Sdholland		C: {char[20]: name}
125*9a53db37Sdholland		C: {char[1]:  team}
126*9a53db37Sdholland		C: {uint32:   'enter status'}
127*9a53db37Sdholland		C: {char[20]: ttyname}
128*9a53db37Sdholland		C: {uint32:   'connect mode'}
129*9a53db37Sdholland		S: {uint32:   server version (-1)}
130*9a53db37Sdholland
131*9a53db37Sdholland	If the 'connect mode' is C_MESSAGE (2) then the server will wait
132*9a53db37Sdholland	for a single packet (no longer than 1024 bytes) containing
133*9a53db37Sdholland	a text message to be displayed to all players. (The message is not
134*9a53db37Sdholland	nul-terminated.)
135*9a53db37Sdholland
136*9a53db37Sdholland		C: {char[]:	client's witty message of abuse}
137*9a53db37Sdholland		S: <close>
138*9a53db37Sdholland
139*9a53db37Sdholland	The only other valid 'connect mode's are C_MONITOR and C_PLAYER.
140*9a53db37Sdholland	The server will attempt to allocate a slot for the client.
141*9a53db37Sdholland	If allocation fails, the server will reply immediately with
142*9a53db37Sdholland	"Too many monitors\n" or "Too many players\n', e.g.:
143*9a53db37Sdholland
144*9a53db37Sdholland		S: Too many players<LF>
145*9a53db37Sdholland		S: <close>
146*9a53db37Sdholland
147*9a53db37Sdholland	The 'enter status' integer is one of the following:
148*9a53db37Sdholland
149*9a53db37Sdholland		1 (Q_CLOAK)	the player wishes to enter cloaked
150*9a53db37Sdholland		2 (Q_FLY)	the player wishes to enter flying
151*9a53db37Sdholland		3 (Q_SCAN)	the player wishes to enter scanning
152*9a53db37Sdholland
153*9a53db37Sdholland	Any other value indicates that the player wishes to enter in
154*9a53db37Sdholland	'normal' mode.
155*9a53db37Sdholland
156*9a53db37Sdholland	A team value of 32 (space character) means no team, otherwise
157*9a53db37Sdholland	it is the ASCII value of a team's symbol.
158*9a53db37Sdholland
159*9a53db37Sdholland	On successful allocation, the server will immediately enter the
160*9a53db37Sdholland	following phase of the protocol.
161*9a53db37Sdholland
162*9a53db37Sdholland    Game play protocol
163*9a53db37Sdholland
164*9a53db37Sdholland	The client provides a thin 'graphical' client to the server, and
165*9a53db37Sdholland	only ever relays keystrokes typed by the user:
166*9a53db37Sdholland
167*9a53db37Sdholland		C: {char[]:	user keystrokes}
168*9a53db37Sdholland
169*9a53db37Sdholland	Each character must be sent by the client as soon as it is typed.
170*9a53db37Sdholland
171*9a53db37Sdholland
172*9a53db37Sdholland	The server only ever sends screen drawing commands to the client.
173*9a53db37Sdholland	The server assumes the initial state of the client is a clear
174*9a53db37Sdholland	80x24 screen with the cursor at the top left (position y=0, x=0)
175*9a53db37Sdholland
176*9a53db37Sdholland	    Literal character	225 (ADDCH)
177*9a53db37Sdholland
178*9a53db37Sdholland		S: {uint8: 225} {uint8: c}
179*9a53db37Sdholland
180*9a53db37Sdholland		The client must draw the character with ASCII value c
181*9a53db37Sdholland		at the cursor position, then advance the cursor to the right.
182*9a53db37Sdholland		If the cursor goes past the rightmost column of the screen,
183*9a53db37Sdholland		it wraps, moving to the first column of the next line down.
184*9a53db37Sdholland		The cursor should never be advanced past the bottom row.
185*9a53db37Sdholland
186*9a53db37Sdholland		(ADDCH is provided as an escape prefix.)
187*9a53db37Sdholland
188*9a53db37Sdholland	    Cursor motion	237 (MOVE)
189*9a53db37Sdholland
190*9a53db37Sdholland		S: {uint8: 237} {uint8: y} {uint8: x}
191*9a53db37Sdholland
192*9a53db37Sdholland		The client must move its cursor to the absolute screen
193*9a53db37Sdholland		location y, x, where y=0 is the top of the screen and
194*9a53db37Sdholland		x=0 is the left of the screen.
195*9a53db37Sdholland
196*9a53db37Sdholland	    Refresh screen	242 (REFRESH)
197*9a53db37Sdholland
198*9a53db37Sdholland		S: {uint8: 242}
199*9a53db37Sdholland
200*9a53db37Sdholland		This indicates to the client that a burst of screen
201*9a53db37Sdholland		drawing has ended. Typically the client will flush its
202*9a53db37Sdholland		own drawing output so that the user can see the results.
203*9a53db37Sdholland
204*9a53db37Sdholland		Refreshing is the only time that the client must
205*9a53db37Sdholland		ensure that the user can see the current screen. (This
206*9a53db37Sdholland		is intended for use with curses' refresh() function.)
207*9a53db37Sdholland
208*9a53db37Sdholland	    Clear to end of line 227 (CLRTOEOL)
209*9a53db37Sdholland
210*9a53db37Sdholland		S: {uint8: 227}
211*9a53db37Sdholland
212*9a53db37Sdholland		The client must replace all columns underneath and
213*9a53db37Sdholland		to the right of the cursor (on the one row) with
214*9a53db37Sdholland		space characters. The cursor must not move.
215*9a53db37Sdholland
216*9a53db37Sdholland	    End game		229 (ENDWIN)
217*9a53db37Sdholland
218*9a53db37Sdholland		S: {uint8: 229} {uint8: 32}
219*9a53db37Sdholland		S,C: <close>
220*9a53db37Sdholland
221*9a53db37Sdholland		S: {uint8: 229} {uint8: 236}
222*9a53db37Sdholland		S,C: <close>
223*9a53db37Sdholland
224*9a53db37Sdholland		The client and server must immediately close the connection.
225*9a53db37Sdholland		The client should also refresh the screen.
226*9a53db37Sdholland		If the second octet is 236 (LAST_PLAYER), then
227*9a53db37Sdholland		the client should give the user an opportunity to quickly
228*9a53db37Sdholland		re-enter the game. Otherwise the client should quit.
229*9a53db37Sdholland
230*9a53db37Sdholland	    Clear screen	195 (CLEAR)
231*9a53db37Sdholland
232*9a53db37Sdholland		S: {uint8: 195}
233*9a53db37Sdholland
234*9a53db37Sdholland		The client must erase all characters from the screen
235*9a53db37Sdholland		and move the cursor to the top left (x=0, y=0).
236*9a53db37Sdholland
237*9a53db37Sdholland	    Redraw screen	210 (REDRAW)
238*9a53db37Sdholland
239*9a53db37Sdholland		S: {uint8: 210}
240*9a53db37Sdholland
241*9a53db37Sdholland		The client should attempt to re-draw its screen.
242*9a53db37Sdholland
243*9a53db37Sdholland	    Audible bell	226 (BELL)
244*9a53db37Sdholland
245*9a53db37Sdholland		S: {uint8: 226}
246*9a53db37Sdholland
247*9a53db37Sdholland		The client should generate a short audible tone for
248*9a53db37Sdholland		the user.
249*9a53db37Sdholland
250*9a53db37Sdholland	    Server ready	231 (READY)
251*9a53db37Sdholland
252*9a53db37Sdholland		S: {uint8: 231} {uint8: n}
253*9a53db37Sdholland
254*9a53db37Sdholland		The client must refresh its screen.
255*9a53db37Sdholland
256*9a53db37Sdholland		The server indicates to the client that it has
257*9a53db37Sdholland		processed n of its characters in order, and is ready
258*9a53db37Sdholland		for more commands. This permits the client to
259*9a53db37Sdholland		synchronise user actions with server responses if need be.
260*9a53db37Sdholland
261*9a53db37Sdholland	    Characters other than the above.
262*9a53db37Sdholland
263*9a53db37Sdholland		S: {uint8: c}
264*9a53db37Sdholland
265*9a53db37Sdholland		The client must draw the character with ASCII value c
266*9a53db37Sdholland		in the same way as if it were preceded with ADDCH
267*9a53db37Sdholland		(see above).
268*9a53db37Sdholland
269*9a53db37Sdholland
270*9a53db37SdhollandDavid Leonard, 1999.
271*9a53db37Sdholland
272*9a53db37Sdholland$OpenBSD: README.protocol,v 1.1 1999/12/12 14:51:03 d Exp $
273