I'm in the process of building a 'qsmack'-like server admin bot for Quake 1 (netquake). I'm creating this bot in python, mainly for the network byte-level programming experience. I've studied the Quake Specs 3.4 and the Unnoficial Quake Network Protocol in great detail. I've also been using wireshark to capture packets sent by a quake client and received by a quake server.
Section 8.6.3 of the Quake specs (above) show in some detail how the initial quake connection works.
Code: Select all
Server sends a big message that contains:
- the server banner "VERSION 1.01 SERVER (21456 CRC)"
- a server info message (code 0x0B) with map name, and precached models and sounds
- an indication that client should move to PRESPAWN state.
Client sends a No Operation (code 0x01)
Client sends a console command (code 0x04) "prespawn", indicating prespawn is finished.
Server sends a big message that contains order to spawn static sounds and static entities
- For all the static entities described in the .BSP file,
One "Spawn Static entity" order, and possibly a Static Sound order.
Client sends a player information message:
- console order "name PLAYER\n" (where PLAYER is the player name)
- console order "color 0 0\n" (shirt and pants colors)
- console order "spawn " to indicate the client is ready to play.
Server sends a big message:
- For each possible player in the game (including those not connected):
a set of orders UPDATE NAME, UPDATE FRAGS, UPDATE COLORS
- For each of the 64 light style:
a SET LIGHT STYLE message.
- an UPDATE STATE message for total and found monsters and secrets
- a SET ANGLE order, to orient the player's view
- a CLIENT DATA order, fix the status bar display
- an order to move to Start 3d Rendering state.
- a last update NAMe, FRAGS, and COLORS, for the client.
Client sends a console message "begin".
After I send the 'begin' packet, the connection is accepted (in full) by the server and I start receiving the expected server packets. The server displays the connection being accepted as well. However, at around the 30 second mark, the server drops the connection with a 'no reply from playername'. My bot sends an acknowledgement packet for every reliable (0x01 and 0x09) packet. It seems to be sending this information correctly. Unreliable packets (0x10 are not acknowledged. Apparently the server is not getting a packet that it is expecting - I know that there is a net_messagetimeout on the server, so I've tried sending game keepalive packets at various intervals to no avail.
When I examine the wireshark captures, the real quake client starts sending a flood of unreliable (0x10) packets with the client movement orders (0x03) regardless of whether movement is actually made or not.
My question is this:
What kind of packets is the server requiring of the client and how often should they be sent? Do I need to duplicate these unreliable client movement orders (even if I do not want the bot to actually move)? That is to say, send the server client movement orders with the exact same coordinates over and over for the server to keep my connection alive? If that's not the case, what am I missing?
Secondary: Can someone point me to some documentation on the character mappings in quake so that I can better parse the server messages. At this point, my bot can parse the message 'header' to determine what kind of packet is being received, but it cannot read the entirety of the message itself. For example, I can distinguish between all the main packet types but not read the rest of the message.
Let me know what you guys think. Thanks!