diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Common.h | 5 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCStores.cpp | 55 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCStores.h | 3 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCStructure.h | 15 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCfmt.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 4 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Handlers/PetHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Tools/PlayerDump.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_character.cpp | 4 |
12 files changed, 102 insertions, 17 deletions
diff --git a/src/common/Common.h b/src/common/Common.h index 4c209f89ec8..54b735f0ca5 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -116,10 +116,11 @@ enum LocaleConstant LOCALE_zhTW = 5, LOCALE_esES = 6, LOCALE_esMX = 7, - LOCALE_ruRU = 8 + LOCALE_ruRU = 8, + + TOTAL_LOCALES }; -const uint8 TOTAL_LOCALES = 9; #define DEFAULT_LOCALE LOCALE_enUS #define MAX_LOCALES 8 diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 14e4631548e..806d9d46763 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -25,6 +25,7 @@ #include "Timer.h" #include "ObjectDefines.h" +#include <boost/regex.hpp> #include <map> typedef std::map<uint16, uint32> AreaFlagByAreaID; @@ -140,6 +141,12 @@ MapDifficultyMap sMapDifficultyMap; DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt); +DBCStorage<NamesProfanityEntry> sNamesProfanityStore(NamesProfanityEntryfmt); +DBCStorage<NamesReservedEntry> sNamesReservedStore(NamesReservedEntryfmt); +typedef std::array<std::vector<boost::regex>, TOTAL_LOCALES> NameValidationRegexContainer; +NameValidationRegexContainer NamesProfaneValidators; +NameValidationRegexContainer NamesReservedValidators; + DBCStorage <OverrideSpellDataEntry> sOverrideSpellDataStore(OverrideSpellDatafmt); DBCStorage <PowerDisplayEntry> sPowerDisplayStore(PowerDisplayfmt); @@ -401,6 +408,37 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales, bad_dbc_files, sMovieStore, dbcPath, "Movie.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sNamesProfanityStore, dbcPath, "NamesProfanity.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sNamesReservedStore, dbcPath, "NamesReserved.dbc"); + for (uint32 i = 0; i < sNamesProfanityStore.GetNumRows(); ++i) + { + NamesProfanityEntry const* namesProfanity = sNamesProfanityStore.LookupEntry(i); + if (!namesProfanity) + continue; + + ASSERT(namesProfanity->Language < TOTAL_LOCALES || namesProfanity->Language == -1); + if (namesProfanity->Language != -1) + NamesProfaneValidators[namesProfanity->Language].emplace_back(namesProfanity->Name, boost::regex::perl | boost::regex::icase | boost::regex::optimize); + else + for (uint32 i = 0; i < TOTAL_LOCALES; ++i) + NamesProfaneValidators[i].emplace_back(namesProfanity->Name, boost::regex::perl | boost::regex::icase | boost::regex::optimize); + } + + for (uint32 i = 0; i < sNamesReservedStore.GetNumRows(); ++i) + { + NamesReservedEntry const* namesReserved = sNamesReservedStore.LookupEntry(i); + if (!namesReserved) + continue; + + ASSERT(namesReserved->Language < TOTAL_LOCALES || namesReserved->Language == -1); + if (namesReserved->Language != -1) + NamesReservedValidators[namesReserved->Language].emplace_back(namesReserved->Name, boost::regex::perl | boost::regex::icase | boost::regex::optimize); + else + for (uint32 i = 0; i < TOTAL_LOCALES; ++i) + NamesReservedValidators[i].emplace_back(namesReserved->Name, boost::regex::perl | boost::regex::icase | boost::regex::optimize); + } + + LoadDBC(availableDbcLocales, bad_dbc_files, sOverrideSpellDataStore, dbcPath, "OverrideSpellData.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sPowerDisplayStore, dbcPath, "PowerDisplay.dbc"); @@ -1005,3 +1043,20 @@ SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, u return NULL; } + +ResponseCodes ValidateName(std::string const& name, LocaleConstant locale) +{ + if (locale >= TOTAL_LOCALES) + return RESPONSE_FAILURE; + + for (boost::regex const& regex : NamesProfaneValidators[locale]) + if (boost::regex_search(name, regex)) + return CHAR_NAME_PROFANE; + + // regexes at TOTAL_LOCALES are loaded from NamesReserved which is not locale specific + for (boost::regex const& regex : NamesReservedValidators[locale]) + if (boost::regex_search(name, regex)) + return CHAR_NAME_RESERVED; + + return CHAR_NAME_SUCCESS; +} diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 858cd33f8fc..2def7901244 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -22,6 +22,7 @@ #include "Common.h" #include "DBCStore.h" #include "DBCStructure.h" +#include "SharedDefines.h" #include <list> @@ -79,6 +80,8 @@ typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRac typedef std::pair<SkillRaceClassInfoMap::iterator, SkillRaceClassInfoMap::iterator> SkillRaceClassInfoBounds; SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_); +ResponseCodes ValidateName(std::string const& name, LocaleConstant locale); + extern DBCStorage <AchievementEntry> sAchievementStore; extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore; extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 72317a196cb..17e6067047f 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -21,7 +21,6 @@ #include "Common.h" #include "DBCEnums.h" -#include "Define.h" #include "Util.h" // Structures using to access raw DBC data and required packing to portability @@ -1405,6 +1404,20 @@ struct MovieEntry //uint32 unk2; // 2 always 100 }; +struct NamesProfanityEntry +{ + //uint32 ID; // 0 + char const* Name; // 1 + int32 Language; // 2 +}; + +struct NamesReservedEntry +{ + //uint32 ID; // 0 + char const* Name; // 1 + int32 Language; // 2 +}; + #define MAX_OVERRIDE_SPELL 10 struct OverrideSpellDataEntry diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 5c24e6f938a..9ca2ce2edd7 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -88,6 +88,8 @@ char const MailTemplateEntryfmt[] = "nxxxxxxxxxxxxxxxxxssssssssssssssssx"; char const MapEntryfmt[] = "nxiixssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxiii"; char const MapDifficultyEntryfmt[] = "diisxxxxxxxxxxxxxxxxiix"; char const MovieEntryfmt[] = "nxx"; +char const NamesProfanityEntryfmt[] = "dsi"; +char const NamesReservedEntryfmt[] = "dsi"; char const OverrideSpellDatafmt[] = "niiiiiiiiiix"; char const QuestFactionRewardfmt[] = "niiiiiiiiii"; char const QuestSortEntryfmt[] = "nxxxxxxxxxxxxxxxxx"; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a21960fc2bd..e23daeae38f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -17117,7 +17117,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) m_name = fields[2].GetString(); // check name limitations - if (ObjectMgr::CheckPlayerName(m_name) != CHAR_NAME_SUCCESS || + if (ObjectMgr::CheckPlayerName(m_name, GetSession()->GetSessionDbcLocale()) != CHAR_NAME_SUCCESS || (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(m_name))) { diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 16c96ca7425..020028e6274 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -7562,7 +7562,7 @@ bool isValidString(const std::wstring& wstr, uint32 strictMask, bool numericOrSp return false; } -ResponseCodes ObjectMgr::CheckPlayerName(const std::string& name, bool create) +ResponseCodes ObjectMgr::CheckPlayerName(std::string const& name, LocaleConstant locale, bool create /*= false*/) { std::wstring wname; if (!Utf8toWStr(name, wname)) @@ -7584,7 +7584,7 @@ ResponseCodes ObjectMgr::CheckPlayerName(const std::string& name, bool create) if (wname[i] == wname[i-1] && wname[i] == wname[i-2]) return CHAR_NAME_THREE_CONSECUTIVE; - return CHAR_NAME_SUCCESS; + return ValidateName(name, locale); } bool ObjectMgr::IsValidCharterName(const std::string& name) @@ -7605,7 +7605,7 @@ bool ObjectMgr::IsValidCharterName(const std::string& name) return isValidString(wname, strictMask, true); } -PetNameInvalidReason ObjectMgr::CheckPetName(const std::string& name) +PetNameInvalidReason ObjectMgr::CheckPetName(const std::string& name, LocaleConstant locale) { std::wstring wname; if (!Utf8toWStr(name, wname)) @@ -7622,6 +7622,17 @@ PetNameInvalidReason ObjectMgr::CheckPetName(const std::string& name) if (!isValidString(wname, strictMask, false)) return PET_NAME_MIXED_LANGUAGES; + switch (ValidateName(name, locale)) + { + case CHAR_NAME_PROFANE: + return PET_NAME_PROFANE; + case CHAR_NAME_RESERVED: + return PET_NAME_RESERVED; + case RESPONSE_FAILURE: + return PET_NAME_INVALID; + default: + break; + } return PET_NAME_SUCCESS; } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index b84d95973cc..875b5547aef 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1230,8 +1230,8 @@ class ObjectMgr bool IsReservedName(std::string const& name) const; // name with valid structure and symbols - static ResponseCodes CheckPlayerName(std::string const& name, bool create = false); - static PetNameInvalidReason CheckPetName(std::string const& name); + static ResponseCodes CheckPlayerName(std::string const& name, LocaleConstant locale, bool create = false); + static PetNameInvalidReason CheckPetName(std::string const& name, LocaleConstant locale); static bool IsValidCharterName(std::string const& name); static bool CheckDeclinedNames(const std::wstring& w_ownname, DeclinedName const& names); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index d4594be132c..d2cf2d4bae7 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -363,7 +363,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) } // check name limitations - ResponseCodes res = ObjectMgr::CheckPlayerName(createInfo.Name, true); + ResponseCodes res = ObjectMgr::CheckPlayerName(createInfo.Name, GetSessionDbcLocale(), true); if (res != CHAR_NAME_SUCCESS) { SendCharCreate(res); @@ -1095,7 +1095,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData) return; } - ResponseCodes res = ObjectMgr::CheckPlayerName(renameInfo.Name, true); + ResponseCodes res = ObjectMgr::CheckPlayerName(renameInfo.Name, GetSessionDbcLocale(), true); if (res != CHAR_NAME_SUCCESS) { SendCharRename(res, renameInfo); @@ -1394,7 +1394,7 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData) return; } - ResponseCodes res = ObjectMgr::CheckPlayerName(customizeInfo.Name, true); + ResponseCodes res = ObjectMgr::CheckPlayerName(customizeInfo.Name, GetSessionDbcLocale(), true); if (res != CHAR_NAME_SUCCESS) { SendCharCustomize(res, customizeInfo); @@ -1652,7 +1652,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) return; } - ResponseCodes res = ObjectMgr::CheckPlayerName(factionChangeInfo.Name, true); + ResponseCodes res = ObjectMgr::CheckPlayerName(factionChangeInfo.Name, GetSessionDbcLocale(), true); if (res != CHAR_NAME_SUCCESS) { SendCharFactionChange(res, factionChangeInfo); diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 4495c044c61..8c3c3e9082b 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -600,7 +600,7 @@ void WorldSession::HandlePetRename(WorldPacket& recvData) pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo()) return; - PetNameInvalidReason res = ObjectMgr::CheckPetName(name); + PetNameInvalidReason res = ObjectMgr::CheckPetName(name, GetSessionDbcLocale()); if (res != PET_NAME_SUCCESS) { SendPetNameInvalid(res, name, NULL); diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index e3a0246633d..0a47da1c788 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -426,7 +426,7 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s if (!normalizePlayerName(name)) name.clear(); - if (ObjectMgr::CheckPlayerName(name, true) == CHAR_NAME_SUCCESS) + if (ObjectMgr::CheckPlayerName(name, sWorld->GetDefaultDbcLocale(), true) == CHAR_NAME_SUCCESS) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME); stmt->setString(0, name); diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp index 230d407b71a..65dd44f8563 100644 --- a/src/server/scripts/Commands/cs_character.cpp +++ b/src/server/scripts/Commands/cs_character.cpp @@ -335,7 +335,7 @@ public: return false; } - if (ObjectMgr::CheckPlayerName(newName, true) != CHAR_NAME_SUCCESS) + if (ObjectMgr::CheckPlayerName(newName, target ? target->GetSession()->GetSessionDbcLocale() : sWorld->GetDefaultDbcLocale(), true) != CHAR_NAME_SUCCESS) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); @@ -895,7 +895,7 @@ public: return false; } - if (ObjectMgr::CheckPlayerName(name, true) != CHAR_NAME_SUCCESS) + if (ObjectMgr::CheckPlayerName(name, sWorld->GetDefaultDbcLocale(), true) != CHAR_NAME_SUCCESS) { handler->PSendSysMessage(LANG_INVALID_CHARACTER_NAME); handler->SetSentErrorMessage(true); |