1 |
Updated $Date$ by $Author$: |
2 |
|
3 |
Outline: |
4 |
|
5 |
This section contains a brief outline of the document. |
6 |
|
7 |
Background: List some of the background for client/server, and current state |
8 |
of affairs. |
9 |
General Socket Notes: How sockets are presently used. |
10 |
Protocol: Commands that are sent back and forth. |
11 |
Example Session: A brief example of what protocol commands would be sent |
12 |
back and forth. |
13 |
Programming notes: A few notes that can be useful for people writing clients |
14 |
are extending the server. |
15 |
Todo: Things to do in the future. |
16 |
|
17 |
Note: each section is seperated by a line of dashes. This should make finding |
18 |
a specific section easier. |
19 |
|
20 |
In order to make things a little for people doing porting, I have |
21 |
added SUMMARY comments in some of the sections. These contain a very |
22 |
brief summary of some aspect that is needed for writing the code. A more |
23 |
detailed explanation of the SUMMARY can be determined by reading the |
24 |
section. |
25 |
|
26 |
------------------------------------------------------------------------------ |
27 |
Background: |
28 |
|
29 |
Originally, the communications plan was set to be a text based system. |
30 |
These messages are what is originally detailed below (now removed). It was |
31 |
up to the server and client to parse these messages and determine what to |
32 |
do. These messages were assumed to be 1 line per message. |
33 |
|
34 |
At a reasonably early stage of developement, Eric Anderson wrote a fairly |
35 |
(but not totally) complete client/server that used his eutl package. This |
36 |
package pretty much set up packets with subpackets - these subpackets would |
37 |
have a tag for the data type, then the data itself. Thus, you could any many |
38 |
types, and after transmission, the other end could decode these commands. |
39 |
|
40 |
This works fairly well, but I think the creation of numerous sub packets has |
41 |
some performance hit. Also, the eutl was not especially well documented, |
42 |
so writing a client for a different platform became more difficult (you |
43 |
needed to first port over eutl.) An example such of this is the Java client |
44 |
currently in production. Also, Eric left to work on other products shortly |
45 |
after writing his client, which didn't really leave anyone with a full |
46 |
understanding. |
47 |
|
48 |
I have decided to remove the eutl dependancy. At least one advantage is |
49 |
that having this network related code directly in the client and server |
50 |
makes error handling a bit easier/cleaner. |
51 |
|
52 |
However, instead of a straight text method, the outside packet method is: |
53 |
<size (2 bytes)><data (size bytes)> The <size> is the size of the data |
54 |
packet, the 2 byte size for the size information is not included here. |
55 |
|
56 |
Eutl originally used 4 bytes for the size - to me, 2 bytes seems plenty (gives |
57 |
a maximum packet of 32767 - I can't see ever going beyond a few thousand, |
58 |
simply because in a fast action game, transmission size of such a packet would |
59 |
probably not make things playable.) While saving 2 bytes might not be much, |
60 |
it makes a least some sense. |
61 |
|
62 |
The actual data is something of the nature of the commands listed below. It |
63 |
is a text command, followed by possible other data. The remaining data can |
64 |
be binary - it is up to the client and server to decode what it sent. |
65 |
|
66 |
The commands as described below is just the data portion of the packet. If |
67 |
writing a new client, remember that you must take into account the size of |
68 |
the packet. there is no termination of packets, other than knowing how long |
69 |
it should be. |
70 |
|
71 |
For now, most everything that is sent is text. This is more or less how |
72 |
things worked under eutl, except it packed the ints into 4 bytes in a known |
73 |
order. In some cases, we handle ints as strings, in others, they are |
74 |
sent as binary information. How any command handles it is detailed |
75 |
below in the command description. |
76 |
|
77 |
The S and C represent the direction of the data (S->C represents something |
78 |
the server sends to the client, C->S represents something the client sends |
79 |
to the server.) |
80 |
|
81 |
In terms of all binary values, we use MSB order (same as eutl used). This |
82 |
includes the initial length information, as well as any ints or shorts that |
83 |
get sent inside the packets. All packets are defined to have at least one |
84 |
word of text, followed by a space, then followed by optional data (which can |
85 |
be binary.) |
86 |
|
87 |
Side note: Generally, the data the client sends to the server is text, |
88 |
but a fair amount of data the server sends to the client is binary. This |
89 |
has somewhat to do with who wrote what code, and also has to do that the |
90 |
S->C bandwidth is going to more the more serious limitation - the client |
91 |
generally won't be sending so much data that the its flow is much problem. |
92 |
|
93 |
Note that all the commands as detailed below are up to date descriptions |
94 |
I removed a lot of the old notes on this file, because they were |
95 |
out of date, and while might be good ideas, were not all that relevent to |
96 |
how things currently work. |
97 |
|
98 |
Summary: Packets sent back and forth have a 2 byte header (MSB order) |
99 |
which contains the length of the rest of the packet. |
100 |
|
101 |
------------------------------------------------------------------------------ |
102 |
General socket notes: |
103 |
|
104 |
We are using a TCP/IP socket. Other methods could be used, but the |
105 |
present protocol does not make very good provisions for missing data, so |
106 |
it needs to be something that corrects errors/does resends automatically |
107 |
(or just doesn't get errors in the first place.) |
108 |
|
109 |
For now, we set non blocking output on the server side. This means we don't |
110 |
have to worry about internal buffering. |
111 |
|
112 |
If the connection is lost (which will also happen if the output buffer |
113 |
overflowing), it looks like we just terminate the connection without saving |
114 |
(meaning last save takes effect.) This can certainly be abused the same way |
115 |
that currently killing the server (ie, go to treasure chamber, get all the |
116 |
treasure, kill server, wait for map to reset, play again, with you starting |
117 |
in the treasure chamber.) |
118 |
|
119 |
I don't know if there is a really good way to handle it. The other method |
120 |
would be to save the player back in town. But this then gets the situation |
121 |
of 'oops, I'm trapped', lose connection, start back in town. |
122 |
|
123 |
This is probably preferable - all you really gained there is a word of |
124 |
recall spell/scroll. Also, it doesn't really hurt the honest players who |
125 |
lost their connection for various reasons (and in fact, could be a disadvantage |
126 |
if they can't connect again until after the map resets, and they lost all |
127 |
the loot they were working on..) |
128 |
|
129 |
The server only reads data from the socket if the player has an action. |
130 |
This isn't really good, since many of the commands below might not be actual |
131 |
commands for the player. The alternative is to look at the data, and if it |
132 |
is a player command and there isn't time, store it away to be processed later. |
133 |
But this increases complexity, in that the server must start buffering the |
134 |
commands. Fortunately, for now, there are few such client commands. |
135 |
|
136 |
If it becomes a case where the client is requesting images/sounds, dual |
137 |
channels could probably be used, since requesting that data is not related |
138 |
to the actual playing of the game (or a special daemon that serves those |
139 |
requests could also be done.) |
140 |
|
141 |
SUMMARY: TCP/IP sockets are used for exchange data. Server uses non |
142 |
blocking i/o when writing to the socket, and the server only reads from the |
143 |
socket when the player actually has time for an action. |
144 |
|
145 |
------------------------------------------------------------------------------ |
146 |
Protocol: |
147 |
|
148 |
Object tags: Many of the commands below refer to 'object tags'. Whenever |
149 |
the server creates an object, it creates a unique tag for that object |
150 |
(starting at 1 when the server is first run, and ever increasing.) Tags |
151 |
are unique, but are not consistent between runs. Thus, the client can |
152 |
not store tags when it exits and hope to re-use them when it joins the |
153 |
server at a later time - tags are only valid for the current connection. |
154 |
|
155 |
I have decided to break the protocol into various sections which based |
156 |
somewhat on what the commands are for (ie, item related commands, |
157 |
map commands, image commands, etc.) |
158 |
|
159 |
****************************************************************************** |
160 |
COMMANDS RELATING TO ESTABLISHING THE INITIAL CONNECTION AND CLOSING THE |
161 |
CONNECTION |
162 |
|
163 |
C->S: version <csval> [scval [vinfo]] |
164 |
S->C: version <csval> [scval [vinfo]] |
165 |
Through the version command, the client and server exchange what |
166 |
version of the protocol they understand. Neither send this |
167 |
in response to the other - they should both send this |
168 |
shortly after a connection is established. |
169 |
|
170 |
csval is the version level of C->S communications. |
171 |
scval is the version level of S->C communications. |
172 |
vinfo is a string that is purely for informative that general |
173 |
client/server info (ie, javaclient, x11client, winclient, sinix server, |
174 |
etc). It is purely of interest of server admins who can see what |
175 |
type of clients people are using. |
176 |
|
177 |
If a new command is added to the protocol in the C->S direction, then |
178 |
the version number in csval will get increased. Likewise, the same |
179 |
is true for the scval. |
180 |
|
181 |
As far as the client is concerned, its scval must be at least equal |
182 |
to the server, and its csval should not be newer than the server. |
183 |
|
184 |
The server does not care about the version command it receives right |
185 |
now - all it currently does is log mismatches. In theory, the |
186 |
server should keep track of what the client has, and adjust the |
187 |
commands it sends respectively in the S->C direction. The server is |
188 |
resilant enough that it won't crash with a version mistmach |
189 |
(however, client may end up sending commands that the server just |
190 |
ignores). It is really up to the client to enforce versioning and |
191 |
quit if the versions don't match. |
192 |
|
193 |
scval and vinfo was added starting in 1020. Before that version, |
194 |
there was only one version sent in the version command. |
195 |
|
196 |
The version are currently integers, in the form ABCD. |
197 |
A = 1, and will likely for quite a while. This will only really change |
198 |
if needed from rollover of B. |
199 |
|
200 |
B represents major protocol changes - if B mismatches, the clients |
201 |
will be totally unusable. Such an example would be change of map or |
202 |
item sending commands (either new commands or new format.) |
203 |
|
204 |
C represents more minor but still significant changes - clients might |
205 |
still work together, but some features that used to work may now fail |
206 |
due to the mismatch. An example may be a change in the meaning |
207 |
of some field in some command - providing the field is the same size, |
208 |
it still should be decoded properly, but the meaning won't be processed |
209 |
properly. |
210 |
|
211 |
D represents very minor changes or new commands. Things should work no |
212 |
worse if D does not match, however if they do match, some new features |
213 |
might be included. An example of the would be the C->S mark command |
214 |
to mark items. Server not understanding this just means that the |
215 |
server can not process it, and will ignore it. |
216 |
|
217 |
Note: Since all 'packets' have the length as the first 2 bytes, all |
218 |
that either the client or server needs to be able to do is look at |
219 |
the first string and see if it understands it. If not, it knows how |
220 |
many bytes it can skip. As such, exact version matches should not |
221 |
be necessary for proper operation - however, both the client and |
222 |
server needs to be coded to handle such cases. |
223 |
|
224 |
Note 2: For the most part, this has been obsoleted by the |
225 |
setup command which always return status and whether it |
226 |
understood the command or not. However there are still some cases |
227 |
where using this versioning is useful - an example it the |
228 |
addition of the requestinfo/replyinfo commands - the client |
229 |
wants to wait for acknowledge of all the replyinfo commands |
230 |
it has issued before sending the addme command. However, if the |
231 |
server doesn't understand these options, the client will never |
232 |
get a response. With the versioning, the client can look at |
233 |
the version and know if it should wait for a response or if |
234 |
the server will never send back. |
235 |
|
236 |
C->S: addme |
237 |
Tells the server that it should add me (the client) to the game. |
238 |
Generally, the client will always send this command, but I suppose there |
239 |
can be actions the client wants to do before being added. |
240 |
|
241 |
S->C: addme_failed |
242 |
S->C: addme_success |
243 |
|
244 |
This are responses to the last addme command. I really think these |
245 |
should be discontinued, as they are one of the few messages which is |
246 |
just a confirmation of a previous messsage. The addme_failed should |
247 |
really be replaced with a terminate type of of message (player quits |
248 |
game, server could inform us nicely and exit out). addme_success is |
249 |
really of no use - client just throws it away. |
250 |
|
251 |
S->C: goodbye (Added in SC protocol version 1022) |
252 |
Informs the client that the server has finished transmitting data |
253 |
to the client. This is a bit cleaner than the client detecting |
254 |
a read error. In theory, a C->S of the same type could be done, |
255 |
but I don't think it would make a big difference for the server (is |
256 |
going to do the same thing regardless of a clean conection drop |
257 |
or a bad one). |
258 |
|
259 |
Also see the setfacemode command below. |
260 |
|
261 |
****************************************************************************** |
262 |
COMMANDS RELATING TO PLAYER INPUT AND OUTPUT IN THE INFO WINDOW |
263 |
|
264 |
C->S: command [count] <txt> |
265 |
command is the protocol command. It is the <txt> segment which actually |
266 |
includes the command (ie, north, fire, etc.) There should not be any |
267 |
binary data in the <txt> segment. |
268 |
|
269 |
count is an optional value for the number of objects/repeat count |
270 |
(ie, typically used for dropping, but count can be used in other |
271 |
cases) |
272 |
|
273 |
Client sends a command to the server. Ordinary commands (ie, north, |
274 |
west, apply, maps, etc), might be sent, commands with options may be sent |
275 |
(ie, 'invoke create food of booze', 'cast medium fireball'). There are a |
276 |
few special commands that can also be sent. |
277 |
|
278 |
'fire' command is a special case. The server will handle repeat firing. |
279 |
|
280 |
'fire_stop' will be sent to inform the server to stop firing. A |
281 |
different command name has been chosen to make things easier on the |
282 |
server ('fire_stop' should be a 0 time command, with the rest of the |
283 |
fire commands actually taking some time.) In some cases, 'fire_stop' |
284 |
may be sent almost immediately after the first fire (in cases where the |
285 |
player only wants to fire once). |
286 |
|
287 |
C->S: ncom <packet> <repeat> <command> |
288 |
(ncom = new command) |
289 |
This is a replacement for the 'command' above. packet is a 16 |
290 |
bit value which represents what command this is (used is |
291 |
command below). At current time, only the lowest 8 bits should |
292 |
be used (255 should be a plenty large window) - the other 8 bits |
293 |
are reserved for future flags |
294 |
|
295 |
repeat is a 32 bit value and is the repeat value. |
296 |
|
297 |
command is the actual command data (north, whatever). Notes |
298 |
under command above also apply here. |
299 |
|
300 |
S->C: comc <packet> <time> |
301 |
(comc = completed command) |
302 |
This is used in the window of the ncom command above. packet is |
303 |
the command number we just executed (16 bit binary), and time |
304 |
is a 32 bit value represent how many milliseconds the player is |
305 |
currently taking to execute commands. This information can be |
306 |
used by the client to do some throttling. |
307 |
|
308 |
C->S: reply <text> |
309 |
Sends <text> as a reply to the last query command sent. |
310 |
|
311 |
|
312 |
S->C: drawinfo <color> <text> |
313 |
Tell the client to draw whatever text in color. Color are specified |
314 |
in newclient.h, and is sent as a string. The client is free to do |
315 |
whatever it wants with the color information (which may very well |
316 |
mean ignore it.) |
317 |
|
318 |
S->C: query <flags> [text] |
319 |
Asks the client program for input. This is only used in a few places - |
320 |
mostly in creating a character and login, but in fact anyplace in the |
321 |
server that changes the input state (pl->contr->state, ST_*), should |
322 |
send a query. |
323 |
|
324 |
<flags> are detailed in the <newclient.h> file, which is common to both |
325 |
the client and server. The flags of relevance to this command are the |
326 |
CS_QUERY flags. <flags> are sent in plaintext form. |
327 |
|
328 |
The client is free to ignore the flags. However, if the server just |
329 |
wants a single character as a reply, that is all it uses, even if the |
330 |
client sends a long string (Server will use the first character.) |
331 |
|
332 |
[text] is the question/prompt that should be printed. Right now, it is |
333 |
typically just a ':'. Client should display it no matter what is is, |
334 |
however. Text is an optional field. Note - as of 0.94.2, text may |
335 |
be multi line, delimited by newlines. Client should handle this |
336 |
appropriately. |
337 |
|
338 |
C->S: toggleextendedtext <type> |
339 |
Ask the server to send extended text information for a given type. |
340 |
type is the decimal representation of an int. |
341 |
Currently supported/reserved values for types are described in drawextinfo |
342 |
|
343 |
S->C: ExtendedTextSet <type1> <type2> .... <typen> |
344 |
Tell client what actually are the extended infos server may |
345 |
send to the client when this is needed. All those infos will |
346 |
be related to the map and send through mapextended command. |
347 |
Each string represent an info which is enabled. Look |
348 |
at toggleextendedinfos and drawextinfo for details. |
349 |
|
350 |
S->C: drawextinfo <color> <type> <subtype> message |
351 |
Tell the client to draw specific text. Color are specified |
352 |
in newclient.h, and is sent as a string. The client is free to do |
353 |
whatever it wants with the color information (it may very well ignore it.) |
354 |
|
355 |
color same as color infor from S->C drawinfo |
356 |
type is an int in decimal representation, giving the type of message |
357 |
subtype is an int in decimal representation, giving subtype |
358 |
(flavor) of message. |
359 |
message is a string representation of textual message. content of message may |
360 |
very well vary depending on the type. |
361 |
|
362 |
The server will never send a message to a client with a message type not |
363 |
requested at setup by a toggleextendedinfo. Client is however encouraged to handle |
364 |
those case to catch bugs in protocols which may arise in future. |
365 |
|
366 |
It is possible a client handles a given message type but not a given subtype. |
367 |
The server does not care about the client subtype (flavors) and, so, client |
368 |
should have a 'generic representation' for each supported type, which will be |
369 |
used when a given subtype is not supported. The type are made a way subtypes |
370 |
can be considered as just visual variations (eg a scroll,a card, a letter |
371 |
and a book will share the same type) |
372 |
|
373 |
Values for types and description: |
374 |
0 reserved |
375 |
1 books |
376 |
books contains media tags in their body (TODO: document media tags) |
377 |
message has the form <title>\n<body> |
378 |
subtype represent the style of book. |
379 |
MSG_TYPE_BOOK_CLASP_1 1 |
380 |
MSG_TYPE_BOOK_CLASP_2 2 |
381 |
MSG_TYPE_BOOK_ELEGANT_1 3 |
382 |
MSG_TYPE_BOOK_ELEGANT_2 4 |
383 |
MSG_TYPE_BOOK_QUARTO_1 5 |
384 |
MSG_TYPE_BOOK_QUARTO_2 6 |
385 |
MSG_TYPE_BOOK_SPELL_EVOKER 8 |
386 |
MSG_TYPE_BOOK_SPELL_PRAYER 9 |
387 |
MSG_TYPE_BOOK_SPELL_PYRO 10 |
388 |
MSG_TYPE_BOOK_SPELL_SORCERER 11 |
389 |
MSG_TYPE_BOOK_SPELL_SUMMONER 12 |
390 |
2 cards |
391 |
3 papers |
392 |
4 signs |
393 |
5 monuments |
394 |
6 scripted dialogs |
395 |
7 motd |
396 |
no subtype, content of message is the media tag enabled motd |
397 |
|
398 |
****************************************************************************** |
399 |
ITEM MANIPULATION RELATED COMMANDS |
400 |
|
401 |
Client requests to server: |
402 |
|
403 |
C->S: move <to> <tag> <nrof> |
404 |
All parameters are integers sent in string format. <to> is where to move |
405 |
the object to, tag is the object tag, nrof is how many to move. This |
406 |
command is used to pickup/drop objects. If <to> or <tag> is zero, the |
407 |
object is being moved from/to the ground. This command is used to move |
408 |
items from a container into inventory and vice versa. if nrof |
409 |
is zero, all objects will be moved. |
410 |
|
411 |
C->S: examine <val> |
412 |
Tells the server that I want to examine object <val>, where <val> is a |
413 |
text string that represents that objects tag. Objects tags are unique |
414 |
for each object. |
415 |
|
416 |
C->S: apply <val> |
417 |
Tells the server that I want to apply the object <val>. Like examine, |
418 |
<val> is a text representation of an integer tag. |
419 |
|
420 |
C->S: lock <val><tag> |
421 |
Tells to server to set the inventory lock flag of item tag to val. |
422 |
val of 1 means that the item should be locked, 0 means unlocked. |
423 |
val is 1 byte binary, tag is 4 byte binary. The server should send |
424 |
and upditem command with new flags to reflect this change. |
425 |
|
426 |
C->S: mark <tag> |
427 |
'marks' and item for secondary usage. Some actions in crossfire |
428 |
require an action that uses another item (improvement scrolls, flint |
429 |
& steel). In order not to rely on inventory ordering or other |
430 |
gimmicks, this 'marked' item is used. Only one item can be marked |
431 |
at a time - server will only keep track of the latest mark sent. |
432 |
<tag> is a 4 byte binary value. The server will generally send a |
433 |
drawinfo command informing the player, but there is no especially |
434 |
easy way for the client to know what the marked item is (although, |
435 |
client knowing this is not strictly needed) |
436 |
|
437 |
Server updates to client: |
438 |
|
439 |
S->C: item1 <location><tag1><flags1><weight1><face1><name1><anim1> |
440 |
<animspeed1><nrof1><object2....> |
441 |
|
442 |
S->C: item2 <location><tag1><flags1><weight1><face1><name1><anim1> |
443 |
<animspeed1><nrof1><type1><object2....> |
444 |
|
445 |
Sends item information to the client. All parameters are sent as 4 |
446 |
byte ints, except for name, anim, animspeed and (in the case of the |
447 |
item2 command) type. |
448 |
|
449 |
The item1 command is an extension of the item command. It includes |
450 |
additional fields. It has replaced the item command, which is no |
451 |
longer detailed here. |
452 |
|
453 |
location is where the object is located (0=ground, any other value |
454 |
means is the tag of the object (either player or container)). This |
455 |
value is sent as 4 bytes. |
456 |
|
457 |
tag is the item tag - unique for each item (however, a tag might |
458 |
be resend, to tell the client to update some object.) |
459 |
|
460 |
flags are various flags on the item (curse, applied, etc). They are |
461 |
detailed in newclient.h It is 4 bytes |
462 |
|
463 |
weight is the weight of single one of these objects (in grams). |
464 |
The client will need to figure the total weight on its own. |
465 |
|
466 |
face is the face number. These are not guaranteed to be the same |
467 |
across different runs of the game (however, in reality, they will |
468 |
only change on the one server if they make changes to the archetypes |
469 |
and rebuild.) Some face information will be sent from the server |
470 |
to the client before actually sending a face number. |
471 |
|
472 |
name is the name of the object. The first byte of this field is the |
473 |
text length of the name. Starting at SC 1024, this name is two |
474 |
strings, with a null seperation. The first byte (length) is the |
475 |
length for both of these strings. This name information is just |
476 |
the information of what the object is called. It does not include |
477 |
how many of the items there are. |
478 |
|
479 |
anim: This is the animation sequence id to use. It is 2 bytes. |
480 |
The server will send an 'anim' command for this before sending an |
481 |
item1 command with this anim command. |
482 |
|
483 |
animspeed: How often the object should be animated. This is 1 |
484 |
byte, and is the number of ticks that should pass between each |
485 |
animation (a value of 1 means it should be animated every tick.) |
486 |
1 byte limits this to once every 255 ticks - I can't see anything |
487 |
being animated slower than that. |
488 |
|
489 |
nrof: How many objects comprise this item. This is used for |
490 |
the name field and calculating total weight. It is 4 bytes. |
491 |
|
492 |
item2 is an extension, and adds the following information: |
493 |
|
494 |
type: A numeric type id for the item. The only meaining of this |
495 |
value is really for sorting - all armors will have type values |
496 |
the same or near that each other. The client is free to ignore |
497 |
this. This value is 2 bytes. |
498 |
|
499 |
S->C: upditem <flags><tag><vals>+ |
500 |
|
501 |
This updates some item (of tag) with new values. flags determines |
502 |
what values are sent and to be updated (for a definition of the flag |
503 |
values, see the UPD_ flags in newclient.h file.) The order of the |
504 |
vals is the same as in the item command - however, as additional |
505 |
values are added (and the <flags> extended), the order will remain |
506 |
the LSB order of the flags - that is, the value associated with bit |
507 |
1 set is sent first, then bit 2, etc. |
508 |
|
509 |
The format of the values is same as the item command above. |
510 |
|
511 |
Only one item can be updated with the upditem command. An item |
512 |
command should have been sent by the server before an upditem |
513 |
command is set. |
514 |
|
515 |
S->C: delitem <tag1><tag2>... |
516 |
Tells the client to delete items with the tag values. |
517 |
|
518 |
S->C delinv <tag> |
519 |
Tells the client to delete items carried in/by the object <tag>. |
520 |
<tag> is sent as plaintext numbers. Tag of 0 means to delete |
521 |
all items on the space teh character is standing on. This command |
522 |
only affects the inventory of the object. To fully delete a |
523 |
container object, a delinv followed by a delitem should be issued. |
524 |
|
525 |
S->C addspell <tag1> <level1> <casting time1> <mana1> <grace1> <damage1> <skill> |
526 |
<path1> <name1> <display name1> <message1> <spell2 ....> |
527 |
Tells the client to add the spell(s) listed to the list of spells |
528 |
the client knows about. This will be sent at login, and again whenever |
529 |
new spells are sent. |
530 |
|
531 |
The fields are; |
532 |
<tag> - (4 bytes - int) The ID number for the spell item. This is |
533 |
going to be unique, for each spell and will be used to refer |
534 |
to it henceforth. The string form of this should also be |
535 |
appended to the cast/invoke commands in order to cast the spell. |
536 |
|
537 |
<level> (2 bytes, signed int) |
538 |
The level of the spell. |
539 |
|
540 |
<casting time> (2 bytes, signed int) |
541 |
The time it will take to cast the spell, in server ticks. |
542 |
|
543 |
<mana> (2 bytes, signed int) |
544 |
The mana cost to cast the spell (may be zero) |
545 |
|
546 |
<grace> (2 bytes, signed int) |
547 |
The grace cost to cast the spell (may be zero) |
548 |
|
549 |
<damage> (2 bytes, signed int) |
550 |
The current damage done by the spell. Note that the meaning of |
551 |
this number is to a large part spell dependent, what damage it |
552 |
actually does will depend on how the spell works. |
553 |
|
554 |
<skill> (1 byte, unsigned int) |
555 |
The skill that the spell uses to be cast, if zero, no skill is |
556 |
used in the casting of this spell. |
557 |
The numbers are the same as for request_info skill_info |
558 |
|
559 |
<path> (4 bytes, unsigned integer) |
560 |
The path that the spell belongs to. |
561 |
The client should determine the effect of this by comparing |
562 |
these values to both the spell_paths request_info data and the |
563 |
stats info concerning attunement/repulsion, etc. |
564 |
|
565 |
<face> (4 bytes, signed int) |
566 |
The number of the face that corresponds to the spell, the client |
567 |
can request this facenumber if they want to show a graphical spell |
568 |
representation. |
569 |
|
570 |
<name> (1 (non-zero) length byte, followed by that many bytes of ascii text) |
571 |
This is a name to identify the spell, which the client can use |
572 |
for display purposes, it should /NOT/ be used with the 'cast' |
573 |
command, whilst it might work, no such guarentee is made by the |
574 |
server. - Use tag instead. |
575 |
|
576 |
<message> (2 length bytes (which may be zero) followed by that many |
577 |
bytes of ascii text) |
578 |
The description of the spell. Note that this has an extra length |
579 |
byte because the messages may well be longer than 256 bytes in |
580 |
length. |
581 |
|
582 |
S->C updspell <flags><tag><vals>+ |
583 |
|
584 |
This updates some spell (of tag) with new values. The flags are 1 byte |
585 |
and determine which values have been updated, and should be re-read. |
586 |
Not all fields may be updated by this command, only those that can be |
587 |
changed. |
588 |
|
589 |
If new fields are added in future, they will extend the flags bitmask |
590 |
and the order will remain the LSB order of the flags - that is, the |
591 |
value associated with bit 1 set is sent first, then bit 2, etc. |
592 |
|
593 |
The format of the values is same as the addspell command above. |
594 |
|
595 |
Only one spell can be updated with the updspell command. A spell |
596 |
command should have been sent by the server before an updspell |
597 |
command is set. |
598 |
|
599 |
S->C delspell <tag> |
600 |
Tells the client to remove its information about the spell Tag is a 4 |
601 |
byte value, the same as the one sent when the spell was added. |
602 |
|
603 |
****************************************************************************** |
604 |
COMMANDS RELATING TO THE PLAYER OBJECT/STATS |
605 |
|
606 |
S->C: player <tag><weight><face><name> |
607 |
All fields are the same as described in item above. The only |
608 |
difference is that player tells the client that this is the central |
609 |
object it needs to care about. |
610 |
|
611 |
S->C: stats <stat1><val1><stat2><val2>... |
612 |
The is a server message that tells the client values of the various |
613 |
stats. All values are binary. that <stat> values are listed in the |
614 |
newclient.h file. All the values sent are 16 bits with these |
615 |
exceptions: |
616 |
-weight limit: |
617 |
data is 32 bits. |
618 |
-speed, weapon_sp is converted to an int first by multiply by |
619 |
FLOAT_MULTI (as defined innewclient.h) and then sent as |
620 |
32 bits. |
621 |
-range, title are sent as strings with their length preceded. The |
622 |
length is 1 byte. |
623 |
-experience: If the client uses the 'exp64' setup flag, this is sent |
624 |
as 64 bit data, otherwise, 32 bit data (with appropriate loss of |
625 |
information. To make tracking of this easier, a different stat |
626 |
type is used for 64 bit data (CS_STAT_EXP64) compared to 32 bit - |
627 |
thus, the client can know what to do based on stat type. However, |
628 |
for the run of the session, either CS_STAT_EXP64 of CS_STAT_EXP will |
629 |
get used, never both. |
630 |
|
631 |
-skill experience: this is only set if exp64 is set. This is sent |
632 |
as the skill level, followed by the skill exp (thus, 9 bytes + |
633 |
the stat type byte) |
634 |
|
635 |
-spell paths: if spellmon is set in setup, the bitmask of attuned, |
636 |
repelled and denied paths is sent. These are all 32bits |
637 |
|
638 |
****************************************************************************** |
639 |
COMMANDS RELATING TO IMAGE INFORMATION TRANSMISSION |
640 |
|
641 |
S->C: anim <num><flags><face1><face2>... |
642 |
Informs the client of an animation sequence. The client is responsible |
643 |
for animating the objects in the inventory window, and upditem |
644 |
and other items command will refer to the animation number with |
645 |
num above. All values are 2 byte binary values. |
646 |
|
647 |
<num> is the animation number we are defining. The server will only |
648 |
send the anim command for a particular <num> once per run - the |
649 |
client needs to keep track what has been sent. On new runs, |
650 |
anim commands will be resent. |
651 |
|
652 |
<flags> is currently unused, but is included because I think there |
653 |
may end up being cases were more about the animation than just the |
654 |
num and faces are needed. |
655 |
|
656 |
<face1>... is the various faces that comprise the animation |
657 |
sequence. The number of faces can be determined by checking the |
658 |
length of the packet. These values correspond in the same |
659 |
way as all referances to face do. |
660 |
|
661 |
Note that how fast the object is animated is contained in the |
662 |
item commands. |
663 |
|
664 |
S->C: pixmap <face><len><data> |
665 |
Sends xpm version of an image to the client. All data is in binary |
666 |
form (4 byte for face & len). <face> is the face number. <len> is |
667 |
the length of data, and <data> is the xpm data itself. |
668 |
|
669 |
S->C: bitmap <face><fg><bg><data> |
670 |
Sends a bitmap version of an image to the client. <face> is the face |
671 |
number (4 bytes), <fg> and <bg> are 1 byte, and determine the |
672 |
foreground and background colors. <data> is 72 bytes of data. |
673 |
(Images are 24x24, but you get 8 bits/byte, so 24*24/8 = 72) |
674 |
|
675 |
S->C: image <face><len><data> |
676 |
S->C: image2 <face><set><len><data> |
677 |
Command added in SC version 1023. |
678 |
This command is much the same as the pixmap command above. face |
679 |
and len are 4 binary bytes. Data is the png data used to |
680 |
the image. |
681 |
|
682 |
If the client has requested a specific faceset, then the |
683 |
image2 command will be used. This includes the faceset the |
684 |
image belongs to (8 bit data). |
685 |
|
686 |
There is no image1 command. Image2 was used to keep the versionin |
687 |
in sync with the face2 command below. It is also more intuitive |
688 |
as in the server, the image2 flag is used to determine if we are |
689 |
using these new commands. |
690 |
|
691 |
S->C: face <num><name> |
692 |
S->C: face1 <num><checksum><name> |
693 |
S->C: face2 <num><setnum><checksum><name> |
694 |
Informs the client that <num> (binary short) is associated with |
695 |
<name>. This is used when the client is caching images. In normal |
696 |
operation, when the server runs accross a face that it hasn't sent |
697 |
the client, it sends a pixmap or bitmap for that face. If the face |
698 |
mode is none, the server then sends this command. The client can |
699 |
then check to see if it might have cached this face, and if not, |
700 |
should then request it from the server. Note that the num to name |
701 |
mappings can change between server and different runs of the |
702 |
server. For this reason, this data needs to be sent each |
703 |
time run. The client should be able to load/determine what face |
704 |
to load via the name. |
705 |
|
706 |
In sc version 1026 and later, the server will use the face1 command |
707 |
which include a checksum that is a 32 bit value. This can be used by |
708 |
the client to know if its face is up to date. The checksum is a 32 |
709 |
bit unsigned value. If the client reports a sc_version of 1025 |
710 |
or earlier, the server will use the face command not not face1. |
711 |
|
712 |
The face2 command is used if the client has sent used the |
713 |
faceset setup command. This is the same as the face1 command, |
714 |
except we also include what faceset the image belongs to. This |
715 |
lets the client has multiple image sets installed and still |
716 |
be able to cache properly. setnum is 8 bit binary data. |
717 |
|
718 |
C->S: setfacemode <val> |
719 |
This tells the server what type of display mode the client is using. |
720 |
<val> is a plaintext integer. 0=no faces, 1=bitmap, 2=xpm (pixmap). |
721 |
3=png (added in CS version 1022) |
722 |
If the 5'th bit is true (ie, 0x10 & val is true), that then informs |
723 |
the server that client is caching the images, and only send image |
724 |
names. |
725 |
This command is depreciated, as the only type of images currently |
726 |
supported is PNG. The client should instead use the setup command |
727 |
to request if it wants to cache images or not. |
728 |
|
729 |
C->S: askface <num> |
730 |
Requests that the server send the client face <num>. It will rely |
731 |
on the previous set facemode to determine what facetype to send. |
732 |
num is a plaintext integer. |
733 |
|
734 |
S->C: smooth <facenbr><smoothpic> |
735 |
All parameters are short int in binary form (2 bytes each) |
736 |
This command informs the client on how to smooth a face, when it will need it. |
737 |
Following are the facenbr of the picture involved in the |
738 |
smoothing algorithm. See doc on smoothing on how to use them. |
739 |
This info may be send automatically from server if client has |
740 |
smoothing enabled but may also be requested by client using |
741 |
the asksmooth command below |
742 |
C->S: asksmooth <facenbr> |
743 |
Parameters is a plain text integer. |
744 |
Ask server to send a smooth sequence. Server will respond with a smooth command. |
745 |
<facenbr> is an integer telling server which face we want smooth informations on. |
746 |
|
747 |
****************************************************************************** |
748 |
MAP UPDATE COMMANDS |
749 |
|
750 |
S->C: map <ecell1><ecell2>...<255>[<face1><cell1...><face2><cell2...>] |
751 |
Sends a map to the client. All cell type values are stored as |
752 |
x*mapy+y. Thus, we can fit the map coordinates into 1 byte up to |
753 |
a mapsize of 11x11. (this size is limited by needing to set |
754 |
the high bit) |
755 |
|
756 |
<ecell1><ecell2>... is a list of cells that are empty. This list |
757 |
could be empty. 255 is used to mark the end of this list, whether |
758 |
anything is included or not. Note that the max xy hash value is |
759 |
121, so we never need to worry about this value appearing as a map |
760 |
cell. |
761 |
|
762 |
the face values are 16 bit values representing the face for that |
763 |
space. Like other data, they are stored MSB first. The MSB of |
764 |
the last face in a layer has the high bit set. this makes the max |
765 |
theoretical face number that is supported to 32767 (old code says |
766 |
16383, but that certainly does not seem right). It would seem that |
767 |
a marker of 0xff could be put at the end of a layer, and only cost |
768 |
a byte, but at present, that doesn't seem really important. |
769 |
|
770 |
<cell1...> is a list of cells that use this face. The last face in |
771 |
this list has the high bit set. Being the max cell value is 121, |
772 |
this does does not pose a problem. This cell list is only for the |
773 |
current layer. |
774 |
|
775 |
The section in brackets ([]) represent data that is sent for each |
776 |
layer. At present time, only 3 layers are supported, but in theory, |
777 |
any number could be. It is up to the client to detect the end of |
778 |
one layer, and know to put the next information a layer down. |
779 |
|
780 |
Note: The server does try to do some intelligence in only sending data |
781 |
that has changed and packing repetative data. Thus, the server doesn't |
782 |
send a full map each tick, only a portion of the map. Worst case |
783 |
data scenario right now is roughly 1100 bytes of data sent (a very |
784 |
unlikely scenario - it assumes 3 images per space and no redundant |
785 |
images. |
786 |
|
787 |
Note: The map command may get depreciated and instead replaced by |
788 |
the map1 command below. While the map1 command needs 2 bytes for |
789 |
coordinates, it is smarter for other updates, so may not in |
790 |
face use more bandwidth. |
791 |
|
792 |
S->C: map1 <coord1>[darkness1][face1a][face1b][face1c]<coord2>[darkness2][face2a]... |
793 |
S->C: map1a <coord1>[darkness1][face1a][face1b][face1c]<coord2>[darkness2][face2a]... |
794 |
|
795 |
This is an update of the map command to support large map sizes. |
796 |
The old map command supported a maximum map size of 15x15 - |
797 |
anything larger than that required a new command. |
798 |
|
799 |
Given that this larger map now needs 2 bytes for the coordinates - |
800 |
the same as for the images, trying to optimize one vs the other |
801 |
does not makes much sense. |
802 |
|
803 |
The map1a is an enhancement to the map1 command. |
804 |
|
805 |
All data is in standard binary form. |
806 |
|
807 |
the coord values are flags + x + y values. The value itself, but |
808 |
the data represented looks like this: |
809 |
first 6 bits: The x coordinate |
810 |
next 6 bits: the y coordinate |
811 |
last 4 bits: MSB - true if we send darkness |
812 |
MSB-1 - will send floor face |
813 |
MSB-2 - will send intermediate face |
814 |
MSB-3 (aka LSB) - will send top face |
815 |
|
816 |
6 bits is enough for 63x63 maps. For the time being, it should |
817 |
be a safe assumption that we won't be sending anything larger |
818 |
than that. |
819 |
|
820 |
Through the use of this bitmasks, any and all of the following values |
821 |
may be optional. This allows the update of one face on the space |
822 |
without needing to send the others (in the old map command, this is |
823 |
not possible, so as an arrow flies over a space, the floor + arrow |
824 |
needs to get resent - this allows just the arrow to get sent). |
825 |
This should conserve bandwidth when spells are cast (we have an |
826 |
extra byte for the coordinate, but save 2 bytes for the image |
827 |
itself, plus another 2 potential bytes if there is something on the |
828 |
space.) |
829 |
|
830 |
If all the flag values are 0, this then means the space is considered |
831 |
blocked from view, and should be drawn as black. This conserves |
832 |
bandwidth for sending blocked spaces, which occur pretty frequently. |
833 |
Once a space is marked as block, if it re-appears within view, the 3 |
834 |
layers should be marked is blank. |
835 |
|
836 |
For spaces that are empty, one or more of the faces will be sent as |
837 |
blank faces (exactly how many will depend on what was on the floor |
838 |
before - for example, if a floor disappears, then only the floor needs |
839 |
to get updated, but if there was stuff on the floor, then that face |
840 |
will also need to get cleared). There may be cases where |
841 |
transitioning from the blocked to empty space occurs, in which case |
842 |
the server will send the floor as an empty space. |
843 |
|
844 |
The darkness value is a single byte - 0 is pitch black, while 255 is |
845 |
fully illuminated. It is up to the client to figure out what it wants |
846 |
to do with this (use masking to reduce visibility, or actually do a |
847 |
real light reduction on the image). |
848 |
|
849 |
The face values are 16 bit values, as before. They will be sent |
850 |
in MSB order of the flag (ie, floor, then intermediate, then |
851 |
top, presuming the bit in the flag is set that says that layer |
852 |
is being sent). Blank faces may get sent if an object disappears - |
853 |
in the example of the flying arrow, for the space the arrow |
854 |
leaves, a blank face will be sent in place of the arrow. Blank faces |
855 |
will be sent as face 0. |
856 |
|
857 |
Map1a refinements: |
858 |
|
859 |
The main addition to the map1a command is handling of big images. Big |
860 |
images are those images that do not fit in one space, eg, if a store |
861 |
is combined into 1 64x64 image, this falls into a big image. The |
862 |
archetype/object of a big image has the same face for all the spaces. |
863 |
|
864 |
When the server detects such an object, it only sends the face for the |
865 |
lower right corner. The client then needs to extrapolate where this |
866 |
should be drawn. By only sending the lower right, the client can much |
867 |
more easily handle tall objects. The sending of a big image face is |
868 |
no different in either the map1 or map1a command. |
869 |
|
870 |
The main difference in the map1a command is what to do when the lower |
871 |
right corner would not normally be visible to the client (blocked, |
872 |
darkness, or off the edge of the map). The map1 command will just not |
873 |
send any data - thus, even if some part is visible, it won't be sent. |
874 |
The map1a command will send this big face for such squares even if |
875 |
that square is not visible. It only sends this information if some |
876 |
other part of the object is visible (eg, top portion). Also, for such |
877 |
spaces, it only sends the big face number, and not any other faces |
878 |
that may be on that space. The map1a command will also send |
879 |
coordinates outside the normal map size. For example, the player |
880 |
selected a 25x25 map size. There is a big image (3x3) whose left side |
881 |
is just at the edge of the players map (upper corner of it at 25,18). |
882 |
The server will send this face at 27,20 - the lower right space of |
883 |
this big image. |
884 |
|
885 |
The server tries to keep the same layer for the head as what appears |
886 |
on the map. Thus, a 2x2 store would normally be on layer 2 (with |
887 |
layer 1 being the grass, stone, whatever). In such a case, even if |
888 |
the lower right corner was not visible, it will send the big face at |
889 |
layer 2 on that space. There can be spaces in which a big image is on |
890 |
different layers on different spaces - in that case, if the lower |
891 |
right is visible, the layer it appears on there will be used. |
892 |
Otherwise, the layer of the first visible space it appears on |
893 |
(starting from upper left) will be used. |
894 |
|
895 |
The server does remember the heads for out of normal map bounds. |
896 |
However, these values are not shifted but cleared when the map scrolls. |
897 |
Taking the example of an image at 27,20 above, if the player moves to |
898 |
the east, the server will send the map scroll command, send the face at |
899 |
26,20, and send neither a clear nor update for 27,20. When the player |
900 |
moves east again, the image is now on the normal map at 25,20, and |
901 |
will once again get sent, no delete for 26,20 will be sent. |
902 |
OTOH, if the object was a living object and was partially off the |
903 |
map when killed, an update removing that face for the object it was |
904 |
standing on will be sent by the server. |
905 |
|
906 |
Various notes about the map1 command: |
907 |
|
908 |
this implementation is much simpler than the map command |
909 |
because it now works on spaces rather than layers, and most all the |
910 |
code also works on spaces. |
911 |
|
912 |
The downside of this is that this will need to get redone |
913 |
if we want to put more than 3 faces on a space (as we are then |
914 |
out of bits). It would be trivial to do something different, like |
915 |
send as many faces as desired and just have a marking tag at the |
916 |
end - the problem with this is that if something changes, |
917 |
then once again, you need to send the entire space as there is |
918 |
no way to say 'face xyz has disappeared'. And in any case, to |
919 |
support more faces will require more work on the server. |
920 |
|
921 |
|
922 |
S->C: map2 <coord1><len1/type1><data1><len2/type2><data2>...<coord2> |
923 |
|
924 |
NOTE: THIS IS ONLY A PROPOSAL. This is not currently implemented. |
925 |
Mail has been sent to the mailing list |
926 |
|
927 |
This is an update of the map1 commands above. It is meant to be |
928 |
extensible. It is also meant to incorporate the ideas of the |
929 |
extended map info command. |
930 |
|
931 |
All data is in standard binary form. |
932 |
|
933 |
The coord value is 16 bites. |
934 |
|
935 |
the coord values are length + x + y values. |
936 |
The data represented looks like this: |
937 |
|
938 |
first 5 bits: The x coordinate (0-31) |
939 |
next 5 bits: the y coordinate (0-31) |
940 |
last 6 bits: the number of type/data pairs to follow (0-63). While |
941 |
a limit of 63 data encodings is hard coded, I can't forsee reaching |
942 |
that limit anytime soon - remember, this is the number of type/data |
943 |
pairs that are sent for this space - there could be cases where there |
944 |
are 300 things on the space, but if we are only sending 63 of them |
945 |
this is also fine. |
946 |
|
947 |
<len/type> This is a single byte of data. |
948 |
This describes the data that is to follow. |
949 |
|
950 |
The top 3 bits (len) denote the number of bytes that follow - it is |
951 |
possible that this is zero, to denote all the relevant information is |
952 |
included in the type. If this is 7 (all bits set) then the following |
953 |
byte is an additive length value. |
954 |
|
955 |
The bottom 5 bits is the type of data - this allows for 31 different |
956 |
types of data (0-31/0x0-0x1f). The meaning of the data itself depends |
957 |
on what the type is. List of various types: |
958 |
|
959 |
0x0: Denotes this space should be cleared. Length in this case should |
960 |
also be zero, as there is no data that follows. |
961 |
|
962 |
0x1: Darkness information - typically a single byte follows that |
963 |
denotes how dark the square is. |
964 |
|
965 |
0x2: Sound? |
966 |
|
967 |
0x10-0x17: Image information - 2 or 3 bytes follow, which is the image |
968 |
for the particular layer. Layer 0x10 is the lowest, 0x17 is the |
969 |
highest. If 3 bytes follow, the first byte is smoothing |
970 |
information, followed by 2 bytes for the face. If only 2 bytes |
971 |
follow, then this is only the face. The number of bytes that |
972 |
follow is determined by the len field above. |
973 |
|
974 |
Some notes: |
975 |
|
976 |
Coordinates outside the viewable map may |
977 |
be sent. In these cases, it means that a big image that extends onto |
978 |
the viewable map is on that space. For big images, only the bottom |
979 |
right coordinate is sent - this is why it may be off the viewable |
980 |
coordinates. For such spaces, only the actual big image itself will |
981 |
be sent for that space. |
982 |
|
983 |
Note that unless the 0x0 code to clear the space is sent, all |
984 |
operations are considered updates to the space (eg, new image, new |
985 |
light level, etc) |
986 |
|
987 |
Relative to the map1/map1a commands, this is more bandwidth intensive - |
988 |
basically, an additional byte is needed for each piece of data sent. |
989 |
Thus, on a 25x25 map, if we presume 1.5 objects/space, this is |
990 |
an extra 940 bytes to send. OTOH, typically the entire map |
991 |
is not being sent - only those bits that change, so this may not |
992 |
be as costly as that. |
993 |
|
994 |
If the player is using smoothing, this may actually save bytes, |
995 |
as the redundant coordinates and type/length information |
996 |
does not need to be sent. With the map2 command, the mapextend |
997 |
command is deprecated and is not used. |
998 |
|
999 |
|
1000 |
|
1001 |
|
1002 |
S->C: map_scroll <dx> <dy> |
1003 |
This tells the client to scroll the map dx and dy direction. dx and |
1004 |
dy will typically be -1, 0, or 1, depending on how the player moved. |
1005 |
<dx> and <dy> are sent as plaintext. positive values are down and to |
1006 |
the right respectively, negative values are opposite. |
1007 |
|
1008 |
C->S: mapredraw |
1009 |
Requests that the server resend the entire map to the client - |
1010 |
can be useful if the client or client player knows that the map |
1011 |
is out of date/corrupted. |
1012 |
|
1013 |
S->C: newmap |
1014 |
This tells the client to clear the map state. This command will be sent |
1015 |
only if negotiated by the newmapcmd option. |
1016 |
|
1017 |
S->C: magicmap <width> <height> <px> <py> <data> |
1018 |
This gives the client information from a magic map command. |
1019 |
<width> <height> and text integers of the size. <px> <py> is |
1020 |
the players location, and data is binary data of the |
1021 |
appropriate color. It is 1 byte per space, with the low |
1022 |
nibble containing the color information, and the high nibble |
1023 |
containing extra flags, like the existance of walls and floors. |
1024 |
See the FACE_FLOOR and FACE_WALL values. |
1025 |
The string of data represents the space from left to right, |
1026 |
then up to down. |
1027 |
|
1028 |
C->S: toggleextendedinfos <string1> <string2> .... <stringn> |
1029 |
Ask the server to send some additionnal informations about the map. |
1030 |
This command is followed by 1 or more strings. String are separated |
1031 |
with spaces. Each string toggle an info. The server will respond |
1032 |
with the command ExtendedInfoSet telling client what actual |
1033 |
extended infos will be send to the client. |
1034 |
Valid extended infos are as follow: |
1035 |
smooth |
1036 |
send smoothlevel informations to the client. |
1037 |
|
1038 |
S->C: ExtendedInfoSet <string1> <string2> .... <stringn> |
1039 |
Tell client what actually are the extended infos server may |
1040 |
send to the client when this is needed. All those infos will |
1041 |
be related to the map and send through mapextended command. |
1042 |
Each string represent an info which is enabled. Look |
1043 |
at toggleextendedinfos and mapextended for details. |
1044 |
|
1045 |
S->C: mapextended <what><length><coord1>[data1a][data1b][data1c]<coord2>... |
1046 |
This command is send from server when there is at least |
1047 |
1 ExtendedInfo activated using toggleextendedinfos and |
1048 |
the client called setup extendedMapInfos 1 (see setup command). |
1049 |
Basically this command is made of a block telling what infos comes |
1050 |
with this command, a block telling what length this info is and then |
1051 |
the infos themselfes. Here is described more in details those blocks. |
1052 |
<what> (uses N bytes) |
1053 |
How to know N? |
1054 |
In each byte, if the highest bit (bit 7) is set, this mean |
1055 |
another byte will follow. This would allow easy extension of protocol |
1056 |
without breaking client and needing a new command. |
1057 |
Here is described, for each byte, the signifiance of the bits: |
1058 |
Byte 0: |
1059 |
bit 0 EMI_NOREDRAW |
1060 |
Tells the client it's useless to redraw screen immediatly, |
1061 |
another map command will follow. |
1062 |
bit 1 EMI_SMOOTH |
1063 |
Tells the client there is datas in the [datas] blocks about |
1064 |
smoothing. |
1065 |
bit 7 EMI_HASMOREBITS |
1066 |
Tells the client to read the next byte as part of the <what> |
1067 |
block too. See above signifiance of higher bit. |
1068 |
<length> (uses 1 byte) |
1069 |
A one byte info describing the size (in bytes) of each data block. So |
1070 |
each data block may have a size of 0 to 255 bytes. Note that all data blocks |
1071 |
send in one mapextended command have the same size but different |
1072 |
mapextended commands may have different blocksize, even with same datas |
1073 |
present. |
1074 |
Following is a set of blocks made of a <coord> and 0 to 3 <data> |
1075 |
<coord> (uses 2 bytes) |
1076 |
This is the same as for the map1 and map1a commands, except the darkness bit |
1077 |
is reserved for future use. If it is set to 1, the next byte will be part |
1078 |
of the coords too (for larger visible map, but not used yet). |
1079 |
<data> (uses <length> bytes) |
1080 |
the coord block tells the client which square is concerned and which layers |
1081 |
in this square are concerned. According to this there may be up to 3 <data> |
1082 |
blocks following the <coord> block (same as for map1 and map1a). Ok, now |
1083 |
what stand in those <data>? |
1084 |
First each <data> block has a length determined by the <length> block. So |
1085 |
if ther are parts of the data the client may not understand, it's ok, he will |
1086 |
skip to the end of the <data> block, jumoing to the next. Should help add |
1087 |
additionnal informations. Since the protocol evolved as on timeline basis. |
1088 |
If a client can't understand a data type cause it is too old, he won't |
1089 |
understand the next one too, etc, until the next <data> block is reached. |
1090 |
So to prevent problem, the server take care to put informations in the data |
1091 |
block following the order of protocol evolution. If server need to |
1092 |
say to the client A BB C, assuming that A was defined in the |
1093 |
protocol before BB was defined which was before C was defined, it would say |
1094 |
ABBC and never ACBB. Now let's say later a developper want to extend BB to BBB, |
1095 |
the server should put the datas in the following order: ABBCB cause the last B |
1096 |
is more recent in protocol than the 2 first BB and the C. All this make sure |
1097 |
there will be no mistakes or conflict between different protocol versions. |
1098 |
Ok, following is the informations which may be present in a <data> block if |
1099 |
the corresponding flags are put. |
1100 |
|
1101 |
if EMI_SMOOTH is present in <WHAT> |
1102 |
1 byte telling the smoothlevel of the object at <coord> |
1103 |
see developper notes on smoothing to know what this means. (TODO) |
1104 |
|
1105 |
<data> stops here for now. Later there will be datas for sending text from |
1106 |
a specific location, telling client to play special effects, etc. |
1107 |
gime some time |
1108 |
Tchize. |
1109 |
|
1110 |
|
1111 |
****************************************************************************** |
1112 |
SOUND RELATED COMMANDS: |
1113 |
|
1114 |
C->S: setsound <val> |
1115 |
<val> is a plaintext integer. Current supported values are 0 and 1. |
1116 |
0 says that the client does not want sounds, 1 says it does want |
1117 |
sound information. By default, the server does not send sound |
1118 |
information. |
1119 |
Note that the player can use the 'sound' command once the game |
1120 |
is started to control future sound transmissions. However, if |
1121 |
the client was not started with sound support, the necessary |
1122 |
initialization of the sound device might not have happened. |
1123 |
However, if the client started with sounds enabled, the user can |
1124 |
certainly disable future sounds. |
1125 |
|
1126 |
S->C: sound <x><y><num><type> |
1127 |
Informs the client to play a sound. All arguments are binary data. |
1128 |
x,y are signed 1 byte values which are offsets from the player. |
1129 |
num is the sound number stored as a short (16 bit). |
1130 |
(IT is up to client to determine which sound to |
1131 |
play based on that.) Since sound numbers seldom change (and in fact, |
1132 |
new sounds will have a higher number than the old sounds - old |
1133 |
sounds numbers will not change in meaning like what can happen with |
1134 |
the images), this should not be much of a problem. |
1135 |
type is a 1 byte value which determines sound type. Currently, 0 |
1136 |
is normal sound, 1 is spell sound. This may be extended in the |
1137 |
future. |
1138 |
|
1139 |
****************************************************************************** |
1140 |
MISC COMMANDS: |
1141 |
|
1142 |
C->S: lookat <dx> <dy> |
1143 |
Client (player) is looking at space dx,dy. dx and dy are delta |
1144 |
offsets from the player (client doesnt know where the player is |
1145 |
on the map, so this is the only real way to deal with it.) dx |
1146 |
and dy plaintext integers. This is only a request to the |
1147 |
server - a response will typically come back in drawinfo commands. |
1148 |
|
1149 |
C->S |
1150 |
S->C: setup <option1> <value1> <option2> <value2> |
1151 |
Client first sends a setup command to the server to request a change |
1152 |
in some value (option1). |
1153 |
|
1154 |
The following options are supported: |
1155 |
|
1156 |
sound |
1157 |
Set to true if the client wants to get sent sound information. |
1158 |
This is an integer in string form (0/1). |
1159 |
|
1160 |
exp64: If true, client can handle the 64 bit exp values that |
1161 |
are now used. Otherwise, values are sent as 32 bit. Setting |
1162 |
this flag also means that skill exp will be sent, and it will |
1163 |
be sent in revised method as described in the stats command. |
1164 |
Value is an integer in string format. |
1165 |
|
1166 |
sexp (send skill experience): |
1167 |
Obsolete - was used to denote that client wanted skill exp |
1168 |
sent. Under revised skill system, this info just doesn't |
1169 |
exist anymore in the same form. |
1170 |
|
1171 |
map1cmd: parameter is an integer in string form like above. |
1172 |
this requests the server to use/not use the map1 protocol |
1173 |
command. Note that if the map size is greater than 11 in either |
1174 |
direction, the server will use the map1 protocol command no |
1175 |
matter what. This parameter can be useful if the client wants |
1176 |
the map1 protocol command for smaller maps because of the |
1177 |
the additional information provided. |
1178 |
Note that the server will return the mode it will be using |
1179 |
when it sends back the setup command, and not necessarily |
1180 |
what the client requests. Thus, if the mapsize is 15x15, |
1181 |
and the client does a 'setup map1cmd 0', the server will |
1182 |
send back a 'setup map1cmd 1' because it will still end up |
1183 |
using the map1cmd due to the map size. |
1184 |
|
1185 |
itemcmd (1/2): |
1186 |
Defines the revision of the item command that will be used to send |
1187 |
information about objects. If set to 1 (the default) item1 commands |
1188 |
will be sent. If set to 2, item2 commands will be sent. This may in |
1189 |
future accept extra values beyond these two. |
1190 |
|
1191 |
darkness (0/1 value): |
1192 |
If set to 1 (default), the server will send darkness information |
1193 |
in the map protocol commands. If 0, the server will not |
1194 |
include darkness, thus saving a minor amount of bandwidth. |
1195 |
Since the client is free to ignore the darkness information, |
1196 |
this does not allow the client to cheat. In the case of the |
1197 |
old 'map' protocol command, turning darkness off will result |
1198 |
in the masking faces not getting sent to the client. |
1199 |
|
1200 |
mapsize x X y |
1201 |
Sets the map size to x X y. Note the spaces here are only for |
1202 |
clarity - there should be no spaces when actually sent (it |
1203 |
should be 11x11 or 25x25). The default map size unless changed |
1204 |
is 11x11. The minimum map size the server will allow is 9x9 |
1205 |
(no technical reason this could be smaller, but I don't think |
1206 |
the game would be smaller). The maximum map size supported in the |
1207 |
current protocol is 63x63. However, each server can have its |
1208 |
maximum map size sent to most any value. |
1209 |
|
1210 |
If the client sends a mapsize command out of valid range, the |
1211 |
server will respond with a mapsize with the maximum size |
1212 |
the server supports. Thus, if the client wants to know the maximum |
1213 |
map size, it can just do a 'mapsize 0x0' and it will get the |
1214 |
maximum size back. |
1215 |
|
1216 |
The server will only set the mapsize for the client if both x & y values |
1217 |
are valid. For example, if the maximum map size is 25x25, and the |
1218 |
client sends a 31x23 mapsize request, the mapsize will remain at |
1219 |
11x11 (default) and the server will send back a mapsize 25x25 |
1220 |
setup command. |
1221 |
|
1222 |
When the values are valid, the server will send back a mapsize |
1223 |
XxY setup command. Note that this is from its parsed values, |
1224 |
so it may not match stringwise with what the client sent, but will |
1225 |
match 0 wise. For example, the client may send a 'mapsize 025X025' |
1226 |
command, in which case the server will respond with a |
1227 |
'mapsize 25x25' command - the data is functionally the same. |
1228 |
|
1229 |
While the server in theory supports non square viewing regions, |
1230 |
this has not be tested. |
1231 |
|
1232 |
newmapcmd (0/1) |
1233 |
This tells the server if the client understands the newmap |
1234 |
protocol command. This is used by the client in the fog |
1235 |
of war mode to receive newmap commands from the server each time |
1236 |
the player changes maps. |
1237 |
|
1238 |
facecache (0/1) |
1239 |
Determines if the client is caching images (1) or wants the |
1240 |
images sent to it without caching them. This replaces the |
1241 |
setfacemode command. |
1242 |
|
1243 |
faceset (8 bit) |
1244 |
Faceset the client wishes to use. If the faceset is not |
1245 |
valid, the server returns the faceset the client will be |
1246 |
using (default 0). |
1247 |
|
1248 |
extendedMapInfos (0/1) |
1249 |
Toggle sending from server of extended map informations. |
1250 |
What lies in this extended info depended on what extended |
1251 |
infos the client asked. See ToggleExtendedInfos command for details. |
1252 |
|
1253 |
extendedTextInfos (0/1) |
1254 |
Toggle sending from server of extended text informations. |
1255 |
What lies in this extended info depended on what extended |
1256 |
infos the client asked. See toggleextendedtext command for details. |
1257 |
|
1258 |
spellmon (0/1) |
1259 |
If set to 1 the client has indicated that it wishes to be |
1260 |
sent the spell list and updated when it changes. |
1261 |
|
1262 |
All data in the setup command is in ascii text form. options and |
1263 |
values can not have whitepace - the client and server use whitspace |
1264 |
to split the options and values. |
1265 |
|
1266 |
Currently (2001-05-28), the server only sends a setup in response to |
1267 |
client first having sent a setup command. |
1268 |
|
1269 |
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1270 |
This section describes the requestinfo and replyinfo commands. |
1271 |
Because these commands may handle different types of data with different |
1272 |
return formats, this section is formatted a bit differently to make |
1273 |
it easier to read the different structures. |
1274 |
|
1275 |
C->S: requestinfo <info_type>[options] |
1276 |
S->C: replyinfo <info_type>[options]<data> |
1277 |
|
1278 |
The requestinfo command is a general purpose way for the client to request |
1279 |
some piece of data the server may have. The server still needs to be |
1280 |
coded to respond to the specific info_type, but if the passed info_type is |
1281 |
not supported, the server will still respond with the replyinfo, but with |
1282 |
an empty data list. |
1283 |
|
1284 |
This mechanism allows the client to send requests for data and not need to |
1285 |
do complicated checking if the server would understand the specific |
1286 |
request - if the server understands it, the data gets sent back. If the |
1287 |
server doesn't understand it, the client gets no data, but does get the |
1288 |
replyinfo so that it knows that the server does not support that |
1289 |
particular aspect. |
1290 |
|
1291 |
Only one info_type is allowed for each requestinfo. If the client |
1292 |
requests many pieces of information (say image sets available, spell |
1293 |
listings, etc), it should send multiple requestinfos. |
1294 |
|
1295 |
[options] is specific to the info_type - it could be a range of values, or |
1296 |
empty. |
1297 |
|
1298 |
Requestinfo requests will not change any data on the server - the setup |
1299 |
command should be used for that. The requestinfo just requests data. |
1300 |
Note that since the requests can be made before a player logs in, the |
1301 |
requestinfo command will not generally support getting information related |
1302 |
to the player object. |
1303 |
|
1304 |
The following info_types are supported: |
1305 |
|
1306 |
image_info: |
1307 |
'image_info' (no options): |
1308 |
|
1309 |
Request basic image information the server has. The data is sent in |
1310 |
text format - the replyinfo is newline terminated. Since the packet |
1311 |
length is sent in the header, that is used to figure out the length of |
1312 |
returned data. |
1313 |
|
1314 |
Line 1: The last image number the server has. Note that there is |
1315 |
no image 0, so this also amounts to the number of images |
1316 |
if you start counting from one. |
1317 |
|
1318 |
Line 2: checksum of all the image name information. This can |
1319 |
basically be used to determine if the number to name mapping is |
1320 |
the same, eg, if on server 1 the total is 123456, and the player |
1321 |
goes to server 2 and the total is the same, we can say with a high |
1322 |
degree of confidence that the name to number mappings are the name. |
1323 |
If instead the numbers differ, we know we can't rely on using the |
1324 |
same mappings. |
1325 |
|
1326 |
Line 3+:The image set information the client has. The format |
1327 |
is the same as the format in the image_info file, sans comments. |
1328 |
The server will ignore any parameters the client sends. |
1329 |
|
1330 |
An examply response: |
1331 |
|
1332 |
replyinfo image_info |
1333 |
3512 |
1334 |
1169234 |
1335 |
0:base:standard:0:32x32:none:The standard image set. |
1336 |
1:clsc:classic:0:32x32:none:Classic and new styling. |
1337 |
|
1338 |
|
1339 |
image_sums <start> <stop> |
1340 |
|
1341 |
Request the image number to name (and checksum) values - in this way, |
1342 |
the client can build all images before play starts and also request |
1343 |
any missing images. The returned data is |
1344 |
|
1345 |
image_sums <start> <stop> <imagenum><checksum><faceset><namelength><name> |
1346 |
|
1347 |
There is an initial space after the stop value, but no spaces after |
1348 |
that point. The <start> and <stop> values are ascii text (same |
1349 |
format as it is sent to the server in). The start and stop |
1350 |
values are inclusive - thus, if the start is 0 and the stop |
1351 |
is 100, 101 checksums will be set. |
1352 |
|
1353 |
imagenum is 16 bit binary data. |
1354 |
checksum is 32 bit binary data. It contains the checksum for |
1355 |
the image in the current selected set, and will use whatever |
1356 |
fallback logic the imagesets specify. |
1357 |
faceset is 8 bit binary data. |
1358 |
namelength is 8 bit binary data. It is the length of the |
1359 |
name field below, including the null terminator. |
1360 |
name is chraracter data. It is null terminated to make processing |
1361 |
easier - in this way, the client doesn't need to copy the data |
1362 |
to make it null terminated. |
1363 |
|
1364 |
Note that due to possible OS system constraints on the maximum single |
1365 |
write supported to a socket, the complete set can not be requested at |
1366 |
once - instead, the images information should be requested in blocks |
1367 |
of less than 1000. The server will not process a block larger than |
1368 |
1000 at a time. Smaller blocks may be desired if the client wants to |
1369 |
try to reduce the potential lag caused. |
1370 |
|
1371 |
Multiple requests for all the information can be sent at once, as the |
1372 |
server will buffer the response data, but constraints prevent the |
1373 |
server from sending the entire data back in one replyinfo (one being |
1374 |
that the data would be beyond 65535 bytes, so the length information |
1375 |
in the packet would not be accurate.) |
1376 |
|
1377 |
If the client sends invalid data (stop is less than start, missing |
1378 |
stop paremeter, stop is beyond the number of images, or asking for |
1379 |
more than 1000 at a time), the reply will just be an empty list. |
1380 |
|
1381 |
Note that the server will track that it has sent the face |
1382 |
information for the requested images, and thus will not send |
1383 |
it again (unless requested via requestinfo). Thus, this |
1384 |
request should always do the right thing with the |
1385 |
returned information. |
1386 |
|
1387 |
skill_info (no parameters) |
1388 |
This returns the skill number to skill name mappings. In this |
1389 |
way, new skills can be added in the server, and the client |
1390 |
can use this new skill information with no changes to the code. |
1391 |
|
1392 |
All data below is in text format. Format is: |
1393 |
|
1394 |
stat number:skill name |
1395 |
|
1396 |
Where stat number is the number that will be used to send |
1397 |
that skill information. Example: |
1398 |
141:lockpicking |
1399 |
142:hiding |
1400 |
143:smithery |
1401 |
|
1402 |
spell_paths (no parameters) |
1403 |
This returns a list of all spell paths in the game, along with the |
1404 |
number associated with them. This should be used to parse spell_path |
1405 |
data in the stats command. The number is a bitmask but is sent as a |
1406 |
decimal value. |
1407 |
|
1408 |
All data is sent in text format. Format is: |
1409 |
|
1410 |
number:name |
1411 |
|
1412 |
eg |
1413 |
|
1414 |
16:missiles |
1415 |
|
1416 |
------------------------------------------------------------------------------ |
1417 |
|
1418 |
Example Session: |
1419 |
|
1420 |
The client first opens a connection to the server. |
1421 |
|
1422 |
S->C: version 1001 |
1423 |
C->S: version 1001 |
1424 |
|
1425 |
The client/server are exchanging version information, to verify that |
1426 |
they can both properly communicate with each other. If there is |
1427 |
a mismatch, one or both of the sides might close the connection. |
1428 |
|
1429 |
|
1430 |
C->S: setfacemode 2 |
1431 |
|
1432 |
The client is informing the server that is wants to use XPM images. Note |
1433 |
that setfacemode is an optional command - if the client wants to live with |
1434 |
the default (XPM) mode, it doesn't need to send this. |
1435 |
|
1436 |
C->S: addme |
1437 |
S->C: addme_success |
1438 |
|
1439 |
Client is informing the server it wants to be added to the game. Server |
1440 |
is telling client that the command has succeeded, and it will then |
1441 |
be added. |
1442 |
|
1443 |
NOTE: I am not sure if this is the exact order of the next few commands, |
1444 |
since a whole bunch of stuff is being done at once. |
1445 |
|
1446 |
S->C: pixmap (All that the map command uses wil lbe sent.) |
1447 |
S->C: map (display starting town map.) |
1448 |
S->C: stats (display default character stats) |
1449 |
S->C: drawinfo (display motd) |
1450 |
S->C: query (get player name) |
1451 |
C->S: reply (return player name) |
1452 |
S->C: drawinfo (inform player to enter password) |
1453 |
S->C: query (request password) |
1454 |
C->S: reply (return player password.) |
1455 |
|
1456 |
At this point, things could deviate two ways - player could be |
1457 |
starting a new character, in which case, numerous draw infos, query's |
1458 |
(stat rolling), replys, stats (change stats that were just |
1459 |
rolled), map updates (player changing clasS) could be sent. However, |
1460 |
we will assume that the player actually entered the proper password |
1461 |
and an existing character is rejoining the game. |
1462 |
|
1463 |
Once again, I am not positive this is the correct order or not. |
1464 |
|
1465 |
S->C: player (send player object.) |
1466 |
S->C: stats (send player stats) |
1467 |
S->C: pixmap (assuming on different map and we haven't sent some of |
1468 |
the images before) |
1469 |
S->C: map (map player was saved on) |
1470 |
S->C: pixmap (assuming we have not sent image for item before) |
1471 |
S->C: item (item in players inventory or where he is standing) |
1472 |
|
1473 |
|
1474 |
After that is established, a loop is established that typically will result |
1475 |
in these commands being sent at various times: |
1476 |
|
1477 |
S->C: stats - to inform the client when stats go up or down. |
1478 |
S->C: map_scroll (when the player moves) |
1479 |
S->C: map (update after map_scroll, or when player changes maps.) |
1480 |
S->C: pixmap/bitmap (with maps commands) to update faces. |
1481 |
S->C: drawinfo (Tell about hitting creatures, applying, etc.) |
1482 |
S->C: item (tell what objects are in players inventory, or space he is standing |
1483 |
on. |
1484 |
C->S: command (general commands, like north, fire, cast, etc.) |
1485 |
C->S: apply (applying and object.) |
1486 |
C->S: move (moving and object) |
1487 |
C->S: examine (examine an object.) |
1488 |
|
1489 |
S->C: query (keypress for shop listing, some other areas) |
1490 |
C->S: reply (from last query) |
1491 |
|
1492 |
------------------------------------------------------------------------------ |
1493 |
Programming Notes: |
1494 |
|
1495 |
These are a few quick notes on how things work. Note that they really |
1496 |
only apply to the code in the standard distribution, most of the direct |
1497 |
i/o is handled by functions that are talked about. IF writing a client |
1498 |
from scratch, you will need to port this over (or write your own - it |
1499 |
isn't very complicated.) |
1500 |
|
1501 |
For the server and the C client, a SockList structure is used for basic |
1502 |
data handling. Basically, this is just a structure that has an unsigned |
1503 |
character buffer and a length field (which contains the length of data in |
1504 |
the buffer, not the actual buffer length.) |
1505 |
|
1506 |
As a side note, when sending a packet, you can supply the length of the |
1507 |
data and the sending routines will take care of sending the 2 bytes of |
1508 |
length information. |
1509 |
|
1510 |
When getting a packet, these 2 bytes are at the start of the buffer and |
1511 |
not removed. |
1512 |
|
1513 |
There is a file called newsocket.c - this file is shared between the` |
1514 |
client and server distribution, but except for the SockList data type, |
1515 |
it could probably be used by itself. The newsocket.c file contains |
1516 |
some routines to pack ints, shorts, and single chars into SockList |
1517 |
structs, as well as functions for the reverse. IT also contains a |
1518 |
function to send socklists, as well as read them. The Add??? functions |
1519 |
increase the len field of the socklist, the Get??? functions do not |
1520 |
change the pointer in anyways. Thus, to get and int and move the buffer, |
1521 |
you do something like: |
1522 |
int = GetIntString(data); data+=4 |
1523 |
As a side note, if you malloc the data for the buffer, make sure to free |
1524 |
it when done. |
1525 |
|
1526 |
There is also the newclient.h file which is shared between the client and |
1527 |
server. This file contains the definition of the SockList, as well as |
1528 |
many defined values for constants of varying means (ie, that in the |
1529 |
stats command, a stat value of 1 is hit points, etc.) When porting to |
1530 |
a new system, you will need to grab these constant values for yourself. |
1531 |
|
1532 |
A few other notes: |
1533 |
The item command lists the weight for an individual item of that type. It |
1534 |
thus becomes the responsibility of the client to parse the name to see how |
1535 |
many there are, and then multiply the weight by that nrof for an accurate |
1536 |
value. This should probably be changed, with the item command including |
1537 |
an nrof, with that being removed from the string we send. Also, the client |
1538 |
is responsible for computing the weight of containers, and thus the player |
1539 |
itself. |
1540 |
|
1541 |
------------------------------------------------------------------------------ |
1542 |
Image caching: |
1543 |
|
1544 |
Image caching has been implemented on the client, with necessary server |
1545 |
support to handle it. This section will briefly describe how image |
1546 |
caching works on the protocol level, as well as how the current client does |
1547 |
it. |
1548 |
|
1549 |
First, the client checks for an option denoting the image caching |
1550 |
is desired. If so, we initialize all the images to a default value - this |
1551 |
means we don't need to put special checks into the drawing code to see if |
1552 |
we have an image - we just draw the default images (I use a question mark |
1553 |
pixmap, since that makes it very easy to see what stuff is cached.) We |
1554 |
also initialize an array which will hold the number to name mapping so |
1555 |
that when we actually get the image, we know what filename to store it |
1556 |
as. |
1557 |
|
1558 |
Second, we request the server to do image caching. This is done |
1559 |
by oring the cache directive to the image mode we want. |
1560 |
|
1561 |
C->S: setfacemode 18 |
1562 |
|
1563 |
Then, when the server finds an image number that it has not send to the |
1564 |
client, it sends us a name command information us the number to name mapping: |
1565 |
|
1566 |
S->C: face 65 CSword.115 |
1567 |
|
1568 |
Note that this is not exactly how the send - the number is actually send |
1569 |
in binary form, and there is no space between that the and the name. Such |
1570 |
formating is difficult here, but the above example illustrates the |
1571 |
data is sent. |
1572 |
|
1573 |
The client then checks for the existence of the image locally. Note that it |
1574 |
is up to the client to apply any extensions based on display type (ie, |
1575 |
add .xpm or .gif or whatever.) The current client stores images in |
1576 |
~/.crossfire/images, and then splits them into sub directories based on |
1577 |
the first 2 letters - in the above example, the file would be |
1578 |
~/.crossfire/images/CS/CSword.115 |
1579 |
|
1580 |
If the client does not have the image or otherwise needs a copy from the |
1581 |
server, it then requests it: |
1582 |
|
1583 |
C->S: askface 65 |
1584 |
|
1585 |
The server will then send the image via the normal bitmap/pixmap |
1586 |
routines. |
1587 |
|
1588 |
S->C: pixmap <data> |
1589 |
|
1590 |
Because the pixmap/bitmap routines do include the image name, |
1591 |
we must store the name & number mapping someplace before sending the |
1592 |
askface. I just used an array of character pointers, so then in |
1593 |
position 65, we do a strdup of the name, store it, then use it when |
1594 |
the pixmap/bitmap command comes in, and free that data. |
1595 |
|
1596 |
Also, the client does occasional redraws of all data if it has received |
1597 |
new images and is running in cached mode. Otherwise, the map can remain |
1598 |
out of date indefinately (although, once the player moves, things will get |
1599 |
redrawn.) |
1600 |
|
1601 |
This has the effect that first time running in cached mode, performance |
1602 |
will actually be a little bit worse for the client (after all, it needs |
1603 |
to still request all the images, but isstill doing pretty constand redraws |
1604 |
of the data.) But times after that, performance is greatly improved. |
1605 |
|
1606 |
------------------------------------------------------------------------------ |
1607 |
Changes: |
1608 |
|
1609 |
This area documents changes in the protocol version and what happened between |
1610 |
them. Note that this is not a complete list, as the setup command |
1611 |
is used to control many cases.: |
1612 |
|
1613 |
CS version 1022 -> 1023: just to sync version with server |
1614 |
|
1615 |
CS version 1021 -> 1022: Client supports sending of verbal image type |
1616 |
questions. |
1617 |
|
1618 |
SC version 1022 -> 1023: Server supports sending png images (addition of |
1619 |
image command). |
1620 |
|
1621 |
SC version 1023 -> 1024: Server will send two part names (described in |
1622 |
item command) which contains the singular & plural form of the name) |
1623 |
|
1624 |
SC version 1024 -> 1025: Support for sending all resistance |
1625 |
values in the stats command. |
1626 |
|
1627 |
SC version 1025 -> 1026: Add face1 command that includes the image |
1628 |
checksum. |
1629 |
|
1630 |
SC version 1026 -> 1027: Add requestinfo/replyinfo commands - client |
1631 |
can check this to know if it should expect a replyinfo to its requestinfo. |
1632 |
|
1633 |
------------------------------------------------------------------------------ |
1634 |
Todo: |
1635 |
|
1636 |
It probably makes more sense to do a more preemptive handling of socket |
1637 |
events. That is, instead of sleeping 120 ms, then checking all the |
1638 |
sockets, we do a select on all the file descriptors with an appropriate |
1639 |
sleep time. |
1640 |
|
1641 |
If we get input, we handle it at that time if the player has an action. In |
1642 |
this way, instead of handling all the actions after sleeping for the 120ms, |
1643 |
we can instead spread them out more. Only when the 120ms expire do we |
1644 |
then do all the actions like move the monsters, regenerate HP, etc. |
1645 |
|
1646 |
The only potential problem I see with this right now is that select will |
1647 |
return immediately if there is data on the socket (player has used up all |
1648 |
their time, are paralyzed, etc.) This would probably mean that the server |
1649 |
needs to do internal buffering, which complicates things some. The |
1650 |
potential advantage with this is that we could peek at the data, and |
1651 |
if the command is not a player action (ie, maybe requesting an image, or |
1652 |
a misc command like who), we could still execute it. Actually, we can |
1653 |
get around the select problem by only adding the file descriptors from |
1654 |
sockets that actually have time to perform actions. |
1655 |
|
1656 |
It probably also makes sense to look at the map at the end of each tick |
1657 |
and determine what needs to be sent (same for the look window.) If a player |
1658 |
is moving really fast (speed > 1), they could in theory move 2 spaces in |
1659 |
1 tick - what is the point then of sending a map and the items for the space |
1660 |
the skip over quickly? |
1661 |
|
1662 |
However, what might also make more sense (but becomes a bit more complicated) |
1663 |
is adjust the players speed by these smaller amounts. Thus, if the player |
1664 |
has speed of 2.0, every (half a tick) we add 1 point or something. What |
1665 |
might be smarter is if we do set up the sleep system above, then anytime |
1666 |
we get an event that we see how much time has passed and increase all the |
1667 |
players speed by that amount. Thus, if a player is running, they will move |
1668 |
whenever they have proper speed - this may make things feel a bit snappier. |