feat(net): implement character creation (request and response)

This commit is contained in:
VDm 2025-06-22 15:45:12 +04:00
parent 3fb86ab12e
commit f67c8cfc04
13 changed files with 167 additions and 16 deletions

View file

@ -1218,6 +1218,34 @@ enum WOWCS_OPS {
COP_WAIT_QUEUE = 10,
};
enum VALIDATE_NAME_RESULT {
NAME_SUCCESS = 0,
NAME_FAILURE,
NAME_NO_NAME,
NAME_TOO_SHORT,
NAME_TOO_LONG,
NAME_INVALID_CHARACTER,
NAME_MIXED_LANGUAGES,
NAME_PROFANE,
NAME_RESERVED,
NAME_INVALID_APOSTROPHE,
NAME_MULTIPLE_APOSTROPHES,
NAME_THREE_CONSECUTIVE,
NAME_INVALID_SPACE,
NAME_CONSECUTIVE_SPACES,
NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS,
NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END,
NAME_DECLENSION_DOESNT_MATCH_BASE_NAME,
NUM_NAME_RESULTS,
};
enum CHAR_NAME_RESULT {
CHAR_NAME_RESULT_START = 87,
CHAR_NAME_SUCCESS = 87,
CHAR_NAME_NO_NAME = 89,
LAST_CHAR_NAME_RESULT = 103,
};
struct LoginData {
char m_account[1280];
int32_t m_loginServerID;
@ -1286,17 +1314,30 @@ struct CHARACTER_INFO {
uint8_t firstLogin;
};
struct CHARACTER_CREATE_INFO {
struct CHARACTER_PREFERENCES {
uint32_t raceID;
uint32_t sexID;
uint32_t classID;
uint32_t hairColorID;
uint32_t skinID;
uint32_t faceID;
uint32_t facialFeatureID;
uint32_t facialHairStyleID;
uint32_t hairStyleID;
};
struct CHARACTER_CREATE_INFO {
char name[48];
uint8_t raceID;
uint8_t classID;
uint8_t sexID;
uint8_t skinID;
uint8_t faceID;
uint8_t hairStyleID;
uint8_t hairColorID;
uint8_t facialHairStyleID;
uint8_t outfitID;
};
struct CLIENT_NETSTATS {
uint32_t bytesSent;
uint32_t messagesSent;

View file

@ -65,6 +65,28 @@ void ClientConnection::DeleteCharacter(uint64_t guid) {
}
}
void ClientConnection::CharacterCreate(const CHARACTER_CREATE_INFO* info) {
this->Initiate(COP_CREATE_CHARACTER, 46, nullptr);
if (this->m_connected) {
CDataStore msg;
msg.Put(static_cast<uint32_t>(CMSG_CREATE_CHARACTER));
msg.PutString(info->name);
msg.Put(info->raceID);
msg.Put(info->classID);
msg.Put(info->sexID);
msg.Put(info->skinID);
msg.Put(info->faceID);
msg.Put(info->hairStyleID);
msg.Put(info->hairColorID);
msg.Put(info->facialHairStyleID);
msg.Put(info->outfitID);
msg.Finalize();
this->Send(&msg);
} else {
this->Cancel(4);
}
}
void ClientConnection::Cancel(int32_t errorCode) {
this->Complete(0, errorCode);
}

View file

@ -31,6 +31,7 @@ class ClientConnection : public RealmConnection {
void EnumerateCharacters(ENUMERATE_CHARACTERS_CALLBACK fcn, void* param);
void CharacterLogin(uint64_t id);
void DeleteCharacter(uint64_t guid);
void CharacterCreate(const CHARACTER_CREATE_INFO* info);
void Cancel(int32_t errorCode);
void Cleanup();
void Connect();

View file

@ -20,7 +20,7 @@ int32_t RealmConnection::MessageHandler(void* param, NETMESSAGE msgId, uint32_t
}
case SMSG_CREATE_CHAR: {
// TODO
result = connection->HandleCharacterCreate(msgId, time, msg);
break;
}
@ -279,6 +279,13 @@ int32_t RealmConnection::HandleCharacterDelete(uint32_t msgId, uint32_t time, CD
return 1;
}
int32_t RealmConnection::HandleCharacterCreate(uint32_t msgId, uint32_t time, CDataStore* msg) {
uint8_t result;
msg->Get(result);
static_cast<ClientConnection*>(this)->Complete(1, result);
return 1;
}
void RealmConnection::SetSelectedRealm(uint32_t a2, uint32_t a3, uint32_t a4) {
// TODO
}

View file

@ -42,6 +42,7 @@ class RealmConnection : public NetClient {
int32_t HandleAuthResponse(uint32_t msgId, uint32_t time, CDataStore* msg);
int32_t HandleCharEnum(uint32_t msgId, uint32_t time, CDataStore* msg);
int32_t HandleCharacterDelete(uint32_t msgId, uint32_t time, CDataStore* msg);
int32_t HandleCharacterCreate(uint32_t msgId, uint32_t time, CDataStore* msg);
void SetSelectedRealm(uint32_t a2, uint32_t a3, uint32_t a4);
void RequestCharacterEnum();
void RequestCharacterLogin(uint64_t id);