From John Cash, 8/12/96, quoted on a page by Scott Olsson: OK, here (finally) is the info you (definitely plural) have been asking for about Quake's non-game packets and getting more info out of a server. All Quake net packets start with an 4 byte header. The first two bytes are flags. For these control packets they will always be 0x80 0x00. The next two byte are the length of the packet inclusive of this header. Quake passes all multi-byte numbers over the wire in big endian format, so on little endian machine (like anything with an intel CPU, for example) these two bytes will need to be swapped. OK, now for the good stuff. The next byte is a operation code. There are nine currently defined; four requests and five responses. For each request there is a corresponding response; the expection is a connect request which has two possible responses. First, a few general notes. NET_PROTOCOL_VERSION is currently 3. All of these messages are via UDP; reliability is the responsability of the client. The requests and/or replies can (and will) get dropped from time to time. The first set is what is used by a client to request entry into a game. This is the request that is sent every time the console says "trying". Notice that the CCREP_ACCEPT response only has a port number; it is implied that the client will use that port on the same address to which it sent the CCREQ_CONNECT packet. The CCREP_REJECT's reason is just a null terminated string that Quake will print out on the console. #define CCREQ_CONNECT 0x01 // string game_name "QUAKE" // byte net_protocol_version NET_PROTOCOL_VERSION #define CCREP_ACCEPT 0x81 // long port #define CCREP_REJECT 0x82 // string reason Next is the one you're all most familiar with. This is the request that's made all the cool stuff you've done so far possible. I don't really think this one requires much explanation anymore. OK, one thing ;-) The net_protocol_version is there both directions so we can upgrade the network protocol and have the option of supporting older versions. #define CCREQ_SERVER_INFO 0x02 // string game_name "QUAKE" // byte net_protocol_version NET_PROTOCOL_VERSION #define CCREP_SERVER_INFO 0x83 // string server_address // string host_name // string level_name // byte current_players // byte max_players // byte net_protocol_version NET_PROTOCOL_VERSION All right, now for some new stuff. Here's how you can get all the scoop on the players on a given server without being in the game. player_number starts at zero and goes up to current_players-1 (from CCREP_SERVER_INFO). If you send a bad player number (like asking for info on player 8 in a game with only 3 players) you will not get any response. colors is made up of the shirt color*16 + the pants color; each one of those is in the raneg 0-13. connect_time is in seconds. You can play with this from the Quake console by doing "TEST servername". It will just display the returned info to the console screen. #define CCREQ_PLAYER_INFO 0x03 // byte player_number #define CCREP_PLAYER_INFO 0x84 // byte player_number // string name // long colors // long frags // long connect_time // string address The rule info is to let you find out how some of the key variables on the server are currently set. That list currently includes: fraglimit, timelimit, teamplay, noexit, sv_friction, sv_gravity, and sv_maxspeed. The first time you make the request you use an empty string (just a null byte) for the rule. Thereafter you send the name of the rule from the last response to step through the list. When you reach the end of the list you'll get a response that doesn't have a rule or value... at all. No null byte, nothing. The length of the packet will be 5. Ugly, but that's how it works. You can play with this from the Quake console by doing "TEST2 servername". It will just display the returned info to the console screen. #define CCREQ_RULE_INFO 0x04 // string rule #define CCREP_RULE_INFO 0x85 // string rule // string value Well, digest on that any post any further questions about it on this list. Hopefully I've not made too many typos to confuse you. I've tried to cut and paste the info out of the 1.01 source, so this should be pretty accurate. If you do see somthing here that doesn't jive with what you're seeing on the wire just ask and I'll straighten it out. Remember that this is all subject to change, but we'll only change it to make it better. And please don't ask why some of this is the way that it is. There a number of things than can and will be imroved; this is just a quick doc on how things are right now - please accept it as such. --- John Cash ----------------------------------------------------------------------------