diff --git a/world/client.cpp b/world/client.cpp index 684020137..811d53b31 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -87,6 +87,17 @@ extern uint32 numclients; extern volatile bool RunLoops; extern volatile bool UCSServerAvailable_; +// unused ATM, but here for reference, should match RoF2 +enum class NameApprovalResponse : int { + NotValid = -1, // string ID 1576 + Rejected = 0, // string ID 1581 + Approved = 1, + CharacterLimit = 2, // string ID 1591 older clients mention 1 char on server + ThreeDeity = 3, // string ID 5502. 3 toons same deity team limit + HeadStartPreOoW = 4, // string ID 6862, head start failed due to OoW not being unlocked + HeadStartNoOoW = 5, // string ID 6863, head start failed due to not owning OoW +}; + Client::Client(EQStreamInterface* ieqs) : autobootup_timeout(RuleI(World, ZoneAutobootTimeoutMS)), connect(1000), @@ -497,7 +508,7 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) return false; } - snprintf(char_name, 64, "%s", (char*)app->pBuffer); + auto length = snprintf(char_name, 64, "%s", (char*)app->pBuffer); uchar race = app->pBuffer[64]; uchar clas = app->pBuffer[68]; @@ -509,22 +520,39 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) outapp->pBuffer = new uchar[1]; outapp->size = 1; - bool valid = false; - if(!database.CheckNameFilter(char_name)) { + bool valid = true; + /* Name must be between 4 and 15 characters long, packet forged if this is true */ + if (length < 4 || length > 15) { valid = false; } - /* Name must begin with an upper-case letter. */ + /* Name must begin with an upper-case letter, can be sent with some tricking of the client */ else if (islower(char_name[0])) { valid = false; } - else if (database.ReserveName(GetAccountID(), char_name)) { - valid = true; - } - else { + /* Name must not have any spaces, packet forged if this is true */ + else if (strstr(char_name, " ")) { valid = false; } + /* I would like to do this later, since it's likely more expensive, but oh well */ + else if (!database.CheckNameFilter(char_name)) { + valid = false; + } + else { + /* Name must not not contain any uppercase letters, can be sent with some tricking of the client */ + for (int i = 1; i < length; ++i) { + if (isupper(char_name[i])) { + valid = false; + break; + } + } + } - outapp->pBuffer[0] = valid? 1 : 0; + /* Still not invalid, let's see if it's taken */ + if (valid) { + valid = database.ReserveName(GetAccountID(), char_name); + } + + outapp->pBuffer[0] = valid ? 1 : 0; QueuePacket(outapp); safe_delete(outapp);