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