The way most servers are set up, they handle to packet flows from the client: Relay and Game play. Yes, a client can (and normally does) connect to you server twice. First for the relay sequence and the second the actually game play.
We can go over those sequences, but first understand a tad about packets.
- Packets :
Packets are the way the client/server communicate. They are just byte streams sent over TCP sockets (IPV4). A "packet" is just a set of those bytes in the stream that represent information. How does one know where the set of data for one packet in the stream starts and ends? Well, a packet has a structure of the first byte representing the ID (0-0xFF) of the packet. With that information, one can determine if that packet is either fixed or variable. Not all packet ids are used. Packet documents exist(POL has one) that have been community generated to aid in understanding.- Fixed:
A fixed packet is a predetermined number of bytes (including the packet id). These are documented in packet ids, or obtained via extracting the information out of the client. If one reads this amount of the bytes (including the packet id read), the stream should then be positioned for the next byte in the stream to represent the next packet. Understand that the fixed length of the packet can vary based on version of the client, so that needs to be accounted for. - Variable:
A variable packet has the size of the packet represented in the two bytes following the packet id (big endian/network byte order). So one can read this information, and then read that number of bytes (minus the the 3 bytes that represented the packet id and length of the packet), to obtain all data for the packet.
- Relay:
Client connect
Client -----------Packet: 0xEF KR/2D Client Login/Seed------->Server
Client -----------Packet: 0x80 Login Request-------------------->Server- Valid credentials
Client <-----------Packet: 0xA8 Game Server List-----------------Server.
Client ------------Packet: 0xA0 Select Server-------------------->Server
Client <-----------Packet: 0x8C Connect To Game Server---------Server - Invalid credentials
Client <-----------Packet: 0x82 Login Denied-----------------Server.
- Valid credentials
- Game :
Client connect
Client -------4 byte seed that was sent in Relay flow by server in Packet 0x8C----->Server
Client ---------Packet: 0x91 Game Server Login------------------------->Server- Valid credentials
Client <-----------Packet: 0xB9 Enable Locked Client Features-----------------Server.
Client <-----------Packet: 0xA9 "Character/Starting Locations"-----------------Server.
...
...
Client <-----------------Rest of normal game flow-------------->Server - Invalid credentials
Client <-----------Packet: 0x82 Login Denied-----------------Server.
- Valid credentials
So what is the issue? Well, notice that the Game Flow doesn't start with a packet, it starts with a 4 byte key.
Depending on the seed, that first byte could be a valid packet id.- Initial solution(but it isn't)
So ideally one does special processing for the first input.
But wait, during the relay flow, the first input is a PACKET. So if you use the same code to handle relay/game, that first input processing is
different between the two flows (ideally, more on that later). There really isn't anyway to know on connection, what flow this is for (if you try to use ip information, remember, it could be coming from a proxy, nat, etc). - Common solution
Well, remember the key is given to the client in the relay flow (packet 0x8C). If one ensures that the key given is structured that the MSByte corresponds to some unused packet, one can code it to a "fake packet of size 4 bytes). Then everything is ok.
But wait, older clients, don't send the key, but send their IP address. you have no control over that. So that first byte, could be a valid
packet. So you have to make assumptions. - Correct solution (imho)
The correct solution is to use two ports. One for relay, one for game. Then the game can always read a fixed 4 bytes and know it isn't a packet. Relay can read the one byte, and process it as a packet.
- Fixed: