diff options
-rw-r--r-- | sql/updates/83_realmd.sql | 2 | ||||
-rw-r--r-- | src/game/CharacterHandler.cpp | 20 | ||||
-rw-r--r-- | src/game/Chat.cpp | 2 | ||||
-rw-r--r-- | src/game/Map.cpp | 2 | ||||
-rw-r--r-- | src/game/ObjectMgr.cpp | 4 | ||||
-rw-r--r-- | src/game/Player.cpp | 27 | ||||
-rw-r--r-- | src/game/SharedDefines.h | 8 | ||||
-rw-r--r-- | src/game/WorldSession.cpp | 4 | ||||
-rw-r--r-- | src/game/WorldSession.h | 7 | ||||
-rw-r--r-- | src/game/WorldSocket.cpp | 11 | ||||
-rw-r--r-- | src/shared/ByteBuffer.h | 8 | ||||
-rw-r--r-- | src/shared/Database/DBCStores.cpp | 10 | ||||
-rw-r--r-- | src/shared/Database/DBCStores.h | 3 | ||||
-rw-r--r-- | src/shared/Database/DBCStructure.h | 4 | ||||
-rw-r--r-- | src/shared/Database/DBCfmt.cpp | 2 | ||||
-rw-r--r-- | src/trinitycore/CliRunnable.cpp | 24 | ||||
-rw-r--r-- | src/trinitycore/trinitycore.conf.dist | 10 |
17 files changed, 80 insertions, 68 deletions
diff --git a/sql/updates/83_realmd.sql b/sql/updates/83_realmd.sql new file mode 100644 index 00000000000..344fdbed948 --- /dev/null +++ b/sql/updates/83_realmd.sql @@ -0,0 +1,2 @@ +ALTER TABLE account
+ CHANGE COLUMN tbc expansion tinyint(3) unsigned NOT NULL default '0';
\ No newline at end of file diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 36e0720a08d..efcc337fc30 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -179,7 +179,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) std::string name; uint8 race_,class_; - bool pTbc = this->IsTBC() && sWorld.getConfig(CONFIG_EXPANSION) > 0; recv_data >> name; // recheck with known string size @@ -212,8 +211,9 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) } } - if (!sChrClassesStore.LookupEntry(class_)|| - !sChrRacesStore.LookupEntry(race_)) + ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_); + ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race_); + if( !classEntry || !raceEntry ) { data << (uint8)CHAR_CREATE_FAILED; SendPacket( &data ); @@ -222,10 +222,20 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) } // prevent character creating Expansion race without Expansion account - if (!pTbc&&(race_>RACE_TROLL)) + if (raceEntry->addon > Expansion()) { data << (uint8)CHAR_CREATE_EXPANSION; - sLog.outError("No Expansion Account:[%d] but tried to Create TBC character",GetAccountId()); + sLog.outError("Not Expansion 1 account:[%d] but tried to Create character with expansion 1 race (%u)",GetAccountId(),race_); + SendPacket( &data ); + return; + } + + // prevent character creating Expansion class without Expansion account + // TODO: use possible addon field in ChrClassesEntry in next dbc version + if (Expansion() < 2 && class_ == CLASS_DEATH_KNIGHT) + { + data << (uint8)CHAR_CREATE_EXPANSION; + sLog.outError("Not Expansion 2 account:[%d] but tried to Create character with expansion 2 class (%u)",GetAccountId(),class_); SendPacket( &data ); return; } diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index b8950d5da82..2f5eb5d71fb 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -626,7 +626,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, st for(uint32 i = 0; table[i].Name != NULL; i++) { - if( !hasStringAbbr(table[i].Name, cmd.c_str()) ) + if( *subcmd && !hasStringAbbr(table[i].Name, subcmd)) continue; // select subcommand from child commands list diff --git a/src/game/Map.cpp b/src/game/Map.cpp index b3d41ed254d..123cbeef2f1 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -18,6 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "MapManager.h" #include "Player.h" #include "GridNotifiers.h" #include "WorldSession.h" @@ -35,7 +36,6 @@ #include "ScriptCalls.h" #include "Group.h" -#include "MapManager.h" #include "MapInstanced.h" #include "InstanceSaveMgr.h" #include "VMapFactory.h" diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 3783efaf0f9..7affe141f89 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -2370,6 +2370,10 @@ void ObjectMgr::LoadPlayerInfo() // skip expansion races if not playing with expansion if (sWorld.getConfig(CONFIG_EXPANSION) < 1 && (race == RACE_BLOODELF || race == RACE_DRAENEI)) continue; + + // skip expansion classes if not playing with expansion + if (sWorld.getConfig(CONFIG_EXPANSION) < 2 && class_ == CLASS_DEATH_KNIGHT) + continue; // fatal error if no level 1 data if(!pInfo->levelInfo || pInfo->levelInfo[0].stats[0] == 0 ) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 561bf938df8..8e692eaccee 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1515,12 +1515,10 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if(!InBattleGround() && mEntry->IsBattleGroundOrArena()) return false; - bool tbc = GetSession()->IsTBC() && sWorld.getConfig(CONFIG_EXPANSION) > 0; - - // normal client and TBC map - if(!tbc && mEntry->IsExpansionMap()) + // client without expansion support + if(GetSession()->Expansion() < mEntry->Expansion()) { - sLog.outDebug("Player %s using Normal client and tried teleport to non existing map %u", GetName(), mapid); + sLog.outDebug("Player %s using client without required expansion tried teleport to non accessable map %u", GetName(), mapid); if(GetTransport()) RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :) @@ -1529,27 +1527,10 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return false; // normal client can't teleport to this map... } - else if(tbc) // can teleport to any existing map - { - sLog.outDebug("Player %s have TBC client and will teleported to map %u", GetName(), mapid); - } else { - sLog.outDebug("Player %s have normal client and will teleported to standard map %u", GetName(), mapid); + sLog.outDebug("Player %s will teleported to map %u", GetName(), mapid); } - /* - only TBC (no 0x80000 and 0x10 flags...) - 3604590=0x37006E=0x200000 + 0x100000 + 0x40000 + 0x20000 + 0x10000 + 0x40 + 0x20 + 0x8 + 0x4 + 0x2 - - Kharazan (normal/TBC??), but not have 0x10 flag (accessible by normal client?) - 4128878=0x3F006E=0x200000 + 0x100000 + 0x80000 + 0x40000 + 0x20000 + 0x10000 + 0x40 + 0x20 + 0x8 + 0x4 + 0x2 - - normal+TBC maps - 4128894=0x3F007E=0x200000 + 0x100000 + 0x80000 + 0x40000 + 0x20000 + 0x10000 + 0x40 + 0x20 + 0x10 + 0x8 + 0x4 + 0x2 - - normal+TBC maps - 8323198=0x7F007E=0x400000 + 0x200000 + 0x100000 + 0x80000 + 0x40000 + 0x20000 + 0x10000 + 0x40 + 0x20 + 0x10 + 0x8 + 0x4 + 0x2 - */ // if we were on a transport, leave if (!(options & TELE_TO_NOT_LEAVE_TRANSPORT) && m_transport) diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 4d001b37183..ad5426aeff1 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -66,7 +66,7 @@ enum Classes CLASS_HUNTER = 3, CLASS_ROGUE = 4, CLASS_PRIEST = 5, - // CLASS_UNK1 = 6, DK + CLASS_DEATH_KNIGHT = 6, CLASS_SHAMAN = 7, CLASS_MAGE = 8, CLASS_WARLOCK = 9, @@ -961,7 +961,7 @@ enum GameobjectTypes GAMEOBJECT_TYPE_CAPTURE_POINT = 29, GAMEOBJECT_TYPE_AURA_GENERATOR = 30, GAMEOBJECT_TYPE_DUNGEON_DIFFICULTY = 31, - GAMEOBJECT_TYPE_DO_NOT_USE_YET = 32, + GAMEOBJECT_TYPE_BARBER_CHAIR = 32, GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING = 33, GAMEOBJECT_TYPE_GUILD_BANK = 34, }; @@ -1549,7 +1549,7 @@ enum TrainerType // this is important enum CreatureType { CREATURE_TYPE_BEAST = 1, - CREATURE_TYPE_DRAGON = 2, + CREATURE_TYPE_DRAGONKIN = 2, CREATURE_TYPE_DEMON = 3, CREATURE_TYPE_ELEMENTAL = 4, CREATURE_TYPE_GIANT = 5, @@ -1557,7 +1557,7 @@ enum CreatureType CREATURE_TYPE_HUMANOID = 7, CREATURE_TYPE_CRITTER = 8, CREATURE_TYPE_MECHANICAL = 9, - CREATURE_TYPE_NOTSPECIFIED = 10, + CREATURE_TYPE_NOT_SPECIFIED = 10, CREATURE_TYPE_TOTEM = 11, CREATURE_TYPE_NON_COMBAT_PET = 12, CREATURE_TYPE_GAS_CLOUD = 13 diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index fe605df17ab..194c2da640f 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -44,9 +44,9 @@ #include "SocialMgr.h" /// WorldSession constructor -WorldSession::WorldSession(uint32 id, WorldSocket *sock, uint32 sec, bool tbc, time_t mute_time, LocaleConstant locale) : +WorldSession::WorldSession(uint32 id, WorldSocket *sock, uint32 sec, uint8 expansion, time_t mute_time, LocaleConstant locale) : LookingForGroup_auto_join(false), LookingForGroup_auto_add(false), m_muteTime(mute_time), -_player(NULL), m_Socket(sock),_security(sec), _accountId(id), m_isTBC(tbc), +_player(NULL), m_Socket(sock),_security(sec), _accountId(id), m_expansion(expansion), m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(objmgr.GetIndexForLocale(locale)), _logoutTime(0), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false), m_latency(0) { diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 125785c5e5a..56e390526cd 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -71,7 +71,7 @@ class TRINITY_DLL_SPEC WorldSession { friend class CharacterHandler; public: - WorldSession(uint32 id, WorldSocket *sock, uint32 sec, bool tbc, time_t mute_time, LocaleConstant locale); + WorldSession(uint32 id, WorldSocket *sock, uint32 sec, uint8 expansion, time_t mute_time, LocaleConstant locale); ~WorldSession(); bool PlayerLoading() const { return m_playerLoading; } @@ -88,12 +88,13 @@ class TRINITY_DLL_SPEC WorldSession uint32 GetSecurity() const { return _security; } uint32 GetAccountId() const { return _accountId; } + //std::string const& GetRemoteAddress() const { return m_remoteaddress; } Player* GetPlayer() const { return _player; } char const* GetPlayerName() const; void SetSecurity(uint32 security) { _security = security; } std::string& GetRemoteAddress() { return m_Address; } void SetPlayer(Player *plr) { _player = plr; } - bool IsTBC() const { return m_isTBC; } + uint8 Expansion() const { return m_expansion; } /// Is the user engaged in a log out process? bool isLogingOut() const { return _logoutTime || m_playerLogout; } @@ -629,7 +630,7 @@ class TRINITY_DLL_SPEC WorldSession uint32 _security; uint32 _accountId; - bool m_isTBC; + uint8 m_expansion; time_t _logoutTime; bool m_playerLoading; // code processed in LoginPlayer diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp index aecee68b002..8df89ac40f5 100644 --- a/src/game/WorldSocket.cpp +++ b/src/game/WorldSocket.cpp @@ -678,7 +678,7 @@ WorldSocket::HandleAuthSession (WorldPacket& recvPacket) uint32 unk2; uint32 BuiltNumberClient; uint32 id, security; - bool tbc = false; + uint8 expansion = 0; LocaleConstant locale; std::string account; Sha1Hash sha1; @@ -728,7 +728,7 @@ WorldSocket::HandleAuthSession (WorldPacket& recvPacket) "sha_pass_hash, " //5 "v, " //6 "s, " //7 - "tbc, " //8 + "expansion, " //8 "mutetime, " //9 "locale " //10 "FROM account " @@ -749,7 +749,10 @@ WorldSocket::HandleAuthSession (WorldPacket& recvPacket) Field* fields = result->Fetch (); - tbc = fields[8].GetUInt8 () && sWorld.getConfig (CONFIG_EXPANSION) > 0; + uint8 expansion = fields[8].GetUInt8(); + uint32 world_expansion = sWorld.getConfig(CONFIG_EXPANSION); + if(expansion > world_expansion) + expansion = world_expansion; N.SetHexStr ("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); g.SetDword (7); @@ -909,7 +912,7 @@ WorldSocket::HandleAuthSession (WorldPacket& recvPacket) // TODO protect here probably ? // Althought atm the socket is singlethreaded - ACE_NEW_RETURN (m_Session, WorldSession (id, this, security, tbc, mutetime, locale), -1); + ACE_NEW_RETURN (m_Session, WorldSession (id, this, security, expansion, mutetime, locale), -1); m_Crypt.SetKey (&K); m_Crypt.Init (); diff --git a/src/shared/ByteBuffer.h b/src/shared/ByteBuffer.h index f2f6f45acbd..e7a28d739ba 100644 --- a/src/shared/ByteBuffer.h +++ b/src/shared/ByteBuffer.h @@ -201,7 +201,7 @@ class ByteBuffer return *this; } - uint8 operator[](size_t pos) + uint8 operator[](size_t pos) const { return read<uint8>(pos); } @@ -309,7 +309,7 @@ class ByteBuffer ASSERT(pos + cnt <= size() || PrintPosError(true,pos,cnt)); memcpy(&_storage[pos], src, cnt); } - void print_storage() + void print_storage() const { if(!sLog.IsOutDebug()) // optimize disabled debug output return; @@ -320,7 +320,7 @@ class ByteBuffer sLog.outDebug(" "); } - void textlike() + void textlike() const { if(!sLog.IsOutDebug()) // optimize disabled debug output return; @@ -331,7 +331,7 @@ class ByteBuffer sLog.outDebug(" "); } - void hexlike() + void hexlike() const { if(!sLog.IsOutDebug()) // optimize disabled debug output return; diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp index 685f9c893ce..0bcc177e500 100644 --- a/src/shared/Database/DBCStores.cpp +++ b/src/shared/Database/DBCStores.cpp @@ -554,7 +554,15 @@ ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId) return CONTENT_1_60; MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); - return (!mapEntry || !mapEntry->IsExpansionMap()) ? CONTENT_1_60 : CONTENT_61_70; + if(!mapEntry) + return CONTENT_1_60; + + switch(mapEntry->Expansion()) + { + default: return CONTENT_1_60; + case 1: return CONTENT_61_70; + case 2: return CONTENT_71_80; + } } ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id) diff --git a/src/shared/Database/DBCStores.h b/src/shared/Database/DBCStores.h index 5d2d60bd117..73c718b4971 100644 --- a/src/shared/Database/DBCStores.h +++ b/src/shared/Database/DBCStores.h @@ -44,7 +44,8 @@ uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId); enum ContentLevels { CONTENT_1_60 = 0, - CONTENT_61_70 + CONTENT_61_70, + CONTENT_71_80 }; ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId); diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index fa8048b96a4..68ade69dfe9 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -179,7 +179,7 @@ struct ChrRacesEntry //char* string2[16]; // 48-63 used for DBC language detection/selection // 64 string flags, unused // 65-67 unused - //uint32 addon // 68 (0 - original race, 1 - tbc addon, ...) unused + uint32 addon; // 68 (0 - original race, 1 - tbc addon, ...) }; struct CreatureDisplayInfoEntry @@ -473,7 +473,7 @@ struct MapEntry uint32 addon; // 124 (0-original maps,1-tbc addon) // Helpers - bool IsExpansionMap() const { return addon != 0; } + uint32 Expansion() const { return addon; } bool IsDungeon() const { return map_type == MAP_INSTANCE || map_type == MAP_RAID; } diff --git a/src/shared/Database/DBCfmt.cpp b/src/shared/Database/DBCfmt.cpp index 52b5e5faf47..c2a6c1e4b33 100644 --- a/src/shared/Database/DBCfmt.cpp +++ b/src/shared/Database/DBCfmt.cpp @@ -27,7 +27,7 @@ const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx"; // ChatChannelsEntryfmt, index not used (more compact store) //const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix"; const char ChrClassesEntryfmt[]="nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix"; -const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxx"; const char CreatureFamilyfmt[]="nfifiiiissssssssssssssssxx"; const char CreatureSpellDatafmt[]="nxxxxxxxx"; diff --git a/src/trinitycore/CliRunnable.cpp b/src/trinitycore/CliRunnable.cpp index b94176178f8..ee4e5c3be54 100644 --- a/src/trinitycore/CliRunnable.cpp +++ b/src/trinitycore/CliRunnable.cpp @@ -67,7 +67,7 @@ void CliMotd(char*,pPrintf); void CliCorpses(char*,pPrintf); void CliSetLogLevel(char*,pPrintf); void CliUpTime(char*,pPrintf); -void CliSetTBC(char*,pPrintf); +void CliSetAddon(char*,pPrintf); void CliWritePlayerDump(char*,pPrintf); void CliLoadPlayerDump(char*,pPrintf); void CliSave(char*,pPrintf); @@ -91,7 +91,7 @@ const CliCommand Commands[]= {"unban", & CliRemoveBan,"Remove ban from account|ip"}, {"setgm", & CliSetGM,"Edit user privileges"}, {"setpass", & CliSetPassword,"Set password for account"}, - {"setbc", & CliSetTBC,"Set user expansion allowed"}, + {"setaddon", & CliSetAddon,"Set user expansion addon level allowed"}, {"listgm", & CliListGM,"Display user privileges"}, {"loadscripts", & CliLoadScripts,"Load script library"}, {"setloglevel", & CliSetLogLevel,"Set Log Level"}, @@ -472,7 +472,7 @@ void CliInfo(char*,pPrintf zprintf) ///- Display the list of account/characters online zprintf("=====================================================================\r\n"); - zprintf("| Account | Character | IP | GM | TBC |\r\n"); + zprintf("| Account | Character | IP | GM | Exp |\r\n"); zprintf("=====================================================================\r\n"); ///- Circle through accounts @@ -485,7 +485,7 @@ void CliInfo(char*,pPrintf zprintf) ///- Get the username, last IP and GM level of each account // No SQL injection. account is uint32. // 0 1 2 3 - QueryResult *resultLogin = loginDatabase.PQuery("SELECT username, last_ip, gmlevel, tbc FROM account WHERE id = '%u'",account); + QueryResult *resultLogin = loginDatabase.PQuery("SELECT username, last_ip, gmlevel, expansion FROM account WHERE id = '%u'",account); if(resultLogin) { @@ -1037,23 +1037,23 @@ void CliUpTime(char*,pPrintf zprintf) } /// Set/Unset the TBC flag for an account -void CliSetTBC(char *command,pPrintf zprintf) +void CliSetAddon(char *command,pPrintf zprintf) { ///- Get the command line arguments char *szAcc = strtok(command," "); - char *szTBC = strtok(NULL," "); + char *szExp = strtok(NULL," "); - if(!szAcc||!szTBC) + if(!szAcc||!szExp) { - zprintf("Syntax is: setbc $account $number (0 - normal, 1 - tbc)>\r\n"); + zprintf("Syntax is: setbc $account $number (0 - normal, 1 - tbc, 2 - wotlk)>\r\n"); return; } - int lev=atoi(szTBC); //get int anyway (0 if error) + int lev=atoi(szExp); //get int anyway (0 if error) - if((lev > 1)|| (lev < 0)) + if(lev < 0) { - zprintf("Syntax is: setbc $account $number (0 - normal, 1 - tbc)>\r\n"); + zprintf("Syntax is: setbc $account $number (0 - normal, 1 - tbc, 2 - wotlk)>\r\n"); return; } @@ -1074,7 +1074,7 @@ void CliSetTBC(char *command,pPrintf zprintf) if (result) { // No SQL injection (account name is escaped) - loginDatabase.PExecute("UPDATE account SET tbc = '%d' WHERE username = '%s'",lev,safe_account_name.c_str()); + loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE username = '%s'",lev,safe_account_name.c_str()); zprintf("We set %s to expansion allowed %d\r\n",safe_account_name.c_str(),lev); delete result; diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist index 7e4351e8779..9bd69ec6c5e 100644 --- a/src/trinitycore/trinitycore.conf.dist +++ b/src/trinitycore/trinitycore.conf.dist @@ -354,10 +354,12 @@ LogColors = "" # 29 CN9 - basic-Latin at create, any at login # # Expansion -# Allow server use expansion content -# Default: 1 - check expansion maps existence, and if client support expansion and account have -# expansion setting then allow visit expansion maps, allow create new races character) -# 0 - not check expansion maps existence, not allow wisit its, not allow create new race +# Allow server use content from expansion +# 2 - check expansion 2 maps existence, and if client support expansion 2 and account have +# expansion 2 setting then allow visit expansion 2 maps, allow create new class character) +# Default: 1 - check expansion 1 maps existence, and if client support expansion 1 and account have +# expansion 1 setting then allow visit expansion 1 maps, allow create new races character) +# 0 - not check expansion maps existence, not allow wisit its, not allow create new race or new class # characters, ignore account expansion setting) # # DBC.Locale |