- Joined
- Aug 6, 2009
- Messages
- 2,132
- Reaction score
- 429
if (bytesReceived > 0)
{
Console.WriteLine("[" + clientIP + "](" + bytesReceived.ToString() + "): " + BitConverter.ToString(clientBuffer, 0, bytesReceived));
}
if (BytesReceived==0)
{
Client is Disconnected... you can clean up now, nothing more can be sent or received
Do not read more data
}
else
{
Process whatever you got, and make the call to read more data
}
Code:if (BytesReceived==0) { Client is Disconnected... you can clean up now, nothing more can be sent or received Do not read more data } else { Process whatever you got, and make the call to read more data }
---------- Post added at 05:32 PM ---------- Previous post was at 05:29 PM ----------
For clarity, what i'm saying is... don't call BeginReceive again, if bytesReceived == 0
Returning bytesreceived = 0 is how sockets tell you that they're now disconnected.
If you call .Close or .Disconnect or .Dispose or whatever on a socket, the outstanding read will finish right away and you'll get bytesreceived = 0
So, you can handle all your disconnect handling inside the "dataArrival" function after you call EndReceive and get bytesreceived==0
Which also means, if you need to close a socket, you can just call .Close and forget about it - and your dataArrival function will take care of the cleanup.
Create a dictionary with OP code => function
Then when packet arrives just call
functionsDictionary["opcode"]();
recv_packets = {
'account': {
0x0201: ['auth', 'AccountAuth'],
0x0203: ['request_world_list', 'RequestWorldList'],
0x0205: ['select_world', 'SelectWorld'],
}
6A 6D 32 6D 65 00 72 00 7A 76 72 00 98 FD 18 00 A0
do not use a switch if you are building an emulator. Use a combination of Custom Attributes + Dictionary, and do something like I made:
[Packet(OPCODE HERE,DESCRIPTION)]
func goes here
[Packet(ANOTHER ONE,DESCRIPTION)]
another one
Then, when your program starts, load them into a dictionar, with the OPcode and the MethodInfo, so when a packet is received you can get the MethodInfo passing the opcode, and further use the Invoke function to call it.
do not use a switch if you are building an emulator. Use a combination of Custom Attributes + Dictionary, and do something like I made:
[Packet(OPCODE HERE,DESCRIPTION)]
func goes here
[Packet(ANOTHER ONE,DESCRIPTION)]
another one
Then, when your program starts, load them into a dictionar, with the OPcode and the MethodInfo, so when a packet is received you can get the MethodInfo passing the opcode, and further use the Invoke function to call it.
public string ReadString(short length)
{
string tempBuff = BitConverter.ToString(packetData, index, length).Split("00".ToCharArray())[0].Replace("-", "");
byte[] stringBytes = new byte[tempBuff.Length / 2];
for (int i = 0; i < stringBytes.Length; i++)
{
stringBytes[i] = Convert.ToByte(tempBuff.Substring(i * 2, 2), 16);
}
index += length;
return Encoding.ASCII.GetString(stringBytes);
}
Ya thats what I did for login server. It's weird that game developers went that way.
One more question so far.
Username field has 17 bytes reserved for 17 characters.
But if username length is less than 17 it creates bunch of gebrish after login.
Example
Code:6A 6D 32 6D 65 00 72 00 7A 76 72 00 98 FD 18 00 A0
Only first 5 bytes have username the rest is just random I guess.
How would I read username only from that?
They aren't all random. It's null terminated. You can stop reading after the first "00" byte.
If it's C# and allowing unsafe code, you can pass in a char* to the string constructor to make it easy. I think it takes byte* too