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