i suppose the sequence goes like this(?):
1-> client sends (valid, meaning acc and pass are ok) login request to server
2-> server check for a character being existent on that account
3-> if no character is created on the specified account, server sends sends back a MessagePacket with the message "NEW_ROLE"
4-> client then goes into the class selection screen, chooses name, class, gender and body type and sends the coresponding character creation packet to the server
5-> server creates the character and disconnects the player in order to re-log.
however, it seems that i get a garbage packet on step (4) instead of a valid one which causes the server to disconnect the client and discard the data. for whatever reason i cannot find the problem, hope you guys can help me.
Screenshot:
CODES:
Code:
// this is the function called when a player tries to login void StartLogin(CGameClient *Client, PACKET_HEAD *pHead) { struct Packet_Data { PACKET_HEAD Header; DWORD Key2; DWORD Key1; }; Packet_Data* Packet = (Packet_Data*)pHead; Client->ID = Packet->Key1; CMsgPacket *msg = new CMsgPacket( ); msg->Color = 0x00FFFFFF; msg->ChatType = CHAT_TYPE_DIALOG; msg->To = "ALLUSERS"; msg->From = "SYSTEM"; try { // finding the AuthClient coresponding to the GameClient bool result = false; CDatabaseRoot::Core->AuthClients->ObtainSyncHandle( ); for(int i = 0; i < CDatabaseRoot::Core->AuthClients->Count; i++) { if(CDatabaseRoot::Core->AuthClients->Elements[i]->ID == Client->ID) { memcpy(Client->szUsername, CDatabaseRoot::Core->AuthClients->Elements[i]->szUsername, 16); memcpy(Client->szPassword, CDatabaseRoot::Core->AuthClients->Elements[i]->szPassword, 16); result = true; CDatabaseRoot::Core->AuthClients->RemoveAt(i, false); break; } } CDatabaseRoot::Core->AuthClients->FreeSyncHandle( ); if(!result) { // couldn't find the coresponding AuthClient for the GameClient throw "Login failed. Please try again later!"; } // check if the account is already logged on and disconnect him if so CGameClient *C = CDatabaseRoot::Core->FindClient(Client->szName); if(C) { // account was already logged in, disconnect both clients C->Disconnect( ); throw "Someone is already logged on this account. Please try again later!"; // Client will be disconnected in the catch statement } string charname = CDatabaseRoot::Core->GetCharacterFromAccount(Client->szUsername); if(charname.empty( )) { // there is no character created on that account msg->Message = "NEW_ROLE"; Client->Send(msg); return; } CDatabaseRoot::Core->LoadCharacter(Client); CharacterInfoPacket* cInfo = (CharacterInfoPacket*)CharacterInfoPacket::Create(Client->szName, Client->szSpouse); cInfo->UID = Client->ID; cInfo->Model = Client->Data->Model; cInfo->HairStyle = Client->Data->HairStyle; cInfo->Money = Client->Money; cInfo->ConquerPoints = Client->ConquerPoints; memcpy(cInfo->Stats, &Client->Stats, sizeof(UserStats)); cInfo->Hitpoints = Client->Hitpoints; cInfo->Mana = Client->Mana; cInfo->Level = (BYTE)Client->Data->Level; cInfo->Job = Client->Job.GetID( ); cInfo->Reborn = (BYTE)Client->Data->Reborn; CDatabaseRoot::Core->Clients->Add(Client); Client->Crypto->SetKeys(&Packet->Key1, &Packet->Key2); msg->Message = "ANSWER_OK"; Client->Send(cInfo, true); Client->Send(msg); } catch(char* exception) { msg->Message = exception; Client->Send(msg); Client->Disconnect(false); // do not save the account as the variables haven't been loaded // and this would corrup the account file } }
Code:
// function responsible for received data processing void GameReceive(CCustomWinsockClient* client, CServerSocket* server, unsigned char* buf, int buflen) { CGameClient* pWrapper = (CGameClient*)client->PublicWrapper; pWrapper->Crypto->Decrypt(buf, buf, buflen); for(int Counter = 0; Counter < buflen; /*Counter += Size*/) { PACKET_HEAD* header = (PACKET_HEAD*)(buf + Counter); WriteLn("buflen: " + ConvertToString(buflen) + " header->Size: " + ConvertToString(header->Size)); PrintHexStr(buf + Counter, buflen - Counter); if(header->Size > buflen) { pWrapper->Disconnect( ); // INVALID_LEN } else { //PrintHexStr(buf + Counter, header->Size); PacketProcessor::Process(pWrapper, header); } Counter += header->Size; } }