-
Member
Writing C# emu from scratch (3.3.5), stuck on character list. Can someone help?
Hello!
I'm implementing 3.3.5a emulator from zero for learning purposes, but stuck on a place without progress. What I have now:
-auth challenge/proof works, server-side and client proof match correcrly
-sending realmlist works
-worldserver sends SMSG_AUTH_CHALLENGE and receives CMSG_AUTH_SESSION, calculated proof matches client proof (so I assume this step works correctly)
-worldserver sends SMSG_AUTH_RESPONSE encrypted header and client starts retrieving characters, i'm getting CMSG_READY_FOR_ACCOUNT_DATA_TIMES, CMSG_REALM_SPLIT, CMSG_CHAR_ENUM.
-if I stay online, client keeps CMSG_PING periodically
After replying to all three packets I'm getting an "error while loading character list". I also tried to implement CMSG_CHAR_CREATE/SMSG_CHAR_CREATE, sending 1 byte 0x2E, but client is now stuck at "Creating character" and that's it. If I cancel creating character, the client again throws all three packets (ready for times, split, enum), and stuck on loading. At this point I assume something is wrong with packet sending or one of packet structures is wrong, while receiving works correctly (Sending 1 byte char enum with zero inside leads to no error tho, while creating char after is still stuck)
Here's my connection.log
Code:
7/17 02:39:51.044 GRUNT: state: LOGIN_STATE_CONNECTING result: LOGIN_OK
7/17 02:39:51.044 GRUNT: state: RESPONSE_CONNECTED result: LOGIN_OK 127.0.0.1:3724
7/17 02:39:51.145 GRUNT: state: LOGIN_STATE_AUTHENTICATING result: LOGIN_OK
7/17 02:39:51.220 GRUNT: state: LOGIN_STATE_CHECKINGVERSIONS result: LOGIN_OK
7/17 02:39:51.259 GRUNT: state: LOGIN_STATE_HANDSHAKING result: LOGIN_OK
7/17 02:39:51.259 GRUNT: state: LOGIN_STATE_AUTHENTICATED result: LOGIN_OK
7/17 02:39:51.259 ClientConnection Initiating: COP_CONNECT code=CSTATUS_CONNECTING
7/17 02:39:51.301 ClientConnection Completed: COP_CONNECT code=RESPONSE_CONNECTED result=TRUE
7/17 02:39:51.301 ClientConnection Initiating: COP_AUTHENTICATE code=CSTATUS_AUTHENTICATING
7/17 02:39:51.376 ClientConnection Completed: COP_AUTHENTICATE code=AUTH_OK result=TRUE
7/17 02:39:51.876 ClientConnection Initiating: COP_GET_CHARACTERS code=43
7/17 02:39:51.891 ClientConnection Completed: COP_GET_CHARACTERS code=45 result=FALSE <--- error loading characters
7/17 02:39:57.076 ClientConnection Initiating: COP_CREATE_CHARACTER code=46
7/17 02:45:07.510 ClientConnection Completed: COP_CREATE_CHARACTER code=RESPONSE_CANCELLED result=FALSE <---- stuck at creating character, manually cancelled
7/17 02:45:08.486 ClientConnection Initiating: COP_GET_CHARACTERS code=43
7/17 02:45:12.876 ClientConnection Completed: COP_GET_CHARACTERS code=RESPONSE_CANCELLED result=FALSE <---- stuck at loading characters, manually cancelled
7/17 02:45:12.879 ClientConnection Initiating: COP_GET_REALMS code=REALM_LIST_IN_PROGRESS <--- client DCed himself and returned to realmlist
7/17 02:45:12.879 ClientConnection Completed: COP_GET_REALMS code=REALM_LIST_SUCCESS result=TRUE
7/17 02:45:14.068 ClientConnection Initiating: COP_CONNECT code=CSTATUS_CONNECTING
7/17 02:45:14.068 ClientConnection Completed: COP_CONNECT code=RESPONSE_CONNECTED result=TRUE
7/17 02:45:14.068 ClientConnection Initiating: COP_AUTHENTICATE code=CSTATUS_AUTHENTICATING
7/17 02:45:14.084 ClientConnection Completed: COP_AUTHENTICATE code=AUTH_OK result=TRUE
7/17 02:45:14.084 ClientConnection Initiating: COP_GET_CHARACTERS code=43
7/17 02:45:14.084 ClientConnection Completed: COP_GET_CHARACTERS code=45 result=FALSE
7/17 02:45:43.810 GRUNT: state: LOGIN_STATE_DISCONNECTED result: LOGIN_OK
I also can't understand what is account data times, so probably here's some error. Here's what I'm responding with
Code:
var sheader = new ServerPacketHeader(4 + 1 + 4 + 8 * 4, Opcode.SMSG_ACCOUNT_DATA_TIMES);
_encryptor.Encrypt(ref sheader);
_smsg.Write(sheader);
var time = (uint)DateTimeOffset.Now.ToUnixTimeSeconds();
_smsg.Write(time);
_smsg.Write(1);
_smsg.Write((uint)0x15);
for (int i = 0; i < 8; i++)
{
_smsg.Write((uint)0);
}
_stream.PushPacket(_smsg);
Also char enum code:
Code:
_smsg.Position = 4; //leave space for header
_smsg.Write(1); //char count
_smsg.Write((ulong)1); // character guid
_smsg.Write("Test"); //extension method, null-terminated
_smsg.Write(1); // race
_smsg.Write(1); //class
_smsg.Write(1); //gender
_smsg.Write(8); //skin
_smsg.Write(2); //face
_smsg.Write(8); //hairstyle
_smsg.Write(5); //haircolor
_smsg.Write(6); //facialstyle
_smsg.Write(80); //level
_smsg.Write((uint)12); //zone
_smsg.Write((uint)0); //map
_smsg.Write(-8949.95F); //x coords and zone/map is some race' starting location
_smsg.Write(-132.493F); //y
_smsg.Write(83.5312F); //z
_smsg.Write((uint)0); //guild id
_smsg.Write((uint)0); // char flags
_smsg.Write((uint)0); // at login flags
_smsg.Write(0); //first login
_smsg.Write((uint)0); //pet display id
_smsg.Write((uint)0); //pet level
_smsg.Write((uint)0); //pet family
for (int i = 0; i < 23; i++) //gear info
{
_smsg.Write((uint)0);
_smsg.Write(0);
_smsg.Write((uint)0);
}
var pos = _smsg.Position;
var header = new ServerPacketHeader((ushort)_smsg.Position, Opcode.SMSG_CHAR_ENUM);
_encryptor.Encrypt(ref header);
_smsg.Position = 0; //write header at start
_smsg.Write(header);
_smsg.Position = pos; //restore position for writer method
_stream.PushPacket(_smsg);
Can someone help figuring out where I'm failing?
Edit: I was sending wrong character create result, now I'm sending 47 and after creating it successfully returns me back to the character list. List loading still not working tho.
Last edited by GobVs; 07-17-2022 at 01:20 AM.
Reason: Fixed char_create bug
-
Post Thanks / Like - 1 Thanks
eSko (1 members gave Thanks to GobVs for this useful post)
-
Member
Ok the problem is figured out and I feel a bit dumb now. I was setting Position to 4 for header offset, and then calculating packet size from stream position, which was 4 bytes more than intended.
-
Post Thanks / Like - 1 Thanks
stoneharry (1 members gave Thanks to GobVs for this useful post)
-
Established Member
is it open source at the moment? I'm curious to see a modern C# emulator.
-
Member
Originally Posted by
Vragoth
is it open source at the moment? I'm curious to see a modern C# emulator.
My goal is to implement a very basic blizz-style auth-char-worldnodes model on a fresh codebase (i.e. enter charserver, select char, redirect to worldnode during load and successfully proof connection is the goal). If I can achieve this, I have plans on making repo open-source, but right now I think there's nothing to show, as a decent part of code is "throw as is, to see how it works"