[help][client 5017] character creation packet.

09/08/2013 17:27 dospy#1
i am trying to make the character creation work on a C++ source(Hybrid's one) and i am having some troubles.
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;
	}
}
09/08/2013 19:46 Spirited#2
Don't forget to generate keys. You should be generating new keys before telling the client to do anything where it could send back a packet. Also, this is in the wrong section. I'll be moving it shortly.
09/08/2013 20:21 dospy#3
thx for the reply, really appreciate it, dono how i missed that.
you are a lifesaver
#can be closed
09/08/2013 20:25 Spirited#4
No problem.
Closed as requested.