LEGENDES PROTOCOL SPECIFICATION Version 2.1.1 1999/05/29 by Benjamin Lerman David A. Madore Status of this memo This document is the specification of the communication protocol used by the Legendes meta-game, and requests discussion and suggestions for improvements. Distribution of this memo is unlimited. This is a working version and it is susceptible to change without prior notice. The CVS string that uniquely identifies this version of the memo is the following: $Id: lgdproto.txt,v 1.5 1999/05/29 18:15:06 david Exp $ INTRODUCTION This specification describes the protocol used for communication between the Legendes meta-game server and clients. It describes the requirements of the server and those of the clients. Description of Legendes itself can be found at the following URL: http://www.eleves.ens.fr:8080/home/madore/legendes/ CONNECTION TYPE The client / server connection is a full duplex connection, normally over a TCP/IP tube. Both sides of the connection consist of a sequence of messages, each as described below (see the ``MESSAGE FORMAT'' section). An arbitrary delay can occur between two messages, or within a single message. Both sides of the connection are completely asynchronous, i.e. the server can send a client a message while the client is sending one to the server. On the other hand, each side of the connection is non-reentrant, that is, a message cannot be interrupted to make way for another message. In what follows: * a ``request'' is a message sent by a client to the server, * a ``reply'' is a message sent by the server to a client; any reply is sent in reply to a particular request, with the exception of the connection greeting which is sent in reply to the act of opening the connection. There are four types of replies: ``synchronous responses'', ``error messages'', ``asynchronous events'' and the ``connection greeting''. The normal reply to a client request is a ``synchronous response''. However, if an abnormal situation condition is encountered, the server will generate an ``error message'' type of reply. Every client request (that meets the requirements of this protocol) MUST generate exactly one of either a synchronous response or an error message from the server. Asynchronous events are replies generated by the server in response to a particular event in the game, after the client has authorized them by means of a certain request (to which they remain attached). The current version of the protocol does not define or specify any asynchronous event, nor does it state how they are enabled or disabled. It is expected that future versions of this memo will do so. MESSAGE FORMAT Any message exchanged between the server and a client has the following format: 31 0 +------------------------------+ 0 | Code | +------------------------------+ 4 | Message length | +------------------------------+ 8 | Reserved | +------------------------------+ 12 | Callback | +------------------------------+ 16 | Message data | | ... | +------------------------------+ All quantities are 32-bit integers in network order (big-endian format). The first quantity (``Code'') determines the message type. In the case of a request it gives the request type (opcode). In the case of a reply, it indicates whether the message is a synchronous response, an error message, an asynchronous event or the connection greeting. The second quantity (``Message length'') gives the total size in bytes (octets) of the message, including the Code and Message length fields. Thus the sender MUST set this to at least 16, and various types of messages will impose stronger bounds on this quantity. The message length set by the sender MUST be a multiple of 4, and it MUST NOT exceed 1024 bytes. The third quantity (``Reserved'') is reserved for future use. The sender of the message MUST set this to 0 and the receiver MUST ignore its value. The fourth quantity (``Callback'') is a client callback. Clients may set this field to any value of its choice when sending a request, and the server will return the same value in the corresponding place in any reply to that request (whether a normal synchronous response or an error message, or even any asynchronous event that was allowed by the request in question). The exception is the connection greeting from the server, that is not generated in response to a particular request and that does not have a callback field: instead, it has a ``Magic number field'' whose value is the Legendes magic number, 0x1e6e7de5 (510557669). The callback field is not interpreted in any way by the server. The idea of this field is to make it easier for clients to track down which request a particular reply is associated to: for example, in a threaded client it could be set to the identifier of the thread that the reply should be sent to; or it might be set to a special value if the client does not care about the reply and wishes to ignore it. The remaining quantities are interpreted according to the particular kind of message being transmitted. CONNECTION GREETING The connection greeting is sent by the Legendes server to any client as soon as the latter connects. It has the following form: 31 0 +------------------------------+ 0 | 0x00000003 | +------------------------------+ 4 | Message length | +------------------------------+ 8 | Reserved | +------------------------------+ 12 | Magic number | +------------------------------+ 16 | Protocol version | +------------------------------+ 20 | 0x00000001 | +------------------------------+ The first field is the big-endian 32-bit quantity 0x3. This is the code of the connection greeting. The server MUST send 24 (0x18) as second field. However, clients MUST also accept any greater value that does not exceed 1024, in which case they MUST ignore the extra data at the end of the message. The third field is reserved for future use. The server MUST set this to 0, and clients MUST ignore its value. The fourth field is the magic number. The server MUST set this to 0x1e6e7de5 (510557669). The fifth field is the protocol version. The top 16 bits (i.e. the first 2 bytes) are the major version number and the bottom 16 bits are the minor version number. An increase in the major version number indicates an incompatible change in protocol. An increase in the minor version number indicates a compatible change in protocol (in the sense that the server may support additional functionalities but that using the protocol as described by an older version with the same major number will work). The protocol version described by this document is 2.1 (that is, major number 2 and minor number 1). A server conforming strictly to the specifications of this document MUST therefore set the version number field to 0x00020001. The sixth field MUST be set to 0x00000001 by the server to indicate succesful connection and readiness to accept requests. Clients MUST accept any value whose last (least significant) four bits are 0001, and they SHOULD quit with an error message if the value of the sixth field has another pattern than 0001 in the last four bits. To summarize, the server MUST write the following data on any connection that is opened 00 00 00 03 00 00 00 18 - 00 00 00 00 1e 6e 7d e5 00 02 00 01 00 00 00 01 On the other hand, clients MUST accept any greeting message that follows the following pattern: 00 00 00 03 00 00 0x xx - xx xx xx xx 1e 6e 7d e5 00 02 xx xx xx xx xx x1 where the value of the message length field is at least equal to 24 and no more than 1024, and where the minor version number of the protocol is at least 1. Clients MUST reject any greeting message whose bytes 12-15 are not 0x1e6e7de5. They SHOULD reject any greeting message which does not follow the pattern indicated above, and in fact they SHOULD reject such a message as soon as a byte not following the pattern is read. REQUESTS A request is a message sent to the Legendes server by a client. It has the following form: 31 0 +------------------------------+ 0 | Request opcode | +------------------------------+ 4 | Request length | +------------------------------+ 8 | Reserved | +------------------------------+ 12 | User callback data | +------------------------------+ 16 | Request parameters | | ... | +------------------------------+ The first field (``Request opcode'') is a big-endian 32-bit quantity that specifies the nature of the request. Possible values for this field will be described below. The second field (``Request length'') gives the total size of the request in bytes of the request. Clients MUST give this field a multiple of 4 value no less than 16 and no greater than 1024. On the other hand, the server MUST accept any request whose length is at least equal to 8 and no greater than 1024. If the length is larger than the expected size of the particular kind of request, the server MUST ignore the extra data. If the length is smaller than the expected length, the server MUST use reasonable default values for the parameters - and it MUST use 0 for the default of the reserved field and of the user callback data. The client MUST NOT close the connection inside a request (i.e. before a request is finished). However, if this happens, the server MUST pretend that the request length field of the interrupted request was equal to the number of bytes which can be read from the connection; this test MAY be done before or after the test on the legality of the value of the field (thus, an 8 byte interrupted message with request length set to 0xffffffff MAY be rejected as too long or MAY be accepted as if it had request length 0x8). The third field is reserved for future use. Clients MUST set this to 0, and the server MUST ignore its value. The fourth field (``User callback data'') is read and ignored by the server. The server MUST duplicate that field in the fourth field of any reply to the request. The meaning of the following fields (``Request parameters'') depends on the particular kind of request. Their number is given by the request length field as explained above. SYNCHRONOUS RESPONSES A synchronous response is generated by the server in response to any request that has been successfully carried out. It generally contains the answer to the questions asked by a client within a request. A synchronous response has the following form: 31 0 +------------------------------+ 0 | 0x00000000 | +------------------------------+ 4 | Response length | +------------------------------+ 8 | Reserved | +------------------------------+ 12 | User callback return | +------------------------------+ 16 | Response data | | ... | +------------------------------+ The first field is the big-endian 32-bit quantity 0x0. This is the code of a synchronous response. The second field is the response length. The server MUST set this to the number of bytes in the response, between 16 (0x10) and 1024. The client MUST ignore any data in the response that it did not expect (i.e. it MUST accept any value of the response length that is at least what it expected and no greater than 1024). The third field is reserved for future use. The server MUST set this to 0, and clients MUST ignore its value. The fourth field is the user callback return. The server MUST set this to the value of the corresponding field in the request that generated the response. The meaning of the following fields depends on the nature of the request that generated the response. ASYNCHRONOUS EVENTS Asynchronous events have a code field of 0x2. They are not generated under the current version of the protocol. Thus, the server MUST not send any such message. Clients MUST ignore all messages with a code field of 0x2 and a message length between 8 and 1024, even if that message is received between a request and its response. ERROR MESSAGES Error messages are generated by the server in response to an abnormal situation. They have the following form: 31 0 +------------------------------+ 0 | 0x00000001 | +------------------------------+ 4 | Message length | +------------------------------+ 8 | Reserved | +------------------------------+ 12 | User callback data | +------------------------------+ 16 | Error code | +------------------------------+ The first field is the big-endian 32-bit quantity 0x1. This is the code of an error message. The server MUST send 20 (0x14) as second field. However, clients MUST also accept any value that is at least 16 and does not exceed 1024, in which case they MUST ignore the extra data at the end of the message or use a generic error message if the error code is absent. The third field is reserved for future use. The server MUST set this to 0, and clients MUST ignore its value. The fourth field is the user callback data. The server MUST set this to the value of the corresponding field in the request that produced the error, if it is possible to determine this value. The fifth field is the error code. The meaning of the error codes is given below. REQUEST VALUES 0. NOP This request requests that the server do nothing. The opcode value of a NOP request is 0x00000000. The expected value of the request length for a NOP request is 16 (0x10): clients MUST use that value for sending a NOP request, and the server MUST accept any value between 8 and 1024, and ignore all the data past the first eight bytes. The server MUST reply to a NOP request by sending a synchronous response whose message length is 16 (0x10), having no further data beyond the required fields. 1. ACK? This request requests that the server respond by sending the number 1 (0x00000001). The opcode value of an ACK? request is 0x00000001. The expected value of the request length for an ACK? request is 16 (0x10): clients MUST use that value for sending an ACK? request, and the server MUST accept any value between 8 and 1024, and ignore all the data past the first eight bytes. The server MUST reply to the ACK? request by sending a synchronous response whose message length is 20 (0x14) and whose first and only data word is 0x00000001; the client MUST accept any response with length at least 20 (0x14) and whose first data word has 0001 as last (least significant) four bits, as a positive response. 2. MAGIC This request requests that the server respond by sending the magic number 0x1e6e7de5. The opcode value of a MAGIC request is 0x00000002. The expected value of the request length for a MAGIC request is 16 (0x10): clients MUST use that value for sending a MAGIC request, and the server MUST accept any value between 8 and 1024, and ignore all the data past the first eight bytes. The server MUST reply to the MAGIC request by sending a synchronous response whose message length is 20 (0x14) and whose first and only data word is 0x1e6e7de5; the client MUST accept any response with length at least 20 (0x14) and whose first data word is 0x1e6e7de5, as a positive response. 3. VERNUM This request requests that the server respond by sending the protocol version number as in the greeting message. The opcode value of a VERNUM request is 0x00000003. The expected value of the request length for a VERNUM request is 16 (0x10): clients MUST use that value for sending a VERNUM request, and the server MUST accept any value between 8 and 1024, and ignore all the data past the first eight bytes. The server MUST reply to the VERNUM request by sending a synchronous response whose message length is 20 (0x14) and whose first and only data word is the protocol version number, thus 0x00010002 for servers that conform strictly to this specification. 4. DIE This request requests that the server cease functioning. The opcode value of a DIE request is 0x00000004. The expected value of the request length for a DIE request is 16 (0x10): clients MUST use that value for sending a DIE request, and the server MUST accept any value between 8 and 1024, and ignore all the data past the first eight bytes. The server MUST reply to a NOP request by sending a synchronous response whose message length is 16 (0x10), having no further data beyond the required fields and then immediately stop all operation. Note that in future versions of this protocol, the DIE request will be a privileged operation. 5. IDENT This request requests that the server identify the client. The opcode value of an IDENT request is 0x00000005. The value of the request length for a IDENT request SHOULD be 16 plus the smallest multiple of 4 greater than the length of the name that the client will use. The client MUST send as Request parameters his name completed with a 0 byte; the server MUST accept (as a valid IDENT request) any name terminated with at least one 0 and ignore the rest of the message. The server MUST answer this request (if it is correctly formed) with either an error having error code 3 - which means the server refuses the client - or with a synchronous response exactly as an answer to the ACK? request. The client MUST accept any response with length at least 20 (0x14) and whose first data word has 0001 as last (least significant) four bits, as a positive response (that is, as a sign that it has been successfully identified by the server), and it MUST consider any similar response with 0000 as last bits in the first data word as a negative response to the authentication request (future versions of the protocol might use this mechanism instead of an error message). 6. MAPQ This request is still experimental and its semantics are liable to change. This requests that the server respond by sending the content of a certain position of the map. The opcode value of an MAPQ request is 0x00000006. The expected value of the request length for an MAPQ request is 24 (0x18): clients MUST use that value for sending an MAPQ request, and the server MUST accept any value between 8 and 1024. The x and y values of the position that the client requests the server to read are indicated by the 32-bit quantities at offsets 16 and 20 respectively in the request. The server MUST reply to the MAPQ request by sending either an error message (typically, OBOUNDS) or a synchronous response whose message length is 20 (0x14) and whose first and only data word is the value of the map content at the given position. 7. WHERE This request is still experimental and its semantics are liable to change. This requests that the server respond by sending the position (x and y components) of the client's critter in the world. The opcode value of a WHERE request is 0x00000007. The expected value of the request length for a WHERE request is 16 (0x10): clients MUST use that value for sending a WHERE request, and the server MUST accept any value between 8 and 1024. The sever MUST reply to the WHERE request by sending either an error message or a synchronous response whose length is 24 (0x18) and whose two data words are the x and y components (in that order) of the critter's position. ERROR CODES 0. GENERIC This error code has value 0x00000000 and corresponds to the case when the server send a error with a length less than 20 (0x14). The server MUST NOT do this, but if it does, clients MUST consider this as a GENERIC error. 1. TOOLONG This error code has value 0x00000001 and is sent by the server when a client made a request whose length exceeds 1024. 2. UNKNOWN This error code has value 0x00000002 and is sent by the server when a client made a request whose opcode is not in the list of known opcode values. 3. REFUSED This error code has value 0x00000003 and is sent by the server when it refuses the identification of a client. 4. OBOUNDS This error code has value 0x00000004 and is sent by the server when one of the numeric values in a client's request was out of bounds.