diff options
23 files changed, 223 insertions, 140 deletions
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 9b8f0447527..69617deee5f 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -17,6 +17,7 @@ */ #include "DBCStores.h" +#include "Containers.h" #include "Log.h" #include "SharedDefines.h" #include "SpellMgr.h" @@ -164,7 +165,7 @@ DBCStorage <MountCapabilityEntry> sMountCapabilityStore(MountCapabilityfmt); DBCStorage <MountTypeEntry> sMountTypeStore(MountTypefmt); DBCStorage <NameGenEntry> sNameGenStore(NameGenfmt); -NameGenVectorArraysMap sGenNameVectoArraysMap; +NameGenContainer sGenerateNamesMap; DBCStorage <NumTalentsAtLevelEntry> sNumTalentsAtLevelStore(NumTalentsAtLevelfmt); DBCStorage <OverrideSpellDataEntry> sOverrideSpellDataStore(OverrideSpellDatafmt); @@ -488,11 +489,12 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales, bad_dbc_files, sMountCapabilityStore, dbcPath, "MountCapability.dbc");//15595 LoadDBC(availableDbcLocales, bad_dbc_files, sMountTypeStore, dbcPath, "MountType.dbc");//15595 - LoadDBC(availableDbcLocales, bad_dbc_files, sNameGenStore, dbcPath, "NameGen.dbc");//15595 + LoadDBC(availableDbcLocales, bad_dbc_files, sNameGenStore, dbcPath, "NameGen.dbc"); // 19116 for (uint32 i = 0; i < sNameGenStore.GetNumRows(); ++i) if (NameGenEntry const* entry = sNameGenStore.LookupEntry(i)) - sGenNameVectoArraysMap[entry->race].stringVectorArray[entry->gender].push_back(std::string(entry->name)); + sGenerateNamesMap[entry->Race].Contents[entry->Sex].emplace_back(entry->Name); sNameGenStore.Clear(); + LoadDBC(availableDbcLocales, bad_dbc_files, sNumTalentsAtLevelStore, dbcPath, "NumTalentsAtLevel.dbc");//15595 LoadDBC(availableDbcLocales, bad_dbc_files, sMovieStore, dbcPath, "Movie.dbc");//15595 @@ -800,7 +802,7 @@ void LoadDBCStores(const std::string& dataPath) sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry)); LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc");//15595 LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapOverlayStore, dbcPath, "WorldMapOverlay.dbc");//15595 - LoadDBC(availableDbcLocales, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc");//15595 + LoadDBC(availableDbcLocales, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc"); // 19116 // error checks if (bad_dbc_files.size() >= DBCFileCount) @@ -832,12 +834,10 @@ void LoadDBCStores(const std::string& dataPath) TC_LOG_INFO("server.loading", ">> Initialized %d DBC data stores in %u ms", DBCFileCount, GetMSTimeDiffToNow(oldMSTime)); } -const std::string* GetRandomCharacterName(uint8 race, uint8 gender) +std::string const& GetRandomCharacterName(uint8 race, uint8 gender) { - uint32 size = sGenNameVectoArraysMap[race].stringVectorArray[gender].size(); - uint32 randPos = urand(0, size-1); - - return &sGenNameVectoArraysMap[race].stringVectorArray[gender][randPos]; + ASSERT(gender < GENDER_NONE); + return Trinity::Containers::SelectRandomContainerElement(sGenerateNamesMap[race].Contents[gender]); } SimpleFactionsList const* GetFactionTeamList(uint32 faction) diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 885f6041a60..994e830431e 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -44,7 +44,7 @@ WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId); -const std::string* GetRandomCharacterName(uint8 race, uint8 gender); +std::string const& GetRandomCharacterName(uint8 race, uint8 gender); enum ContentLevels { diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index f13abe888ae..8ac2af5d8ab 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -1578,10 +1578,10 @@ struct MovieEntry struct NameGenEntry { - //uint32 id; - char* name; - uint32 race; - uint32 gender; + //uint32 Id; + char* Name; + uint32 Race; + uint32 Sex; }; struct NumTalentsAtLevelEntry @@ -2475,10 +2475,10 @@ struct WorldStateUI struct VectorArray { - std::vector<std::string> stringVectorArray[2]; + std::vector<std::string> Contents[2]; }; -typedef std::map<uint32, VectorArray> NameGenVectorArraysMap; +typedef std::map<uint32, VectorArray> NameGenContainer; // Structures not used for casting to loaded DBC data and not required then packing struct MapDifficulty diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 2df22b0f9e2..a7fd0ca34ef 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -1477,12 +1477,12 @@ void Guild::HandleRoster(WorldSession* session) void Guild::SendQueryResponse(WorldSession* session) { - WorldPackets::Guild::GuildQueryResponse response; + WorldPackets::Guild::QueryGuildInfoResponse response; response.GuildGuid = GetGUID(); response.Info.HasValue = true; - response.Info.value.GuildGuid = GetGUID(); - response.Info.value.VirtualRealmAddress = realmHandle.Index; + response.Info.value.GuildGUID = GetGUID(); + response.Info.value.VirtualRealmAddress = GetVirtualRealmAddress(); response.Info.value.EmblemStyle = m_emblemInfo.GetStyle(); response.Info.value.EmblemColor = m_emblemInfo.GetColor(); @@ -1493,7 +1493,7 @@ void Guild::SendQueryResponse(WorldSession* session) for (uint8 i = 0; i < _GetRanksSize(); ++i) response.Info.value.Ranks.emplace(m_ranks[i].GetId(), i, m_ranks[i].GetName()); - response.Info.value.Name = m_name; + response.Info.value.GuildName = m_name; session->SendPacket(response.Write()); TC_LOG_DEBUG("guild", "SMSG_GUILD_QUERY_RESPONSE [%s]", session->GetPlayerInfo().c_str()); diff --git a/src/server/game/Handlers/AuthHandler.cpp b/src/server/game/Handlers/AuthHandler.cpp index fee7ad2542f..c9e1e6508b9 100644 --- a/src/server/game/Handlers/AuthHandler.cpp +++ b/src/server/game/Handlers/AuthHandler.cpp @@ -15,11 +15,10 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ObjectMgr.h" -#include "Opcodes.h" #include "WorldSession.h" -#include "WorldPacket.h" +#include "ObjectMgr.h" #include "AuthenticationPackets.h" +#include "ClientConfigPackets.h" #include "SystemPackets.h" void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos) @@ -33,12 +32,12 @@ void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos) { response.SuccessInfo.value.AccountExpansionLevel = Expansion(); response.SuccessInfo.value.ActiveExpansionLevel = Expansion(); - response.SuccessInfo.value.VirtualRealmAddress = realmHandle.Index; + response.SuccessInfo.value.VirtualRealmAddress = GetVirtualRealmAddress(); std::string realmName = sObjectMgr->GetRealmName(realmHandle.Index); // Send current home realm. Also there is no need to send it later in realm queries. - response.SuccessInfo.value.VirtualRealms.emplace_back(realmHandle.Index, true, false, realmName, realmName); + response.SuccessInfo.value.VirtualRealms.emplace_back(GetVirtualRealmAddress(), true, false, realmName, realmName); response.SuccessInfo.value.AvailableClasses = &sObjectMgr->GetClassExpansionRequirements(); response.SuccessInfo.value.AvailableRaces = &sObjectMgr->GetRaceExpansionRequirements(); @@ -70,9 +69,10 @@ void WorldSession::SendAuthWaitQue(uint32 position) void WorldSession::SendClientCacheVersion(uint32 version) { - WorldPacket data(SMSG_CLIENTCACHE_VERSION, 4); - data << uint32(version); - SendPacket(&data); + WorldPackets::ClientConfig::ClientCacheVersion cache; + cache.CacheVersion = version; + + SendPacket(cache.Write()); } void WorldSession::SendSetTimeZoneInformation() diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 797f7de6210..6845ebb383b 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -44,6 +44,7 @@ #include "SharedDefines.h" #include "SocialMgr.h" #include "SystemConfig.h" +#include "SystemPackets.h" #include "UpdateMask.h" #include "Util.h" #include "World.h" @@ -863,36 +864,14 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) // Send MOTD { - data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 - data << (uint32)0; - - uint32 linecount=0; - std::string str_motd = sWorld->GetMotd(); - std::string::size_type pos, nextpos; - - pos = 0; - while ((nextpos= str_motd.find('@', pos)) != std::string::npos) - { - if (nextpos != pos) - { - data << str_motd.substr(pos, nextpos-pos); - ++linecount; - } - pos = nextpos+1; - } - - if (pos<str_motd.length()) - { - data << str_motd.substr(pos); - ++linecount; - } - - data.put(0, linecount); - - SendPacket(&data); + WorldPackets::System::MOTD motd; + motd.Text = &sWorld->GetMotd(); + SendPacket(motd.Write()); TC_LOG_DEBUG("network", "WORLD: Sent motd (SMSG_MOTD)"); + } - // send server info + // send server info + { if (sWorld->getIntConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1) chH.PSendSysMessage(_FULLVERSION); @@ -2163,31 +2142,25 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) SendCharFactionChange(RESPONSE_SUCCESS, factionChangeInfo); } -void WorldSession::HandleRandomizeCharNameOpcode(WorldPacket& recvData) +void WorldSession::HandleRandomizeCharNameOpcode(WorldPackets::Character::GenerateRandomCharacterName& packet) { - uint8 gender, race; - - recvData >> race; - recvData >> gender; - - if (!Player::IsValidRace(race)) + if (!Player::IsValidRace(packet.Race)) { - TC_LOG_ERROR("misc", "Invalid race (%u) sent by accountId: %u", race, GetAccountId()); + TC_LOG_ERROR("misc", "Invalid race (%u) sent by accountId: %u", packet.Race, GetAccountId()); return; } - if (!Player::IsValidGender(gender)) + if (!Player::IsValidGender(packet.Sex)) { - TC_LOG_ERROR("misc", "Invalid gender (%u) sent by accountId: %u", gender, GetAccountId()); + TC_LOG_ERROR("misc", "Invalid gender (%u) sent by accountId: %u", packet.Sex, GetAccountId()); return; } - std::string const* name = GetRandomCharacterName(race, gender); - WorldPacket data(SMSG_RANDOMIZE_CHAR_NAME, 10); - data.WriteBit(0); // unk - data.WriteBits(name->size(), 7); - data.WriteString(*name); - SendPacket(&data); + WorldPackets::Character::GenerateRandomCharacterNameResult result; + result.Success = true; + result.Name = GetRandomCharacterName(packet.Race, packet.Sex); + + SendPacket(result.Write()); } void WorldSession::HandleReorderCharacters(WorldPackets::Character::ReorderCharacters& reorderChars) diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp index 9370dd726ba..23078ea5fc9 100644 --- a/src/server/game/Handlers/GuildHandler.cpp +++ b/src/server/game/Handlers/GuildHandler.cpp @@ -29,7 +29,7 @@ #include "SocialMgr.h" #include "GuildPackets.h" -void WorldSession::HandleGuildQueryOpcode(WorldPackets::Guild::GuildQuery& query) +void WorldSession::HandleGuildQueryOpcode(WorldPackets::Guild::QueryGuildInfo& query) { TC_LOG_DEBUG("guild", "CMSG_GUILD_QUERY [%s]: Guild: %s Target: %s", GetPlayerInfo().c_str(), query.GuildGuid.ToString().c_str(), query.PlayerGuid.ToString().c_str()); @@ -41,7 +41,7 @@ void WorldSession::HandleGuildQueryOpcode(WorldPackets::Guild::GuildQuery& query return; } - WorldPackets::Guild::GuildQueryResponse response; + WorldPackets::Guild::QueryGuildInfoResponse response; response.GuildGuid = query.GuildGuid; SendPacket(response.Write()); diff --git a/src/server/game/Server/Packets/AuthenticationPackets.h b/src/server/game/Server/Packets/AuthenticationPackets.h index e19dfc812e8..1d194b0b2a9 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.h +++ b/src/server/game/Server/Packets/AuthenticationPackets.h @@ -105,7 +105,7 @@ namespace WorldPackets uint32 TimeRested = 0; ///< affects the return value of the GetBillingTimeRested() client API call, it is the number of seconds you have left until the experience points and loot you receive from creatures and quests is reduced. It is only used in the Asia region in retail, it's not implemented in TC and will probably never be. uint8 TimeOptions = 0; ///< controls the behavior of the client regarding billing, used in Asia realms, as they don't have monthly subscriptions, possible values are in @ref BillingPlanFlags. It is not currently implemented and will probably never be. - uint32 VirtualRealmAddress = 0; ///< a special identifier made from the Index, BattleGroup and Region. @todo implement + uint32 VirtualRealmAddress = 0; ///< a special identifier made from the Index, BattleGroup and Region. uint32 RealmNamesCount = 0; ///< the number of realms connected to this one (inclusive). @todo implement uint32 TimeSecondsUntilPCKick = 0; ///< @todo research uint32 CurrencyID = 0; ///< this is probably used for the ingame shop. @todo implement diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp index 500799989fc..790402c473f 100644 --- a/src/server/game/Server/Packets/CharacterPackets.cpp +++ b/src/server/game/Server/Packets/CharacterPackets.cpp @@ -241,6 +241,29 @@ WorldPacket const* WorldPackets::Character::CharacterDeleteResponse::Write() return &_worldPacket; } +WorldPackets::Character::GenerateRandomCharacterName::GenerateRandomCharacterName(WorldPacket&& packet) + : ClientPacket(std::move(packet)) +{ + ASSERT(_worldPacket.GetOpcode() == CMSG_RANDOMIZE_CHAR_NAME); +} + +void WorldPackets::Character::GenerateRandomCharacterName::Read() +{ + _worldPacket >> Race; + _worldPacket >> Sex; +} + +WorldPackets::Character::GenerateRandomCharacterNameResult::GenerateRandomCharacterNameResult() + : ServerPacket(SMSG_RANDOMIZE_CHAR_NAME, 20) { } + +WorldPacket const* WorldPackets::Character::GenerateRandomCharacterNameResult::Write() +{ + _worldPacket.WriteBit(Success); + _worldPacket.WriteBits(Name.length(), 6); + _worldPacket.WriteString(Name); + return &_worldPacket; +} + WorldPackets::Character::ReorderCharacters::ReorderCharacters(WorldPacket&& packet) : ClientPacket(std::move(packet)) { diff --git a/src/server/game/Server/Packets/CharacterPackets.h b/src/server/game/Server/Packets/CharacterPackets.h index 4bb97d8a2d2..57a81e0ed11 100644 --- a/src/server/game/Server/Packets/CharacterPackets.h +++ b/src/server/game/Server/Packets/CharacterPackets.h @@ -203,6 +203,28 @@ namespace WorldPackets uint8 Code = 0; ///< Result code @see enum ResponseCodes }; + class GenerateRandomCharacterName final : public ClientPacket + { + public: + GenerateRandomCharacterName(WorldPacket&& packet); + + void Read() override; + + uint8 Sex = 0; + uint8 Race = 0; + }; + + class GenerateRandomCharacterNameResult final : public ServerPacket + { + public: + GenerateRandomCharacterNameResult(); + + WorldPacket const* Write() override; + + std::string Name; + bool Success = false; + }; + class ReorderCharacters final : public ClientPacket { public: diff --git a/src/server/game/Server/Packets/ClientConfigPackets.cpp b/src/server/game/Server/Packets/ClientConfigPackets.cpp index a2807b1b755..b46288f86cb 100644 --- a/src/server/game/Server/Packets/ClientConfigPackets.cpp +++ b/src/server/game/Server/Packets/ClientConfigPackets.cpp @@ -87,3 +87,10 @@ WorldPacket const* WorldPackets::ClientConfig::AccountDataTimes::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::ClientConfig::ClientCacheVersion::Write() +{ + _worldPacket << uint32(CacheVersion); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/ClientConfigPackets.h b/src/server/game/Server/Packets/ClientConfigPackets.h index 3b891f828f2..0dbcfd7d577 100644 --- a/src/server/game/Server/Packets/ClientConfigPackets.h +++ b/src/server/game/Server/Packets/ClientConfigPackets.h @@ -50,6 +50,16 @@ namespace WorldPackets uint32 ServerTime = 0; uint32 AccountTimes[NUM_ACCOUNT_DATA_TYPES]; }; + + class ClientCacheVersion final : public ServerPacket + { + public: + ClientCacheVersion() : ServerPacket(SMSG_CLIENTCACHE_VERSION, 4) { } + + WorldPacket const* Write() override; + + uint32 CacheVersion = 0; + }; } } diff --git a/src/server/game/Server/Packets/GuildPackets.cpp b/src/server/game/Server/Packets/GuildPackets.cpp index f3bba39ac08..ee864b256bb 100644 --- a/src/server/game/Server/Packets/GuildPackets.cpp +++ b/src/server/game/Server/Packets/GuildPackets.cpp @@ -18,29 +18,29 @@ #include "GuildPackets.h" #include "ObjectGuid.h" -WorldPackets::Guild::GuildQuery::GuildQuery(WorldPacket&& packet) +WorldPackets::Guild::QueryGuildInfo::QueryGuildInfo(WorldPacket&& packet) : ClientPacket(std::move(packet)) { ASSERT(_worldPacket.GetOpcode() == CMSG_GUILD_QUERY); } -void WorldPackets::Guild::GuildQuery::Read() +void WorldPackets::Guild::QueryGuildInfo::Read() { _worldPacket >> GuildGuid; _worldPacket >> PlayerGuid; } -WorldPackets::Guild::GuildQueryResponse::GuildQueryResponse() +WorldPackets::Guild::QueryGuildInfoResponse::QueryGuildInfoResponse() : ServerPacket(SMSG_GUILD_QUERY_RESPONSE) { } -WorldPacket const* WorldPackets::Guild::GuildQueryResponse::Write() +WorldPacket const* WorldPackets::Guild::QueryGuildInfoResponse::Write() { _worldPacket << GuildGuid; _worldPacket.WriteBit(Info.HasValue); if (Info.HasValue) { - _worldPacket << Info.value.GuildGuid; + _worldPacket << Info.value.GuildGUID; _worldPacket << uint32(Info.value.VirtualRealmAddress); _worldPacket << uint32(Info.value.Ranks.size()); _worldPacket << uint32(Info.value.EmblemStyle); @@ -49,17 +49,17 @@ WorldPacket const* WorldPackets::Guild::GuildQueryResponse::Write() _worldPacket << uint32(Info.value.BorderColor); _worldPacket << uint32(Info.value.BackgroundColor); - for (GuildInfo::RankInfo const& rank : Info.value.Ranks) + for (GuildInfo::GuildInfoRank const& rank : Info.value.Ranks) { - _worldPacket << uint32(rank.Id); - _worldPacket << uint32(rank.Order); + _worldPacket << uint32(rank.RankID); + _worldPacket << uint32(rank.RankOrder); - _worldPacket.WriteBits(rank.Name.size(), 7); - _worldPacket << rank.Name; + _worldPacket.WriteBits(rank.RankName.size(), 7); + _worldPacket.WriteString(rank.RankName); } - _worldPacket.WriteBits(Info.value.Name.size(), 7); - _worldPacket << Info.value.Name; + _worldPacket.WriteBits(Info.value.GuildName.size(), 7); + _worldPacket.WriteString(Info.value.GuildName); } _worldPacket.FlushBits(); diff --git a/src/server/game/Server/Packets/GuildPackets.h b/src/server/game/Server/Packets/GuildPackets.h index 7b537e0a1db..17159a017e0 100644 --- a/src/server/game/Server/Packets/GuildPackets.h +++ b/src/server/game/Server/Packets/GuildPackets.h @@ -26,52 +26,53 @@ namespace WorldPackets { namespace Guild { - class GuildQuery final : public ClientPacket + class QueryGuildInfo final : public ClientPacket { public: - GuildQuery(WorldPacket&& packet); + QueryGuildInfo(WorldPacket&& packet); void Read() override; - ObjectGuid GuildGuid; ObjectGuid PlayerGuid; + ObjectGuid GuildGuid; }; - class GuildQueryResponse final : public ServerPacket + class QueryGuildInfoResponse final : public ServerPacket { public: struct GuildInfo { - ObjectGuid GuildGuid; + ObjectGuid GuildGUID; - uint32 VirtualRealmAddress = 0; - uint32 EmblemStyle = 0; - uint32 EmblemColor = 0; - uint32 BorderStyle = 0; - uint32 BorderColor = 0; - uint32 BackgroundColor = 0; + uint32 VirtualRealmAddress = 0; ///< a special identifier made from the Index, BattleGroup and Region. - struct RankInfo + std::string GuildName; + + struct GuildInfoRank { - RankInfo(uint32 id, uint32 order, std::string const& name) - : Id(id), Order(order), Name(name) { } + GuildInfoRank(uint32 id, uint32 order, std::string const& name) + : RankID(id), RankOrder(order), RankName(name) { } - uint32 Id; - uint32 Order; - std::string Name; + uint32 RankID; + uint32 RankOrder; + std::string RankName; - bool operator<(RankInfo const& right) const + bool operator<(GuildInfoRank const& right) const { - return Id < right.Id; + return RankID < right.RankID; } }; - std::set<RankInfo> Ranks; + std::set<GuildInfoRank> Ranks; - std::string Name; + uint32 EmblemStyle = 0; + uint32 EmblemColor = 0; + uint32 BorderStyle = 0; + uint32 BorderColor = 0; + uint32 BackgroundColor = 0; }; - GuildQueryResponse(); + QueryGuildInfoResponse(); WorldPacket const* Write() override; diff --git a/src/server/game/Server/Packets/SystemPackets.cpp b/src/server/game/Server/Packets/SystemPackets.cpp index e6e6fbe9aa2..8181558cae7 100644 --- a/src/server/game/Server/Packets/SystemPackets.cpp +++ b/src/server/game/Server/Packets/SystemPackets.cpp @@ -17,9 +17,6 @@ #include "SystemPackets.h" -WorldPackets::System::FeatureSystemStatusGlueScreen::FeatureSystemStatusGlueScreen() - : ServerPacket(SMSG_FEATURE_SYSTEM_STATUS_GLUE_SCREEN, 1) { } - WorldPacket const* WorldPackets::System::FeatureSystemStatusGlueScreen::Write() { _worldPacket.WriteBit(BpayStoreEnabled); @@ -31,8 +28,21 @@ WorldPacket const* WorldPackets::System::FeatureSystemStatusGlueScreen::Write() return &_worldPacket; } -WorldPackets::System::SetTimeZoneInformation::SetTimeZoneInformation() - : ServerPacket(SMSG_SET_TIME_ZONE_INFORMATION) { } +WorldPacket const* WorldPackets::System::MOTD::Write() +{ + ASSERT(Text); + _worldPacket.WriteBits(Text->size(), 4); + _worldPacket.FlushBits(); + + for (std::string const& line : *Text) + { + _worldPacket.WriteBits(line.length(), 7); + _worldPacket.FlushBits(); + _worldPacket.WriteString(line); + } + + return &_worldPacket; +} WorldPacket const* WorldPackets::System::SetTimeZoneInformation::Write() { diff --git a/src/server/game/Server/Packets/SystemPackets.h b/src/server/game/Server/Packets/SystemPackets.h index 0cf075c6317..a2c988ac114 100644 --- a/src/server/game/Server/Packets/SystemPackets.h +++ b/src/server/game/Server/Packets/SystemPackets.h @@ -27,7 +27,7 @@ namespace WorldPackets class FeatureSystemStatusGlueScreen final : public ServerPacket { public: - FeatureSystemStatusGlueScreen(); + FeatureSystemStatusGlueScreen() : ServerPacket(SMSG_FEATURE_SYSTEM_STATUS_GLUE_SCREEN, 1) { } WorldPacket const* Write() override; @@ -37,10 +37,20 @@ namespace WorldPackets bool BpayStoreEnabled = false; // NYI }; + class MOTD final : public ServerPacket + { + public: + MOTD() : ServerPacket(SMSG_MOTD) { } + + WorldPacket const* Write() override; + + std::vector<std::string> const* Text = nullptr; + }; + class SetTimeZoneInformation final : public ServerPacket { public: - SetTimeZoneInformation(); + SetTimeZoneInformation() : ServerPacket(SMSG_SET_TIME_ZONE_INFORMATION) { } WorldPacket const* Write() override; diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index c77f1015372..b22dc575c0c 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -112,6 +112,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_ADDON_REGISTERED_PREFIXES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonRegisteredPrefixesOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_ADD_FRIEND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddFriendOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_ADD_IGNORE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddIgnoreOpcode ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_ADD_MUTE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_ADD_VOICE_IGNORE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_ALTER_APPEARANCE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAlterAppearance ); DEFINE_OPCODE_HANDLER_OLD(CMSG_AREATRIGGER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaTriggerOpcode ); @@ -158,6 +159,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEMASTER_HELLO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterHelloOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEMASTER_JOIN_ARENA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinArena ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEMASTER_JOIN_RATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PAY_GET_PRODUCT_LIST_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BEGIN_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBeginTradeOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BINDER_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBinderActivateOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BUG, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBugOpcode ); @@ -248,6 +250,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_DB_QUERY_BULK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_DEL_FRIEND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleDelFriendOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_DEL_IGNORE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleDelIgnoreOpcode ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_DEL_MUTE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_DEL_VOICE_IGNORE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_DESTROY_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleDestroyItemOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_DISMISS_CONTROLLED_VEHICLE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissControlledVehicle ); @@ -321,7 +324,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_NEWS_UPDATE_STICKY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGuildNewsUpdateStickyOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_PERMISSIONS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPermissions ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_PROMOTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPromoteOpcode ); - DEFINE_HANDLER(CMSG_GUILD_QUERY, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildQuery, &WorldSession::HandleGuildQueryOpcode); + DEFINE_HANDLER(CMSG_GUILD_QUERY, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Guild::QueryGuildInfo, &WorldSession::HandleGuildQueryOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_QUERY_NEWS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGuildQueryNewsOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_QUERY_RANKS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryRanksOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_REMOVE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRemoveOpcode ); @@ -494,7 +497,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_NPC_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestNPCQuery ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_POI_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQuery ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestQueryOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_RANDOMIZE_CHAR_NAME, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRandomizeCharNameOpcode ); + DEFINE_HANDLER(CMSG_RANDOMIZE_CHAR_NAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::GenerateRandomCharacterName, &WorldSession::HandleRandomizeCharNameOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_READ_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItem ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REALM_SPLIT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRealmSplitOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_RECLAIM_CORPSE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReclaimCorpseOpcode ); @@ -689,6 +692,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MESSAGE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MOVEMENT_UPDATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_ERROR, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_SEASON_WORLD_STATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_UNIT_DESTROYED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_COMMAND_RESULT, STATUS_UNHANDLED); @@ -741,6 +745,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_INFO_THROTTLED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_JOINED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_LEFT, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_PRODUCT_LIST_RESPONSE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDER_CONFIRM, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDPOINTUPDATE, STATUS_UNHANDLED); @@ -797,7 +802,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWNS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_TARGET, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLIENTCACHE_VERSION, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLIENTCACHE_VERSION, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLIENT_CONTROL_UPDATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMBAT_EVENT_FAILED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_MAP_INFO, STATUS_UNHANDLED); @@ -813,6 +818,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMSAT_DISCONNECT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMSAT_RECONNECT_TRY, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTACT_LIST, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTACT_STATUS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONVERT_RUNE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_CHEAT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_EVENT, STATUS_UNHANDLED); @@ -1049,7 +1055,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONEY_NOTIFY, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONSTER_MOVE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONSTER_MOVE_TRANSPORT, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOTD, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOTD, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOUNTRESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOUNTSPECIAL_ANIM, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_COLLISION_DISABLE, STATUS_UNHANDLED); @@ -1188,7 +1194,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_MARKERS_CHANGED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_READY_CHECK_THROTTLED_ERROR, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_SUMMON_FAILED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_RANDOMIZE_CHAR_NAME, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_RANDOMIZE_CHAR_NAME, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RATED_BG_RATING, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RATED_BG_STATS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_FAILED, STATUS_UNHANDLED); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index c448eda80fb..d8ac4b68d9e 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -34,7 +34,7 @@ enum OpcodeMisc : uint32 NULL_OPCODE = 0xBADD }; -// CMSGs 6.0.3.19103 +// CMSGs 6.0.3.19116 enum OpcodeClient : uint32 { CMSG_ACCEPT_LEVEL_GRANT = 0xBADD, @@ -42,8 +42,9 @@ enum OpcodeClient : uint32 CMSG_ACTIVATETAXI = 0xBADD, CMSG_ACTIVATETAXIEXPRESS = 0xBADD, CMSG_ADDON_REGISTERED_PREFIXES = 0x03F4, - CMSG_ADD_FRIEND = 0xBADD, + CMSG_ADD_FRIEND = 0x0DB9, CMSG_ADD_IGNORE = 0x1321, + CMSG_ADD_MUTE = 0x098A, CMSG_ADD_VOICE_IGNORE = 0xBADD, CMSG_ALTER_APPEARANCE = 0xBADD, CMSG_AREATRIGGER = 0x01B4, @@ -96,6 +97,7 @@ enum OpcodeClient : uint32 CMSG_BATTLEMASTER_JOIN_ARENA = 0xBADD, CMSG_BATTLEMASTER_JOIN_RATED = 0xBADD, CMSG_BATTLEMASTER_HELLO = 0xBADD, + CMSG_BATTLE_PAY_GET_PRODUCT_LIST_QUERY = 0x1389, CMSG_BEGIN_TRADE = 0xBADD, CMSG_BINDER_ACTIVATE = 0xBADD, CMSG_BOT_DETECTED2 = 0xBADD, @@ -187,8 +189,9 @@ enum OpcodeClient : uint32 CMSG_DANCE_QUERY = 0xBADD, CMSG_DB_QUERY_BULK = 0x138B, CMSG_DECLINE_CHANNEL_INVITE = 0xBADD, - CMSG_DEL_FRIEND = 0xBADD, - CMSG_DEL_IGNORE = 0xBADD, + CMSG_DEL_FRIEND = 0x0F2A, + CMSG_DEL_IGNORE = 0x033D, + CMSG_DEL_MUTE = 0x0128, CMSG_DEL_VOICE_IGNORE = 0xBADD, CMSG_DESTROY_ITEM = 0xBADD, CMSG_DISMISS_CONTROLLED_VEHICLE = 0xBADD, @@ -666,7 +669,7 @@ enum OpcodeClient : uint32 MSG_TALENT_WIPE_CONFIRM = 0xBADD }; -// SMSGs 6.0.3.19103 +// SMSGs 6.0.3.19116 enum OpcodeServer : uint32 { SMSG_ACCOUNT_DATA_TIMES = 0x0120, @@ -741,6 +744,7 @@ enum OpcodeServer : uint32 SMSG_BATTLEGROUND_INFO_THROTTLED = 0xBADD, SMSG_BATTLEGROUND_PLAYER_JOINED = 0xBADD, SMSG_BATTLEGROUND_PLAYER_LEFT = 0xBADD, + SMSG_BATTLE_PAY_GET_PRODUCT_LIST_RESPONSE = 0x12A4, SMSG_BATTLE_PET_JOURNAL = 0x19A2, SMSG_BINDER_CONFIRM = 0xBADD, SMSG_BINDPOINTUPDATE = 0x0A30, @@ -819,6 +823,7 @@ enum OpcodeServer : uint32 SMSG_COMSAT_DISCONNECT = 0xBADD, SMSG_COMSAT_RECONNECT_TRY = 0xBADD, SMSG_CONTACT_LIST = 0xBADD, + SMSG_CONTACT_STATUS = 0x1BEA, SMSG_CONVERT_RUNE = 0xBADD, SMSG_COOLDOWN_CHEAT = 0xBADD, SMSG_COOLDOWN_EVENT = 0xBADD, @@ -1221,7 +1226,7 @@ enum OpcodeServer : uint32 SMSG_RAID_MARKERS_CHANGED = 0xBADD, SMSG_RAID_READY_CHECK_THROTTLED_ERROR = 0xBADD, SMSG_RAID_SUMMON_FAILED = 0xBADD, - SMSG_RANDOMIZE_CHAR_NAME = 0xBADD, + SMSG_RANDOMIZE_CHAR_NAME = 0x0D8F, SMSG_RATED_BG_RATING = 0xBADD, SMSG_RATED_BG_STATS = 0xBADD, SMSG_READ_ITEM_FAILED = 0xBADD, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 53f6b8a8556..c77ad210ebc 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -84,6 +84,7 @@ namespace WorldPackets class CharacterCreate; class CharacterDelete; + class GenerateRandomCharacterName; class ReorderCharacters; class UndeleteCharacter; class PlayerLogin; @@ -91,7 +92,7 @@ namespace WorldPackets namespace Guild { - class GuildQuery; + class QueryGuildInfo; } } @@ -447,7 +448,7 @@ class WorldSession void HandleSetPlayerDeclinedNames(WorldPacket& recvData); void HandleAlterAppearance(WorldPacket& recvData); void HandleCharFactionOrRaceChange(WorldPacket& recvData); - void HandleRandomizeCharNameOpcode(WorldPacket& recvData); + void HandleRandomizeCharNameOpcode(WorldPackets::Character::GenerateRandomCharacterName& packet); void HandleReorderCharacters(WorldPackets::Character::ReorderCharacters& reorderChars); void HandleOpeningCinematic(WorldPacket& recvData); void HandleUndeleteCooldownStatusQuery(WorldPacket& /*recvData*/); @@ -613,7 +614,7 @@ class WorldSession void HandleOfferPetitionOpcode(WorldPacket& recvData); void HandleTurnInPetitionOpcode(WorldPacket& recvData); - void HandleGuildQueryOpcode(WorldPackets::Guild::GuildQuery& query); + void HandleGuildQueryOpcode(WorldPackets::Guild::QueryGuildInfo& query); void HandleGuildInviteOpcode(WorldPacket& recvPacket); void HandleGuildRemoveOpcode(WorldPacket& recvPacket); void HandleGuildAcceptOpcode(WorldPacket& recvPacket); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index e07effe495a..4900b655766 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -65,6 +65,8 @@ #include "WeatherMgr.h" #include "WorldSession.h" +#include <boost/algorithm/string.hpp> + std::atomic<bool> World::m_stopEvent(false); uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; std::atomic<uint32> World::m_worldLoopCounter(0); @@ -172,16 +174,18 @@ void World::SetClosed(bool val) sScriptMgr->OnOpenStateChange(!val); } -void World::SetMotd(const std::string& motd) +void World::SetMotd(std::string motd) { - m_motd = motd; + /// we are using a string copy here to allow modifications in script hooks + sScriptMgr->OnMotdChange(motd); - sScriptMgr->OnMotdChange(m_motd); + _motd.clear(); + boost::split(_motd, motd, boost::is_any_of("@")); } -const char* World::GetMotd() const +std::vector<std::string> const& World::GetMotd() const { - return m_motd.c_str(); + return _motd; } /// Find a session by its id @@ -3320,3 +3324,8 @@ void World::ReloadRBAC() if (WorldSession* session = itr->second) session->InvalidateRBACData(); } + +uint32 GetVirtualRealmAddress() +{ + return uint32(realmHandle.Region) << 24 | uint32(realmHandle.Battlegroup) << 16 | realmHandle.Index; +} diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 4f4c3451b02..3c3e40cc76b 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -617,9 +617,9 @@ class World void SetAllowMovement(bool allow) { m_allowMovement = allow; } /// Set a new Message of the Day - void SetMotd(std::string const& motd); + void SetMotd(std::string motd); /// Get the current Message of the Day - const char* GetMotd() const; + std::vector<std::string> const& GetMotd() const; /// Set the string for new characters (first login) void SetNewCharString(std::string const& str) { m_newCharString = str; } @@ -840,7 +840,7 @@ class World LocaleConstant m_defaultDbcLocale; // from config for one from loaded DBC locales uint32 m_availableDbcLocaleMask; // by loaded DBC bool m_allowMovement; - std::string m_motd; + std::vector<std::string> _motd; std::string m_dataPath; // for max speed access @@ -887,6 +887,7 @@ class World }; extern Battlenet::RealmHandle realmHandle; +uint32 GetVirtualRealmAddress(); #define sWorld World::instance() #endif diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp index 74a947e42e4..a5b2ed045c6 100644 --- a/src/server/scripts/Commands/cs_server.cpp +++ b/src/server/scripts/Commands/cs_server.cpp @@ -129,7 +129,10 @@ public: // Display the 'Message of the day' for the realm static bool HandleServerMotdCommand(ChatHandler* handler, char const* /*args*/) { - handler->PSendSysMessage(LANG_MOTD_CURRENT, sWorld->GetMotd()); + std::string motd; + for (std::string const& line : sWorld->GetMotd()) + motd += line; + handler->PSendSysMessage(LANG_MOTD_CURRENT, motd.c_str()); return true; } diff --git a/src/server/worldserver/RemoteAccess/RASession.cpp b/src/server/worldserver/RemoteAccess/RASession.cpp index c2b89cc0076..65ba3d4cbd9 100644 --- a/src/server/worldserver/RemoteAccess/RASession.cpp +++ b/src/server/worldserver/RemoteAccess/RASession.cpp @@ -73,7 +73,9 @@ void RASession::Start() TC_LOG_INFO("commands.ra", "User %s (IP: %s) authenticated correctly to RA", username.c_str(), GetRemoteIpAddress().c_str()); // Authentication successful, send the motd - Send(std::string(std::string(sWorld->GetMotd()) + "\r\n").c_str()); + for (std::string const& line : sWorld->GetMotd()) + Send(line.c_str()); + Send("\r\n"); // Read commands for (;;) |