1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
|
/******************************************************************************
File: SocketSpec.txt
Author: Brent Hendricks
Project: NetSpades
This file specifies the socket interface and game protocol between the
client and the server so that anyone can write a client on any
platform and have it be compatible.
Updated: 2/18/99
- New endgame protocol
Updated: 3/24/99
- Added number of victorious team as third bit of gameOver flag
*****************************************************************************/
Port Numbers
============
The default port number for the spades server is 7626, but whoever runs the
server may change this. Likewise, the default TauntServer(tm) port is 7627,
but is configurable.
String and Integer Interactions
===============================
All interactions between the client and the server consist of sending
and receiving strings and integers. I will use SendInt and SendStr to
represent sending an integer and a string.
Integers are sent as 4 byte integers, using network byte order.
Strings are sent by first sending an integer representing the length of the
string (including null terminator!), and then the characters of the string
(including nnull terminator).
Game Flow
=========
Here is C-like pseudocode for the flow of the game:
Registration
WHILE session_is_not_over
{
WHILE game_is_not_over
{
Receive Your Hand
Receive Who Leads
Bidding
FOR( i = 1 to 13 )
{
Receive Who leads
Individual Trick
Receive Updated Tallys
}
Receive Scores
}
if( client responsible for "play again" decisions )
{
Send Play Again Flag
}
Receive New Game
}
Each of the client-server interactions are listed below. For each section,
I've given a list of the exchanges which take place, followed by description
of the information to be sent/received.
Registration
============
RecvInt(Player ID)
SendStr(Player Name)
if( Player ID == 0 AND we want to set options )
{
SendInt(Option Flag)
SendInt(Option Int)
SendInt(End of Game)
SendInt(Minimum Bid)
}
SendInt(Process ID)
RecvInt(Game number)
RecvInt(Game ID)
RecvStr(Player 0 name)
RecvStr(Player 1 name)
RecvStr(Player 2 name)
RecvStr(Player 3 name)
SendInt(Player ID)
*Note:* Sending options is not mandatory and may be skipped. Only player 0
may send options, however.
Player ID: A number from 0 to 3 which represents your player number to the
server. If this number is less than 0, the server is running at maximum
capacity and cannot service your request. After each series of
communications with the server, send your ID as an "all clear" signal. Any
other number will be interpreted as an error.
Player Name: A string of at most 8 characters to represent yourself to the
other players
Option Flag: -2 indicates to the server that we wish to pass options. Any
other value will be interpreted as a Process ID.
Option Int: The least significant Byte of this int contains various game
options. The least significant bit must be set to zero, the next three bits
represent whether players 1, 2, 3 are to be human (bit value of zero) or
computer (bit value of one) players. The next two bits must be set to zero,
and the final two bits must be set to one. Here is a graphical
representation of the least significant byte:
Must be set to 1
| _______________ 0/1 for human/computer players
/\ |
| | /|\
_______________
MSBit-> | 1 1 0 0 xxx 0 | <- LSBit
---------------
| | ___/
\/ /
Must be set to 0
*Note:* Future versions of NetSpades will have more options available,
using the other bits.
End of Game: An positive integer representing at what score the game ends.
Minimum Bid: A positive integer representing the minimum team bid.
Process ID: This should be the unique Process ID of this instance of the
client. This allows the server to distinguish between multiple clients
running on a single host. The TauntServer(tm) also uses this for
authentication purposes.
Game number: This is your game number on the server. It is used with the
Game ID to identify you to the TauntServer(tm)
Game ID: The process ID of the game on the server computer. Used by client
only for authentication.
Player [1-4] name: These are the names of the four people playing NetSpades.
The players are numbered clockwise as if they were sitting at a table.
Player 0 is partnered with Player 2 and Player 1 is partnered with Player 3.
Your number is your Player ID.
Receive Your Hand
=================
13*RecvInt(Card Index)
SendInt(Player ID)
Card Index: A value from 1-52 representing a single playing card. Number
1-13 represent hearts from Ace-King, 14-26 represents clubs, and so on for
diamonds and then spades. These cards are ordered so that later you may
specify which card to play by an index 0-12. The first card you receive
corresponds to index 0.
Receive Who Leads
=================
RecvInt(Leader)
SendInt(Player ID)
Leader: A player number(0-3) indicating who bids first (and will also lead)
Bidding
========
if it's your bid...
SendInt(Your Bid)
RecvInt(Status)
otherwise...
RecvInt(Player Bid)
SendInt(Player ID)
Your Bid: A number between -1 and 13 which represents your bid. Note: this
is your own personal bid, not a collective team bid. -1 represents a bid of
Nil.
Status: A number reflecting the status of your bid attempt. Status=0 means
bid accepted. Status=-1 indicates an invalid bid (<-1 or >13). Status=-2
means that your bid, coupled with your partner's bid does not satisfy the
minimum bid requirement.
Player Bid: A number between -1 and 13 representing another players big. -1
represents a bid of Nil.
Note that the order of bidding begins with the player who will lead and then
sequentially, wrapping around if necessary. Do not try to bid when it is
not your turn.
Individual Trick
================
If it is your turn to play...
SendInt(Hand Index)
RecvInt(Status)
Otherwise...
RecvInt(Card Index)
SendInt(Player ID)
Hand Index: A number from 0 to 12 representing the index of the card which
you wish to play (the index of the card in your hand).
Status: A number reflecting the status of your attempt to play a card.
Status=0 means that you played a valid card. Status=-1 means that you
attempted to play a card which you already played. Status=-2 means that you
didn't follow suit appropriately.
Card Index: A number from 1-52 representing the card of another player.
Receive Updated Tallys
======================
RecvInt(Winner)
4*RecvInt(Player Tally)
SendInt(Player ID)
Winner: The player index (0-3) of the player who won the last trick.
Player Tally: The number tricks taken by a player. These will be sent in
order, from player 0 to player 3.
Receive Scores
==============
RecvInt(Team 0 Score)
RecvInt(Team 1 Score)
RecvInt(Game Over Flag)
SendInt(Player ID)
Team 0 Score: The score for the team consisting of players 0 and 2
Team 1 Score: The score for the team consisting of players 1 and 3
If neither score is over 500, the game will repeat from Receiving your hand.
Game Over Flag: The least significant bit of this flag represents the game
over status. If this bit is 0, the game is still going on. If this bit is
1, the game is over. The next bit is a flag indicating whether you are
responsible for deciding whether or not to play again. If this bit is 0,
you don't have to do anything extra. If this bit is 1, your client must
determine whether or not to play again, and send this information back to
the server according to Send Play Again Flag. The third bit represents
which team has won (if the game is over). 0 indicates victory for team 0,
and simlarly for team 1.
Send Play Again Flag
====================
SendInt(Play Again Flag)
RecvInt(Status)
Play Again Flag: 1 means play another game, 0 means end the session.
Status: should be 0, unless a server error occurred.
Receive New Game
================
RecvInt(New Game Flag)
SendInt(Player ID)
New Game Flag: if this flag is 1, start another game from Receiving Your
Hand. If this flag is 0, the session is over. All players (including the
one who made the decision whether or not to play again) must go through
Recieve New Game
---------------------------------------------------------------------
The TauntServer(tm)
The TauntServer(tm) works in a very similar way to the spades server. It
uses the same routines for sending and recieving intgers and strings.
All players must first register with the TauntServer(tm). If you do not
register, the other players will be able to taunnt behind your back (and we
wouldn't want that, would we?). Once registered, there are two taunting
activties, receiving a taunt, and sending a taunt.
Registration
============
SendInt(Game Number)
SendInt(Game ID)
SendInt(Player ID)
SendInt(Process ID)
RecvInt(Status)
Game Number, Game ID, Player ID, and Process ID are the numbers obtained
through registration with the spades server (see registration section
above). You _must_ therefore register with the spades server before
registering with the TauntServer(tm).
Status: an integer which is 1 if registration was sucessful and -1
otherwise.
Sending A Taunt
===============
SendInt(Game Number)
SendInt(Game ID)
SendInt(Player ID)
SendInt(Process ID)
SendStr(Taunt)
You must send the first four as "authentication" to the TauntServer(tm),
otherwise your taunt will not be accepted.
Receiving A Taunt
=================
RecvInt(Taunter)
RecvStr(Taunt)
Taunter: a number from -1 to 3, representing who is doing the taunting. A
value of -1 is a message from the TauntServer(tm) itself. A value from 0 to
3 is the player ID of the taunter. Note that your taunts will show up this
way too.
**KEY POINT** Taunts may come in at any time. It is best if you set up an
event-driven input model for them, rather than a polling approach.
|