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