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