diff options
Diffstat (limited to 'src')
125 files changed, 5353 insertions, 3249 deletions
diff --git a/src/server/bnetserver/Packets/CachePackets.cpp b/src/server/bnetserver/Packets/CachePackets.cpp index deacfd34065..8ae489fe47c 100644 --- a/src/server/bnetserver/Packets/CachePackets.cpp +++ b/src/server/bnetserver/Packets/CachePackets.cpp @@ -21,7 +21,7 @@ void Battlenet::Cache::GetStreamItemsRequest::Read() { - _stream.WriteSkip(31); + _stream.ReadSkip(31); Index = _stream.Read<uint32>(32); ReferenceTime = _stream.Read<int32>(32) - std::numeric_limits<int32>::min(); _stream.Read<bool>(1); // StreamDirection diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 7f9359053a1..2f99bc0a6cc 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -70,7 +70,9 @@ namespace Trinity private: void do_helper(WorldPacket& data, char const* text) { - ChatHandler::BuildChatPacket(data, _msgtype, LANG_UNIVERSAL, _source, _source, text); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, _msgtype, LANG_UNIVERSAL, _source, _source, text); + data = *packet.Write(); } ChatMsg _msgtype; @@ -94,7 +96,9 @@ namespace Trinity char str[2048]; snprintf(str, 2048, text, arg1str, arg2str); - ChatHandler::BuildChatPacket(data, _msgtype, LANG_UNIVERSAL, _source, _source, str); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, _msgtype, LANG_UNIVERSAL, _source, _source, str); + data = *packet.Write(); } private: @@ -1693,11 +1697,12 @@ void Battleground::SendWarningToAll(uint32 entry, ...) if (!entry) return; - std::map<uint32, WorldPacket> localizedPackets; + std::map<uint32, WorldPackets::Chat::Chat> localizedPackets; for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) if (Player* player = _GetPlayer(itr, "SendWarningToAll")) { - if (localizedPackets.find(player->GetSession()->GetSessionDbLocaleIndex()) == localizedPackets.end()) + auto packetItr = localizedPackets.find(player->GetSession()->GetSessionDbLocaleIndex()); + if (packetItr == localizedPackets.end()) { char const* format = sObjectMgr->GetTrinityString(entry, player->GetSession()->GetSessionDbLocaleIndex()); @@ -1707,10 +1712,10 @@ void Battleground::SendWarningToAll(uint32 entry, ...) vsnprintf(str, 1024, format, ap); va_end(ap); - ChatHandler::BuildChatPacket(localizedPackets[player->GetSession()->GetSessionDbLocaleIndex()], CHAT_MSG_RAID_BOSS_EMOTE, LANG_UNIVERSAL, NULL, NULL, str); + ChatHandler::BuildChatPacket(&packetItr->second, CHAT_MSG_RAID_BOSS_EMOTE, LANG_UNIVERSAL, NULL, NULL, str); } - player->SendDirectMessage(&localizedPackets[player->GetSession()->GetSessionDbLocaleIndex()]); + player->SendDirectMessage(packetItr->second.Write()); } } diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 65f07b625e1..e2b6b16c9f2 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -31,18 +31,16 @@ Channel::Channel(std::string const& name, uint32 channelId, uint32 team): _IsSaved(false), _flags(0), _channelId(channelId), - _Team(team), - _ownerGUID(), - _name(name), - _password("") + _team(team), + _name(name) { // set special flags if built-in channel if (ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(channelId)) // check whether it's a built-in channel { - _announce = false; // no join/leave announces - _ownership = false; // no ownership handout + _announce = false; // no join/leave announces + _ownership = false; // no ownership handout - _flags |= CHANNEL_FLAG_GENERAL; // for all built-in channels + _flags |= CHANNEL_FLAG_GENERAL; // for all built-in channels if (ch->Flags & CHANNEL_DBC_FLAG_TRADE) // for trade channel _flags |= CHANNEL_FLAG_TRADE; @@ -62,31 +60,31 @@ Channel::Channel(std::string const& name, uint32 channelId, uint32 team): // If storing custom channels in the db is enabled either load or save the channel if (sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS)) { - PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHANNEL); - stmt->setString(0, name); - stmt->setUInt32(1, _Team); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHANNEL); + stmt->setString(0, _name); + stmt->setUInt32(1, _team); PreparedQueryResult result = CharacterDatabase.Query(stmt); - if (result) //load + if (result) // load { Field* fields = result->Fetch(); _announce = fields[0].GetBool(); _ownership = fields[1].GetBool(); _password = fields[2].GetString(); - const char* db_BannedList = fields[3].GetCString(); + std::string bannedList = fields[3].GetString(); - if (db_BannedList) + if (!bannedList.empty()) { - Tokenizer tokens(db_BannedList, ' '); + Tokenizer tokens(bannedList, ' '); for (Tokenizer::const_iterator i = tokens.begin(); i != tokens.end(); ++i) { std::string bannedGuidStr(*i); - ObjectGuid banned_guid; - banned_guid.SetRawValue(uint64(strtoull(bannedGuidStr.substr(0, 16).c_str(), NULL, 16)), uint64(strtoull(bannedGuidStr.substr(16).c_str(), NULL, 16))); - if (!banned_guid.IsEmpty()) + ObjectGuid bannedGuid; + bannedGuid.SetRawValue(uint64(strtoull(bannedGuidStr.substr(0, 16).c_str(), nullptr, 16)), uint64(strtoull(bannedGuidStr.substr(16).c_str(), nullptr, 16))); + if (!bannedGuid.IsEmpty()) { - TC_LOG_DEBUG("chat.system", "Channel(%s) loaded bannedStore %s", name.c_str(), banned_guid.ToString().c_str()); - bannedStore.insert(banned_guid); + TC_LOG_DEBUG("chat.system", "Channel (%s) loaded bannedStore %s", _name.c_str(), bannedGuid.ToString().c_str()); + _bannedStore.insert(bannedGuid); } } } @@ -94,10 +92,10 @@ Channel::Channel(std::string const& name, uint32 channelId, uint32 team): else // save { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHANNEL); - stmt->setString(0, name); - stmt->setUInt32(1, _Team); + stmt->setString(0, _name); + stmt->setUInt32(1, _team); CharacterDatabase.Execute(stmt); - TC_LOG_DEBUG("chat.system", "Channel(%s) saved in database", name.c_str()); + TC_LOG_DEBUG("chat.system", "Channel (%s) saved in database", _name.c_str()); } _IsSaved = true; @@ -110,22 +108,19 @@ void Channel::UpdateChannelInDB() const if (_IsSaved) { std::ostringstream banlist; - BannedContainer::const_iterator iter; - for (iter = bannedStore.begin(); iter != bannedStore.end(); ++iter) - banlist << *iter << ' '; - - std::string banListStr = banlist.str(); + for (ObjectGuid const& guid : _bannedStore) + banlist << guid << ' '; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHANNEL); stmt->setBool(0, _announce); stmt->setBool(1, _ownership); stmt->setString(2, _password); - stmt->setString(3, banListStr); + stmt->setString(3, banlist.str()); stmt->setString(4, _name); - stmt->setUInt32(5, _Team); + stmt->setUInt32(5, _team); CharacterDatabase.Execute(stmt); - TC_LOG_DEBUG("chat.system", "Channel(%s) updated in database", _name.c_str()); + TC_LOG_DEBUG("chat.system", "Channel (%s) updated in database", _name.c_str()); } } @@ -133,7 +128,7 @@ void Channel::UpdateChannelUseageInDB() const { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHANNEL_USAGE); stmt->setString(0, _name); - stmt->setUInt32(1, _Team); + stmt->setUInt32(1, _team); CharacterDatabase.Execute(stmt); } @@ -151,32 +146,32 @@ void Channel::CleanOldChannelsInDB() void Channel::JoinChannel(Player* player, std::string const& pass) { - ObjectGuid guid = player->GetGUID(); + ObjectGuid const& guid = player->GetGUID(); if (IsOn(guid)) { // Do not send error message for built-in channels if (!IsConstant()) { - WorldPacket data; - MakePlayerAlreadyMember(&data, guid); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakePlayerAlreadyMember(notify, guid); + player->SendDirectMessage(notify.Write()); } return; } if (IsBanned(guid)) { - WorldPacket data; - MakeBanned(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeBanned(notify); + player->SendDirectMessage(notify.Write()); return; } if (!_password.empty() && pass != _password) { - WorldPacket data; - MakeWrongPassword(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeWrongPassword(notify); + player->SendDirectMessage(notify.Write()); return; } @@ -185,9 +180,9 @@ void Channel::JoinChannel(Player* player, std::string const& pass) AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && //FIXME: Move to RBAC player->GetGroup()) { - WorldPacket data; - MakeNotInLfg(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotInLfg(notify); + player->SendDirectMessage(notify.Write()); return; } @@ -195,73 +190,90 @@ void Channel::JoinChannel(Player* player, std::string const& pass) if (_announce && !player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL)) { - WorldPacket data; - MakeJoined(&data, guid); - SendToAll(&data); + WorldPackets::Channel::ChannelNotify notify; + MakeJoined(notify, guid); + SendToAll(notify.Write()); } - PlayerInfo pinfo; - pinfo.player = guid; - pinfo.flags = MEMBER_FLAG_NONE; - playersStore[guid] = pinfo; + PlayerInfo playerInfo; + playerInfo.PlayerGuid = guid; + _playersStore[guid] = playerInfo; - WorldPacket data; - MakeYouJoined(&data); - SendToOne(&data, guid); + /* + WorldPackets::Channel::ChannelNotify notify; + MakeYouJoined(notify); + player->SendDirectMessage(notify.Write()); + */ - JoinNotify(guid); + WorldPackets::Channel::ChannelNotifyJoined notify; + //notify.ChannelWelcomeMsg = ""; + notify.ChatChannelID = _channelId; + //notify.InstanceID = 0; + notify.ChannelFlags = _flags; + notify.Channel = _name; + player->SendDirectMessage(notify.Write()); + + JoinNotify(player); // Custom channel handling if (!IsConstant()) { // Update last_used timestamp in db - if (!playersStore.empty()) + if (!_playersStore.empty()) UpdateChannelUseageInDB(); // If the channel has no owner yet and ownership is allowed, set the new owner. - if (!_ownerGUID && _ownership) + if (_ownerGUID.IsEmpty() && _ownership) { - SetOwner(guid, playersStore.size() > 1); - playersStore[guid].SetModerator(true); + SetOwner(guid, _playersStore.size() > 1); + _playersStore[guid].SetModerator(true); } } } void Channel::LeaveChannel(Player* player, bool send) { - ObjectGuid guid = player->GetGUID(); + ObjectGuid const& guid = player->GetGUID(); if (!IsOn(guid)) { if (send) { - WorldPacket data; - MakeNotMember(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotMember(notify); + player->SendDirectMessage(notify.Write()); } return; } + player->LeftChannel(this); + if (send) { - WorldPacket data; - MakeYouLeft(&data); - SendToOne(&data, guid); - player->LeftChannel(this); - data.clear(); + /* + WorldPackets::Channel::ChannelNotify notify; + MakeYouLeft(notify); + player->SendDirectMessage(notify.Write()); + */ + + WorldPackets::Channel::ChannelNotifyLeft notify; + notify.Channel = _name; + notify.ChatChannelID = 0; + //notify.Suspended = false; + player->SendDirectMessage(notify.Write()); } - bool changeowner = playersStore[guid].IsOwner(); + bool changeowner = _playersStore[guid].IsOwner(); - playersStore.erase(guid); + _playersStore.erase(guid); if (_announce && !player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL)) { - WorldPacket data; - MakeLeft(&data, guid); - SendToAll(&data); + WorldPackets::Channel::ChannelNotify notify; + MakeLeft(notify, guid); + SendToAll(notify.Write()); } - LeaveNotify(guid); + LeaveNotify(player); if (!IsConstant()) { @@ -269,10 +281,10 @@ void Channel::LeaveChannel(Player* player, bool send) UpdateChannelUseageInDB(); // If the channel owner left and there are still playersStore inside, pick a new owner - if (changeowner && _ownership && !playersStore.empty()) + if (changeowner && _ownership && !_playersStore.empty()) { - ObjectGuid newowner = playersStore.begin()->second.player; - playersStore[newowner].SetModerator(true); + ObjectGuid const& newowner = _playersStore.begin()->second.PlayerGuid; + _playersStore[newowner].SetModerator(true); SetOwner(newowner); } } @@ -280,21 +292,21 @@ void Channel::LeaveChannel(Player* player, bool send) void Channel::KickOrBan(Player const* player, std::string const& badname, bool ban) { - ObjectGuid good = player->GetGUID(); + ObjectGuid const& good = player->GetGUID(); if (!IsOn(good)) { - WorldPacket data; - MakeNotMember(&data); - SendToOne(&data, good); + WorldPackets::Channel::ChannelNotify notify; + MakeNotMember(notify); + player->SendDirectMessage(notify.Write()); return; } - if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) + if (!_playersStore[good].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { - WorldPacket data; - MakeNotModerator(&data); - SendToOne(&data, good); + WorldPackets::Channel::ChannelNotify notify; + MakeNotModerator(notify); + player->SendDirectMessage(notify.Write()); return; } @@ -302,9 +314,9 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty; if (!victim || !IsOn(victim)) { - WorldPacket data; - MakePlayerNotFound(&data, badname); - SendToOne(&data, good); + WorldPackets::Channel::ChannelNotify notify; + MakePlayerNotFound(notify, badname); + player->SendDirectMessage(notify.Write()); return; } @@ -312,154 +324,152 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && changeowner && good != _ownerGUID) { - WorldPacket data; - MakeNotOwner(&data); - SendToOne(&data, good); + WorldPackets::Channel::ChannelNotify notify; + MakeNotOwner(notify); + player->SendDirectMessage(notify.Write()); return; } if (ban && !IsBanned(victim)) { - bannedStore.insert(victim); + _bannedStore.insert(victim); UpdateChannelInDB(); if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL)) { - WorldPacket data; - MakePlayerBanned(&data, victim, good); - SendToAll(&data); + WorldPackets::Channel::ChannelNotify notify; + MakePlayerBanned(notify, victim, good); + SendToAll(notify.Write()); } } else if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL)) { - WorldPacket data; - MakePlayerKicked(&data, victim, good); - SendToAll(&data); + WorldPackets::Channel::ChannelNotify notify; + MakePlayerKicked(notify, victim, good); + SendToAll(notify.Write()); } - playersStore.erase(victim); + _playersStore.erase(victim); bad->LeftChannel(this); - if (changeowner && _ownership && !playersStore.empty()) + if (changeowner && _ownership && !_playersStore.empty()) { - ObjectGuid newowner = good; - playersStore[newowner].SetModerator(true); - SetOwner(newowner); + _playersStore[good].SetModerator(true); + SetOwner(good); } } void Channel::UnBan(Player const* player, std::string const& badname) { - ObjectGuid good = player->GetGUID(); + ObjectGuid const& good = player->GetGUID(); if (!IsOn(good)) { - WorldPacket data; - MakeNotMember(&data); - SendToOne(&data, good); + WorldPackets::Channel::ChannelNotify notify; + MakeNotMember(notify); + player->SendDirectMessage(notify.Write()); return; } - if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) + if (!_playersStore[good].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { - WorldPacket data; - MakeNotModerator(&data); - SendToOne(&data, good); + WorldPackets::Channel::ChannelNotify notify; + MakeNotModerator(notify); + player->SendDirectMessage(notify.Write()); return; } Player* bad = ObjectAccessor::FindConnectedPlayerByName(badname); ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty; - if (!victim || !IsBanned(victim)) + if (victim.IsEmpty() || !IsBanned(victim)) { - WorldPacket data; - MakePlayerNotFound(&data, badname); - SendToOne(&data, good); + WorldPackets::Channel::ChannelNotify notify; + MakePlayerNotFound(notify, badname); + player->SendDirectMessage(notify.Write()); return; } - bannedStore.erase(victim); + _bannedStore.erase(victim); - WorldPacket data; - MakePlayerUnbanned(&data, victim, good); - SendToAll(&data); + WorldPackets::Channel::ChannelNotify notify; + MakePlayerUnbanned(notify, victim, good); + SendToAll(notify.Write()); UpdateChannelInDB(); } void Channel::Password(Player const* player, std::string const& pass) { - ObjectGuid guid = player->GetGUID(); + ObjectGuid const& guid = player->GetGUID(); - ChatHandler chat(player->GetSession()); if (!IsOn(guid)) { - WorldPacket data; - MakeNotMember(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotMember(notify); + player->SendDirectMessage(notify.Write()); return; } - if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) + if (!_playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { - WorldPacket data; - MakeNotModerator(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotModerator(notify); + player->SendDirectMessage(notify.Write()); return; } _password = pass; - WorldPacket data; - MakePasswordChanged(&data, guid); - SendToAll(&data); + WorldPackets::Channel::ChannelNotify notify; + MakePasswordChanged(notify, guid); + SendToAll(notify.Write()); UpdateChannelInDB(); } void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bool set) { - ObjectGuid guid = player->GetGUID(); + ObjectGuid const& guid = player->GetGUID(); if (!IsOn(guid)) { - WorldPacket data; - MakeNotMember(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotMember(notify); + player->SendDirectMessage(notify.Write()); return; } - if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) + if (!_playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { - WorldPacket data; - MakeNotModerator(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotModerator(notify); + player->SendDirectMessage(notify.Write()); return; } - if (guid == _ownerGUID && std::string(p2n) == player->GetName() && mod) + if (guid == _ownerGUID && p2n == player->GetName() && mod) return; Player* newp = ObjectAccessor::FindConnectedPlayerByName(p2n); ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty; - if (!victim || !IsOn(victim) || + if (victim.IsEmpty() || !IsOn(victim) || (player->GetTeam() != newp->GetTeam() && (!player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || !newp->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL)))) { - WorldPacket data; - MakePlayerNotFound(&data, p2n); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakePlayerNotFound(notify, p2n); + player->SendDirectMessage(notify.Write()); return; } if (_ownerGUID == victim && _ownerGUID != guid) { - WorldPacket data; - MakeNotOwner(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotOwner(notify); + player->SendDirectMessage(notify.Write()); return; } @@ -471,21 +481,21 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo void Channel::SetOwner(Player const* player, std::string const& newname) { - ObjectGuid guid = player->GetGUID(); + ObjectGuid const& guid = player->GetGUID(); if (!IsOn(guid)) { - WorldPacket data; - MakeNotMember(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotMember(notify); + player->SendDirectMessage(notify.Write()); return; } if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && guid != _ownerGUID) { - WorldPacket data; - MakeNotOwner(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotOwner(notify); + player->SendDirectMessage(notify.Write()); return; } @@ -497,55 +507,49 @@ void Channel::SetOwner(Player const* player, std::string const& newname) (!player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || !newp->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL)))) { - WorldPacket data; - MakePlayerNotFound(&data, newname); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakePlayerNotFound(notify, newname); + player->SendDirectMessage(notify.Write()); return; } - playersStore[victim].SetModerator(true); + _playersStore[victim].SetModerator(true); SetOwner(victim); } -void Channel::SendWhoOwner(ObjectGuid guid) +void Channel::SendWhoOwner(Player const* player) { - WorldPacket data; - if (IsOn(guid)) - MakeChannelOwner(&data); + WorldPackets::Channel::ChannelNotify notify; + if (IsOn(player->GetGUID())) + MakeChannelOwner(notify); else - MakeNotMember(&data); - SendToOne(&data, guid); + MakeNotMember(notify); + player->SendDirectMessage(notify.Write()); } void Channel::List(Player const* player) { - ObjectGuid guid = player->GetGUID(); - - if (!IsOn(guid)) + if (!IsOn(player->GetGUID())) { - WorldPacket data; - MakeNotMember(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotMember(notify); + player->SendDirectMessage(notify.Write()); return; } TC_LOG_DEBUG("chat.system", "SMSG_CHANNEL_LIST %s Channel: %s", player->GetSession()->GetPlayerInfo().c_str(), GetName().c_str()); - WorldPacket data(SMSG_CHANNEL_LIST, 1+(GetName().size()+1)+1+4+playersStore.size()*(8+1)); - data << uint8(1); // channel type? - data << GetName(); // channel name - data << uint8(GetFlags()); // channel flags? - - size_t pos = data.wpos(); - data << uint32(0); // size of list, placeholder + WorldPackets::Channel::ChannelListResponse list; + list.Display = true; /// always true? + list.Channel = GetName(); + list.ChannelFlags = GetFlags(); uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST); - uint32 count = 0; - for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i) + for (PlayerContainer::value_type const& i : _playersStore) { - Player* member = ObjectAccessor::FindConnectedPlayer(i->first); + Player* member = ObjectAccessor::FindConnectedPlayer(i.first); // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all @@ -554,50 +558,46 @@ void Channel::List(Player const* player) member->GetSession()->GetSecurity() <= AccountTypes(gmLevelInWhoList)) && member->IsVisibleGloballyFor(player)) { - data << i->first; - data << uint8(i->second.flags); // flags seems to be changed... - ++count; + list.Members.emplace_back(i.second.PlayerGuid, GetVirtualRealmAddress(), i.second.GetFlags()); } } - data.put<uint32>(pos, count); - - SendToOne(&data, guid); + player->SendDirectMessage(list.Write()); } void Channel::Announce(Player const* player) { - ObjectGuid guid = player->GetGUID(); + ObjectGuid const& guid = player->GetGUID(); if (!IsOn(guid)) { - WorldPacket data; - MakeNotMember(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotMember(notify); + player->SendDirectMessage(notify.Write()); return; } - if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) + if (!_playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { - WorldPacket data; - MakeNotModerator(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotModerator(notify); + player->SendDirectMessage(notify.Write()); return; } _announce = !_announce; - WorldPacket data; + WorldPackets::Channel::ChannelNotify notify; if (_announce) - MakeAnnouncementsOn(&data, guid); + MakeAnnouncementsOn(notify, guid); else - MakeAnnouncementsOff(&data, guid); - SendToAll(&data); + MakeAnnouncementsOff(notify, guid); + SendToAll(notify.Write()); UpdateChannelInDB(); } -void Channel::Say(ObjectGuid guid, std::string const& what, uint32 lang) +void Channel::Say(ObjectGuid const& guid, std::string const& what, uint32 lang) { if (what.empty()) return; @@ -608,55 +608,59 @@ void Channel::Say(ObjectGuid guid, std::string const& what, uint32 lang) if (!IsOn(guid)) { - WorldPacket data; - MakeNotMember(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotMember(notify); + SendToOne(notify.Write(), guid); return; } - if (playersStore[guid].IsMuted()) + if (_playersStore[guid].IsMuted()) { - WorldPacket data; - MakeMuted(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeMuted(notify); + SendToOne(notify.Write(), guid); return; } - WorldPacket data; + WorldPackets::Chat::Chat packet; if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) - ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name); + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name); else - ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), guid, guid, what, 0, "", "", 0, false, _name); + { + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_CHANNEL, Language(lang), NULL, NULL, what, 0, _name); + packet.SenderGUID = guid; + packet.TargetGUID = guid; + } - SendToAll(&data, !playersStore[guid].IsModerator() ? guid : ObjectGuid::Empty); + SendToAll(packet.Write(), !_playersStore[guid].IsModerator() ? guid : ObjectGuid::Empty); } void Channel::Invite(Player const* player, std::string const& newname) { - ObjectGuid guid = player->GetGUID(); + ObjectGuid const& guid = player->GetGUID(); if (!IsOn(guid)) { - WorldPacket data; - MakeNotMember(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeNotMember(notify); + player->SendDirectMessage(notify.Write()); return; } Player* newp = ObjectAccessor::FindConnectedPlayerByName(newname); if (!newp || !newp->isGMVisible()) { - WorldPacket data; - MakePlayerNotFound(&data, newname); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakePlayerNotFound(notify, newname); + player->SendDirectMessage(notify.Write()); return; } if (IsBanned(newp->GetGUID())) { - WorldPacket data; - MakePlayerInviteBanned(&data, newname); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakePlayerInviteBanned(notify, newname); + player->SendDirectMessage(notify.Write()); return; } @@ -664,169 +668,167 @@ void Channel::Invite(Player const* player, std::string const& newname) (!player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || !newp->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL))) { - WorldPacket data; - MakeInviteWrongFaction(&data); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakeInviteWrongFaction(notify); + player->SendDirectMessage(notify.Write()); return; } if (IsOn(newp->GetGUID())) { - WorldPacket data; - MakePlayerAlreadyMember(&data, newp->GetGUID()); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakePlayerAlreadyMember(notify, newp->GetGUID()); + player->SendDirectMessage(notify.Write()); return; } if (!newp->GetSocial()->HasIgnore(guid)) { - WorldPacket data; - MakeInvite(&data, guid); - SendToOne(&data, newp->GetGUID()); - data.clear(); + WorldPackets::Channel::ChannelNotify notify; + MakeInvite(notify, guid); + newp->SendDirectMessage(notify.Write()); } - WorldPacket data; - MakePlayerInvited(&data, newp->GetName()); - SendToOne(&data, guid); + WorldPackets::Channel::ChannelNotify notify; + MakePlayerInvited(notify, newp->GetName()); + player->SendDirectMessage(notify.Write()); } -void Channel::SetOwner(ObjectGuid guid, bool exclaim) +void Channel::SetOwner(ObjectGuid const& guid, bool exclaim) { if (!_ownerGUID.IsEmpty()) { // [] will re-add player after it possible removed - PlayerContainer::iterator p_itr = playersStore.find(_ownerGUID); - if (p_itr != playersStore.end()) - p_itr->second.SetOwner(false); + PlayerContainer::iterator itr = _playersStore.find(_ownerGUID); + if (itr != _playersStore.end()) + itr->second.SetOwner(false); } _ownerGUID = guid; if (!_ownerGUID.IsEmpty()) { - uint8 oldFlag = GetPlayerFlags(_ownerGUID); - playersStore[_ownerGUID].SetModerator(true); - playersStore[_ownerGUID].SetOwner(true); + uint8 oldFlag = _playersStore[_ownerGUID].GetFlags(); + _playersStore[_ownerGUID].SetModerator(true); + _playersStore[_ownerGUID].SetOwner(true); - WorldPacket data; - MakeModeChange(&data, _ownerGUID, oldFlag); - SendToAll(&data); + WorldPackets::Channel::ChannelNotify notify; + MakeModeChange(notify, _ownerGUID, oldFlag, _playersStore[_ownerGUID].GetFlags()); + SendToAll(notify.Write()); if (exclaim) { - MakeOwnerChanged(&data, _ownerGUID); - SendToAll(&data); + MakeOwnerChanged(notify, _ownerGUID); + SendToAll(notify.Write()); } UpdateChannelInDB(); } } -void Channel::SendToAll(WorldPacket* data, ObjectGuid guid) +void Channel::SendToAll(WorldPacket const* data, ObjectGuid const& guid) { - for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i) - if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first)) - if (!guid || !player->GetSocial()->HasIgnore(guid)) - player->GetSession()->SendPacket(data); + for (PlayerContainer::value_type const& i : _playersStore) + if (Player* player = ObjectAccessor::FindConnectedPlayer(i.first)) + if (guid.IsEmpty() || !player->GetSocial()->HasIgnore(guid)) + player->SendDirectMessage(data); } -void Channel::SendToAllButOne(WorldPacket* data, ObjectGuid who) +void Channel::SendToAllButOne(WorldPacket const* data, ObjectGuid const& who) { - for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i) - if (i->first != who) - if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first)) - player->GetSession()->SendPacket(data); + for (PlayerContainer::value_type const& i : _playersStore) + if (i.first != who) + if (Player* player = ObjectAccessor::FindConnectedPlayer(i.first)) + player->SendDirectMessage(data); } -void Channel::SendToOne(WorldPacket* data, ObjectGuid who) +void Channel::SendToOne(WorldPacket const* data, ObjectGuid const& who) { if (Player* player = ObjectAccessor::FindConnectedPlayer(who)) - player->GetSession()->SendPacket(data); + player->SendDirectMessage(data); } -void Channel::Voice(ObjectGuid /*guid1*/, ObjectGuid /*guid2*/) +void Channel::Voice(ObjectGuid const& /*guid1*/, ObjectGuid const& /*guid2*/) { } -void Channel::DeVoice(ObjectGuid /*guid1*/, ObjectGuid /*guid2*/) +void Channel::DeVoice(ObjectGuid const& /*guid1*/, ObjectGuid const& /*guid2*/) { } -void Channel::MakeNotifyPacket(WorldPacket* data, uint8 notify_type) +void Channel::MakeNotifyPacket(WorldPackets::Channel::ChannelNotify& data, uint8 notifyType) { - data->Initialize(SMSG_CHANNEL_NOTIFY, 1 + _name.size()); - *data << uint8(notify_type); - *data << _name; + data.Type = notifyType; + data.Channel = _name; } -void Channel::MakeJoined(WorldPacket* data, ObjectGuid guid) +void Channel::MakeJoined(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid) { MakeNotifyPacket(data, CHAT_JOINED_NOTICE); - *data << guid; + data.SenderGuid = guid; } -void Channel::MakeLeft(WorldPacket* data, ObjectGuid guid) +void Channel::MakeLeft(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid) { MakeNotifyPacket(data, CHAT_LEFT_NOTICE); - *data << guid; + data.SenderGuid = guid; } -void Channel::MakeYouJoined(WorldPacket* data) +void Channel::MakeYouJoined(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_YOU_JOINED_NOTICE); - *data << uint8(GetFlags()); - *data << uint32(GetChannelId()); - *data << uint32(0); + //*data << uint8(GetFlags()); + data.ChatChannelID = GetChannelId(); + //*data << uint32(0); } -void Channel::MakeYouLeft(WorldPacket* data) +void Channel::MakeYouLeft(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_YOU_LEFT_NOTICE); - *data << uint32(GetChannelId()); - *data << uint8(IsConstant()); + data.ChatChannelID = GetChannelId(); + //*data << uint8(IsConstant()); } -void Channel::MakeWrongPassword(WorldPacket* data) +void Channel::MakeWrongPassword(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_WRONG_PASSWORD_NOTICE); } -void Channel::MakeNotMember(WorldPacket* data) +void Channel::MakeNotMember(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_NOT_MEMBER_NOTICE); } -void Channel::MakeNotModerator(WorldPacket* data) +void Channel::MakeNotModerator(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_NOT_MODERATOR_NOTICE); } -void Channel::MakePasswordChanged(WorldPacket* data, ObjectGuid guid) +void Channel::MakePasswordChanged(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid) { MakeNotifyPacket(data, CHAT_PASSWORD_CHANGED_NOTICE); - *data << guid; + data.SenderGuid = guid; } -void Channel::MakeOwnerChanged(WorldPacket* data, ObjectGuid guid) +void Channel::MakeOwnerChanged(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid) { MakeNotifyPacket(data, CHAT_OWNER_CHANGED_NOTICE); - *data << guid; + data.SenderGuid = guid; } -void Channel::MakePlayerNotFound(WorldPacket* data, std::string const& name) +void Channel::MakePlayerNotFound(WorldPackets::Channel::ChannelNotify& data, std::string const& name) { MakeNotifyPacket(data, CHAT_PLAYER_NOT_FOUND_NOTICE); - *data << name; + data.Sender = name; } -void Channel::MakeNotOwner(WorldPacket* data) +void Channel::MakeNotOwner(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_NOT_OWNER_NOTICE); } -void Channel::MakeChannelOwner(WorldPacket* data) +void Channel::MakeChannelOwner(WorldPackets::Channel::ChannelNotify& data) { std::string name; @@ -834,139 +836,140 @@ void Channel::MakeChannelOwner(WorldPacket* data) name = "PLAYER_NOT_FOUND"; MakeNotifyPacket(data, CHAT_CHANNEL_OWNER_NOTICE); - *data << ((IsConstant() || !_ownerGUID) ? "Nobody" : name); + data.Sender = ((IsConstant() || !_ownerGUID) ? "Nobody" : name); } -void Channel::MakeModeChange(WorldPacket* data, ObjectGuid guid, uint8 oldflags) +void Channel::MakeModeChange(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid, uint8 oldFlags, uint8 newFlags) { MakeNotifyPacket(data, CHAT_MODE_CHANGE_NOTICE); - *data << guid; - *data << uint8(oldflags); - *data << uint8(GetPlayerFlags(guid)); + data.SenderGuid = guid; + data.OldFlags = oldFlags; + data.NewFlags = newFlags; } -void Channel::MakeAnnouncementsOn(WorldPacket* data, ObjectGuid guid) +void Channel::MakeAnnouncementsOn(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid) { MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_ON_NOTICE); - *data << guid; + data.SenderGuid = guid; } -void Channel::MakeAnnouncementsOff(WorldPacket* data, ObjectGuid guid) +void Channel::MakeAnnouncementsOff(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid) { MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_OFF_NOTICE); - *data << guid; + data.SenderGuid = guid; } -void Channel::MakeMuted(WorldPacket* data) +void Channel::MakeMuted(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_MUTED_NOTICE); } -void Channel::MakePlayerKicked(WorldPacket* data, ObjectGuid bad, ObjectGuid good) +void Channel::MakePlayerKicked(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& bad, ObjectGuid const& good) { MakeNotifyPacket(data, CHAT_PLAYER_KICKED_NOTICE); - *data << bad; - *data << good; + data.SenderGuid = good; + data.TargetGuid = bad; } -void Channel::MakeBanned(WorldPacket* data) +void Channel::MakeBanned(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_BANNED_NOTICE); } -void Channel::MakePlayerBanned(WorldPacket* data, ObjectGuid bad, ObjectGuid good) +void Channel::MakePlayerBanned(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& bad, ObjectGuid const& good) { MakeNotifyPacket(data, CHAT_PLAYER_BANNED_NOTICE); - *data << bad; - *data << good; + data.SenderGuid = good; + data.TargetGuid = bad; } -void Channel::MakePlayerUnbanned(WorldPacket* data, ObjectGuid bad, ObjectGuid good) +void Channel::MakePlayerUnbanned(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& bad, ObjectGuid const& good) { MakeNotifyPacket(data, CHAT_PLAYER_UNBANNED_NOTICE); - *data << bad; - *data << good; + data.SenderGuid = good; + data.TargetGuid = bad; } -void Channel::MakePlayerNotBanned(WorldPacket* data, const std::string &name) +void Channel::MakePlayerNotBanned(WorldPackets::Channel::ChannelNotify& data, std::string const& name) { MakeNotifyPacket(data, CHAT_PLAYER_NOT_BANNED_NOTICE); - *data << name; + data.Sender = name; } -void Channel::MakePlayerAlreadyMember(WorldPacket* data, ObjectGuid guid) +void Channel::MakePlayerAlreadyMember(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid) { MakeNotifyPacket(data, CHAT_PLAYER_ALREADY_MEMBER_NOTICE); - *data << guid; + data.SenderGuid = guid; } -void Channel::MakeInvite(WorldPacket* data, ObjectGuid guid) +void Channel::MakeInvite(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid) { MakeNotifyPacket(data, CHAT_INVITE_NOTICE); - *data << guid; + data.SenderGuid = guid; } -void Channel::MakeInviteWrongFaction(WorldPacket* data) +void Channel::MakeInviteWrongFaction(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_INVITE_WRONG_FACTION_NOTICE); } -void Channel::MakeWrongFaction(WorldPacket* data) +void Channel::MakeWrongFaction(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_WRONG_FACTION_NOTICE); } -void Channel::MakeInvalidName(WorldPacket* data) +void Channel::MakeInvalidName(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_INVALID_NAME_NOTICE); } -void Channel::MakeNotModerated(WorldPacket* data) +void Channel::MakeNotModerated(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_NOT_MODERATED_NOTICE); } -void Channel::MakePlayerInvited(WorldPacket* data, const std::string& name) +void Channel::MakePlayerInvited(WorldPackets::Channel::ChannelNotify& data, std::string const& name) { MakeNotifyPacket(data, CHAT_PLAYER_INVITED_NOTICE); - *data << name; + data.Sender = name; } -void Channel::MakePlayerInviteBanned(WorldPacket* data, const std::string& name) +void Channel::MakePlayerInviteBanned(WorldPackets::Channel::ChannelNotify& data, std::string const& name) { MakeNotifyPacket(data, CHAT_PLAYER_INVITE_BANNED_NOTICE); - *data << name; + data.Sender = name; } -void Channel::MakeThrottled(WorldPacket* data) +void Channel::MakeThrottled(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_THROTTLED_NOTICE); } -void Channel::MakeNotInArea(WorldPacket* data) +void Channel::MakeNotInArea(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_NOT_IN_AREA_NOTICE); } -void Channel::MakeNotInLfg(WorldPacket* data) +void Channel::MakeNotInLfg(WorldPackets::Channel::ChannelNotify& data) { MakeNotifyPacket(data, CHAT_NOT_IN_LFG_NOTICE); } -void Channel::MakeVoiceOn(WorldPacket* data, ObjectGuid guid) +void Channel::MakeVoiceOn(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid) { MakeNotifyPacket(data, CHAT_VOICE_ON_NOTICE); - *data << guid; + data.SenderGuid = guid; } -void Channel::MakeVoiceOff(WorldPacket* data, ObjectGuid guid) +void Channel::MakeVoiceOff(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid) { MakeNotifyPacket(data, CHAT_VOICE_OFF_NOTICE); - *data << guid; + data.SenderGuid = guid; } -void Channel::JoinNotify(ObjectGuid guid) +void Channel::JoinNotify(Player const* player) { + ObjectGuid const& guid = player->GetGUID(); WorldPacket data(IsConstant() ? SMSG_USERLIST_ADD : SMSG_USERLIST_UPDATE, 8 + 1 + 1 + 4 + GetName().size()); data << guid; data << uint8(GetPlayerFlags(guid)); @@ -980,8 +983,9 @@ void Channel::JoinNotify(ObjectGuid guid) SendToAll(&data); } -void Channel::LeaveNotify(ObjectGuid guid) +void Channel::LeaveNotify(Player const* player) { + ObjectGuid const& guid = player->GetGUID(); WorldPacket data(SMSG_USERLIST_REMOVE, 8 + 1 + 4 + GetName().size()); data << guid; data << uint8(GetFlags()); diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h index 6489c8b47ad..4ee83b8fbb2 100644 --- a/src/server/game/Chat/Channels/Channel.h +++ b/src/server/game/Chat/Channels/Channel.h @@ -19,14 +19,11 @@ #ifndef _CHANNEL_H #define _CHANNEL_H -#include <list> -#include <map> -#include <string> - #include "Common.h" #include "WorldSession.h" -#include "WorldPacket.h" + +#include "Packets/ChannelPackets.h" class Player; @@ -122,33 +119,47 @@ class Channel { struct PlayerInfo { - ObjectGuid player; - uint8 flags; + ObjectGuid PlayerGuid; + + uint8 GetFlags() const { return _flags; } + inline bool HasFlag(uint8 flag) const { return (_flags & flag) != 0; } + inline void SetFlag(uint8 flag) { _flags |= flag; } + inline void RemoveFlag(uint8 flag) { _flags &= ~flag; } - bool HasFlag(uint8 flag) const { return (flags & flag) != 0; } - void SetFlag(uint8 flag) { flags |= flag; } - bool IsOwner() const { return (flags & MEMBER_FLAG_OWNER) != 0; } + bool IsOwner() const { return HasFlag(MEMBER_FLAG_OWNER); } void SetOwner(bool state) { - if (state) flags |= MEMBER_FLAG_OWNER; - else flags &= ~MEMBER_FLAG_OWNER; + if (state) + SetFlag(MEMBER_FLAG_OWNER); + else + RemoveFlag(MEMBER_FLAG_OWNER); } - bool IsModerator() const { return (flags & MEMBER_FLAG_MODERATOR) != 0; } + + bool IsModerator() const { return HasFlag(MEMBER_FLAG_MODERATOR); } void SetModerator(bool state) { - if (state) flags |= MEMBER_FLAG_MODERATOR; - else flags &= ~MEMBER_FLAG_MODERATOR; + if (state) + SetFlag(MEMBER_FLAG_MODERATOR); + else + RemoveFlag(MEMBER_FLAG_MODERATOR); } - bool IsMuted() const { return (flags & MEMBER_FLAG_MUTED) != 0; } + + bool IsMuted() const { return HasFlag(MEMBER_FLAG_MUTED); } void SetMuted(bool state) { - if (state) flags |= MEMBER_FLAG_MUTED; - else flags &= ~MEMBER_FLAG_MUTED; + if (state) + SetFlag(MEMBER_FLAG_MUTED); + else + RemoveFlag(MEMBER_FLAG_MUTED); } + + private: + uint8 _flags = MEMBER_FLAG_NONE; }; public: Channel(std::string const& name, uint32 channel_id, uint32 Team = 0); + std::string const& GetName() const { return _name; } uint32 GetChannelId() const { return _channelId; } bool IsConstant() const { return _channelId != 0; } @@ -157,7 +168,7 @@ class Channel std::string const& GetPassword() const { return _password; } void SetPassword(std::string const& npassword) { _password = npassword; } void SetAnnounce(bool nannounce) { _announce = nannounce; } - uint32 GetNumPlayers() const { return playersStore.size(); } + uint32 GetNumPlayers() const { return _playersStore.size(); } uint8 GetFlags() const { return _flags; } bool HasFlag(uint8 flag) const { return (_flags & flag) != 0; } @@ -169,102 +180,102 @@ class Channel void UnBan(Player const* player, std::string const& badname); void Password(Player const* player, std::string const& pass); void SetMode(Player const* player, std::string const& p2n, bool mod, bool set); - void SetOwner(ObjectGuid guid, bool exclaim = true); + void SetOwner(ObjectGuid const& guid, bool exclaim = true); void SetOwner(Player const* player, std::string const& name); - void SendWhoOwner(ObjectGuid guid); + void SendWhoOwner(Player const* player); void SetModerator(Player const* player, std::string const& newname) { SetMode(player, newname, true, true); } void UnsetModerator(Player const* player, std::string const& newname) { SetMode(player, newname, true, false); } void SetMute(Player const* player, std::string const& newname) { SetMode(player, newname, false, true); } void UnsetMute(Player const* player, std::string const& newname) { SetMode(player, newname, false, false); } void List(Player const* player); void Announce(Player const* player); - void Say(ObjectGuid guid, std::string const& what, uint32 lang); + void Say(ObjectGuid const& guid, std::string const& what, uint32 lang); void Invite(Player const* player, std::string const& newp); - void Voice(ObjectGuid guid1, ObjectGuid guid2); - void DeVoice(ObjectGuid guid1, ObjectGuid guid2); - void JoinNotify(ObjectGuid guid); // invisible notify - void LeaveNotify(ObjectGuid guid); // invisible notify + void Voice(ObjectGuid const& guid1, ObjectGuid const& guid2); + void DeVoice(ObjectGuid const& guid1, ObjectGuid const& guid2); + void JoinNotify(Player const* player); + void LeaveNotify(Player const* player); void SetOwnership(bool ownership) { _ownership = ownership; }; static void CleanOldChannelsInDB(); private: // initial packet data (notify type and channel name) - void MakeNotifyPacket(WorldPacket* data, uint8 notify_type); + void MakeNotifyPacket(WorldPackets::Channel::ChannelNotify& data, uint8 notifyType); // type specific packet data - void MakeJoined(WorldPacket* data, ObjectGuid guid); //+ 0x00 - void MakeLeft(WorldPacket* data, ObjectGuid guid); //+ 0x01 - void MakeYouJoined(WorldPacket* data); //+ 0x02 - void MakeYouLeft(WorldPacket* data); //+ 0x03 - void MakeWrongPassword(WorldPacket* data); //? 0x04 - void MakeNotMember(WorldPacket* data); //? 0x05 - void MakeNotModerator(WorldPacket* data); //? 0x06 - void MakePasswordChanged(WorldPacket* data, ObjectGuid guid); //+ 0x07 - void MakeOwnerChanged(WorldPacket* data, ObjectGuid guid); //? 0x08 - void MakePlayerNotFound(WorldPacket* data, std::string const& name); //+ 0x09 - void MakeNotOwner(WorldPacket* data); //? 0x0A - void MakeChannelOwner(WorldPacket* data); //? 0x0B - void MakeModeChange(WorldPacket* data, ObjectGuid guid, uint8 oldflags);//+ 0x0C - void MakeAnnouncementsOn(WorldPacket* data, ObjectGuid guid); //+ 0x0D - void MakeAnnouncementsOff(WorldPacket* data, ObjectGuid guid); //+ 0x0E - void MakeMuted(WorldPacket* data); //? 0x11 - void MakePlayerKicked(WorldPacket* data, ObjectGuid bad, ObjectGuid good);//? 0x12 - void MakeBanned(WorldPacket* data); //? 0x13 - void MakePlayerBanned(WorldPacket* data, ObjectGuid bad, ObjectGuid good);//? 0x14 - void MakePlayerUnbanned(WorldPacket* data, ObjectGuid bad, ObjectGuid good);//? 0x15 - void MakePlayerNotBanned(WorldPacket* data, std::string const& name); //? 0x16 - void MakePlayerAlreadyMember(WorldPacket* data, ObjectGuid guid); //+ 0x17 - void MakeInvite(WorldPacket* data, ObjectGuid guid); //? 0x18 - void MakeInviteWrongFaction(WorldPacket* data); //? 0x19 - void MakeWrongFaction(WorldPacket* data); //? 0x1A - void MakeInvalidName(WorldPacket* data); //? 0x1B - void MakeNotModerated(WorldPacket* data); //? 0x1C - void MakePlayerInvited(WorldPacket* data, std::string const& name); //+ 0x1D - void MakePlayerInviteBanned(WorldPacket* data, std::string const& name);//? 0x1E - void MakeThrottled(WorldPacket* data); //? 0x1F - void MakeNotInArea(WorldPacket* data); //? 0x20 - void MakeNotInLfg(WorldPacket* data); //? 0x21 - void MakeVoiceOn(WorldPacket* data, ObjectGuid guid); //+ 0x22 - void MakeVoiceOff(WorldPacket* data, ObjectGuid guid); //+ 0x23 + void MakeJoined(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x00 + void MakeLeft(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x01 + void MakeYouJoined(WorldPackets::Channel::ChannelNotify& data); //+ 0x02 + void MakeYouLeft(WorldPackets::Channel::ChannelNotify& data); //+ 0x03 + void MakeWrongPassword(WorldPackets::Channel::ChannelNotify& data); //? 0x04 + void MakeNotMember(WorldPackets::Channel::ChannelNotify& data); //? 0x05 + void MakeNotModerator(WorldPackets::Channel::ChannelNotify& data); //? 0x06 + void MakePasswordChanged(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x07 + void MakeOwnerChanged(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //? 0x08 + void MakePlayerNotFound(WorldPackets::Channel::ChannelNotify& data, std::string const& name); //+ 0x09 + void MakeNotOwner(WorldPackets::Channel::ChannelNotify& data); //? 0x0A + void MakeChannelOwner(WorldPackets::Channel::ChannelNotify& data); //? 0x0B + void MakeModeChange(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid, uint8 oldFlags, uint8 newFlags); //+ 0x0C + void MakeAnnouncementsOn(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x0D + void MakeAnnouncementsOff(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x0E + void MakeMuted(WorldPackets::Channel::ChannelNotify& data); //? 0x11 + void MakePlayerKicked(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& bad, ObjectGuid const& good); //? 0x12 + void MakeBanned(WorldPackets::Channel::ChannelNotify& data); //? 0x13 + void MakePlayerBanned(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& bad, ObjectGuid const& good); //? 0x14 + void MakePlayerUnbanned(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& bad, ObjectGuid const& good); //? 0x15 + void MakePlayerNotBanned(WorldPackets::Channel::ChannelNotify& data, std::string const& name); //? 0x16 + void MakePlayerAlreadyMember(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x17 + void MakeInvite(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //? 0x18 + void MakeInviteWrongFaction(WorldPackets::Channel::ChannelNotify& data); //? 0x19 + void MakeWrongFaction(WorldPackets::Channel::ChannelNotify& data); //? 0x1A + void MakeInvalidName(WorldPackets::Channel::ChannelNotify& data); //? 0x1B + void MakeNotModerated(WorldPackets::Channel::ChannelNotify& data); //? 0x1C + void MakePlayerInvited(WorldPackets::Channel::ChannelNotify& data, std::string const& name); //+ 0x1D + void MakePlayerInviteBanned(WorldPackets::Channel::ChannelNotify& data, std::string const& name); //? 0x1E + void MakeThrottled(WorldPackets::Channel::ChannelNotify& data); //? 0x1F + void MakeNotInArea(WorldPackets::Channel::ChannelNotify& data); //? 0x20 + void MakeNotInLfg(WorldPackets::Channel::ChannelNotify& data); //? 0x21 + void MakeVoiceOn(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x22 + void MakeVoiceOff(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x23 - void SendToAll(WorldPacket* data, ObjectGuid guid = ObjectGuid::Empty); - void SendToAllButOne(WorldPacket* data, ObjectGuid who); - void SendToOne(WorldPacket* data, ObjectGuid who); + void SendToAll(WorldPacket const* data, ObjectGuid const& guid = ObjectGuid::Empty); + void SendToAllButOne(WorldPacket const* data, ObjectGuid const& who); + void SendToOne(WorldPacket const* data, ObjectGuid const& who); - bool IsOn(ObjectGuid who) const { return playersStore.find(who) != playersStore.end(); } - bool IsBanned(ObjectGuid guid) const { return bannedStore.find(guid) != bannedStore.end(); } + bool IsOn(ObjectGuid const& who) const { return _playersStore.find(who) != _playersStore.end(); } + bool IsBanned(ObjectGuid const& guid) const { return _bannedStore.find(guid) != _bannedStore.end(); } void UpdateChannelInDB() const; void UpdateChannelUseageInDB() const; - uint8 GetPlayerFlags(ObjectGuid guid) const + uint8 GetPlayerFlags(ObjectGuid const& guid) const { - PlayerContainer::const_iterator itr = playersStore.find(guid); - return itr != playersStore.end() ? itr->second.flags : 0; + PlayerContainer::const_iterator itr = _playersStore.find(guid); + return itr != _playersStore.end() ? itr->second.GetFlags() : 0; } - void SetModerator(ObjectGuid guid, bool set) + void SetModerator(ObjectGuid const& guid, bool set) { - if (playersStore[guid].IsModerator() != set) + if (_playersStore[guid].IsModerator() != set) { - uint8 oldFlag = GetPlayerFlags(guid); - playersStore[guid].SetModerator(set); + uint8 oldFlag = _playersStore[guid].GetFlags(); + _playersStore[guid].SetModerator(set); - WorldPacket data; - MakeModeChange(&data, guid, oldFlag); - SendToAll(&data); + WorldPackets::Channel::ChannelNotify data; + MakeModeChange(data, guid, oldFlag, _playersStore[guid].GetFlags()); + SendToAll(data.Write()); } } - void SetMute(ObjectGuid guid, bool set) + void SetMute(ObjectGuid const& guid, bool set) { - if (playersStore[guid].IsMuted() != set) + if (_playersStore[guid].IsMuted() != set) { - uint8 oldFlag = GetPlayerFlags(guid); - playersStore[guid].SetMuted(set); + uint8 oldFlag = _playersStore[guid].GetFlags(); + _playersStore[guid].SetMuted(set); - WorldPacket data; - MakeModeChange(&data, guid, oldFlag); - SendToAll(&data); + WorldPackets::Channel::ChannelNotify data; + MakeModeChange(data, guid, oldFlag, _playersStore[guid].GetFlags()); + SendToAll(data.Write()); } } @@ -276,12 +287,12 @@ class Channel bool _IsSaved; uint8 _flags; uint32 _channelId; - uint32 _Team; + uint32 _team; ObjectGuid _ownerGUID; std::string _name; std::string _password; - PlayerContainer playersStore; - BannedContainer bannedStore; + PlayerContainer _playersStore; + BannedContainer _bannedStore; }; -#endif +#endif diff --git a/src/server/game/Chat/Channels/ChannelMgr.cpp b/src/server/game/Chat/Channels/ChannelMgr.cpp index a3a4ef69e63..ca664abffd9 100644 --- a/src/server/game/Chat/Channels/ChannelMgr.cpp +++ b/src/server/game/Chat/Channels/ChannelMgr.cpp @@ -23,11 +23,11 @@ ChannelMgr::~ChannelMgr() { - for (ChannelMap::iterator itr = channels.begin(); itr != channels.end(); ++itr) + for (ChannelMap::iterator itr = _channels.begin(); itr != _channels.end(); ++itr) delete itr->second; } -ChannelMgr* ChannelMgr::forTeam(uint32 team) +ChannelMgr* ChannelMgr::ForTeam(uint32 team) { static ChannelMgr allianceChannelMgr; static ChannelMgr hordeChannelMgr; @@ -40,49 +40,43 @@ ChannelMgr* ChannelMgr::forTeam(uint32 team) if (team == HORDE) return &hordeChannelMgr; - return NULL; + return nullptr; } Channel* ChannelMgr::GetJoinChannel(std::string const& name, uint32 channelId) { std::wstring wname; if (!Utf8toWStr(name, wname)) - return NULL; + return nullptr; wstrToLower(wname); - ChannelMap::const_iterator i = channels.find(wname); - - if (i == channels.end()) + ChannelMap::const_iterator i = _channels.find(wname); + if (i == _channels.end()) { - Channel* nchan = new Channel(name, channelId, team); - channels[wname] = nchan; + Channel* nchan = new Channel(name, channelId, _team); + _channels[wname] = nchan; return nchan; } return i->second; } -Channel* ChannelMgr::GetChannel(std::string const& name, Player* player, bool pkt) +Channel* ChannelMgr::GetChannel(std::string const& name, Player* player, bool notify /*= true*/) { std::wstring wname; if (!Utf8toWStr(name, wname)) - return NULL; + return nullptr; wstrToLower(wname); - ChannelMap::const_iterator i = channels.find(wname); - - if (i == channels.end()) + ChannelMap::const_iterator i = _channels.find(wname); + if (i == _channels.end()) { - if (pkt) - { - WorldPacket data; - MakeNotOnPacket(&data, name); - player->GetSession()->SendPacket(&data); - } - - return NULL; + if (notify) + SendNotOnChannelNotify(player, name); + + return nullptr; } return i->second; @@ -96,22 +90,23 @@ void ChannelMgr::LeftChannel(std::string const& name) wstrToLower(wname); - ChannelMap::const_iterator i = channels.find(wname); - - if (i == channels.end()) + ChannelMap::const_iterator i = _channels.find(wname); + if (i == _channels.end()) return; Channel* channel = i->second; if (!channel->GetNumPlayers() && !channel->IsConstant()) { - channels.erase(wname); + _channels.erase(i); delete channel; } } -void ChannelMgr::MakeNotOnPacket(WorldPacket* data, std::string const& name) +void ChannelMgr::SendNotOnChannelNotify(Player const* player, std::string const& name) { - data->Initialize(SMSG_CHANNEL_NOTIFY, 1 + name.size()); - (*data) << uint8(5) << name; + WorldPackets::Channel::ChannelNotify notify; + notify.Type = CHAT_NOT_MEMBER_NOTICE; + notify.Channel = name; + player->SendDirectMessage(notify.Write()); } diff --git a/src/server/game/Chat/Channels/ChannelMgr.h b/src/server/game/Chat/Channels/ChannelMgr.h index eee45ba5b97..9a8fdb10767 100644 --- a/src/server/game/Chat/Channels/ChannelMgr.h +++ b/src/server/game/Chat/Channels/ChannelMgr.h @@ -21,11 +21,6 @@ #include "Common.h" #include "Channel.h" -#include <map> -#include <string> - -#include "World.h" - #define MAX_CHANNEL_PASS_STR 31 class ChannelMgr @@ -33,22 +28,22 @@ class ChannelMgr typedef std::map<std::wstring, Channel*> ChannelMap; protected: - ChannelMgr() : team(0) { } + ChannelMgr() : _team(0) { } ~ChannelMgr(); public: - static ChannelMgr* forTeam(uint32 team); - void setTeam(uint32 newTeam) { team = newTeam; } + static ChannelMgr* ForTeam(uint32 team); + void SetTeam(uint32 newTeam) { _team = newTeam; } - Channel* GetJoinChannel(std::string const& name, uint32 channel_id); - Channel* GetChannel(std::string const& name, Player* p, bool pkt = true); + Channel* GetJoinChannel(std::string const& name, uint32 channelId); + Channel* GetChannel(std::string const& name, Player* player, bool notify = true); void LeftChannel(std::string const& name); private: - ChannelMap channels; - uint32 team; + ChannelMap _channels; + uint32 _team; - void MakeNotOnPacket(WorldPacket* data, std::string const& name); + static void SendNotOnChannelNotify(Player const* player, std::string const& name); }; #endif diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index ec3bc458066..cbb0e4683aa 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -35,6 +35,8 @@ #include "SpellMgr.h" #include "ScriptMgr.h" #include "ChatLink.h" +#include "Guild.h" +#include "Group.h" bool ChatHandler::load_command_table = true; @@ -202,7 +204,7 @@ bool ChatHandler::hasStringAbbr(const char* name, const char* part) void ChatHandler::SendSysMessage(const char *str) { - WorldPacket data; + WorldPackets::Chat::Chat packet; // need copy to prevent corruption by strtok call in LineFromMessage original string char* buf = strdup(str); @@ -210,8 +212,8 @@ void ChatHandler::SendSysMessage(const char *str) while (char* line = LineFromMessage(pos)) { - BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); - m_session->SendPacket(&data); + BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + m_session->SendPacket(packet.Write()); } free(buf); @@ -220,7 +222,7 @@ void ChatHandler::SendSysMessage(const char *str) void ChatHandler::SendGlobalSysMessage(const char *str) { // Chat output - WorldPacket data; + WorldPackets::Chat::Chat packet; // need copy to prevent corruption by strtok call in LineFromMessage original string char* buf = strdup(str); @@ -228,8 +230,8 @@ void ChatHandler::SendGlobalSysMessage(const char *str) while (char* line = LineFromMessage(pos)) { - BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); - sWorld->SendGlobalMessage(&data); + BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + sWorld->SendGlobalMessage(packet.Write()); } free(buf); @@ -238,7 +240,7 @@ void ChatHandler::SendGlobalSysMessage(const char *str) void ChatHandler::SendGlobalGMSysMessage(const char *str) { // Chat output - WorldPacket data; + WorldPackets::Chat::Chat packet; // need copy to prevent corruption by strtok call in LineFromMessage original string char* buf = strdup(str); @@ -246,8 +248,8 @@ void ChatHandler::SendGlobalGMSysMessage(const char *str) while (char* line = LineFromMessage(pos)) { - BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); - sWorld->SendGlobalGMMessage(&data); + BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + sWorld->SendGlobalGMMessage(packet.Write()); } free(buf); @@ -628,132 +630,56 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand* table, const char* cmd) return ShowHelpForSubCommands(table, "", cmd); } -size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const& message, uint8 chatTag, - std::string const& senderName /*= ""*/, std::string const& receiverName /*= ""*/, - uint32 achievementId /*= 0*/, bool gmMessage /*= false*/, std::string const& channelName /*= ""*/, - std::string const& addonPrefix /*= ""*/) +void ChatHandler::BuildChatPacket(WorldPackets::Chat::Chat* packet, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message, + uint32 achievementId /*= 0*/, std::string const& channelName /*= ""*/, LocaleConstant locale /*= DEFAULT_LOCALE*/, std::string const& addonPrefix /*= ""*/) { - size_t receiverGUIDPos = 0; - data.Initialize(!gmMessage ? SMSG_MESSAGECHAT : SMSG_GM_MESSAGECHAT); - data << uint8(chatType); - data << int32(language); - data << senderGUID; - data << uint32(0); // some flags - switch (chatType) - { - case CHAT_MSG_MONSTER_SAY: - case CHAT_MSG_MONSTER_PARTY: - case CHAT_MSG_MONSTER_YELL: - case CHAT_MSG_MONSTER_WHISPER: - case CHAT_MSG_MONSTER_EMOTE: - case CHAT_MSG_RAID_BOSS_EMOTE: - case CHAT_MSG_RAID_BOSS_WHISPER: - case CHAT_MSG_BATTLENET: - data << uint32(senderName.length() + 1); - data << senderName; - receiverGUIDPos = data.wpos(); - data << receiverGUID; - if (!receiverGUID.IsEmpty() && !receiverGUID.IsPlayer() && !receiverGUID.IsPet()) - { - data << uint32(receiverName.length() + 1); - data << receiverName; - } - - if (language == LANG_ADDON) - data << addonPrefix; - break; - case CHAT_MSG_WHISPER_FOREIGN: - data << uint32(senderName.length() + 1); - data << senderName; - receiverGUIDPos = data.wpos(); - data << receiverGUID; - if (language == LANG_ADDON) - data << addonPrefix; - break; - case CHAT_MSG_BG_SYSTEM_NEUTRAL: - case CHAT_MSG_BG_SYSTEM_ALLIANCE: - case CHAT_MSG_BG_SYSTEM_HORDE: - receiverGUIDPos = data.wpos(); - data << receiverGUID; - if (!receiverGUID.IsEmpty() && !receiverGUID.IsPlayer()) - { - data << uint32(receiverName.length() + 1); - data << receiverName; - } - - if (language == LANG_ADDON) - data << addonPrefix; - break; - case CHAT_MSG_ACHIEVEMENT: - case CHAT_MSG_GUILD_ACHIEVEMENT: - receiverGUIDPos = data.wpos(); - data << receiverGUID; - if (language == LANG_ADDON) - data << addonPrefix; - break; - default: - if (gmMessage) - { - data << uint32(senderName.length() + 1); - data << senderName; - } - - if (chatType == CHAT_MSG_CHANNEL) - { - ASSERT(channelName.length() > 0); - data << channelName; - } + // Clear everything because same packet can be used multiple times + packet->Reset(); + packet->SenderGUID.Clear(); + packet->SenderAccountGUID.Clear(); + packet->SenderGuildGUID.Clear(); + packet->PartyGUID.Clear(); + packet->TargetGUID.Clear(); + packet->SenderName.clear(); + packet->TargetName.clear(); + packet->ChatFlags = CHAT_FLAG_NONE; + + packet->SlashCmd = chatType; + packet->Language = language; - receiverGUIDPos = data.wpos(); - data << receiverGUID; - - if (language == LANG_ADDON) - data << addonPrefix; - break; - } - - data << uint32(message.length() + 1); - data << message; - data << uint8(chatTag); - - if (chatType == CHAT_MSG_ACHIEVEMENT || chatType == CHAT_MSG_GUILD_ACHIEVEMENT) - data << uint32(achievementId); - else if (chatType == CHAT_MSG_RAID_BOSS_WHISPER || chatType == CHAT_MSG_RAID_BOSS_EMOTE) + if (sender) { - data << float(0.0f); // Display time in middle of the screen (in seconds), defaults to 10 if not set (cannot be below 1) - data << uint8(0); // Hide in chat frame (only shows in middle of the screen) - } + packet->SenderGUID = sender->GetGUID(); - return receiverGUIDPos; -} + if (Creature const* creatureSender = sender->ToCreature()) + packet->SenderName = creatureSender->GetNameForLocaleIdx(locale); -size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message, - uint32 achievementId /*= 0*/, std::string const& channelName /*= ""*/, LocaleConstant locale /*= DEFAULT_LOCALE*/, std::string const& addonPrefix /*= ""*/) -{ - ObjectGuid senderGUID; - std::string senderName = ""; - uint8 chatTag = 0; - bool gmMessage = false; - ObjectGuid receiverGUID; - std::string receiverName = ""; - if (sender) - { - senderGUID = sender->GetGUID(); - senderName = sender->GetNameForLocaleIdx(locale); if (Player const* playerSender = sender->ToPlayer()) { - chatTag = playerSender->GetChatTag(); - gmMessage = playerSender->GetSession()->HasPermission(rbac::RBAC_PERM_COMMAND_GM_CHAT); + packet->SenderAccountGUID = playerSender->GetSession()->GetAccountGUID(); + packet->ChatFlags = playerSender->GetChatFlags(); + + if (Guild const* guild = playerSender->GetGuild()) + packet->SenderGuildGUID = guild->GetGUID(); + + if (Group const* group = playerSender->GetGroup()) + packet->PartyGUID = group->GetGUID(); } } if (receiver) { - receiverGUID = receiver->GetGUID(); - receiverName = receiver->GetNameForLocaleIdx(locale); + packet->TargetGUID = receiver->GetGUID(); + if (Creature const* creatureReceiver = receiver->ToCreature()) + packet->TargetName = creatureReceiver->GetNameForLocaleIdx(locale); } - return BuildChatPacket(data, chatType, language, senderGUID, receiverGUID, message, chatTag, senderName, receiverName, achievementId, gmMessage, channelName, addonPrefix); + packet->SenderVirtualAddress = GetVirtualRealmAddress(); + packet->TargetVirtualAddress = GetVirtualRealmAddress(); + packet->AchievementID = achievementId; + packet->Channel = channelName; + packet->Prefix = addonPrefix; + packet->ChatText = message; } Player* ChatHandler::getSelectedPlayer() @@ -1000,7 +926,7 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text) if (!idS) return 0; - uint32 id = (uint32)atol(idS); + uint32 id = atoul(idS); switch (type) { @@ -1020,7 +946,7 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text) return id; case SPELL_LINK_GLYPH: { - uint32 glyph_prop_id = param1_str ? (uint32)atol(param1_str) : 0; + uint32 glyph_prop_id = param1_str ? atoul(param1_str) : 0; GlyphPropertiesEntry const* glyphPropEntry = sGlyphPropertiesStore.LookupEntry(glyph_prop_id); if (!glyphPropEntry) diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 98c3bc3efbb..5db48db0fbe 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -22,6 +22,7 @@ #include "SharedDefines.h" #include "WorldSession.h" #include "RBAC.h" +#include "Packets/ChatPackets.h" #include <vector> @@ -53,14 +54,7 @@ class ChatHandler explicit ChatHandler(WorldSession* session) : m_session(session), sentErrorMessage(false) { } virtual ~ChatHandler() { } - // Builds chat packet and returns receiver guid position in the packet to substitute in whisper builders - static size_t BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const& message, uint8 chatTag, - std::string const& senderName = "", std::string const& receiverName = "", - uint32 achievementId = 0, bool gmMessage = false, std::string const& channelName = "", - std::string const& addonPrefix = ""); - - // Builds chat packet and returns receiver guid position in the packet to substitute in whisper builders - static size_t BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message, uint32 achievementId = 0, std::string const& channelName = "", LocaleConstant locale = DEFAULT_LOCALE, std::string const& addonPrefix = ""); + static void BuildChatPacket(WorldPackets::Chat::Chat* packet, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message, uint32 achievementId = 0, std::string const& channelName = "", LocaleConstant locale = DEFAULT_LOCALE, std::string const& addonPrefix = ""); static char* LineFromMessage(char*& pos) { char* start = strtok(pos, "\n"); pos = NULL; return start; } diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index debee4056e7..654451af949 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -29,6 +29,79 @@ #include "SpellMgr.h" #include "Spell.h" +char const* ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX] = +{ + "None", + "Creature Loot", + "Disenchant Loot", + "Fishing Loot", + "GameObject Loot", + "Item Loot", + "Mail Loot", + "Milling Loot", + "Pickpocketing Loot", + "Prospecting Loot", + "Reference Loot", + "Skinning Loot", + "Spell Loot", + "Spell Impl. Target", + "Gossip Menu", + "Gossip Menu Option", + "Creature Vehicle", + "Spell Expl. Target", + "Spell Click Event", + "Quest Accept", + "Quest Show Mark", + "Vehicle Spell", + "SmartScript", + "Npc Vendor", + "Spell Proc", + "Phase Def" +}; + +ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[CONDITION_MAX] = +{ + { "None", false, false, false }, + { "Aura", true, true, true }, + { "Item Stored", true, true, true }, + { "Item Equipped", true, false, false }, + { "Zone", true, false, false }, + { "Reputation", true, true, false }, + { "Team", true, false, false }, + { "Skill", true, true, false }, + { "Quest Rewarded", true, false, false }, + { "Quest Taken", true, false, false }, + { "Drunken", true, false, false }, + { "WorldState", true, true, false }, + { "Active Event", true, false, false }, + { "Instance Info", true, true, true }, + { "Quest None", true, false, false }, + { "Class", true, false, false }, + { "Race", true, false, false }, + { "Achievement", true, false, false }, + { "Title", true, false, false }, + { "SpawnMask", true, false, false }, + { "Gender", true, false, false }, + { "Unit State", true, false, false }, + { "Map", true, false, false }, + { "Area", true, false, false }, + { "CreatureType", true, false, false }, + { "Spell Known", true, false, false }, + { "Phase", true, false, false }, + { "Level", true, true, false }, + { "Quest Completed", true, false, false }, + { "Near Creature", true, true, false }, + { "Near GameObject", true, true, false }, + { "Object Entry or Guid", true, true, true }, + { "Object TypeMask", true, false, false }, + { "Relation", true, true, false }, + { "Reaction", true, true, false }, + { "Distance", true, true, true }, + { "Alive", false, false, false }, + { "Health Value", true, true, false }, + { "Health Pct", true, true, false } +}; + // Checks if object meets the condition // Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: SmartAI) bool Condition::Meets(ConditionSourceInfo& sourceInfo) @@ -38,7 +111,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) // object not present, return false if (!object) { - TC_LOG_DEBUG("condition", "Condition object not found for condition (Entry: %u Type: %u Group: %u)", SourceEntry, SourceType, SourceGroup); + TC_LOG_DEBUG("condition", "Condition object not found for %s", ToString().c_str()); return false; } bool condMeets = false; @@ -540,6 +613,34 @@ uint32 Condition::GetMaxAvailableConditionTargets() } } +std::string Condition::ToString(bool ext /*= false*/) const +{ + std::ostringstream ss; + ss << "[Condition "; + ss << "SourceType: " << SourceType; + if (SourceType < CONDITION_SOURCE_TYPE_MAX) + ss << " (" << ConditionMgr::StaticSourceTypeData[SourceType] << ")"; + else + ss << " (Unknown)"; + if (ConditionMgr::CanHaveSourceGroupSet(SourceType)) + ss << ", SourceGroup: " << SourceGroup; + ss << ", SourceEntry: " << SourceEntry; + if (ConditionMgr::CanHaveSourceIdSet(SourceType)) + ss << ", SourceId: " << SourceId; + + if (ext) + { + ss << ", ConditionType: " << ConditionType; + if (ConditionType < CONDITION_MAX) + ss << " (" << ConditionMgr::StaticConditionTypeData[ConditionType].Name << ")"; + else + ss << " (Unknown)"; + } + + ss << "]"; + return ss.str(); +} + ConditionMgr::ConditionMgr() { } ConditionMgr::~ConditionMgr() @@ -602,7 +703,7 @@ bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, std::map<uint32, bool> ElseGroupStore; for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i) { - TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList condType: %u val1: %u", (*i)->ConditionType, (*i)->ConditionValue1); + TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList %s val1: %u", (*i)->ToString().c_str(), (*i)->ConditionValue1); if ((*i)->isLoaded()) { //! Find ElseGroup in ElseGroupStore @@ -623,8 +724,8 @@ bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, } else { - TC_LOG_DEBUG("condition", "IsPlayerMeetToConditionList: Reference template -%u not found", - (*i)->ReferenceId);//checked at loading, should never happen + TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList %s Reference template -%u not found", + (*i)->ToString().c_str(), (*i)->ReferenceId); // checked at loading, should never happen } } @@ -663,7 +764,7 @@ bool ConditionMgr::IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, Con return IsObjectMeetToConditionList(sourceInfo, conditions); } -bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const +bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) { return (sourceType == CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE || @@ -687,7 +788,7 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR); } -bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) const +bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) { return (sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT); } @@ -721,7 +822,7 @@ ConditionList ConditionMgr::GetConditionsForSpellClickEvent(uint32 creatureId, u if (i != (*itr).second.end()) { cond = (*i).second; - TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for Vehicle entry %u spell %u", creatureId, spellId); + TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry %u spell %u", creatureId, spellId); } } return cond; @@ -753,7 +854,7 @@ ConditionList ConditionMgr::GetConditionsForSmartEvent(int64 entryOrGuid, uint32 if (i != (*itr).second.end()) { cond = (*i).second; - TC_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid " SI64FMTD " event_id %u", entryOrGuid, eventId); + TC_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid " SI64FMTD " eventId %u", entryOrGuid, eventId); } } return cond; @@ -917,26 +1018,26 @@ void ConditionMgr::LoadConditions(bool isReload) //Grouping is only allowed for some types (loot templates, gossip menus, gossip items) if (cond->SourceGroup && !CanHaveSourceGroupSet(cond->SourceType)) { - TC_LOG_ERROR("sql.sql", "Condition type %u has not allowed value of SourceGroup = %u!", uint32(cond->SourceType), cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s has not allowed value of SourceGroup = %u!", cond->ToString().c_str(), cond->SourceGroup); delete cond; continue; } if (cond->SourceId && !CanHaveSourceIdSet(cond->SourceType)) { - TC_LOG_ERROR("sql.sql", "Condition type %u has not allowed value of SourceId = %u!", uint32(cond->SourceType), cond->SourceId); + TC_LOG_ERROR("sql.sql", "%s has not allowed value of SourceId = %u!", cond->ToString().c_str(), cond->SourceId); delete cond; continue; } if (cond->ErrorType && cond->SourceType != CONDITION_SOURCE_TYPE_SPELL) { - TC_LOG_ERROR("sql.sql", "Condition type %u entry %i can't have ErrorType (%u), set to 0!", uint32(cond->SourceType), cond->SourceEntry, cond->ErrorType); + TC_LOG_ERROR("sql.sql", "%s can't have ErrorType (%u), set to 0!", cond->ToString().c_str(), cond->ErrorType); cond->ErrorType = 0; } if (cond->ErrorTextId && !cond->ErrorType) { - TC_LOG_ERROR("sql.sql", "Condition type %u entry %i has any ErrorType, ErrorTextId (%u) is set, set to 0!", uint32(cond->SourceType), cond->SourceEntry, cond->ErrorTextId); + TC_LOG_ERROR("sql.sql", "%s has any ErrorType, ErrorTextId (%u) is set, set to 0!", cond->ToString().c_str(), cond->ErrorTextId); cond->ErrorTextId = 0; } @@ -1034,7 +1135,7 @@ void ConditionMgr::LoadConditions(bool isReload) if (!valid) { - TC_LOG_ERROR("sql.sql", "Not handled grouped condition, SourceGroup %u", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s Not handled grouped condition.", cond->ToString().c_str()); delete cond; } else @@ -1067,21 +1168,20 @@ void ConditionMgr::LoadConditions(bool isReload) while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u conditions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - } bool ConditionMgr::addToLootTemplate(Condition* cond, LootTemplate* loot) { if (!loot) { - TC_LOG_ERROR("sql.sql", "ConditionMgr: LootTemplate %u not found", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s LootTemplate %u not found.", cond->ToString().c_str(), cond->SourceGroup); return false; } if (loot->addConditionItem(cond)) return true; - TC_LOG_ERROR("sql.sql", "ConditionMgr: Item %u not found in LootTemplate %u", cond->SourceEntry, cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s Item %u not found in LootTemplate %u.", cond->ToString().c_str(), cond->SourceEntry, cond->SourceGroup); return false; } @@ -1101,7 +1201,7 @@ bool ConditionMgr::addToGossipMenus(Condition* cond) } } - TC_LOG_ERROR("sql.sql", "addToGossipMenus: GossipMenu %u not found", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s GossipMenu %u not found.", cond->ToString().c_str(), cond->SourceGroup); return false; } @@ -1120,7 +1220,7 @@ bool ConditionMgr::addToGossipMenuItems(Condition* cond) } } - TC_LOG_ERROR("sql.sql", "addToGossipMenuItems: GossipMenuId %u Item %u not found", cond->SourceGroup, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s GossipMenuId %u Item %u not found.", cond->ToString().c_str(), cond->SourceGroup, cond->SourceEntry); return false; } @@ -1187,8 +1287,8 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) // we have overlapping masks in db if (conditionEffMask != *itr) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set - " - "effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond->SourceEntry, cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect SourceGroup %u (spell effectMask) set - " + "effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond->ToString().c_str(), cond->SourceGroup); return false; } } @@ -1225,7 +1325,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (cond->SourceType == CONDITION_SOURCE_TYPE_NONE || cond->SourceType >= CONDITION_SOURCE_TYPE_MAX) { - TC_LOG_ERROR("sql.sql", "Invalid ConditionSourceType %u in `condition` table, ignoring.", uint32(cond->SourceType)); + TC_LOG_ERROR("sql.sql", "%s Invalid ConditionSourceType in `condition` table, ignoring.", cond->ToString().c_str()); return false; } @@ -1235,7 +1335,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Creature.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `creature_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `creature_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1243,7 +1343,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1252,7 +1352,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Disenchant.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `disenchant_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `disenchant_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1260,7 +1360,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1269,7 +1369,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Fishing.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `fishing_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `fishing_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1277,7 +1377,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1286,7 +1386,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Gameobject.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `gameobject_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `gameobject_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1294,7 +1394,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1303,7 +1403,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Item.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `item_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `item_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1311,7 +1411,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1320,7 +1420,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Mail.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `mail_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `mail_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1328,7 +1428,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1337,7 +1437,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Milling.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `milling_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `milling_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1345,7 +1445,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1354,7 +1454,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Pickpocketing.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1362,7 +1462,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1371,7 +1471,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Prospecting.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `prospecting_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `prospecting_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1379,7 +1479,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1388,7 +1488,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Reference.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `reference_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `reference_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1396,7 +1496,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1405,7 +1505,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Skinning.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `skinning_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `skinning_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1413,7 +1513,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1422,7 +1522,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Spell.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `spell_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `spell_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1430,7 +1530,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1440,13 +1540,13 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(cond->SourceEntry); if (!spellInfo) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s in `condition` table, SourceEntry does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str()); return false; } if ((cond->SourceGroup > MAX_EFFECT_MASK) || !cond->SourceGroup) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set, ignoring.", cond->SourceEntry, cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect SourceGroup (spell effectMask) set, ignoring.", cond->ToString().c_str()); return false; } @@ -1454,7 +1554,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { - if (!((1<<i) & cond->SourceGroup)) + if (!((1 << i) & cond->SourceGroup)) continue; SpellEffectInfo const* effect = spellInfo->GetEffect(DIFFICULTY_NONE, i); @@ -1482,7 +1582,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) } TC_LOG_ERROR("sql.sql", "SourceEntry %u SourceGroup %u in `condition` table - spell %u does not have implicit targets of types: _AREA_, _CONE_, _NEARBY_ for effect %u, SourceGroup needs correction, ignoring.", cond->SourceEntry, origGroup, cond->SourceEntry, uint32(i)); - cond->SourceGroup &= ~(1<<i); + cond->SourceGroup &= ~(1 << i); } // all effects were removed, no need to add the condition at all if (!cond->SourceGroup) @@ -1493,7 +1593,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!sObjectMgr->GetCreatureTemplate(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1504,48 +1604,42 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(cond->SourceEntry); if (!spellProto) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str()); return false; } break; } case CONDITION_SOURCE_TYPE_QUEST_ACCEPT: - if (!sObjectMgr->GetQuestTemplate(cond->SourceEntry)) - { - TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_QUEST_ACCEPT specifies non-existing quest (%u), skipped", cond->SourceEntry); - return false; - } - break; case CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK: if (!sObjectMgr->GetQuestTemplate(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK specifies non-existing quest (%u), skipped", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceEntry specifies non-existing quest, skipped.", cond->ToString().c_str()); return false; } break; case CONDITION_SOURCE_TYPE_VEHICLE_SPELL: if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str()); return false; } if (!sSpellMgr->GetSpellInfo(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str()); return false; } break; case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT: if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str()); return false; } if (!sSpellMgr->GetSpellInfo(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1560,13 +1654,13 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str()); return false; } ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!itemTemplate) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1586,13 +1680,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (cond->ConditionType == CONDITION_NONE || cond->ConditionType >= CONDITION_MAX) { - TC_LOG_ERROR("sql.sql", "Invalid ConditionType %u at SourceEntry %u in `condition` table, ignoring.", uint32(cond->ConditionType), cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s Invalid ConditionType in `condition` table, ignoring.", cond->ToString().c_str()); return false; } if (cond->ConditionTarget >= cond->GetMaxAvailableConditionTargets()) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u, SourceGroup %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->SourceType, cond->SourceEntry, cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->ToString(true).c_str()); return false; } @@ -1602,17 +1696,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (!sSpellMgr->GetSpellInfo(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "Aura condition has non existing spell (Id: %d), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing spell (Id: %d), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue2 > EFFECT_2) { - TC_LOG_ERROR("sql.sql", "Aura condition has non existing effect index (%u) (must be 0..2), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has non existing effect index (%u) (must be 0..2), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Aura condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_ITEM: @@ -1620,13 +1712,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) ItemTemplate const* proto = sObjectMgr->GetItemTemplate(cond->ConditionValue1); if (!proto) { - TC_LOG_ERROR("sql.sql", "Item condition has non existing item (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s Item (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (!cond->ConditionValue2) { - TC_LOG_ERROR("sql.sql", "Item condition has 0 set for item count in value2 (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s Zero item count in ConditionValue2, skipped.", cond->ToString(true).c_str()); return false; } break; @@ -1636,14 +1728,9 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) ItemTemplate const* proto = sObjectMgr->GetItemTemplate(cond->ConditionValue1); if (!proto) { - TC_LOG_ERROR("sql.sql", "ItemEquipped condition has non existing item (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s Item (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "ItemEquipped condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "ItemEquipped condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_ZONEID: @@ -1651,20 +1738,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(cond->ConditionValue1); if (!areaEntry) { - TC_LOG_ERROR("sql.sql", "ZoneID condition has non existing area (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s Area (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (areaEntry->ParentAreaID != 0) { - TC_LOG_ERROR("sql.sql", "ZoneID condition requires to be in area (%u) which is a subzone but zone expected, skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s requires to be in area (%u) which is a subzone but zone expected, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "ZoneID condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "ZoneID condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_REPUTATION_RANK: @@ -1672,25 +1754,18 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) FactionEntry const* factionEntry = sFactionStore.LookupEntry(cond->ConditionValue1); if (!factionEntry) { - TC_LOG_ERROR("sql.sql", "Reputation condition has non existing faction (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing faction (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Reputation condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_TEAM: { if (cond->ConditionValue1 != ALLIANCE && cond->ConditionValue1 != HORDE) { - TC_LOG_ERROR("sql.sql", "Team condition specifies unknown team (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s specifies unknown team (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Team condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Team condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_SKILL: @@ -1698,17 +1773,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(cond->ConditionValue1); if (!pSkill) { - TC_LOG_ERROR("sql.sql", "Skill condition specifies non-existing skill (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s specifies non-existing skill (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue2 < 1 || cond->ConditionValue2 > sWorld->GetConfigMaxSkillValue()) { - TC_LOG_ERROR("sql.sql", "Skill condition specifies skill (%u) with invalid value (%u), skipped", cond->ConditionValue1, cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s specifies skill (%u) with invalid value (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1, cond->ConditionValue2); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Skill condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_QUESTREWARDED: @@ -1718,30 +1791,19 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (!sObjectMgr->GetQuestTemplate(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "Quest condition (Type: %u) points to non-existing quest (%u) for Source Entry %u. SourceGroup: %u, SourceTypeOrReferenceId: %u", - cond->ConditionType, cond->ConditionValue1, cond->SourceEntry, cond->SourceGroup, cond->SourceType); + TC_LOG_ERROR("sql.sql", "%s points to non-existing quest (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2 > 1) - TC_LOG_ERROR("sql.sql", "Quest condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Quest condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_ACTIVE_EVENT: { GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap(); - if (cond->ConditionValue1 >=events.size() || !events[cond->ConditionValue1].isValid()) + if (cond->ConditionValue1 >= events.size() || !events[cond->ConditionValue1].isValid()) { - TC_LOG_ERROR("sql.sql", "ActiveEvent condition has non existing event id (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing event id (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "ActiveEvent condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "ActiveEvent condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_ACHIEVEMENT: @@ -1749,56 +1811,36 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) AchievementEntry const* achievement = sAchievementMgr->GetAchievement(cond->ConditionValue1); if (!achievement) { - TC_LOG_ERROR("sql.sql", "Achivement condition has non existing achivement id (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing achivement id (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Achivement condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Achivement condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_CLASS: { if (!(cond->ConditionValue1 & CLASSMASK_ALL_PLAYABLE)) { - TC_LOG_ERROR("sql.sql", "Class condition has non existing classmask (%u), skipped", cond->ConditionValue1 & ~CLASSMASK_ALL_PLAYABLE); + TC_LOG_ERROR("sql.sql", "%s has non existing classmask (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1 & ~CLASSMASK_ALL_PLAYABLE); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Class condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Class condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_RACE: { if (!(cond->ConditionValue1 & RACEMASK_ALL_PLAYABLE)) { - TC_LOG_ERROR("sql.sql", "Race condition has non existing racemask (%u), skipped", cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE); + TC_LOG_ERROR("sql.sql", "%s has non existing racemask (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Race condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Race condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_GENDER: { if (!Player::IsValidGender(uint8(cond->ConditionValue1))) { - TC_LOG_ERROR("sql.sql", "Gender condition has invalid gender (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has invalid gender (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Gender condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Gender condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_MAPID: @@ -1806,77 +1848,54 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) MapEntry const* me = sMapStore.LookupEntry(cond->ConditionValue1); if (!me) { - TC_LOG_ERROR("sql.sql", "Map condition has non existing map (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing map (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Map condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Map condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_SPELL: { if (!sSpellMgr->GetSpellInfo(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "Spell condition has non existing spell (Id: %d), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing spell (Id: %d), skipped", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Spell condition has useless data (spell Id: %d) in value2 (%u)!", cond->ConditionValue1, cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Spell condition has useless data (spell Id: %d) in value3 (%u)!", cond->ConditionValue1, cond->ConditionValue3); break; } case CONDITION_LEVEL: { if (cond->ConditionValue2 >= COMP_TYPE_MAX) { - TC_LOG_ERROR("sql.sql", "Level condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Level condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_DRUNKENSTATE: { if (cond->ConditionValue1 > DRUNKEN_SMASHED) { - TC_LOG_ERROR("sql.sql", "DrunkState condition has invalid state (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has invalid state (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - if (cond->ConditionValue2) - { - TC_LOG_ERROR("sql.sql", "DrunkState condition has useless data in value2 (%u)!", cond->ConditionValue2); - return false; - } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "DrunkState condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_NEAR_CREATURE: { if (!sObjectMgr->GetCreatureTemplate(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "NearCreature condition has non existing creature template entry (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing creature template entry (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "NearCreature condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_NEAR_GAMEOBJECT: { if (!sObjectMgr->GetGameObjectTemplate(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "NearGameObject condition has non existing gameobject template entry (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing gameobject template entry (%u), skipped.", cond->ToString().c_str(), cond->ConditionValue1); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "NearGameObject condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_OBJECT_ENTRY_GUID: @@ -1886,7 +1905,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) case TYPEID_UNIT: if (cond->ConditionValue2 && !sObjectMgr->GetCreatureTemplate(cond->ConditionValue2)) { - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing creature template entry (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has non existing creature template entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } if (cond->ConditionValue3) @@ -1895,13 +1914,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (cond->ConditionValue2 && creatureData->id != cond->ConditionValue2) { - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has guid %u set but does not match creature entry (%u), skipped", cond->ConditionValue3, cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has guid %u set but does not match creature entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3, cond->ConditionValue2); return false; } } else { - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing creature guid (%u), skipped", cond->ConditionValue3); + TC_LOG_ERROR("sql.sql", "%s has non existing creature guid (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3); return false; } } @@ -1909,7 +1928,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) case TYPEID_GAMEOBJECT: if (cond->ConditionValue2 && !sObjectMgr->GetGameObjectTemplate(cond->ConditionValue2)) { - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing gameobject template entry (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has non existing gameobject template entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } if (cond->ConditionValue3) @@ -1918,13 +1937,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (cond->ConditionValue2 && goData->id != cond->ConditionValue2) { - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has guid %u set but does not match gameobject entry (%u), skipped", cond->ConditionValue3, cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has guid %u set but does not match gameobject entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3, cond->ConditionValue2); return false; } } else { - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing gameobject guid (%u), skipped", cond->ConditionValue3); + TC_LOG_ERROR("sql.sql", "%s has non existing gameobject guid (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3); return false; } } @@ -1932,12 +1951,12 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) case TYPEID_PLAYER: case TYPEID_CORPSE: if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has useless data in value2 (%u)!", cond->ConditionValue2); + LogUselessConditionValue(cond, 2, cond->ConditionValue2); if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has useless data in value3 (%u)!", cond->ConditionValue3); + LogUselessConditionValue(cond, 3, cond->ConditionValue3); break; default: - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has wrong typeid set (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has wrong typeid set (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } break; @@ -1946,51 +1965,45 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (!cond->ConditionValue1 || (cond->ConditionValue1 & ~(TYPEMASK_UNIT | TYPEMASK_PLAYER | TYPEMASK_GAMEOBJECT | TYPEMASK_CORPSE))) { - TC_LOG_ERROR("sql.sql", "TypeMask condition has invalid typemask set (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid typemask set (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "TypeMask condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "TypeMask condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_RELATION_TO: { if (cond->ConditionValue1 >= cond->GetMaxAvailableConditionTargets()) { - TC_LOG_ERROR("sql.sql", "RelationTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue1(ConditionTarget selection) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue1 == cond->ConditionTarget) { - TC_LOG_ERROR("sql.sql", "RelationTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has ConditionValue1(ConditionTarget selection) set to self (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue2 >= RELATION_MAX) { - TC_LOG_ERROR("sql.sql", "RelationTo condition has invalid ConditionValue2(RelationType) (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue2(RelationType) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "RelationTo condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_REACTION_TO: { if (cond->ConditionValue1 >= cond->GetMaxAvailableConditionTargets()) { - TC_LOG_ERROR("sql.sql", "ReactionTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue1(ConditionTarget selection) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue1 == cond->ConditionTarget) { - TC_LOG_ERROR("sql.sql", "ReactionTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has ConditionValue1(ConditionTarget selection) set to self (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (!cond->ConditionValue2) { - TC_LOG_ERROR("sql.sql", "mConditionValue2 condition has invalid ConditionValue2(rankMask) (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue2(rankMask) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } break; @@ -1999,83 +2012,60 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (cond->ConditionValue1 >= cond->GetMaxAvailableConditionTargets()) { - TC_LOG_ERROR("sql.sql", "DistanceTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue1(ConditionTarget selection) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue1 == cond->ConditionTarget) { - TC_LOG_ERROR("sql.sql", "DistanceTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has ConditionValue1(ConditionTarget selection) set to self (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue3 >= COMP_TYPE_MAX) { - TC_LOG_ERROR("sql.sql", "DistanceTo condition has invalid ComparisionType (%u), skipped", cond->ConditionValue3); + TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3); return false; } break; } - case CONDITION_ALIVE: - { - if (cond->ConditionValue1) - TC_LOG_ERROR("sql.sql", "Alive condition has useless data in value1 (%u)!", cond->ConditionValue1); - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Alive condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Alive condition has useless data in value3 (%u)!", cond->ConditionValue3); - break; - } case CONDITION_HP_VAL: { if (cond->ConditionValue2 >= COMP_TYPE_MAX) { - TC_LOG_ERROR("sql.sql", "HpVal condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "HpVal condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_HP_PCT: { if (cond->ConditionValue1 > 100) { - TC_LOG_ERROR("sql.sql", "HpPct condition has too big percent value (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has too big percent value (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue2 >= COMP_TYPE_MAX) { - TC_LOG_ERROR("sql.sql", "HpPct condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "HpPct condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } - case CONDITION_AREAID: - case CONDITION_INSTANCE_INFO: - break; case CONDITION_WORLD_STATE: { if (!sWorld->getWorldState(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "World state condition has non existing world state in value1 (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing world state in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "World state condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_PHASEID: { if (!sPhaseStore.LookupEntry(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "Phase condition has nonexistent phaseid in value1 (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has nonexistent phaseid in value1 (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Phase condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Phase condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_TITLE: @@ -2083,7 +2073,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(cond->ConditionValue1); if (!titleEntry) { - TC_LOG_ERROR("sql.sql", "Title condition has non existing title in value1 (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing title in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } break; @@ -2092,7 +2082,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (cond->ConditionValue1 > SPAWNMASK_RAID_ALL) { - TC_LOG_ERROR("sql.sql", "SpawnMask condition has non existing SpawnMask in value1 (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing SpawnMask in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } break; @@ -2101,7 +2091,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (!(cond->ConditionValue1 & UNIT_STATE_ALL_STATE_SUPPORTED)) { - TC_LOG_ERROR("sql.sql", "UnitState condition has non existing UnitState in value1 (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing UnitState in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } break; @@ -2110,17 +2100,34 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (!cond->ConditionValue1 || cond->ConditionValue1 > CREATURE_TYPE_GAS_CLOUD) { - TC_LOG_ERROR("sql.sql", "CreatureType condition has non existing CreatureType in value1 (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing CreatureType in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } break; } + case CONDITION_INSTANCE_INFO: + case CONDITION_AREAID: + case CONDITION_ALIVE: + break; default: break; } + + if (cond->ConditionValue1 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue1) + LogUselessConditionValue(cond, 1, cond->ConditionValue1); + if (cond->ConditionValue2 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue2) + LogUselessConditionValue(cond, 2, cond->ConditionValue2); + if (cond->ConditionValue3 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue3) + LogUselessConditionValue(cond, 3, cond->ConditionValue3); + return true; } +void ConditionMgr::LogUselessConditionValue(Condition* cond, uint8 index, uint32 value) +{ + TC_LOG_ERROR("sql.sql", "%s has useless data in ConditionValue%u (%u)!", cond->ToString(true).c_str(), index, value); +} + void ConditionMgr::Clean() { for (ConditionReferenceContainer::iterator itr = ConditionReferenceStore.begin(); itr != ConditionReferenceStore.end(); ++itr) diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index e7f5b64716b..98bc1775e0d 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -23,6 +23,7 @@ #include "Errors.h" #include <list> #include <map> +#include <string> class Player; class Unit; @@ -210,6 +211,8 @@ struct Condition uint32 GetSearcherTypeMaskForCondition(); bool isLoaded() const { return ConditionType > CONDITION_NONE || ReferenceId; } uint32 GetMaxAvailableConditionTargets(); + + std::string ToString(bool ext = false) const; /// For logging purpose }; typedef std::list<Condition*> ConditionList; @@ -229,7 +232,6 @@ class ConditionMgr ~ConditionMgr(); public: - static ConditionMgr* instance() { static ConditionMgr instance; @@ -244,8 +246,8 @@ class ConditionMgr bool IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions); bool IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions); bool IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions); - bool CanHaveSourceGroupSet(ConditionSourceType sourceType) const; - bool CanHaveSourceIdSet(ConditionSourceType sourceType) const; + static bool CanHaveSourceGroupSet(ConditionSourceType sourceType); + static bool CanHaveSourceIdSet(ConditionSourceType sourceType); ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry); ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId); ConditionList GetConditionsForSmartEvent(int64 entryOrGuid, uint32 eventId, uint32 sourceType); @@ -253,6 +255,16 @@ class ConditionMgr ConditionList const* GetConditionsForPhaseDefinition(uint32 zone, uint32 entry); ConditionList GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId); + struct ConditionTypeInfo + { + char const* Name; + bool HasConditionValue1; + bool HasConditionValue2; + bool HasConditionValue3; + }; + static char const* StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX]; + static ConditionTypeInfo const StaticConditionTypeData[CONDITION_MAX]; + private: bool isSourceTypeValid(Condition* cond); bool addToLootTemplate(Condition* cond, LootTemplate* loot); @@ -261,6 +273,8 @@ class ConditionMgr bool addToSpellImplicitTargetConditions(Condition* cond); bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions); + static void LogUselessConditionValue(Condition* cond, uint8 index, uint32 value); + void Clean(); // free up resources std::list<Condition*> AllocatedMemoryStore; // some garbage collection :) diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index c4d47e26468..51669deef9d 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -145,7 +145,7 @@ void LoadDB2Stores(std::string const& dataPath) for (uint32 i = 0; i < sItemAppearanceStore.GetNumRows(); ++i) if (ItemAppearanceEntry const* entry = sItemAppearanceStore.LookupEntry(i)) - sItemDisplayIDMap[entry->AppearanceID] = entry->DisplayID; + sItemDisplayIDMap[entry->FileDataID] = entry->DisplayID; for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index de5436860a6..249f95d80e4 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -21,6 +21,7 @@ #include "Common.h" #include "DBCEnums.h" #include "ItemPrototype.h" +#include "Path.h" // GCC has alternative #pragma pack(N) syntax and old gcc version does not support pack(push, N), also any gcc version does not support it at some platform #if defined(__GNUC__) @@ -60,15 +61,15 @@ struct ItemEntry int32 Material; // 4 uint32 InventoryType; // 5 uint32 Sheath; // 6 - uint32 AppearanceID; // 7 (ItemAppearance.db2) - //uint32 Unk; // 8 + uint32 FileDataID; // 7 + uint32 GroupSoundsID; // 8 }; struct ItemAppearanceEntry { uint32 ID; // 0 (reference to ItemModifiedAppearance.db2?) uint32 DisplayID; // 1 - uint32 AppearanceID; // 2 + uint32 FileDataID; // 2 }; struct ItemCurrencyCostEntry @@ -153,77 +154,7 @@ struct ItemSparseEntry float StatScalingFactor; // 98 uint32 CurrencySubstitutionID; // 99 uint32 CurrencySubstitutionCount; // 100 - //uint32 Unk3; // 101 - - /*uint32 ID; // 0 - uint32 Quality; // 1 - uint32 Flags; // 2 - uint32 Flags2; // 3 - float Unk430_1; - float Unk430_2; - uint32 BuyCount; - uint32 BuyPrice; // 4 - uint32 SellPrice; // 5 - uint32 InventoryType; // 6 - int32 AllowableClass; // 7 - int32 AllowableRace; // 8 - uint32 ItemLevel; // 9 - int32 RequiredLevel; // 10 - uint32 RequiredSkill; // 11 - uint32 RequiredSkillRank; // 12 - uint32 RequiredSpell; // 13 - uint32 RequiredHonorRank; // 14 - uint32 RequiredCityRank; // 15 - uint32 RequiredReputationFaction; // 16 - uint32 RequiredReputationRank; // 17 - uint32 MaxCount; // 18 - uint32 Stackable; // 19 - uint32 ContainerSlots; // 20 - int32 ItemStatType[MAX_ITEM_PROTO_STATS]; // 21 - 30 - uint32 ItemStatValue[MAX_ITEM_PROTO_STATS]; // 31 - 40 - int32 ItemStatUnk1[MAX_ITEM_PROTO_STATS]; // 41 - 50 - int32 ItemStatUnk2[MAX_ITEM_PROTO_STATS]; // 51 - 60 - uint32 ScalingStatDistribution; // 61 - uint32 DamageType; // 62 - uint32 Delay; // 63 - float RangedModRange; // 64 - int32 SpellId[MAX_ITEM_PROTO_SPELLS]; // 65 - 69 - int32 SpellTrigger[MAX_ITEM_PROTO_SPELLS]; // 70 - 74 - int32 SpellCharges[MAX_ITEM_PROTO_SPELLS]; // 75 - 79 - int32 SpellCooldown[MAX_ITEM_PROTO_SPELLS]; // 80 - 84 - int32 SpellCategory[MAX_ITEM_PROTO_SPELLS]; // 85 - 89 - int32 SpellCategoryCooldown[MAX_ITEM_PROTO_SPELLS]; // 90 - 94 - uint32 Bonding; // 95 - LocalizedString* Name; // 96 - LocalizedString* Name2; // 97 - LocalizedString* Name3; // 98 - LocalizedString* Name4; // 99 - LocalizedString* Description; // 100 - uint32 PageText; // 101 - uint32 LanguageID; // 102 - uint32 PageMaterial; // 103 - uint32 StartQuest; // 104 - uint32 LockID; // 105 - int32 Material; // 106 - uint32 Sheath; // 107 - uint32 RandomProperty; // 108 - uint32 RandomSuffix; // 109 - uint32 ItemSet; // 110 - uint32 Area; // 112 - uint32 Map; // 113 - uint32 BagFamily; // 114 - uint32 TotemCategory; // 115 - uint32 Color[MAX_ITEM_PROTO_SOCKETS]; // 116 - 118 - uint32 Content[MAX_ITEM_PROTO_SOCKETS]; // 119 - 121 - int32 SocketBonus; // 122 - uint32 GemProperties; // 123 - float ArmorDamageModifier; // 124 - uint32 Duration; // 125 - uint32 ItemLimitCategory; // 126 - uint32 HolidayId; // 127 - float StatScalingFactor; // 128 - int32 CurrencySubstitutionId; // 129 - int32 CurrencySubstitutionCount; // 130*/ + uint32 ItemNameDescriptionID; // 101 }; #define MAX_ITEM_EXT_COST_ITEMS 5 @@ -232,13 +163,13 @@ struct ItemSparseEntry struct ItemExtendedCostEntry { uint32 ID; // 0 extended-cost entry id - //uint32 reqhonorpoints; // 1 required honor points - //uint32 reqarenapoints; // 2 required arena points + uint32 RequiredHonorPoints; // 1 required honor points + uint32 RequiredArenaPoints; // 2 required arena points uint32 RequiredArenaSlot; // 3 arena slot restrictions (min slot value) uint32 RequiredItem[MAX_ITEM_EXT_COST_ITEMS]; // 4-8 required item id uint32 RequiredItemCount[MAX_ITEM_EXT_COST_ITEMS]; // 9-13 required count of 1st item uint32 RequiredPersonalArenaRating; // 14 required personal arena rating - //uint32 ItemPurchaseGroup; // 15 + uint32 ItemPurchaseGroup; // 15 uint32 RequiredCurrency[MAX_ITEM_EXT_COST_CURRENCIES];// 16-20 required curency id uint32 RequiredCurrencyCount[MAX_ITEM_EXT_COST_CURRENCIES];// 21-25 required curency count uint32 RequiredFactionId; diff --git a/src/server/game/DataStores/DB2Utility.cpp b/src/server/game/DataStores/DB2Utility.cpp index 37b7fb949db..a835547b640 100644 --- a/src/server/game/DataStores/DB2Utility.cpp +++ b/src/server/game/DataStores/DB2Utility.cpp @@ -42,15 +42,15 @@ void DB2Utilities::WriteItemDbReply(DB2Storage<ItemEntry> const& /*store*/, uint buffer << uint32(proto->Class); buffer << uint32(proto->SubClass); buffer << int32(proto->SoundOverrideSubclass); - buffer << uint32(proto->Material); - buffer << uint32(proto->DisplayInfoID); + buffer << int32(proto->Material); buffer << uint32(proto->InventoryType); buffer << uint32(proto->Sheath); + buffer << uint32(proto->FileDataID); + buffer << uint32(proto->GroupSoundsID); } void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*store*/, uint32 id, uint32 locale, ByteBuffer& buffer) { - /* TODO: 6.x update ItemTemplate const* proto = sObjectMgr->GetItemTemplate(id); ASSERT(proto); @@ -58,10 +58,12 @@ void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*s buffer << uint32(proto->ItemId); buffer << uint32(proto->Quality); - buffer << uint32(proto->Flags); - buffer << uint32(proto->Flags2); - buffer << float(proto->Unk430_1); - buffer << float(proto->Unk430_2); + + for (uint32 i = 0; i < MAX_ITEM_PROTO_FLAGS; ++i) + buffer << uint32(proto->Flags[i]); + + buffer << float(proto->Unk1); + buffer << float(proto->Unk2); buffer << uint32(proto->BuyCount); buffer << int32(proto->BuyPrice); buffer << uint32(proto->SellPrice); @@ -97,25 +99,6 @@ void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*s buffer << uint32(proto->DamageType); buffer << uint32(proto->Delay); buffer << float(proto->RangedModRange); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) - buffer << int32(proto->Spells[x].SpellId); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) - buffer << uint32(proto->Spells[x].SpellTrigger); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) - buffer << int32(proto->Spells[x].SpellCharges); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) - buffer << int32(proto->Spells[x].SpellCooldown); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) - buffer << uint32(proto->Spells[x].SpellCategory); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) - buffer << int32(proto->Spells[x].SpellCategoryCooldown); - buffer << uint32(proto->Bonding); // item name @@ -145,8 +128,8 @@ void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*s buffer << uint32(proto->LockID); buffer << int32(proto->Material); buffer << uint32(proto->Sheath); - buffer << int32(proto->RandomProperty); - buffer << int32(proto->RandomSuffix); + buffer << uint32(proto->RandomProperty); + buffer << uint32(proto->RandomSuffix); buffer << uint32(proto->ItemSet); buffer << uint32(proto->Area); @@ -157,9 +140,6 @@ void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*s for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x) buffer << uint32(proto->Socket[x].Color); - for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x) - buffer << uint32(proto->Socket[x].Content); - buffer << uint32(proto->socketBonus); buffer << uint32(proto->GemProperties); buffer << float(proto->ArmorDamageModifier); @@ -169,5 +149,5 @@ void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*s buffer << float(proto->StatScalingFactor); // StatScalingFactor buffer << uint32(proto->CurrencySubstitutionId); buffer << uint32(proto->CurrencySubstitutionCount); - */ + buffer << uint32(proto->ItemNameDescriptionID); } diff --git a/src/server/game/DataStores/DB2fmt.h b/src/server/game/DataStores/DB2fmt.h index 5d2f374f2a7..f47efa43f89 100644 --- a/src/server/game/DataStores/DB2fmt.h +++ b/src/server/game/DataStores/DB2fmt.h @@ -19,11 +19,11 @@ #define TRINITY_DB2SFRM_H char const HolidaysEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiixxsiix"; -char const Itemfmt[]="niiiiiiix"; +char const Itemfmt[]="niiiiiiii"; char const ItemAppearanceEntryfmt[]="nii"; char const ItemCurrencyCostfmt[]="xn"; -char const ItemSparsefmt[]="niiiiffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifisssssiiiiiiiiiiiiiiiiiiifiiifiix"; -char const ItemExtendedCostEntryfmt[]="nxxiiiiiiiiiiiixiiiiiiiiiiiiii"; +char const ItemSparsefmt[]="niiiiffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifisssssiiiiiiiiiiiiiiiiiiifiiifiii"; +char const ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii"; char const ItemEffectEntryfmt[]="niiiiiiii"; char const KeyChainfmt[]="nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; char const OverrideSpellDataEntryfmt[] = "niiiiiiiiiixx"; diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index db35db880be..a4ba710f5db 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -17,6 +17,7 @@ */ #include "DBCStores.h" +#include "DB2Stores.h" #include "Containers.h" #include "Log.h" #include "SharedDefines.h" @@ -75,6 +76,7 @@ DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt); DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt); DBCStorage <ChrPowerTypesEntry> sChrPowerTypesStore(ChrClassesXPowerTypesfmt); DBCStorage <ChrSpecializationEntry> sChrSpecializationStore(ChrSpecializationEntryfmt); +ChrSpecializationByIndexArray sChrSpecializationByIndexStore; SpecializationSpellsBySpecStore sSpecializationSpellsBySpecStore; DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt); DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt); @@ -352,6 +354,10 @@ void LoadDBCStores(const std::string& dataPath) } LoadDBC(availableDbcLocales, bad_dbc_files, sChrSpecializationStore, dbcPath, "ChrSpecialization.dbc"); + memset(sChrSpecializationByIndexStore, 0, sizeof(sChrSpecializationByIndexStore)); + for (uint32 i = 0; i < sChrSpecializationStore.GetNumRows(); ++i) + if (ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(i)) + sChrSpecializationByIndexStore[chrSpec->ClassID][chrSpec->OrderIndex] = chrSpec; LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc");//19116 LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc");//19116 diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index bb7885c8bc2..e9a9b3c692f 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> @@ -90,6 +91,7 @@ SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, u typedef std::set<SpecializationSpellsEntry const*> SpecializationSpellsBySpecEntry; typedef std::unordered_map<uint32, SpecializationSpellsBySpecEntry> SpecializationSpellsBySpecStore; +typedef ChrSpecializationEntry const* ChrSpecializationByIndexArray[MAX_CLASSES][MAX_SPECIALIZATIONS]; typedef std::unordered_map<uint32, TalentEntry const*> TalentBySpellIDMap; extern DBCStorage <AchievementEntry> sAchievementStore; @@ -110,6 +112,7 @@ extern DBCStorage <ChrClassesEntry> sChrClassesStore; extern DBCStorage <ChrRacesEntry> sChrRacesStore; extern DBCStorage <ChrPowerTypesEntry> sChrPowerTypesStore; extern DBCStorage <ChrSpecializationEntry> sChrSpecializationStore; +extern ChrSpecializationByIndexArray sChrSpecializationByIndexStore; extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore; extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore; extern DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 803e2dcf96b..77182b1bdf9 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -812,7 +812,7 @@ struct CreatureDisplayInfoEntry //uint32 ObjectEffectPackageID; // 16 //uint32 AnimReplacementSetID; // 17 //uint32 Flags; // 18 - //uint32 Gender; // 19 + int32 Gender; // 19 //uint32 StateSpellVisualKitID; // 20 }; diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 867e64ef92e..9f53cb09ad8 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -43,7 +43,7 @@ char const ChrRacesEntryfmt[] = "niixiixxxxxxiisxxxxxxxxxxxxxxxxxxxxxxxxx"; char const ChrClassesXPowerTypesfmt[] = "nii"; char const ChrSpecializationEntryfmt[] = "nxiiiiiiiiixxxii"; char const CinematicSequencesEntryfmt[] = "nxxxxxxxxx"; -char const CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxxxxxxx"; +char const CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxxxxxix"; char const CreatureDisplayInfoExtrafmt[] = "dixxxxxxxxxxxxxxxxxxxx"; char const CreatureFamilyfmt[] = "nfifiiiiixsx"; char const CreatureModelDatafmt[] = "nixxxxxxxxxxxxxffxxxxxxxxxxxxxxxxx"; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index d342bb3c431..05405d6eddb 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -51,6 +51,7 @@ #include "WaypointMovementGenerator.h" #include "World.h" #include "WorldPacket.h" +#include "CombatPackets.h" #include "Transport.h" @@ -1829,12 +1830,12 @@ Player* Creature::SelectNearestPlayer(float distance) const void Creature::SendAIReaction(AiReaction reactionType) { - WorldPacket data(SMSG_AI_REACTION, 12); + WorldPackets::Combat::AIReaction packet; - data << GetGUID(); - data << uint32(reactionType); + packet.UnitGUID = GetGUID(); + packet.Reaction = reactionType; - ((WorldObject*)this)->SendMessageToSet(&data, true); + SendMessageToSet(packet.Write(), true); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_AI_REACTION, type %u.", reactionType); } @@ -2576,7 +2577,7 @@ void Creature::SetDisplayId(uint32 modelId) } } -void Creature::SetTarget(ObjectGuid guid) +void Creature::SetTarget(ObjectGuid const& guid) { if (!_focusSpell) SetGuidValue(UNIT_FIELD_TARGET, guid); diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 2de22942a62..523a2eb2f4d 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -287,8 +287,8 @@ struct CreatureModelInfo { float bounding_radius; float combat_reach; - uint8 gender; - uint32 modelid_other_gender; + int8 gender; + uint32 displayId_other_gender; }; // Benchmarked: Faster than std::map (insert/find) @@ -392,11 +392,13 @@ struct VendorItemCount typedef std::list<VendorItemCount> VendorItemCounts; +#define MAX_TRAINERSPELL_ABILITY_REQS 3 + struct TrainerSpell { TrainerSpell() : SpellID(0), MoneyCost(0), ReqSkillLine(0), ReqSkillRank(0), ReqLevel(0) { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (uint8 i = 0; i < MAX_TRAINERSPELL_ABILITY_REQS; ++i) ReqAbility[i] = 0; } @@ -405,7 +407,7 @@ struct TrainerSpell uint32 ReqSkillLine; uint32 ReqSkillRank; uint32 ReqLevel; - uint32 ReqAbility[MAX_SPELL_EFFECTS]; + uint32 ReqAbility[MAX_TRAINERSPELL_ABILITY_REQS]; // helpers bool IsCastable() const { return ReqAbility[0] != SpellID; } @@ -674,7 +676,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject bool m_isTempWorldObject; //true when possessed // Handling caster facing during spellcast - void SetTarget(ObjectGuid guid) override; + void SetTarget(ObjectGuid const& guid) override; void FocusTarget(Spell const* focusSpell, WorldObject const* target); void ReleaseFocus(Spell const* focusSpell); diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 4d14ede70fe..2b07683d335 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -23,6 +23,8 @@ #include "WorldPacket.h" #include "WorldSession.h" #include "Formulas.h" +#include "QuestPackets.h" +#include "NPCPackets.h" GossipMenu::GossipMenu() { @@ -192,44 +194,45 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) { _gossipMenu.SetSenderGUID(objectGUID); - WorldPacket data(SMSG_GOSSIP_MESSAGE, 100); // guess size - data << objectGUID; - data << uint32(_gossipMenu.GetMenuId()); // new 2.4.0 - data << uint32(titleTextId); - data << uint32(_gossipMenu.GetMenuItemCount()); // max count 0x10 + WorldPackets::NPC::GossipMessage packet; + packet.GossipGUID = objectGUID; + packet.TextID = titleTextId; + packet.GossipOptions.resize(_gossipMenu.GetMenuItems().size()); + uint32 count = 0; for (GossipMenuItemContainer::const_iterator itr = _gossipMenu.GetMenuItems().begin(); itr != _gossipMenu.GetMenuItems().end(); ++itr) { + WorldPackets::NPC::ClientGossipOptions& opt = packet.GossipOptions[count]; GossipMenuItem const& item = itr->second; - data << uint32(itr->first); - data << uint8(item.MenuItemIcon); - data << uint8(item.IsCoded); // makes pop up box password - data << uint32(item.BoxMoney); // money required to open menu, 2.0.3 - data << item.Message; // text for gossip item - data << item.BoxMessage; // accept text (related to money) pop up box, 2.0.3 + opt.ClientOption = itr->first; + opt.OptionNPC = item.MenuItemIcon; + opt.OptionFlags = item.IsCoded; // makes pop up box password + opt.OptionCost = item.BoxMoney; // money required to open menu, 2.0.3 + opt.Text = item.Message; // text for gossip item + opt.Confirm = item.BoxMessage; // accept text (related to money) pop up box, 2.0.3 + ++count; } - size_t count_pos = data.wpos(); - data << uint32(0); // max count 0x20 - uint32 count = 0; - // Store this instead of checking the Singleton every loop iteration bool questLevelInTitle = sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS); + packet.GossipText.resize(_questMenu.GetMenuItemCount()); + count = 0; for (uint8 i = 0; i < _questMenu.GetMenuItemCount(); ++i) { QuestMenuItem const& item = _questMenu.GetItem(i); uint32 questID = item.QuestId; if (Quest const* quest = sObjectMgr->GetQuestTemplate(questID)) { - ++count; - data << uint32(questID); - data << uint32(item.QuestIcon); - data << int32(quest->GetQuestLevel()); - data << uint32(quest->GetFlags()); // 3.3.3 quest flags - data << uint8(0); // 3.3.3 changes icon: blue question or yellow exclamation - std::string title = quest->GetTitle(); + WorldPackets::NPC::ClientGossipText& text = packet.GossipText[count]; + text.QuestID = questID; + text.QuestType = item.QuestIcon; + text.QuestLevel = quest->GetQuestLevel(); + text.QuestFlags[0] = quest->GetFlags(); + text.QuestFlags[1] = 0; + text.Repeatable = quest->IsRepeatable(); + std::string title = quest->GetTitle(); int32 locale = _session->GetSessionDbLocaleIndex(); if (locale >= 0) if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID)) @@ -238,12 +241,15 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) if (questLevelInTitle) AddQuestLevelToTitle(title, quest->GetQuestLevel()); - data << title; // max 0x200 + text.QuestTitle = title; + ++count; } } - data.put<uint8>(count_pos, count); - _session->SendPacket(&data); + // Shrink to the real size + packet.GossipText.resize(count); + + _session->SendPacket(packet.Write()); } void PlayerMenu::SendCloseGossip() @@ -373,11 +379,11 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string void PlayerMenu::SendQuestGiverStatus(uint32 questStatus, ObjectGuid npcGUID) const { - WorldPacket data(SMSG_QUESTGIVER_STATUS, 8 + 4); - data << npcGUID; - data << uint32(questStatus); + WorldPackets::Quest::QuestGiverStatus packet; + packet.QuestGiver.Guid = npcGUID; + packet.QuestGiver.Status = questStatus; - _session->SendPacket(&data); + _session->SendPacket(packet.Write()); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC=%s, status=%u", npcGUID.ToString().c_str(), questStatus); } diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h index e28e8a21678..fe6051b4f9c 100644 --- a/src/server/game/Entities/Item/ItemPrototype.h +++ b/src/server/game/Entities/Item/ItemPrototype.h @@ -611,6 +611,7 @@ struct ItemEffect #pragma pack(pop) #endif +#define MAX_ITEM_PROTO_FLAGS 3 #define MAX_ITEM_PROTO_DAMAGES 2 // changed in 3.1.0 #define MAX_ITEM_PROTO_SOCKETS 3 #define MAX_ITEM_PROTO_STATS 10 @@ -623,8 +624,10 @@ struct ItemTemplate int32 SoundOverrideSubclass; // < 0: id from ItemSubClass.dbc, used to override weapon sound from actual SubClass std::string Name1; uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc + uint32 FileDataID; + uint32 GroupSoundsID; uint32 Quality; - uint32 Flags[3]; + uint32 Flags[MAX_ITEM_PROTO_FLAGS]; float Unk1; float Unk2; uint32 BuyCount; @@ -678,6 +681,7 @@ struct ItemTemplate float StatScalingFactor; uint32 CurrencySubstitutionId; // May be used instead of a currency uint32 CurrencySubstitutionCount; + uint32 ItemNameDescriptionID; // extra fields, not part of db2 files float DamageMin; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index e482e0a449d..d2ac852bbfe 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1001,7 +1001,7 @@ void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uin for (uint32 index = 0; index < count; ++index) { - m_uint32Values[startOffset + index] = atol(tokens[index]); + m_uint32Values[startOffset + index] = atoul(tokens[index]); _changesMask.SetBit(startOffset + index); } } @@ -2359,19 +2359,19 @@ void Object::ForceValuesUpdateAtIndex(uint32 i) } } -void WorldObject::SendMessageToSet(WorldPacket* data, bool self) +void WorldObject::SendMessageToSet(WorldPacket const* data, bool self) { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), self); } -void WorldObject::SendMessageToSetInRange(WorldPacket* data, float dist, bool /*self*/) +void WorldObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/) { Trinity::MessageDistDeliverer notifier(this, data, dist); VisitNearbyWorldObject(dist, notifier); } -void WorldObject::SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr) +void WorldObject::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) { Trinity::MessageDistDeliverer notifier(this, data, GetVisibilityRange(), false, skipped_rcvr); VisitNearbyWorldObject(GetVisibilityRange(), notifier); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index bae3a8b07c1..d2dd0108d20 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -661,9 +661,9 @@ class WorldObject : public Object, public WorldLocation virtual void CleanupsBeforeDelete(bool finalCleanup = true); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units - virtual void SendMessageToSet(WorldPacket* data, bool self); - virtual void SendMessageToSetInRange(WorldPacket* data, float dist, bool self); - virtual void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr); + virtual void SendMessageToSet(WorldPacket const* data, bool self); + virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self); + virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr); virtual uint8 getLevelForTarget(WorldObject const* /*target*/) const { return 1; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 567b240db07..cfc7e233458 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -28,7 +28,6 @@ #include "BattlegroundMgr.h" #include "BattlegroundScore.h" #include "CellImpl.h" -#include "Channel.h" #include "ChannelMgr.h" #include "CharacterDatabaseCleaner.h" #include "CharacterPackets.h" @@ -40,6 +39,7 @@ #include "DatabaseEnv.h" #include "DB2Stores.h" #include "DisableMgr.h" +#include "EquipmentSetPackets.h" #include "Formulas.h" #include "GameEventMgr.h" #include "GameObjectAI.h" @@ -86,6 +86,10 @@ #include "WorldPacket.h" #include "WorldSession.h" #include "WorldStatePackets.h" +#include "MiscPackets.h" +#include "ChatPackets.h" +#include "MovementPackets.h" +#include "ItemPackets.h" #define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS) @@ -168,7 +172,7 @@ void PlayerTaxi::LoadTaxiMask(std::string const &data) for (Tokenizer::const_iterator iter = tokens.begin(); index < TaxiMaskSize && iter != tokens.end(); ++iter, ++index) { // load and set bits only for existing taxi nodes - m_taximask[index] = sTaxiNodesMask[index] & uint32(atol(*iter)); + m_taximask[index] = sTaxiNodesMask[index] & atoul(*iter); } } @@ -195,7 +199,7 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString(const std::string& values, uint3 for (Tokenizer::const_iterator iter = Tokenizer.begin(); iter != Tokenizer.end(); ++iter) { - uint32 node = uint32(atol(*iter)); + uint32 node = atoul(*iter); AddTaxiDestination(node); } @@ -1145,14 +1149,17 @@ bool Player::Create(ObjectGuid::LowType guidlow, WorldPackets::Character::Charac // special amount for food/drink if (iProto->Class == ITEM_CLASS_CONSUMABLE && iProto->SubClass == ITEM_SUBCLASS_FOOD_DRINK) { - switch (iProto->Effects[0].Category) + if (iProto->Effects.size() >= 1) { - case SPELL_CATEGORY_FOOD: // food - count = getClass() == CLASS_DEATH_KNIGHT ? 10 : 4; - break; - case SPELL_CATEGORY_DRINK: // drink - count = 2; - break; + switch (iProto->Effects[0].Category) + { + case SPELL_CATEGORY_FOOD: // food + count = getClass() == CLASS_DEATH_KNIGHT ? 10 : 4; + break; + case SPELL_CATEGORY_DRINK: // drink + count = 2; + break; + } } if (iProto->GetMaxStackSize() < count) count = iProto->GetMaxStackSize(); @@ -1926,18 +1933,18 @@ void Player::ToggleDND() ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_DND); } -uint8 Player::GetChatTag() const +uint8 Player::GetChatFlags() const { - uint8 tag = CHAT_TAG_NONE; + uint8 tag = CHAT_FLAG_NONE; if (isGMChat()) - tag |= CHAT_TAG_GM; + tag |= CHAT_FLAG_GM; if (isDND()) - tag |= CHAT_TAG_DND; + tag |= CHAT_FLAG_DND; if (isAFK()) - tag |= CHAT_TAG_AFK; + tag |= CHAT_FLAG_AFK; if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER)) - tag |= CHAT_TAG_DEV; + tag |= CHAT_FLAG_DEV; return tag; } @@ -2129,18 +2136,16 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (!GetSession()->PlayerLogout()) { // send transfer packets - WorldPacket data(SMSG_TRANSFER_PENDING, 4 + 4 + 4); - data.WriteBit(0); // unknown + WorldPackets::Movement::TransferPending transferPending; + transferPending.MapID = mapid; if (Transport* transport = GetTransport()) { - data.WriteBit(1); // has transport - data << GetMapId() << transport->GetEntry(); + transferPending.Ship.HasValue = true; + transferPending.Ship.Value.ID = transport->GetEntry(); + transferPending.Ship.Value.OriginMapID = GetMapId(); } - else - data.WriteBit(0); // has transport - data << uint32(mapid); - GetSession()->SendPacket(&data); + GetSession()->SendPacket(transferPending.Write()); } // remove from old map now @@ -2154,14 +2159,12 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (!GetSession()->PlayerLogout()) { - WorldPacket data(SMSG_NEW_WORLD, 4 + 4 + 4 + 4 + 4); - data << float(m_teleport_dest.GetPositionX()); - data << float(m_teleport_dest.GetOrientation()); - data << float(m_teleport_dest.GetPositionZ()); - data << uint32(mapid); - data << float(m_teleport_dest.GetPositionY()); + WorldPackets::Movement::NewWorld packet; + packet.MapID = mapid; + packet.Pos = m_teleport_dest; + packet.Reason = NEW_WORLD_NORMAL; - GetSession()->SendPacket(&data); + SendDirectMessage(packet.Write()); SendSavedInstances(); } @@ -3163,6 +3166,7 @@ void Player::SendKnownSpells() WorldPackets::Spell::SendKnownSpells knownSpells; knownSpells.InitialLogin = false; /// @todo + knownSpells.KnownSpells.reserve(m_spells.size()); for (PlayerSpellMap::value_type const& spell : m_spells) { if (spell.second->state == PLAYERSPELL_REMOVED) @@ -5221,8 +5225,8 @@ void Player::CleanupChannels() { Channel* ch = *m_channels.begin(); m_channels.erase(m_channels.begin()); // remove from player's channel list - ch->LeaveChannel(this, false); // not send to client, not remove from player's channel list - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetTeam())) + ch->LeaveChannel(this, false); // not send to client, not remove from player's channel list + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetTeam())) cMgr->LeftChannel(ch->GetName()); // deleted channel if empty } TC_LOG_DEBUG("chat.system", "Player %s: channels cleaned up!", GetName().c_str()); @@ -5237,12 +5241,10 @@ void Player::UpdateLocalChannels(uint32 newZone) if (!current_zone) return; - ChannelMgr* cMgr = ChannelMgr::forTeam(GetTeam()); + ChannelMgr* cMgr = ChannelMgr::ForTeam(GetTeam()); if (!cMgr) return; - std::string current_zone_name = current_zone->ZoneName; - for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i) { if (ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(i)) @@ -5275,7 +5277,7 @@ void Player::UpdateLocalChannels(uint32 newZone) if (channel->Flags & CHANNEL_DBC_FLAG_CITY_ONLY) currentNameExt = sObjectMgr->GetTrinityStringForDBCLocale(LANG_CHANNEL_CITY); else - currentNameExt = current_zone_name.c_str(); + currentNameExt = current_zone->ZoneName; snprintf(new_channel_name_buf, 100, channel->Name_lang, currentNameExt); @@ -6199,29 +6201,20 @@ int16 Player::GetSkillTempBonusValue(uint32 skill) const void Player::SendActionButtons(uint32 state) const { - WorldPacket data(SMSG_ACTION_BUTTONS, 1+(MAX_ACTION_BUTTONS*4)); - /* - state can be 0, 1, 2 - 0 - Sends initial action buttons, client does not validate if we have the spell or not - 1 - Used used after spec swaps, client validates if a spell is known. - 2 - Clears the action bars client sided. This is sent during spec swap before unlearning and before sending the new buttons - */ - if (state != 2) + WorldPackets::Spell::UpdateActionButtons packet; + + for (uint8 button = 0; button < MAX_ACTION_BUTTONS; ++button) { - for (uint8 button = 0; button < MAX_ACTION_BUTTONS; ++button) - { - ActionButtonList::const_iterator itr = m_actionButtons.find(button); - if (itr != m_actionButtons.end() && itr->second.uState != ACTIONBUTTON_DELETED) - data << uint32(itr->second.packedData); - else - data << uint32(0); - } + ActionButtonList::const_iterator itr = m_actionButtons.find(button); + if (itr != m_actionButtons.end() && itr->second.uState != ACTIONBUTTON_DELETED) + packet.ActionButtons[button] = uint32(itr->second.packedData); + else + packet.ActionButtons[button] = 0; } - else - data.resize(MAX_ACTION_BUTTONS * 4); // insert crap, client doesnt even parse this for state == 2 - data << uint8(state); - GetSession()->SendPacket(&data); + packet.Reason = state; + + SendDirectMessage(packet.Write()); TC_LOG_INFO("network", "Action Buttons for '%s' group '%u' Sent", GetGUID().ToString().c_str(), GetActiveTalentGroup()); } @@ -6351,7 +6344,7 @@ void Player::SaveRecallPosition() m_recallO = GetOrientation(); } -void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self) +void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) { if (self) GetSession()->SendPacket(data); @@ -6360,7 +6353,7 @@ void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self) VisitNearbyWorldObject(dist, notifier); } -void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only) +void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool own_team_only) { if (self) GetSession()->SendPacket(data); @@ -6369,7 +6362,7 @@ void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self, b VisitNearbyWorldObject(dist, notifier); } -void Player::SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr) +void Player::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) { if (skipped_rcvr != this) GetSession()->SendPacket(data); @@ -6380,7 +6373,7 @@ void Player::SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr) VisitNearbyWorldObject(GetVisibilityRange(), notifier); } -void Player::SendDirectMessage(WorldPacket const* data) +void Player::SendDirectMessage(WorldPacket const* data) const { m_session->SendPacket(data); } @@ -8358,25 +8351,28 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 { ItemTemplate const* proto = item->GetTemplate(); // special learning case - if (proto->Effects[0].SpellID == 483 || proto->Effects[0].SpellID == 55884) + if (proto->Effects.size() >= 2) { - uint32 learn_spell_id = proto->Effects[0].SpellID; - uint32 learning_spell_id = proto->Effects[1].SpellID; - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(learn_spell_id); - if (!spellInfo) + if (proto->Effects[0].SpellID == 483 || proto->Effects[0].SpellID == 55884) { - TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring ", proto->ItemId, learn_spell_id); - SendEquipError(EQUIP_ERR_INTERNAL_BAG_ERROR, item, NULL); + uint32 learn_spell_id = proto->Effects[0].SpellID; + uint32 learning_spell_id = proto->Effects[1].SpellID; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(learn_spell_id); + if (!spellInfo) + { + TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring ", proto->ItemId, learn_spell_id); + SendEquipError(EQUIP_ERR_INTERNAL_BAG_ERROR, item, NULL); + return; + } + + Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE); + spell->m_CastItem = item; + spell->m_cast_count = cast_count; //set count of casts + spell->SetSpellValue(SPELLVALUE_BASE_POINT0, learning_spell_id); + spell->prepare(&targets); return; } - - Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE); - spell->m_CastItem = item; - spell->m_cast_count = cast_count; //set count of casts - spell->SetSpellValue(SPELLVALUE_BASE_POINT0, learning_spell_id); - spell->prepare(&targets); - return; } // use triggered flag only for items with many spell casts and for not first cast @@ -11537,9 +11533,10 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const return EQUIP_ERR_CLIENT_LOCKED_OUT; // learning (recipes, mounts, pets, etc.) - if (proto->Effects[0].SpellID == 483 || proto->Effects[0].SpellID == 55884) - if (HasSpell(proto->Effects[1].SpellID)) - return EQUIP_ERR_INTERNAL_BAG_ERROR; + if (proto->Effects.size() >= 2) + if (proto->Effects[0].SpellID == 483 || proto->Effects[0].SpellID == 55884) + if (HasSpell(proto->Effects[1].SpellID)) + return EQUIP_ERR_INTERNAL_BAG_ERROR; return EQUIP_ERR_OK; } @@ -16745,28 +16742,26 @@ void Player::_LoadEquipmentSets(PreparedQueryResult result) if (!result) return; - uint32 count = 0; do { Field* fields = result->Fetch(); - EquipmentSet eqSet; + EquipmentSetInfo eqSet; - eqSet.Guid = fields[0].GetUInt64(); - uint8 index = fields[1].GetUInt8(); - eqSet.Name = fields[2].GetString(); - eqSet.IconName = fields[3].GetString(); - eqSet.IgnoreMask = fields[4].GetUInt32(); - eqSet.state = EQUIPMENT_SET_UNCHANGED; + eqSet.Data.Guid = fields[0].GetUInt64(); + eqSet.Data.SetID = fields[1].GetUInt8(); + eqSet.Data.SetName = fields[2].GetString(); + eqSet.Data.SetIcon = fields[3].GetString(); + eqSet.Data.IgnoreMask = fields[4].GetUInt32(); + eqSet.State = EQUIPMENT_SET_UNCHANGED; for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) - eqSet.Items[i] = fields[5 + i].GetUInt64(); - - m_EquipmentSets[index] = eqSet; + if (uint64 guid = fields[5 + i].GetUInt64()) + eqSet.Data.Pieces[i] = ObjectGuid::Create<HighGuid::Item>(guid); - ++count; + if (eqSet.Data.SetID >= MAX_EQUIPMENT_SET_INDEX) // client limit + continue; - if (count >= MAX_EQUIPMENT_SET_INDEX) // client limit - break; + _equipmentSets[eqSet.Data.SetID] = eqSet; } while (result->NextRow()); } @@ -16831,6 +16826,17 @@ void Player::SetHomebind(WorldLocation const& loc, uint32 areaId) CharacterDatabase.Execute(stmt); } +void Player::SendBindPointUpdate() +{ + WorldPackets::Misc::BindPointUpdate packet; + packet.BindPosition.x = m_homebindX; + packet.BindPosition.y = m_homebindY; + packet.BindPosition.z = m_homebindZ; + packet.BindMapID = m_homebindMapId; + packet.BindAreaID = m_homebindAreaId; + SendDirectMessage(packet.Write()); +} + uint32 Player::GetUInt32ValueFromArray(Tokenizer const& data, uint16 index) { if (index >= data.size()) @@ -17391,7 +17397,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) if (i >= talentSpecs.size()) break; - uint32 talentSpec = atol(talentSpecs[i]); + uint32 talentSpec = atoul(talentSpecs[i]); if (sChrSpecializationStore.LookupEntry(talentSpec)) SetTalentSpec(i, talentSpec); else @@ -20417,9 +20423,9 @@ void Player::Say(std::string const& text, Language language, WorldObject const* std::string _text(text); sScriptMgr->OnPlayerChat(this, CHAT_MSG_SAY, language, _text); - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, language, this, this, _text); - SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_SAY, language, this, this, _text); + SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); } void Player::Yell(std::string const& text, Language language, WorldObject const* /*= nullptr*/) @@ -20427,9 +20433,9 @@ void Player::Yell(std::string const& text, Language language, WorldObject const* std::string _text(text); sScriptMgr->OnPlayerChat(this, CHAT_MSG_YELL, language, _text); - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, language, this, this, _text); - SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_YELL, language, this, this, _text); + SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true); } void Player::TextEmote(std::string const& text, WorldObject const* /*= nullptr*/, bool /*= false*/) @@ -20437,9 +20443,9 @@ void Player::TextEmote(std::string const& text, WorldObject const* /*= nullptr*/ std::string _text(text); sScriptMgr->OnPlayerChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text); - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text); - SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text); + SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)); } void Player::WhisperAddon(std::string const& text, const std::string& prefix, Player* receiver) @@ -20450,9 +20456,9 @@ void Player::WhisperAddon(std::string const& text, const std::string& prefix, Pl if (!receiver->GetSession()->IsAddonRegistered(prefix)) return; - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, LANG_ADDON, this, this, text, 0, "", DEFAULT_LOCALE, prefix); - receiver->GetSession()->SendPacket(&data); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_WHISPER, LANG_ADDON, this, this, text, 0, "", DEFAULT_LOCALE, prefix); + receiver->SendDirectMessage(packet.Write()); } void Player::Whisper(std::string const& text, Language language, Player* target, bool /*= false*/) @@ -20467,16 +20473,16 @@ void Player::Whisper(std::string const& text, Language language, Player* target, std::string _text(text); sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, target); - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, Language(language), this, this, _text); - target->GetSession()->SendPacket(&data); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_WHISPER, Language(language), this, this, _text); + target->SendDirectMessage(packet.Write()); // rest stuff shouldn't happen in case of addon message if (isAddonMessage) return; - ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER_INFORM, Language(language), target, target, _text); - GetSession()->SendPacket(&data); + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_WHISPER_INFORM, Language(language), target, target, _text); + SendDirectMessage(packet.Write()); if (!isAcceptWhispers() && !IsGameMaster() && !target->IsGameMaster()) { @@ -20966,9 +20972,10 @@ void Player::SetSpellModTakingSpell(Spell* spell, bool apply) // send Proficiency void Player::SendProficiency(ItemClass itemClass, uint32 itemSubclassMask) { - WorldPacket data(SMSG_SET_PROFICIENCY, 1 + 4); - data << uint8(itemClass) << uint32(itemSubclassMask); - GetSession()->SendPacket(&data); + WorldPackets::Item::SetProficiency packet; + packet.ProficiencyMask = itemSubclassMask; + packet.ProficiencyClass = itemClass; + SendDirectMessage(packet.Write()); } void Player::RemovePetitionsAndSigns(ObjectGuid guid, uint32 type) @@ -22971,68 +22978,67 @@ void Player::SendInitialPacketsBeforeAddToMap() /// Pass 'this' as argument because we're not stored in ObjectAccessor yet GetSocial()->SendSocialList(this); - // guild bank list wtf? - + /// SMSG_SPELL_CATEGORY_COOLDOWN GetSession()->SendSpellCategoryCooldowns(); - // Homebind - WorldPacket data(SMSG_BINDPOINTUPDATE, 5*4); - data << m_homebindX << m_homebindY << m_homebindZ; - data << (uint32) m_homebindMapId; - data << (uint32) m_homebindAreaId; - GetSession()->SendPacket(&data); + /// SMSG_BINDPOINTUPDATE + SendBindPointUpdate(); // SMSG_SET_PROFICIENCY // SMSG_SET_PCT_SPELL_MODIFIER // SMSG_SET_FLAT_SPELL_MODIFIER - // SMSG_UPDATE_AURA_DURATION + /// SMSG_TALENTS_INFO SendTalentsInfoData(); - - data.Initialize(SMSG_WORLD_SERVER_INFO, 1 + 1 + 4 + 4); - data.WriteBit(0); // HasRestrictedLevel - data.WriteBit(0); // HasRestrictedMoney - data.WriteBit(0); // IneligibleForLoot - data.FlushBits(); - //if (IneligibleForLoot) - // data << uint32(0); // EncounterMask - - data << uint8(0); // IsOnTournamentRealm - //if (HasRestrictedMoney) - // data << uint32(100000); // RestrictedMoney (starter accounts) - //if (HasRestrictedLevel) - // data << uint32(20); // RestrictedLevel (starter accounts) - - data << uint32(sWorld->GetNextWeeklyQuestsResetTime() - WEEK); // LastWeeklyReset (not instance reset) - data << uint32(GetMap()->GetDifficulty()); - GetSession()->SendPacket(&data); - + /// SMSG_INITIAL_SPELLS SendKnownSpells(); - data.Initialize(SMSG_SEND_UNLEARN_SPELLS, 4); - data << uint32(0); // count, for (count) uint32; - GetSession()->SendPacket(&data); + /// SMSG_SEND_UNLEARN_SPELLS + SendDirectMessage(WorldPackets::Spell::SendUnlearnSpells().Write()); + + /// @todo: SMSG_SEND_SPELL_HISTORY + /// @todo: SMSG_SEND_SPELL_CHARGES + /// SMSG_ACTION_BUTTONS SendInitialActionButtons(); - m_reputationMgr->SendInitialReputations(); - m_achievementMgr->SendAllAchievementData(this); + /// SMSG_INITIALIZE_FACTIONS + m_reputationMgr->SendInitialReputations(); + /// SMSG_SET_FORCED_REACTIONS + m_reputationMgr->SendForceReactions(); + /// SMSG_INIT_CURRENCY + SendCurrencies(); + /// SMSG_EQUIPMENT_SET_LIST SendEquipmentSetList(); - data.Initialize(SMSG_LOGIN_SETTIMESPEED, 4 + 4 + 4); - data.AppendPackedTime(sWorld->GetGameTime()); - data << float(0.01666667f); // game speed - data << uint32(0); // added in 3.1.2 - GetSession()->SendPacket(&data); + m_achievementMgr->SendAllAchievementData(this); - GetReputationMgr().SendForceReactions(); // SMSG_SET_FORCED_REACTIONS + /// SMSG_LOGIN_SETTIMESPEED + static float const TimeSpeed = 0.01666667f; + WorldPackets::Misc::LoginSetTimeSpeed loginSetTimeSpeed; + loginSetTimeSpeed.NewSpeed = TimeSpeed; + loginSetTimeSpeed.GameTime = sWorld->GetGameTime(); + loginSetTimeSpeed.ServerTime = sWorld->GetGameTime(); + loginSetTimeSpeed.GameTimeHolidayOffset = 0; /// @todo + loginSetTimeSpeed.ServerTimeHolidayOffset = 0; /// @todo + SendDirectMessage(loginSetTimeSpeed.Write()); + + /// SMSG_WORLD_SERVER_INFO + WorldPackets::Misc::WorldServerInfo worldServerInfo; + worldServerInfo.IneligibleForLootMask.Clear(); /// @todo + worldServerInfo.WeeklyReset = sWorld->GetNextWeeklyQuestsResetTime() - WEEK; + worldServerInfo.InstanceGroupSize.Clear(); /// @todo + worldServerInfo.IsTournamentRealm = 0; /// @todo + worldServerInfo.RestrictedAccountMaxLevel.Clear(); /// @todo + worldServerInfo.RestrictedAccountMaxMoney.Clear(); /// @todo + worldServerInfo.DifficultyID = GetMap()->GetDifficulty(); + SendDirectMessage(worldServerInfo.Write()); // SMSG_TALENTS_INFO x 2 for pet (unspent points and talents in separate packets...) // SMSG_PET_GUIDS // SMSG_UPDATE_WORLD_STATE // SMSG_POWER_UPDATE - SendCurrencies(); SetMover(this); } @@ -23107,11 +23113,11 @@ void Player::SendUpdateToOutOfRangeGroupMembers() void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg) { - WorldPacket data(SMSG_TRANSFER_ABORTED, 4+2); - data << uint32(mapid); - data << uint8(reason); // transfer abort reason - data << uint8(arg); - GetSession()->SendPacket(&data); + WorldPackets::Movement::TransferAborted transferAborted; + transferAborted.MapID = mapid; + transferAborted.Arg = arg; + transferAborted.TransfertAbort = reason; + GetSession()->SendPacket(transferAborted.Write()); } void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time) @@ -25440,6 +25446,10 @@ bool Player::LearnTalent(uint32 talentId) { uint8 group = GetActiveTalentGroup(); + // check if talent specialization is learnt + if (!GetTalentSpec(group)) + return false; + TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId); if (!talentInfo) @@ -25472,34 +25482,6 @@ bool Player::LearnTalent(uint32 talentId) if (HasSpell(spellid)) return false; - // set talent spec for player - if (!GetTalentSpec(group)) - { - SetTalentSpec(group, talentInfo->SpecID); - - // Replace default spells by specialization spells - auto specSpells = sSpecializationSpellsBySpecStore.find(talentInfo->SpecID); - if (specSpells != sSpecializationSpellsBySpecStore.end()) - { - for (auto it = specSpells->second.begin(); it != specSpells->second.end(); ++it) - { - SpecializationSpellsEntry const* specSpell = *it; - if (HasSpell(specSpell->OverridesSpellID)) { - RemoveSpell(specSpell->OverridesSpellID, true); - LearnSpell(specSpell->SpellID, false); - } - } - } - - if (CanUseMastery()) { - ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(talentInfo->SpecID); - for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i) - if (SpellInfo const* masterySpell = sSpellMgr->GetSpellInfo(chrSpec->MasterySpellID[i])) - if (masterySpell->IsPassive() && IsNeedCastPassiveSpellAtLearn(masterySpell)) - CastSpell(this, masterySpell->Id, true); - } - } - // Check talent spec if (talentInfo->SpecID != GetTalentSpec(group)) return false; @@ -25513,6 +25495,41 @@ bool Player::LearnTalent(uint32 talentId) return true; } +void Player::LearnTalentSpecialization(uint32 talentSpec) +{ + SetTalentSpec(GetActiveTalentGroup(), talentSpec); + + // Replace default spells by specialization spells + auto specSpells = sSpecializationSpellsBySpecStore.find(talentSpec); + if (specSpells != sSpecializationSpellsBySpecStore.end()) + { + for (auto it = specSpells->second.begin(); it != specSpells->second.end(); ++it) + { + SpecializationSpellsEntry const* specSpell = *it; + + // Unlearn spell if it is replaced by new specialization + if (specSpell->OverridesSpellID) + RemoveSpell(specSpell->OverridesSpellID, true); + + // Learn new spell + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(specSpell->SpellID)) + if (spellInfo->BaseLevel <= getLevel()) + LearnSpell(specSpell->SpellID, false); + } + } + + if (CanUseMastery()) + { + ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(talentSpec); + for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i) + if (SpellInfo const* masterySpell = sSpellMgr->GetSpellInfo(chrSpec->MasterySpellID[i])) + if (masterySpell->IsPassive() && IsNeedCastPassiveSpellAtLearn(masterySpell)) + CastSpell(this, masterySpell->Id, true); + } + + SendTalentsInfoData(); +} + void Player::AddKnownCurrency(uint32 itemId) { if (CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemId)) @@ -25618,7 +25635,7 @@ void Player::SendTalentsInfoData() packet.Info.TalentGroups.push_back(groupInfoPkt); } - GetSession()->SendPacket(packet.Write()); + SendDirectMessage(packet.Write()); } void Player::BuildEnchantmentsInfoData(WorldPacket* data) @@ -25666,122 +25683,100 @@ void Player::BuildEnchantmentsInfoData(WorldPacket* data) void Player::SendEquipmentSetList() { - ObjectGuid ignoredItemGuid; - ignoredItemGuid.SetRawValue(0, 1); - uint32 count = 0; - WorldPacket data(SMSG_EQUIPMENT_SET_LIST, 4); - size_t count_pos = data.wpos(); - data << uint32(count); // count placeholder - for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr) + WorldPackets::EquipmentSet::LoadEquipmentSet data; + + for (EquipmentSetContainer::value_type const& eqSet : _equipmentSets) { - if (itr->second.state == EQUIPMENT_SET_DELETED) + if (eqSet.second.State == EQUIPMENT_SET_DELETED) continue; - data.AppendPackedUInt64(itr->second.Guid); - data << uint32(itr->first); - data << itr->second.Name; - data << itr->second.IconName; - for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) - { - // ignored slots stored in IgnoreMask, client wants "1" as raw GUID, so no HIGHGUID_ITEM - if (itr->second.IgnoreMask & (1 << i)) - data << ignoredItemGuid; - else - data << ObjectGuid::Create<HighGuid::Item>(itr->second.Items[i]); - } - ++count; // client have limit but it checked at loading and set + data.SetData.push_back(&eqSet.second.Data); } - data.put<uint32>(count_pos, count); - GetSession()->SendPacket(&data); + + SendDirectMessage(data.Write()); } -void Player::SetEquipmentSet(uint32 index, EquipmentSet eqset) +void Player::SetEquipmentSet(EquipmentSetInfo::EquipmentSetData&& newEqSet) { - if (eqset.Guid != 0) + if (newEqSet.Guid != 0) { - bool found = false; - - for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr) + // something wrong... + EquipmentSetContainer::const_iterator itr = _equipmentSets.find(newEqSet.SetID); + if (itr == _equipmentSets.end() || itr->second.Data.Guid != newEqSet.Guid) { - if ((itr->second.Guid == eqset.Guid) && (itr->first == index)) - { - found = true; - break; - } - } - - if (!found) // something wrong... - { - TC_LOG_ERROR("entities.player", "Player %s tried to save equipment set " UI64FMTD " (index %u), but that equipment set not found!", GetName().c_str(), eqset.Guid, index); + TC_LOG_ERROR("entities.player", "Player %s tried to save equipment set " UI64FMTD " (index: %u), but that equipment set not found!", GetName().c_str(), newEqSet.Guid, newEqSet.SetID); return; } } - EquipmentSet& eqslot = m_EquipmentSets[index]; + EquipmentSetInfo& eqSlot = _equipmentSets[newEqSet.SetID]; - EquipmentSetUpdateState old_state = eqslot.state; + EquipmentSetUpdateState oldState = eqSlot.State; - eqslot = eqset; + eqSlot.Data = newEqSet; - if (eqset.Guid == 0) + if (eqSlot.Data.Guid == 0) { - eqslot.Guid = sObjectMgr->GenerateEquipmentSetGuid(); + eqSlot.Data.Guid = sObjectMgr->GenerateEquipmentSetGuid(); - WorldPacket data(SMSG_EQUIPMENT_SET_SAVED, 4 + 1); - data << uint32(index); - data.AppendPackedUInt64(eqslot.Guid); - GetSession()->SendPacket(&data); + WorldPackets::EquipmentSet::EquipmentSetID data; + data.GUID = eqSlot.Data.Guid; + data.SetID = eqSlot.Data.SetID; + SendDirectMessage(data.Write()); } - eqslot.state = old_state == EQUIPMENT_SET_NEW ? EQUIPMENT_SET_NEW : EQUIPMENT_SET_CHANGED; + eqSlot.State = oldState == EQUIPMENT_SET_NEW ? EQUIPMENT_SET_NEW : EQUIPMENT_SET_CHANGED; } void Player::_SaveEquipmentSets(SQLTransaction& trans) { - for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end();) + for (EquipmentSetContainer::iterator itr = _equipmentSets.begin(); itr != _equipmentSets.end();) { - uint32 index = itr->first; - EquipmentSet& eqset = itr->second; - PreparedStatement* stmt = NULL; + EquipmentSetInfo& eqSet = itr->second; + PreparedStatement* stmt = nullptr; uint8 j = 0; - switch (eqset.state) + switch (eqSet.State) { case EQUIPMENT_SET_UNCHANGED: ++itr; break; // nothing do case EQUIPMENT_SET_CHANGED: stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_EQUIP_SET); - stmt->setString(j++, eqset.Name.c_str()); - stmt->setString(j++, eqset.IconName.c_str()); - stmt->setUInt32(j++, eqset.IgnoreMask); - for (uint8 i=0; i<EQUIPMENT_SLOT_END; ++i) - stmt->setUInt64(j++, eqset.Items[i]); + stmt->setString(j++, eqSet.Data.SetName); + stmt->setString(j++, eqSet.Data.SetIcon); + stmt->setUInt32(j++, eqSet.Data.IgnoreMask); + + for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) + stmt->setUInt64(j++, eqSet.Data.Pieces[i].GetCounter()); + stmt->setUInt64(j++, GetGUID().GetCounter()); - stmt->setUInt64(j++, eqset.Guid); - stmt->setUInt32(j, index); + stmt->setUInt64(j++, eqSet.Data.Guid); + stmt->setUInt32(j, eqSet.Data.SetID); trans->Append(stmt); - eqset.state = EQUIPMENT_SET_UNCHANGED; + eqSet.State = EQUIPMENT_SET_UNCHANGED; ++itr; break; case EQUIPMENT_SET_NEW: stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_EQUIP_SET); stmt->setUInt64(j++, GetGUID().GetCounter()); - stmt->setUInt64(j++, eqset.Guid); - stmt->setUInt32(j++, index); - stmt->setString(j++, eqset.Name.c_str()); - stmt->setString(j++, eqset.IconName.c_str()); - stmt->setUInt32(j++, eqset.IgnoreMask); - for (uint8 i=0; i<EQUIPMENT_SLOT_END; ++i) - stmt->setUInt64(j++, eqset.Items[i]); + stmt->setUInt64(j++, eqSet.Data.Guid); + stmt->setUInt32(j++, eqSet.Data.SetID); + stmt->setString(j++, eqSet.Data.SetName); + stmt->setString(j++, eqSet.Data.SetIcon); + stmt->setUInt32(j++, eqSet.Data.IgnoreMask); + + for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) + stmt->setUInt64(j++, eqSet.Data.Pieces[i].GetCounter()); + trans->Append(stmt); - eqset.state = EQUIPMENT_SET_UNCHANGED; + eqSet.State = EQUIPMENT_SET_UNCHANGED; ++itr; break; case EQUIPMENT_SET_DELETED: stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_EQUIP_SET); - stmt->setUInt64(0, eqset.Guid); + stmt->setUInt64(0, eqSet.Data.Guid); trans->Append(stmt); - m_EquipmentSets.erase(itr++); + itr = _equipmentSets.erase(itr); break; } } @@ -25810,16 +25805,17 @@ void Player::_SaveBGData(SQLTransaction& trans) void Player::DeleteEquipmentSet(uint64 setGuid) { - for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr) + for (EquipmentSetContainer::iterator itr = _equipmentSets.begin(); itr != _equipmentSets.end();) { - if (itr->second.Guid == setGuid) + if (itr->second.Data.Guid == setGuid) { - if (itr->second.state == EQUIPMENT_SET_NEW) - m_EquipmentSets.erase(itr); + if (itr->second.State == EQUIPMENT_SET_NEW) + itr = _equipmentSets.erase(itr); else - itr->second.state = EQUIPMENT_SET_DELETED; + itr->second.State = EQUIPMENT_SET_DELETED; break; } + ++itr; } } @@ -26183,9 +26179,9 @@ void Player::SendTimeSync() { m_timeSyncQueue.push(m_movementCounter++); - WorldPacket data(SMSG_TIME_SYNC_REQ, 4); - data << uint32(m_timeSyncQueue.back()); - GetSession()->SendPacket(&data); + WorldPackets::Misc::TimeSyncRequest packet; + packet.SequenceIndex = m_timeSyncQueue.back(); + SendDirectMessage(packet.Write()); // Schedule next sync in 10 sec m_timeSyncTimer = 10000; @@ -26753,7 +26749,13 @@ std::string Player::GetCoordsMapAreaAndZoneString() Guild* Player::GetGuild() { ObjectGuid::LowType guildId = GetGuildId(); - return guildId ? sGuildMgr->GetGuildById(guildId) : NULL; + return guildId ? sGuildMgr->GetGuildById(guildId) : nullptr; +} + +Guild const* Player::GetGuild() const +{ + ObjectGuid::LowType guildId = GetGuildId(); + return guildId ? sGuildMgr->GetGuildById(guildId) : nullptr; } Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 duration) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a5698740092..1dcd75a156e 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -328,15 +328,15 @@ enum ReputationSource REPUTATION_SOURCE_SPELL }; -#define ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF) -#define ACTION_BUTTON_TYPE(X) ((uint32(X) & 0xFF000000) >> 24) -#define MAX_ACTION_BUTTON_ACTION_VALUE (0x00FFFFFF+1) +#define ACTION_BUTTON_ACTION(X) (uint64(X) & 0x00000000FFFFFFFF) +#define ACTION_BUTTON_TYPE(X) ((uint64(X) & 0xFFFFFFFF00000000) >> 32) +#define MAX_ACTION_BUTTON_ACTION_VALUE (0xFFFFFFFF) struct ActionButton { ActionButton() : packedData(0), uState(ACTIONBUTTON_NEW) { } - uint32 packedData; + uint64 packedData; ActionButtonUpdateState uState; // helpers @@ -344,7 +344,7 @@ struct ActionButton uint32 GetAction() const { return ACTION_BUTTON_ACTION(packedData); } void SetActionAndType(uint32 action, ActionButtonType type) { - uint32 newData = action | (uint32(type) << 24); + uint64 newData = uint64(action) | (uint64(type) << 32); if (newData != packedData || uState == ACTIONBUTTON_DELETED) { packedData = newData; @@ -354,7 +354,7 @@ struct ActionButton } }; -#define MAX_ACTION_BUTTONS 144 //checked in 3.2.0 +#define MAX_ACTION_BUTTONS 132 typedef std::map<uint8, ActionButton> ActionButtonList; @@ -747,24 +747,26 @@ enum EquipmentSetUpdateState EQUIPMENT_SET_DELETED = 3 }; -struct EquipmentSet +struct EquipmentSetInfo { - EquipmentSet() : Guid(0), IgnoreMask(0), state(EQUIPMENT_SET_NEW) + /// Data sent in EquipmentSet related packets + struct EquipmentSetData { - memset(Items, 0, sizeof(Items)); - } + uint64 Guid = 0; ///< Set Identifier + uint32 SetID = 0; ///< Index + uint32 IgnoreMask = 0; ///< Mask of EquipmentSlot + std::string SetName; + std::string SetIcon; + ObjectGuid Pieces[EQUIPMENT_SLOT_END]; + } Data; - uint64 Guid; - std::string Name; - std::string IconName; - uint32 IgnoreMask; - ObjectGuid::LowType Items[EQUIPMENT_SLOT_END]; - EquipmentSetUpdateState state; + /// Server-side data + EquipmentSetUpdateState State = EQUIPMENT_SET_NEW; }; #define MAX_EQUIPMENT_SET_INDEX 10 // client limit -typedef std::map<uint32, EquipmentSet> EquipmentSets; +typedef std::map<uint32, EquipmentSetInfo> EquipmentSetContainer; struct ItemPosCount { @@ -785,24 +787,45 @@ enum TradeSlots enum TransferAbortReason { - TRANSFER_ABORT_NONE = 0x00, - TRANSFER_ABORT_ERROR = 0x01, - TRANSFER_ABORT_MAX_PLAYERS = 0x02, // Transfer Aborted: instance is full - TRANSFER_ABORT_NOT_FOUND = 0x03, // Transfer Aborted: instance not found - TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x04, // You have entered too many instances recently. - TRANSFER_ABORT_ZONE_IN_COMBAT = 0x06, // Unable to zone in while an encounter is in progress. - TRANSFER_ABORT_INSUF_EXPAN_LVL = 0x07, // You must have <TBC, WotLK> expansion installed to access this area. - TRANSFER_ABORT_DIFFICULTY = 0x08, // <Normal, Heroic, Epic> difficulty mode is not available for %s. - TRANSFER_ABORT_UNIQUE_MESSAGE = 0x09, // Until you've escaped TLK's grasp, you cannot leave this place! - TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 0x0A, // Additional instances cannot be launched, please try again later. - TRANSFER_ABORT_NEED_GROUP = 0x0B, // 3.1 - TRANSFER_ABORT_NOT_FOUND1 = 0x0C, // 3.1 - TRANSFER_ABORT_NOT_FOUND2 = 0x0D, // 3.1 - TRANSFER_ABORT_NOT_FOUND3 = 0x0E, // 3.2 - TRANSFER_ABORT_REALM_ONLY = 0x0F, // All players on party must be from the same realm. - TRANSFER_ABORT_MAP_NOT_ALLOWED = 0x10, // Map can't be entered at this time. - TRANSFER_ABORT_LOCKED_TO_DIFFERENT_INSTANCE = 0x12, // 4.2.2 - TRANSFER_ABORT_ALREADY_COMPLETED_ENCOUNTER = 0x13 // 4.2.2 + TRANSFER_ABORT_NONE = 0, + TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 1, // Additional instances cannot be launched, please try again later. + TRANSFER_ABORT_DIFFICULTY = 3, // <Normal, Heroic, Epic> difficulty mode is not available for %s. + TRANSFER_ABORT_INSUF_EXPAN_LVL = 8, // You must have <TBC, WotLK> expansion installed to access this area. + TRANSFER_ABORT_NOT_FOUND = 10, // Transfer Aborted: instance not found + TRANSFER_ABORT_TOO_MANY_INSTANCES = 11, // You have entered too many instances recently. + TRANSFER_ABORT_MAX_PLAYERS = 12, // Transfer Aborted: instance is full + TRANSFER_ABORT_XREALM_ZONE_DOWN = 14, // Transfer Aborted: cross-realm zone is down + TRANSFER_ABORT_NOT_FOUND_2 = 15, // Transfer Aborted: instance not found + TRANSFER_ABORT_DIFFICULTY_NOT_FOUND = 16, // client writes to console "Unable to resolve requested difficultyID %u to actual difficulty for map %d" + TRANSFER_ABORT_NOT_FOUND_3 = 17, // Transfer Aborted: instance not found + TRANSFER_ABORT_NOT_FOUND_4 = 18, // Transfer Aborted: instance not found + TRANSFER_ABORT_ZONE_IN_COMBAT = 19, // Unable to zone in while an encounter is in progress. + TRANSFER_ABORT_ALREADY_COMPLETED_ENCOUNTER = 20, // You are ineligible to participate in at least one encounter in this instance because you are already locked to an instance in which it has been defeated. + TRANSFER_ABORT_LOCKED_TO_DIFFERENT_INSTANCE = 24, // You are already locked to %s + TRANSFER_ABORT_REALM_ONLY = 25, // All players in the party must be from the same realm to enter %s. + TRANSFER_ABORT_MAP_NOT_ALLOWED = 27, // Map cannot be entered at this time. + TRANSFER_ABORT_SOLO_PLAYER_SWITCH_DIFFICULTY = 28, // This instance is already in progress. You may only switch difficulties from inside the instance. + TRANSFER_ABORT_NEED_GROUP = 29, // Transfer Aborted: you must be in a raid group to enter this instance + TRANSFER_ABORT_UNIQUE_MESSAGE = 30, // Until you've escaped TLK's grasp, you cannot leave this place! + TRANSFER_ABORT_ERROR = 31, + /* + // Unknown values - not used by the client to display any error + TRANSFER_ABORT_MANY_REALM_INSTANCES + TRANSFER_ABORT_AREA_NOT_ZONED + TRANSFER_ABORT_TIMEOUT + TRANSFER_ABORT_SHUTTING_DOWN + TRANSFER_ABORT_PLAYER_CONDITION + TRANSFER_ABORT_BUSY + TRANSFER_ABORT_DISCONNECTED + TRANSFER_ABORT_LOGGING_OUT + TRANSFER_ABORT_NEED_SERVER + */ +}; + +enum NewWorldReason +{ + NEW_WORLD_NORMAL = 16, // Normal map change + NEW_WORLD_SEAMLESS = 21, // Teleport to another map without a loading screen, used for outdoor scenarios }; enum InstanceResetWarningType @@ -858,18 +881,6 @@ enum EnviromentalDamage DAMAGE_FALL_TO_VOID = 6 // custom case for fall without durability loss }; -enum PlayerChatTag -{ - CHAT_TAG_NONE = 0x00, - CHAT_TAG_AFK = 0x01, - CHAT_TAG_DND = 0x02, - CHAT_TAG_GM = 0x04, - CHAT_TAG_COM = 0x08, // Commentator - CHAT_TAG_DEV = 0x10, - CHAT_TAG_BOSS_SOUND = 0x20, // Plays "RaidBossEmoteWarning" sound on raid boss emote/whisper - CHAT_TAG_MOBILE = 0x40 -}; - enum PlayedTimeIndex { PLAYED_TIME_TOTAL = 0, @@ -1314,7 +1325,7 @@ class Player : public Unit, public GridObject<Player> void ToggleDND(); bool isAFK() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK); } bool isDND() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DND); } - uint8 GetChatTag() const; + uint8 GetChatFlags() const; std::string autoReplyMsg; uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const* newSkin=NULL); @@ -1747,8 +1758,8 @@ class Player : public Unit, public GridObject<Player> Unit* GetSelectedUnit() const; Player* GetSelectedPlayer() const; - void SetTarget(ObjectGuid /*guid*/) override { } /// Used for serverside target changes, does not apply to players - void SetSelection(ObjectGuid guid) { SetGuidValue(UNIT_FIELD_TARGET, guid); } + void SetTarget(ObjectGuid const& /*guid*/) override { } /// Used for serverside target changes, does not apply to players + void SetSelection(ObjectGuid const& guid) { SetGuidValue(UNIT_FIELD_TARGET, guid); } uint8 GetComboPoints() const { return m_comboPoints; } ObjectGuid GetComboTarget() const { return m_comboTarget; } @@ -1841,6 +1852,7 @@ class Player : public Unit, public GridObject<Player> bool LearnTalent(uint32 talentId); bool AddTalent(uint32 talentId, uint8 spec); bool HasTalent(uint32 talentId, uint8 spec); + void LearnTalentSpecialization(uint32 talentSpec); // Dual Spec void UpdateTalentGroupCount(uint8 count); @@ -1967,6 +1979,7 @@ class Player : public Unit, public GridObject<Player> void SetGuildIdInvited(ObjectGuid::LowType GuildId) { m_GuildIdInvited = GuildId; } ObjectGuid::LowType GetGuildId() const { return GetUInt64Value(OBJECT_FIELD_DATA); /* return only lower part */ } Guild* GetGuild(); + Guild const* GetGuild() const; static ObjectGuid::LowType GetGuildIdFromDB(ObjectGuid guid); static uint8 GetRankFromDB(ObjectGuid guid); ObjectGuid::LowType GetGuildIdInvited() { return m_GuildIdInvited; } @@ -2088,10 +2101,10 @@ class Player : public Unit, public GridObject<Player> bool UpdatePosition(const Position &pos, bool teleport = false) { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); } void UpdateUnderwaterState(Map* m, float x, float y, float z) override; - void SendMessageToSet(WorldPacket* data, bool self) override {SendMessageToSetInRange(data, GetVisibilityRange(), self); };// overwrite Object::SendMessageToSet - void SendMessageToSetInRange(WorldPacket* data, float fist, bool self) override;// overwrite Object::SendMessageToSetInRange - void SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only); - void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr) override; + void SendMessageToSet(WorldPacket const* data, bool self) override {SendMessageToSetInRange(data, GetVisibilityRange(), self); };// overwrite Object::SendMessageToSet + void SendMessageToSetInRange(WorldPacket const* data, float fist, bool self) override;// overwrite Object::SendMessageToSetInRange + void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool own_team_only); + void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) override; Corpse* GetCorpse() const; void SpawnCorpseBones(); @@ -2239,12 +2252,12 @@ class Player : public Unit, public GridObject<Player> void CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item* item, ItemTemplate const* proto); void SendEquipmentSetList(); - void SetEquipmentSet(uint32 index, EquipmentSet eqset); + void SetEquipmentSet(EquipmentSetInfo::EquipmentSetData&& newEqSet); void DeleteEquipmentSet(uint64 setGuid); void SendInitWorldStates(uint32 zone, uint32 area); void SendUpdateWorldState(uint32 variable, uint32 value, bool hidden = false); - void SendDirectMessage(WorldPacket const* data); + void SendDirectMessage(WorldPacket const* data) const; void SendBGWeekendWorldStates(); void SendBattlefieldWorldStates(); @@ -2378,6 +2391,7 @@ class Player : public Unit, public GridObject<Player> void SaveRecallPosition(); void SetHomebind(WorldLocation const& loc, uint32 areaId); + void SendBindPointUpdate(); // Homebind coordinates uint32 m_homebindMapId; @@ -2851,7 +2865,7 @@ class Player : public Unit, public GridObject<Player> DeclinedName *m_declinedname; Runes *m_runes; - EquipmentSets m_EquipmentSets; + EquipmentSetContainer _equipmentSets; bool CanAlwaysSee(WorldObject const* obj) const override; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index fd75103ab7d..9831ad342d7 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -62,6 +62,9 @@ #include "WorldPacket.h" #include "MovementStructures.h" #include "WorldSession.h" +#include "ChatPackets.h" +#include "MovementPackets.h" +#include "CombatPackets.h" #include <cmath> @@ -1409,10 +1412,10 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) void Unit::HandleEmoteCommand(uint32 anim_id) { - WorldPacket data(SMSG_EMOTE, 4 + 8); - data << uint32(anim_id); - data << GetGUID(); - SendMessageToSet(&data, true); + WorldPackets::Chat::Emote packet; + packet.Guid = GetGUID(); + packet.EmoteID = anim_id; + SendMessageToSet(packet.Write(), true); } bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* spellInfo, uint8 effIndex) @@ -2108,24 +2111,24 @@ float Unit::CalculateLevelPenalty(SpellInfo const* spellProto) const void Unit::SendMeleeAttackStart(Unit* victim) { - WorldPacket data(SMSG_ATTACKSTART, 8 + 8); - data << GetGUID(); - data << victim->GetGUID(); - SendMessageToSet(&data, true); + WorldPackets::Combat::AttackStart packet; + packet.Attacker = GetGUID(); + packet.Victim = victim->GetGUID(); + SendMessageToSet(packet.Write(), true); TC_LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTART"); } void Unit::SendMeleeAttackStop(Unit* victim) { - WorldPacket data(SMSG_ATTACKSTOP, (8+8+4)); - data << GetPackGUID(); + WorldPackets::Combat::SAttackStop packet; + packet.Attacker = GetGUID(); if (victim) - data << victim->GetPackGUID(); - else - data << uint8(0); + { + packet.Victim = victim->GetGUID(); + packet.Dead = victim->isDead(); + } - data << uint32(0); //! Can also take the value 0x01, which seems related to updating rotation - SendMessageToSet(&data, true); + SendMessageToSet(packet.Write(), true); TC_LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTOP"); if (victim) @@ -3021,12 +3024,16 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint3 if (!effect) continue; + AuraEffect const* eff = foundAura->GetEffect(effect->EffectIndex); + if (!eff) + continue; + int bp; if (baseAmount) bp = *(baseAmount + effect->EffectIndex); else bp = effect->BasePoints; - + TC_LOG_ERROR("spells", "_TryStackingOrRefreshingExistingAura spell %u effMask %u currIdx %u", newAura->Id, effMask, effect->EffectIndex); int32* oldBP = const_cast<int32*>(&(foundAura->GetEffect(effect->EffectIndex)->m_baseAmount)); // todo 6.x review GetBaseAmount and GetCastItemGUID in this case *oldBP = bp; } @@ -4848,67 +4855,26 @@ void Unit::SendAttackStateUpdate(CalcDamageInfo* damageInfo) { TC_LOG_DEBUG("entities.unit", "WORLD: Sending SMSG_ATTACKERSTATEUPDATE"); - uint32 count = 1; - size_t maxsize = 4+5+5+4+4+1+4+4+4+4+4+1+4+4+4+4+4*12; - WorldPacket data(SMSG_ATTACKERSTATEUPDATE, maxsize); // we guess size - data << uint32(damageInfo->HitInfo); - data << damageInfo->attacker->GetPackGUID(); - data << damageInfo->target->GetPackGUID(); - data << uint32(damageInfo->damage); // Full damage + WorldPackets::Combat::AttackerStateUpdate packet; + packet.HitInfo = damageInfo->HitInfo; + packet.AttackerGUID = damageInfo->attacker->GetGUID(); + packet.VictimGUID = damageInfo->target->GetGUID(); + packet.Damage = damageInfo->damage; int32 overkill = damageInfo->damage - damageInfo->target->GetHealth(); - data << uint32(overkill < 0 ? 0 : overkill); // Overkill - data << uint8(count); // Sub damage count + packet.OverDamage = (overkill < 0 ? -1 : overkill); - for (uint32 i = 0; i < count; ++i) - { - data << uint32(damageInfo->damageSchoolMask); // School of sub damage - data << float(damageInfo->damage); // sub damage - data << uint32(damageInfo->damage); // Sub Damage - } + WorldPackets::Combat::SubDamage& subDmg = packet.SubDmg.Value; + subDmg.SchoolMask = damageInfo->damageSchoolMask; // School of sub damage + subDmg.FDamage = damageInfo->damage; // sub damage + subDmg.Damage = damageInfo->damage; // Sub Damage + subDmg.Absorbed = damageInfo->absorb; + subDmg.Resisted = damageInfo->resist; + packet.SubDmg.HasValue = true; - if (damageInfo->HitInfo & (HITINFO_FULL_ABSORB | HITINFO_PARTIAL_ABSORB)) - { - for (uint32 i = 0; i < count; ++i) - data << uint32(damageInfo->absorb); // Absorb - } + packet.VictimState = damageInfo->TargetState; + packet.BlockAmount = damageInfo->blocked_amount; - if (damageInfo->HitInfo & (HITINFO_FULL_RESIST | HITINFO_PARTIAL_RESIST)) - { - for (uint32 i = 0; i < count; ++i) - data << uint32(damageInfo->resist); // Resist - } - - data << uint8(damageInfo->TargetState); - data << uint32(0); // Unknown attackerstate - data << uint32(0); // Melee spellid - - if (damageInfo->HitInfo & HITINFO_BLOCK) - data << uint32(damageInfo->blocked_amount); - - if (damageInfo->HitInfo & HITINFO_RAGE_GAIN) - data << uint32(0); - - //! Probably used for debugging purposes, as it is not known to appear on retail servers - if (damageInfo->HitInfo & HITINFO_UNK1) - { - data << uint32(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - for (uint8 i = 0; i < 2; ++i) - { - data << float(0); - data << float(0); - } - data << uint32(0); - } - - SendMessageToSet(&data, true); + SendMessageToSet(packet.Write(), true); } void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType*/, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount) @@ -10636,11 +10602,22 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) pet->SetSpeed(mtype, m_speed_rate[mtype], forced); } - static MovementStatusElements const speedVal = MSEExtraFloat; - Movement::ExtraMovementStatusElement extra(&speedVal); - extra.Data.floatData = GetSpeed(mtype); - - Movement::PacketSender(this, moveTypeToOpcode[mtype][0], moveTypeToOpcode[mtype][1], moveTypeToOpcode[mtype][2], &extra).Send(); + if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->m_mover->GetTypeId() == TYPEID_PLAYER) + { + /// @todo fix SMSG_MOVE_SET packets (were they removed?) + //_selfOpcode = playerControl; + WorldPackets::Movement::MoveUpdate packet(moveTypeToOpcode[mtype][2]); + packet.movementInfo = m_movementInfo; + packet.Speed = rate; + SendMessageToSet(packet.Write(), false); + } + else + { + WorldPackets::Movement::MoveSplineSet packet(moveTypeToOpcode[mtype][0]); + packet.MoverGUID = GetGUID(); + packet.Speed = rate; + SendMessageToSet(packet.Write(), true); + } } void Unit::setDeathState(DeathState s) @@ -12082,7 +12059,7 @@ void CharmInfo::LoadPetActionBar(const std::string& data) // use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion ActiveStates type = ActiveStates(atol(*iter)); ++iter; - uint32 action = uint32(atol(*iter)); + uint32 action = atoul(*iter); PetActionBar[index].SetActionAndType(action, type); @@ -12745,10 +12722,10 @@ void Unit::SendPetAIReaction(ObjectGuid guid) if (!owner || owner->GetTypeId() != TYPEID_PLAYER) return; - WorldPacket data(SMSG_AI_REACTION, 8 + 4); - data << guid; - data << uint32(AI_REACTION_HOSTILE); - owner->ToPlayer()->GetSession()->SendPacket(&data); + WorldPackets::Combat::AIReaction packet; + packet.UnitGUID = guid; + packet.Reaction = AI_REACTION_HOSTILE; + owner->ToPlayer()->SendDirectMessage(packet.Write()); } ///----------End of Pet responses methods---------- @@ -15690,7 +15667,7 @@ void Unit::SendTeleportPacket(Position& pos) if (GetTypeId() == TYPEID_PLAYER) { - WorldPacket data2(MSG_MOVE_TELEPORT, 38); + WorldPacket data2(SMSG_MOVE_TELEPORT, 38); data2.WriteBit(guid[6]); data2.WriteBit(guid[0]); data2.WriteBit(guid[3]); @@ -15813,19 +15790,19 @@ void Unit::SendThreatListUpdate() { if (!getThreatManager().isThreatListEmpty()) { - uint32 count = getThreatManager().getThreatList().size(); - TC_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_UPDATE Message"); - WorldPacket data(SMSG_THREAT_UPDATE, 8 + count * 8); - data << GetPackGUID(); - data << uint32(count); + WorldPackets::Combat::ThreatUpdate packet; + packet.UnitGUID = GetGUID(); ThreatContainer::StorageType const &tlist = getThreatManager().getThreatList(); + packet.ThreatList.reserve(tlist.size()); for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr) { - data << (*itr)->getUnitGuid().WriteAsPacked(); - data << uint32((*itr)->getThreat() * 100); + WorldPackets::Combat::ThreatInfo info; + info.UnitGUID = (*itr)->getUnitGuid(); + info.Threat = (*itr)->getThreat() * 100; + packet.ThreatList.push_back(info); } - SendMessageToSet(&data, false); + SendMessageToSet(packet.Write(), false); } } @@ -15833,20 +15810,20 @@ void Unit::SendChangeCurrentVictimOpcode(HostileReference* pHostileReference) { if (!getThreatManager().isThreatListEmpty()) { - uint32 count = getThreatManager().getThreatList().size(); - TC_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_HIGHEST_THREAT_UPDATE Message"); - WorldPacket data(SMSG_HIGHEST_THREAT_UPDATE, 8 + 8 + count * 8); - data << GetPackGUID(); - data << pHostileReference->getUnitGuid().WriteAsPacked(); - data << uint32(count); + WorldPackets::Combat::HighestThreatUpdate packet; + packet.UnitGUID = GetGUID(); + packet.HighestThreatGUID = pHostileReference->getUnitGuid(); ThreatContainer::StorageType const &tlist = getThreatManager().getThreatList(); + packet.ThreatList.reserve(tlist.size()); for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr) { - data << (*itr)->getUnitGuid().WriteAsPacked(); - data << uint32((*itr)->getThreat()); + WorldPackets::Combat::ThreatInfo info; + info.UnitGUID = (*itr)->getUnitGuid(); + info.Threat = int32((*itr)->getThreat()); + packet.ThreatList.push_back(info); } - SendMessageToSet(&data, false); + SendMessageToSet(packet.Write(), false); } } @@ -15861,10 +15838,10 @@ void Unit::SendClearThreatListOpcode() void Unit::SendRemoveFromThreatListOpcode(HostileReference* pHostileReference) { TC_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_REMOVE Message"); - WorldPacket data(SMSG_THREAT_REMOVE, 8 + 8); - data << GetPackGUID(); - data << pHostileReference->getUnitGuid().WriteAsPacked(); - SendMessageToSet(&data, false); + WorldPackets::Combat::ThreatRemove packet; + packet.UnitGUID = GetGUID(); + packet.AboutGUID = pHostileReference->getUnitGuid(); + SendMessageToSet(packet.Write(), false); } // baseRage means damage taken when attacker = false @@ -16625,9 +16602,9 @@ void Unit::Whisper(std::string const& text, Language language, Player* target, b return; LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex(); - WorldPacket data; - ChatHandler::BuildChatPacket(data, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, language, this, target, text, 0, "", locale); - target->SendDirectMessage(&data); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, language, this, target, text, 0, "", locale); + target->SendDirectMessage(packet.Write()); } void Unit::Talk(uint32 textId, ChatMsg msgType, float textRange, WorldObject const* target) @@ -16672,7 +16649,7 @@ void Unit::Whisper(uint32 textId, Player* target, bool isBossWhisper /*= false*/ } LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex(); - WorldPacket data; - ChatHandler::BuildChatPacket(data, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, bct->GetText(locale, getGender()), 0, "", locale); - target->SendDirectMessage(&data); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, bct->GetText(locale, getGender()), 0, "", locale); + target->SendDirectMessage(packet.Write()); } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 94bc911c945..120eef7ae51 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -339,7 +339,7 @@ enum HitInfo HITINFO_CRITICALHIT = 0x00000200, // critical hit // 0x00000400 // 0x00000800 - // 0x00001000 + HITINFO_UNK12 = 0x00001000, HITINFO_BLOCK = 0x00002000, // blocked damage // 0x00004000 // Hides worldtext for 0 damage // 0x00008000 // Related to blood visual @@ -2194,7 +2194,7 @@ class Unit : public WorldObject TempSummon const* ToTempSummon() const { if (IsSummon()) return reinterpret_cast<TempSummon const*>(this); else return NULL; } ObjectGuid GetTarget() const { return GetGuidValue(UNIT_FIELD_TARGET); } - virtual void SetTarget(ObjectGuid /*guid*/) = 0; + virtual void SetTarget(ObjectGuid const& /*guid*/) = 0; // Movement info Movement::MoveSpline * movespline; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 71064b3d9fd..a01251af433 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -155,6 +155,16 @@ bool normalizePlayerName(std::string& name) return true; } +// Extracts player and realm names delimited by - +ExtendedPlayerName ExtractExtendedPlayerName(std::string& name) +{ + size_t pos = name.find('-'); + if (pos != std::string::npos) + return ExtendedPlayerName(name.substr(0, pos), name.substr(pos+1)); + else + return ExtendedPlayerName(name, ""); +} + LanguageDesc lang_description[LANGUAGES_COUNT] = { { LANG_ADDON, 0, 0 }, @@ -574,17 +584,17 @@ void ObjectMgr::LoadCreatureTemplateAddons() creatureAddon.auras.resize(tokens.size()); for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) { - SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(uint32(atol(*itr))); + SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(atoul(*itr)); if (!AdditionalSpellInfo) { - TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong spell %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr))); + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong spell %lu defined in `auras` field in `creature_template_addon`.", entry, atoul(*itr)); continue; } if (AdditionalSpellInfo->HasAura(DIFFICULTY_NONE, SPELL_AURA_CONTROL_VEHICLE)) TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr))); - creatureAddon.auras[i++] = uint32(atol(*itr)); + creatureAddon.auras[i++] = atoul(*itr); } if (creatureAddon.mount) @@ -1022,17 +1032,18 @@ void ObjectMgr::LoadCreatureAddons() creatureAddon.auras.resize(tokens.size()); for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) { - SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(uint32(atol(*itr))); + SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(atoul(*itr)); if (!AdditionalSpellInfo) { - TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has wrong spell %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr))); + TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has wrong spell %lu defined in `auras` field in `creature_addon`.", guid, atoul(*itr)); continue; } if (AdditionalSpellInfo->HasAura(DIFFICULTY_NONE, SPELL_AURA_CONTROL_VEHICLE)) - TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr))); + TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has SPELL_AURA_CONTROL_VEHICLE aura %lu defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr))); - creatureAddon.auras[i++] = uint32(atol(*itr)); + + creatureAddon.auras[i++] = atoul(*itr); } if (creatureAddon.mount) @@ -1222,15 +1233,15 @@ CreatureModelInfo const* ObjectMgr::GetCreatureModelRandomGender(uint32* display return NULL; // If a model for another gender exists, 50% chance to use it - if (modelInfo->modelid_other_gender != 0 && urand(0, 1) == 0) + if (modelInfo->displayId_other_gender != 0 && urand(0, 1) == 0) { - CreatureModelInfo const* minfo_tmp = GetCreatureModelInfo(modelInfo->modelid_other_gender); + CreatureModelInfo const* minfo_tmp = GetCreatureModelInfo(modelInfo->displayId_other_gender); if (!minfo_tmp) - TC_LOG_ERROR("sql.sql", "Model (Entry: %u) has modelid_other_gender %u not found in table `creature_model_info`. ", *displayID, modelInfo->modelid_other_gender); + TC_LOG_ERROR("sql.sql", "Model (Entry: %u) has modelid_other_gender %u not found in table `creature_model_info`. ", *displayID, modelInfo->displayId_other_gender); else { - // Model ID changed - *displayID = modelInfo->modelid_other_gender; + // DisplayID changed + *displayID = modelInfo->displayId_other_gender; return minfo_tmp; } } @@ -1242,7 +1253,7 @@ void ObjectMgr::LoadCreatureModelInfo() { uint32 oldMSTime = getMSTime(); - QueryResult result = WorldDatabase.Query("SELECT modelid, bounding_radius, combat_reach, gender, modelid_other_gender FROM creature_model_info"); + QueryResult result = WorldDatabase.Query("SELECT DisplayID, BoundingRadius, CombatReach, DisplayID_Other_Gender FROM creature_model_info"); if (!result) { @@ -1257,30 +1268,36 @@ void ObjectMgr::LoadCreatureModelInfo() { Field* fields = result->Fetch(); - uint32 modelId = fields[0].GetUInt32(); + uint32 displayId = fields[0].GetUInt32(); + + CreatureDisplayInfoEntry const* creatureDisplay = sCreatureDisplayInfoStore.LookupEntry(displayId); + if (!creatureDisplay) + { + TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has a non-existent DisplayID (ID: %u). Skipped.", displayId); + continue; + } - CreatureModelInfo& modelInfo = _creatureModelStore[modelId]; + CreatureModelInfo& modelInfo = _creatureModelStore[displayId]; - modelInfo.bounding_radius = fields[1].GetFloat(); - modelInfo.combat_reach = fields[2].GetFloat(); - modelInfo.gender = fields[3].GetUInt8(); - modelInfo.modelid_other_gender = fields[4].GetUInt32(); + modelInfo.bounding_radius = fields[1].GetFloat(); + modelInfo.combat_reach = fields[2].GetFloat(); + modelInfo.displayId_other_gender = fields[3].GetUInt32(); + modelInfo.gender = creatureDisplay->Gender; // Checks - if (!sCreatureDisplayInfoStore.LookupEntry(modelId)) - TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has model for nonexistent display id (%u).", modelId); - - if (modelInfo.gender > GENDER_NONE) + // to remove when the purpose of GENDER_UNKNOWN is known + if (modelInfo.gender == GENDER_UNKNOWN) { - TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has wrong gender (%u) for display id (%u).", uint32(modelInfo.gender), modelId); + // We don't need more errors + //TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has an unimplemented Gender (ID: %i) being used by DisplayID (ID: %u). Gender set to GENDER_MALE.", modelInfo.gender, modelId); modelInfo.gender = GENDER_MALE; } - if (modelInfo.modelid_other_gender && !sCreatureDisplayInfoStore.LookupEntry(modelInfo.modelid_other_gender)) + if (modelInfo.displayId_other_gender && !sCreatureDisplayInfoStore.LookupEntry(modelInfo.displayId_other_gender)) { - TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has nonexistent alt.gender model (%u) for existed display id (%u).", modelInfo.modelid_other_gender, modelId); - modelInfo.modelid_other_gender = 0; + TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has a non-existent DisplayID_Other_Gender (ID: %u) being used by DisplayID (ID: %u).", modelInfo.displayId_other_gender, displayId); + modelInfo.displayId_other_gender = 0; } if (modelInfo.combat_reach < 0.1f) @@ -2492,7 +2509,9 @@ void ObjectMgr::LoadItemTemplates() itemTemplate.SubClass = db2Data->SubClass; itemTemplate.SoundOverrideSubclass = db2Data->SoundOverrideSubclass; itemTemplate.Name1 = sparse->Name->Str[sWorld->GetDefaultDbcLocale()]; - itemTemplate.DisplayInfoID = GetItemDisplayID(db2Data->AppearanceID); + itemTemplate.DisplayInfoID = GetItemDisplayID(db2Data->FileDataID); + itemTemplate.FileDataID = db2Data->FileDataID; + itemTemplate.GroupSoundsID = db2Data->GroupSoundsID; itemTemplate.Quality = sparse->Quality; memcpy(itemTemplate.Flags, sparse->Flags, sizeof(itemTemplate.Flags)); itemTemplate.Unk1 = sparse->Unk1; @@ -2571,6 +2590,7 @@ void ObjectMgr::LoadItemTemplates() itemTemplate.StatScalingFactor = sparse->StatScalingFactor; itemTemplate.CurrencySubstitutionId = sparse->CurrencySubstitutionID; itemTemplate.CurrencySubstitutionCount = sparse->CurrencySubstitutionCount; + itemTemplate.ItemNameDescriptionID = sparse->ItemNameDescriptionID; itemTemplate.ScriptId = 0; itemTemplate.FoodType = 0; itemTemplate.MinMoneyLoot = 0; @@ -9015,6 +9035,12 @@ void ObjectMgr::LoadMissingKeyChains() uint32 id = fields[0].GetUInt32(); KeyChainEntry* kce = sKeyChainStore.CreateEntry(id, true); + if (!kce) + { + TC_LOG_ERROR("sql.sql", "Could not create KeyChainEntry %u, skipped.", id); + continue; + } + kce->Id = id; for (uint32 i = 0; i < KEYCHAIN_SIZE; ++i) kce->Key[i] = fields[1 + i].GetUInt8(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index bb392caeffb..e7191735ca1 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -677,6 +677,15 @@ SkillRangeType GetSkillRangeType(SkillRaceClassInfoEntry const* rcEntry); bool normalizePlayerName(std::string& name); +struct ExtendedPlayerName +{ + ExtendedPlayerName(std::string const& name, std::string const& realm) : Name(name), Realm(realm) {} + std::string Name; + std::string Realm; +}; + +ExtendedPlayerName ExtractExtendedPlayerName(std::string& name); + struct LanguageDesc { Language lang_id; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index ae3bef5a8df..b693d2e13ac 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -33,6 +33,7 @@ #include "CreatureAI.h" #include "Spell.h" #include "WorldSession.h" +#include "Packets/ChatPackets.h" class Player; //class Map; @@ -125,11 +126,11 @@ namespace Trinity struct MessageDistDeliverer { WorldObject* i_source; - WorldPacket* i_message; + WorldPacket const* i_message; float i_distSq; uint32 team; Player const* skipped_receiver; - MessageDistDeliverer(WorldObject* src, WorldPacket* msg, float dist, bool own_team_only = false, Player const* skipped = NULL) + MessageDistDeliverer(WorldObject* src, WorldPacket const* msg, float dist, bool own_team_only = false, Player const* skipped = NULL) : i_source(src), i_message(msg), i_distSq(dist * dist) , team(0) , skipped_receiver(skipped) diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 894f87f6145..9c4a2a5a2d1 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1623,7 +1623,7 @@ void Group::UpdatePlayerOutOfRange(Player* player) } } -void Group::BroadcastAddonMessagePacket(WorldPacket* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group /*= -1*/, ObjectGuid ignore /*= ObjectGuid::Empty*/) +void Group::BroadcastAddonMessagePacket(WorldPacket const* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group /*= -1*/, ObjectGuid ignore /*= ObjectGuid::Empty*/) { for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) { @@ -1638,7 +1638,7 @@ void Group::BroadcastAddonMessagePacket(WorldPacket* packet, const std::string& } } -void Group::BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int group, ObjectGuid ignoredPlayer) +void Group::BroadcastPacket(WorldPacket const* packet, bool ignorePlayersInBGRaid, int group, ObjectGuid ignoredPlayer) { for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) { @@ -1651,7 +1651,7 @@ void Group::BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int } } -void Group::BroadcastReadyCheck(WorldPacket* packet) +void Group::BroadcastReadyCheck(WorldPacket const* packet) { for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) { diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 0bdfbf24a71..6216b7323b0 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -288,9 +288,9 @@ class Group worker(itr->GetSource()); } - void BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignoredPlayer = ObjectGuid::Empty); - void BroadcastAddonMessagePacket(WorldPacket* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignore = ObjectGuid::Empty); - void BroadcastReadyCheck(WorldPacket* packet); + void BroadcastPacket(WorldPacket const* packet, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignoredPlayer = ObjectGuid::Empty); + void BroadcastAddonMessagePacket(WorldPacket const* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignore = ObjectGuid::Empty); + void BroadcastReadyCheck(WorldPacket const* packet); void OfflineReadyCheck(); /*********************************************************/ diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 4fb361209c1..0b703d4bcb2 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -30,6 +30,7 @@ #include "ScriptMgr.h" #include "SocialMgr.h" #include "Opcodes.h" +#include "ChatPackets.h" #define MAX_GUILD_BANK_TAB_TEXT_LEN 500 #define EMBLEM_PRICE 10 * GOLD @@ -1481,23 +1482,23 @@ void Guild::SendQueryResponse(WorldSession* session) response.GuildGuid = GetGUID(); response.Info.HasValue = true; - response.Info.value.GuildGUID = GetGUID(); - response.Info.value.VirtualRealmAddress = GetVirtualRealmAddress(); + response.Info.Value.GuildGUID = GetGUID(); + response.Info.Value.VirtualRealmAddress = GetVirtualRealmAddress(); - response.Info.value.EmblemStyle = m_emblemInfo.GetStyle(); - response.Info.value.EmblemColor = m_emblemInfo.GetColor(); - response.Info.value.BorderStyle = m_emblemInfo.GetBorderStyle(); - response.Info.value.BorderColor = m_emblemInfo.GetBorderColor(); - response.Info.value.BackgroundColor = m_emblemInfo.GetBackgroundColor(); + response.Info.Value.EmblemStyle = m_emblemInfo.GetStyle(); + response.Info.Value.EmblemColor = m_emblemInfo.GetColor(); + response.Info.Value.BorderStyle = m_emblemInfo.GetBorderStyle(); + response.Info.Value.BorderColor = m_emblemInfo.GetBorderColor(); + response.Info.Value.BackgroundColor = m_emblemInfo.GetBackgroundColor(); for (uint8 i = 0; i < _GetRanksSize(); ++i) { WorldPackets::Guild::QueryGuildInfoResponse::GuildInfo::GuildInfoRank info (m_ranks[i].GetId(), i, m_ranks[i].GetName()); - response.Info.value.Ranks.insert(info); + response.Info.Value.Ranks.insert(info); } - response.Info.value.GuildName = 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()); @@ -2593,13 +2594,14 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::strin { if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) { - WorldPacket data; - ChatHandler::BuildChatPacket(data, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), NULL, msg); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), NULL, msg); + WorldPacket const* data = packet.Write(); for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if (Player* player = itr->second->FindConnectedPlayer()) if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) && !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUID())) - player->GetSession()->SendPacket(&data); + player->GetSession()->SendPacket(data); } } @@ -2607,14 +2609,15 @@ void Guild::BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std:: { if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) { - WorldPacket data; - ChatHandler::BuildChatPacket(data, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, LANG_ADDON, session->GetPlayer(), NULL, msg, 0, "", DEFAULT_LOCALE, prefix); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, LANG_ADDON, session->GetPlayer(), NULL, msg, 0, "", DEFAULT_LOCALE, prefix); + WorldPacket const* data = packet.Write(); for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if (Player* player = itr->second->FindPlayer()) if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) && !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUID()) && player->GetSession()->IsAddonRegistered(prefix)) - player->GetSession()->SendPacket(&data); + player->GetSession()->SendPacket(data); } } diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index d52e218e66d..fcd96ec9370 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -728,7 +728,7 @@ void WorldSession::HandleAuctionListItems(WorldPacket& recvData) TC_LOG_DEBUG("auctionHouse", "Auctionhouse search (%s) list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", guid.ToString().c_str(), listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable); - WorldPacket data(SMSG_AUCTION_LIST_RESULT, (4+4+4)); + WorldPacket data(SMSG_AUCTION_LIST_ITEMS_RESULT, (4+4+4)); uint32 count = 0; uint32 totalcount = 0; data << uint32(0); diff --git a/src/server/game/Handlers/AuthHandler.cpp b/src/server/game/Handlers/AuthHandler.cpp index c9e1e6508b9..d8b8f4fe018 100644 --- a/src/server/game/Handlers/AuthHandler.cpp +++ b/src/server/game/Handlers/AuthHandler.cpp @@ -27,20 +27,20 @@ void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos) response.SuccessInfo.HasValue = code == AUTH_OK; response.Result = code; response.WaitInfo.HasValue = queued; - response.WaitInfo.value.WaitCount = queuePos; + response.WaitInfo.Value.WaitCount = queuePos; if (code == AUTH_OK) { - response.SuccessInfo.value.AccountExpansionLevel = Expansion(); - response.SuccessInfo.value.ActiveExpansionLevel = Expansion(); - response.SuccessInfo.value.VirtualRealmAddress = GetVirtualRealmAddress(); + response.SuccessInfo.Value.AccountExpansionLevel = Expansion(); + response.SuccessInfo.Value.ActiveExpansionLevel = Expansion(); + 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(GetVirtualRealmAddress(), 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(); + response.SuccessInfo.Value.AvailableClasses = &sObjectMgr->GetClassExpansionRequirements(); + response.SuccessInfo.Value.AvailableRaces = &sObjectMgr->GetRaceExpansionRequirements(); } SendPacket(response.Write()); @@ -60,7 +60,7 @@ void WorldSession::SendAuthWaitQue(uint32 position) { response.WaitInfo.HasValue = true; response.SuccessInfo.HasValue = false; - response.WaitInfo.value.WaitCount = position; + response.WaitInfo.Value.WaitCount = position; response.Result = AUTH_WAIT_QUEUE; } diff --git a/src/server/game/Handlers/ChannelHandler.cpp b/src/server/game/Handlers/ChannelHandler.cpp index 5826415a201..c6cd5337c5b 100644 --- a/src/server/game/Handlers/ChannelHandler.cpp +++ b/src/server/game/Handlers/ChannelHandler.cpp @@ -18,31 +18,20 @@ #include "ObjectMgr.h" // for normalizePlayerName #include "ChannelMgr.h" +#include "ChannelPackets.h" #include "Player.h" #include "WorldSession.h" #include <cctype> -void WorldSession::HandleJoinChannel(WorldPacket& recvPacket) +void WorldSession::HandleJoinChannel(WorldPackets::Channel::JoinChannel& packet) { - uint32 channelId; - uint32 channelLength, passLength; - std::string channelName, password; + TC_LOG_DEBUG("chat.system", "CMSG_JOIN_CHANNEL %s ChatChannelId: %u, CreateVoiceSession: %u, Internal: %u, ChannelName: %s, Password: %s", + GetPlayerInfo().c_str(), packet.ChatChannelId, packet.CreateVoiceSession, packet.Internal, packet.ChannelName.c_str(), packet.Password.c_str()); - recvPacket >> channelId; - uint8 unknown1 = recvPacket.ReadBit(); // unknowns - uint8 unknown2 = recvPacket.ReadBit(); - channelLength = recvPacket.ReadBits(8); - passLength = recvPacket.ReadBits(8); - channelName = recvPacket.ReadString(channelLength); - password = recvPacket.ReadString(passLength); - - TC_LOG_DEBUG("chat.system", "CMSG_JOIN_CHANNEL %s Channel: %u, unk1: %u, unk2: %u, channel: %s, password: %s", - GetPlayerInfo().c_str(), channelId, unknown1, unknown2, channelName.c_str(), password.c_str()); - - if (channelId) + if (packet.ChatChannelId) { - ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(channelId); + ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(packet.ChatChannelId); if (!channel) return; @@ -51,53 +40,43 @@ void WorldSession::HandleJoinChannel(WorldPacket& recvPacket) return; } - if (channelName.empty()) + if (packet.ChannelName.empty()) return; - if (isdigit(channelName[0])) + if (isdigit(packet.ChannelName[0])) return; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) { - cMgr->setTeam(GetPlayer()->GetTeam()); - if (Channel* channel = cMgr->GetJoinChannel(channelName, channelId)) - channel->JoinChannel(GetPlayer(), password); + cMgr->SetTeam(GetPlayer()->GetTeam()); + if (Channel* channel = cMgr->GetJoinChannel(packet.ChannelName, packet.ChatChannelId)) + channel->JoinChannel(GetPlayer(), packet.Password); } } -void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket) +void WorldSession::HandleLeaveChannel(WorldPackets::Channel::LeaveChannel& packet) { - uint32 unk; - std::string channelName; - recvPacket >> unk; // channel id? - uint32 length = recvPacket.ReadBits(8); - channelName = recvPacket.ReadString(length); + TC_LOG_DEBUG("chat.system", "CMSG_LEAVE_CHANNEL %s ChannelName: %s, ZoneChannelID: %u", + GetPlayerInfo().c_str(), packet.ChannelName.c_str(), packet.ZoneChannelID); - TC_LOG_DEBUG("chat.system", "CMSG_LEAVE_CHANNEL %s Channel: %s, unk1: %u", - GetPlayerInfo().c_str(), channelName.c_str(), unk); - - if (channelName.empty()) + if (packet.ChannelName.empty()) return; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) { - if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) + if (Channel* channel = cMgr->GetChannel(packet.ChannelName, GetPlayer())) channel->LeaveChannel(GetPlayer(), true); - cMgr->LeftChannel(channelName); + cMgr->LeftChannel(packet.ChannelName); } } -void WorldSession::HandleChannelList(WorldPacket& recvPacket) +void WorldSession::HandleChannelList(WorldPackets::Channel::ChannelListRequest& packet) { - uint32 length = recvPacket.ReadBits(8); - std::string channelName = recvPacket.ReadString(length); - - TC_LOG_DEBUG("chat.system", "%s %s Channel: %s", - recvPacket.GetOpcode() == CMSG_CHANNEL_DISPLAY_LIST ? "CMSG_CHANNEL_DISPLAY_LIST" : "CMSG_CHANNEL_LIST", - GetPlayerInfo().c_str(), channelName.c_str()); + TC_LOG_DEBUG("chat.system", "%s %s ChannelName: %s", + GetOpcodeNameForLogging(packet.GetOpcode()).c_str(), GetPlayerInfo().c_str(), packet.ChannelName.c_str()); - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) - if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) + if (Channel* channel = cMgr->GetChannel(packet.ChannelName, GetPlayer())) channel->List(GetPlayer()); } @@ -115,7 +94,7 @@ void WorldSession::HandleChannelPassword(WorldPacket& recvPacket) if (password.length() > MAX_CHANNEL_PASS_STR) return; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) channel->Password(GetPlayer(), password); } @@ -134,7 +113,7 @@ void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket) if (!normalizePlayerName(targetName)) return; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) channel->SetOwner(GetPlayer(), targetName); } @@ -147,9 +126,9 @@ void WorldSession::HandleChannelOwner(WorldPacket& recvPacket) TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_OWNER %s Channel: %s", GetPlayerInfo().c_str(), channelName.c_str()); - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) - channel->SendWhoOwner(GetPlayer()->GetGUID()); + channel->SendWhoOwner(GetPlayer()); } void WorldSession::HandleChannelModerator(WorldPacket& recvPacket) @@ -166,7 +145,7 @@ void WorldSession::HandleChannelModerator(WorldPacket& recvPacket) if (!normalizePlayerName(targetName)) return; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) channel->SetModerator(GetPlayer(), targetName); } @@ -185,7 +164,7 @@ void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket) if (!normalizePlayerName(targetName)) return; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) channel->UnsetModerator(GetPlayer(), targetName); } @@ -204,7 +183,7 @@ void WorldSession::HandleChannelMute(WorldPacket& recvPacket) if (!normalizePlayerName(targetName)) return; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) channel->SetMute(GetPlayer(), targetName); } @@ -223,7 +202,7 @@ void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket) if (!normalizePlayerName(targetName)) return; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) channel->UnsetMute(GetPlayer(), targetName); } @@ -242,7 +221,7 @@ void WorldSession::HandleChannelInvite(WorldPacket& recvPacket) if (!normalizePlayerName(targetName)) return; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) channel->Invite(GetPlayer(), targetName); } @@ -261,7 +240,7 @@ void WorldSession::HandleChannelKick(WorldPacket& recvPacket) if (!normalizePlayerName(targetName)) return; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) channel->Kick(GetPlayer(), targetName); } @@ -283,7 +262,7 @@ void WorldSession::HandleChannelBan(WorldPacket& recvPacket) if (!normalizePlayerName(targetName)) return; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) channel->Ban(GetPlayer(), targetName); } @@ -302,7 +281,7 @@ void WorldSession::HandleChannelUnban(WorldPacket& recvPacket) if (!normalizePlayerName(targetName)) return; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) channel->UnBan(GetPlayer(), targetName); } @@ -315,17 +294,11 @@ void WorldSession::HandleChannelAnnouncements(WorldPacket& recvPacket) TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_ANNOUNCEMENTS %s Channel: %s", GetPlayerInfo().c_str(), channelName.c_str()); - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) channel->Announce(GetPlayer()); } -void WorldSession::HandleChannelDisplayListQuery(WorldPacket &recvPacket) -{ - // this should be OK because the 2 function _were_ the same - HandleChannelList(recvPacket); -} - void WorldSession::HandleGetChannelMemberCount(WorldPacket &recvPacket) { std::string channelName; @@ -334,7 +307,7 @@ void WorldSession::HandleGetChannelMemberCount(WorldPacket &recvPacket) TC_LOG_DEBUG("chat.system", "CMSG_GET_CHANNEL_MEMBER_COUNT %s Channel: %s", GetPlayerInfo().c_str(), channelName.c_str()); - if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam())) { if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) { diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index a2e6f4b0340..de7d44bdc69 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -29,6 +29,7 @@ #include "ClientConfigPackets.h" #include "Common.h" #include "DatabaseEnv.h" +#include "EquipmentSetPackets.h" #include "Group.h" #include "Guild.h" #include "GuildFinderMgr.h" @@ -36,6 +37,7 @@ #include "Language.h" #include "LFGMgr.h" #include "Log.h" +#include "MiscPackets.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Opcodes.h" @@ -835,6 +837,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) return; } + SendTutorialsData(); + pCurrChar->GetMotionMaster()->Initialize(); pCurrChar->SendDungeonDifficulty(false); @@ -857,6 +861,16 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) /// Send FeatureSystemStatus { WorldPackets::System::FeatureSystemStatus features; + + /// START OF DUMMY VALUES + features.ComplaintStatus = 2; + features.ScrollOfResurrectionRequestsRemaining = 1; + features.ScrollOfResurrectionMaxRequestsPerDay = 1; + features.CfgRealmID = 2; + features.CfgRealmRecID = 0; + features.VoiceEnabled = true; + /// END OF DUMMY VALUES + features.CharUndeleteEnabled = sWorld->getBoolConfig(CONFIG_FEATURE_SYSTEM_CHARACTER_UNDELETE_ENABLED); features.BpayStoreEnabled = sWorld->getBoolConfig(CONFIG_FEATURE_SYSTEM_BPAY_STORE_ENABLED); @@ -1096,32 +1110,35 @@ void WorldSession::HandleSetFactionCheat(WorldPacket& /*recvData*/) GetPlayer()->GetReputationMgr().SendStates(); } -void WorldSession::HandleTutorialFlag(WorldPacket& recvData) -{ - uint32 data; - recvData >> data; - - uint8 index = uint8(data / 32); - if (index >= MAX_ACCOUNT_TUTORIAL_VALUES) - return; - - uint32 value = (data % 32); - - uint32 flag = GetTutorialInt(index); - flag |= (1 << value); - SetTutorialInt(index, flag); -} - -void WorldSession::HandleTutorialClear(WorldPacket& /*recvData*/) -{ - for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i) - SetTutorialInt(i, 0xFFFFFFFF); -} - -void WorldSession::HandleTutorialReset(WorldPacket& /*recvData*/) +void WorldSession::HandleTutorialFlag(WorldPackets::Misc::TutorialSetFlag& packet) { - for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i) - SetTutorialInt(i, 0x00000000); + switch (packet.Action) + { + case TUTORIAL_ACTION_UPDATE: + { + uint8 index = uint8(packet.TutorialBit >> 5); + if (index >= MAX_ACCOUNT_TUTORIAL_VALUES) + { + TC_LOG_ERROR("network", "CMSG_TUTORIAL_FLAG received bad TutorialBit %u.", packet.TutorialBit); + return; + } + uint32 flag = GetTutorialInt(index); + flag |= (1 << (packet.TutorialBit & 0x1F)); + SetTutorialInt(index, flag); + break; + } + case TUTORIAL_ACTION_CLEAR: + for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i) + SetTutorialInt(i, 0xFFFFFFFF); + break; + case TUTORIAL_ACTION_RESET: + for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i) + SetTutorialInt(i, 0x00000000); + break; + default: + TC_LOG_ERROR("network", "CMSG_TUTORIAL_FLAG received unknown TutorialAction %u.", packet.Action); + return; + } } void WorldSession::HandleSetWatchedFactionOpcode(WorldPacket& recvData) @@ -1525,59 +1542,36 @@ void WorldSession::HandleCharCustomizeCallback(PreparedQueryResult result, World GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), customizeInfo->CharGUID.ToString().c_str(), customizeInfo->CharName.c_str()); } -void WorldSession::HandleEquipmentSetSave(WorldPacket& recvData) +void WorldSession::HandleEquipmentSetSave(WorldPackets::EquipmentSet::SaveEquipmentSet& packet) { TC_LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_SAVE"); - uint64 setGuid; - recvData.ReadPackedUInt64(setGuid); - - uint32 index; - recvData >> index; - if (index >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount + if (packet.Set.SetID >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount return; - std::string name; - recvData >> name; - - std::string iconName; - recvData >> iconName; - - EquipmentSet eqSet; - - eqSet.Guid = setGuid; - eqSet.Name = name; - eqSet.IconName = iconName; - eqSet.state = EQUIPMENT_SET_NEW; - - ObjectGuid ignoredItemGuid; - ignoredItemGuid.SetRawValue(0, 1); - - for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) + for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) { - ObjectGuid itemGuid; - recvData >> itemGuid.ReadAsPacked(); - - // equipment manager sends "1" (as raw GUID) for slots set to "ignore" (don't touch slot at equip set) - if (itemGuid == ignoredItemGuid) + if (!(packet.Set.IgnoreMask & (1 << i))) { - // ignored slots saved as bit mask because we have no free special values for Items[i] - eqSet.IgnoreMask |= 1 << i; - continue; - } - - Item* item = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); + ObjectGuid const& itemGuid = packet.Set.Pieces[i]; - if (!item && !itemGuid.IsEmpty()) // cheating check 1 - return; + Item* item = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (item && item->GetGUID() != itemGuid) // cheating check 2 - return; + /// cheating check 1 (item equipped but sent empty guid) + if (!item && !itemGuid.IsEmpty()) + return; - eqSet.Items[i] = itemGuid.GetCounter(); + /// cheating check 2 (sent guid does not match equipped item) + if (item && item->GetGUID() != itemGuid) + return; + } + else + packet.Set.Pieces[i].Clear(); } - _player->SetEquipmentSet(index, eqSet); + packet.Set.IgnoreMask &= 0x7FFFF; /// clear invalid bits (i > EQUIPMENT_SLOT_END) + + _player->SetEquipmentSet(std::move(packet.Set)); } void WorldSession::HandleEquipmentSetDelete(WorldPacket& recvData) @@ -1799,7 +1793,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res if (factionChangeInfo->SkinID.HasValue) { playerBytes &= ~uint32(0xFF); - playerBytes |= factionChangeInfo->SkinID.value; + playerBytes |= factionChangeInfo->SkinID.Value; } else factionChangeInfo->SkinID.Set(uint8(playerBytes & 0xFF)); @@ -1807,7 +1801,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res if (factionChangeInfo->FaceID.HasValue) { playerBytes &= ~(uint32(0xFF) << 8); - playerBytes |= uint32(factionChangeInfo->FaceID.value) << 8; + playerBytes |= uint32(factionChangeInfo->FaceID.Value) << 8; } else factionChangeInfo->FaceID.Set(uint8((playerBytes2 >> 8) & 0xFF)); @@ -1815,7 +1809,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res if (factionChangeInfo->HairStyleID.HasValue) { playerBytes &= ~(uint32(0xFF) << 16); - playerBytes |= uint32(factionChangeInfo->HairStyleID.value) << 16; + playerBytes |= uint32(factionChangeInfo->HairStyleID.Value) << 16; } else factionChangeInfo->HairStyleID.Set(uint8((playerBytes2 >> 16) & 0xFF)); @@ -1823,7 +1817,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res if (factionChangeInfo->HairColorID.HasValue) { playerBytes &= ~(uint32(0xFF) << 24); - playerBytes |= uint32(factionChangeInfo->HairColorID.value) << 24; + playerBytes |= uint32(factionChangeInfo->HairColorID.Value) << 24; } else factionChangeInfo->HairColorID.Set(uint8((playerBytes2 >> 24) & 0xFF)); @@ -1831,7 +1825,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res if (factionChangeInfo->FacialHairStyleID.HasValue) { playerBytes2 &= ~0xFF; - playerBytes2 |= factionChangeInfo->FacialHairStyleID.value; + playerBytes2 |= factionChangeInfo->FacialHairStyleID.Value; } else factionChangeInfo->FacialHairStyleID.Set(uint8(playerBytes2 & 0xFF)); @@ -2181,7 +2175,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res } for (uint32 index = 0; index < ktcount; ++index) - knownTitles[index] = atol(tokens[index]); + knownTitles[index] = atoul(tokens[index]); for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeTitles.begin(); it != sObjectMgr->FactionChangeTitles.end(); ++it) { @@ -2526,14 +2520,14 @@ void WorldSession::SendCharFactionChange(ResponseCodes result, WorldPackets::Cha if (result == RESPONSE_SUCCESS) { packet.Display.HasValue = true; - packet.Display.value.Name = factionChangeInfo->Name; - packet.Display.value.SexID = factionChangeInfo->SexID; - packet.Display.value.SkinID = factionChangeInfo->SkinID.value; - packet.Display.value.HairColorID = factionChangeInfo->HairColorID.value; - packet.Display.value.HairStyleID = factionChangeInfo->HairStyleID.value; - packet.Display.value.FacialHairStyleID = factionChangeInfo->FacialHairStyleID.value; - packet.Display.value.FaceID = factionChangeInfo->FaceID.value; - packet.Display.value.RaceID = factionChangeInfo->RaceID; + packet.Display.Value.Name = factionChangeInfo->Name; + packet.Display.Value.SexID = factionChangeInfo->SexID; + packet.Display.Value.SkinID = factionChangeInfo->SkinID.Value; + packet.Display.Value.HairColorID = factionChangeInfo->HairColorID.Value; + packet.Display.Value.HairStyleID = factionChangeInfo->HairStyleID.Value; + packet.Display.Value.FacialHairStyleID = factionChangeInfo->FacialHairStyleID.Value; + packet.Display.Value.FaceID = factionChangeInfo->FaceID.Value; + packet.Display.Value.RaceID = factionChangeInfo->RaceID; } SendPacket(packet.Write()); diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index a2fc248bb61..2c0fe333b00 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -39,261 +39,163 @@ #include "Util.h" #include "ScriptMgr.h" #include "AccountMgr.h" +#include "ChatPackets.h" -void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) +void WorldSession::HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage& packet) { - uint32 type = 0; - uint32 lang; + ChatMsg type; - switch (recvData.GetOpcode()) + switch (packet.GetOpcode()) { - /* case CMSG_MESSAGECHAT_SAY: type = CHAT_MSG_SAY; break; case CMSG_MESSAGECHAT_YELL: type = CHAT_MSG_YELL; break; - case CMSG_MESSAGECHAT_CHANNEL: - type = CHAT_MSG_CHANNEL; - break; - case CMSG_MESSAGECHAT_WHISPER: - type = CHAT_MSG_WHISPER; - break; case CMSG_MESSAGECHAT_GUILD: type = CHAT_MSG_GUILD; break; case CMSG_MESSAGECHAT_OFFICER: type = CHAT_MSG_OFFICER; break; - case CMSG_MESSAGECHAT_AFK: - type = CHAT_MSG_AFK; - break; - case CMSG_MESSAGECHAT_DND: - type = CHAT_MSG_DND; - break; - case CMSG_MESSAGECHAT_EMOTE: - type = CHAT_MSG_EMOTE; - break; case CMSG_MESSAGECHAT_PARTY: type = CHAT_MSG_PARTY; break; case CMSG_MESSAGECHAT_RAID: type = CHAT_MSG_RAID; break; - case CMSG_MESSAGECHAT_BATTLEGROUND: - type = CHAT_MSG_BATTLEGROUND; - break; case CMSG_MESSAGECHAT_RAID_WARNING: type = CHAT_MSG_RAID_WARNING; break; - */ default: - TC_LOG_ERROR("network", "HandleMessagechatOpcode : Unknown chat opcode (%u)", recvData.GetOpcode()); - recvData.hexlike(); + TC_LOG_ERROR("network", "HandleMessagechatOpcode : Unknown chat opcode (%u)", packet.GetOpcode()); return; } - if (type >= MAX_CHAT_MSG_TYPE) - { - TC_LOG_ERROR("network", "CHAT: Wrong message type received: %u", type); - recvData.rfinish(); - return; - } + HandleChatMessage(type, packet.Language, packet.Text); +} + +void WorldSession::HandleChatMessageWhisperOpcode(WorldPackets::Chat::ChatMessageWhisper& packet) +{ + HandleChatMessage(CHAT_MSG_WHISPER, packet.Language, packet.Text, packet.Target); +} +void WorldSession::HandleChatMessageChannelOpcode(WorldPackets::Chat::ChatMessageChannel& packet) +{ + HandleChatMessage(CHAT_MSG_CHANNEL, packet.Language, packet.Text, packet.Target); +} + +void WorldSession::HandleChatMessageEmoteOpcode(WorldPackets::Chat::ChatMessageEmote& packet) +{ + HandleChatMessage(CHAT_MSG_EMOTE, LANG_UNIVERSAL, packet.Text); +} + +void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, std::string target /*= ""*/) +{ Player* sender = GetPlayer(); - //TC_LOG_DEBUG("misc", "CHAT: packet received. type %u, lang %u", type, lang); + if (lang == LANG_UNIVERSAL && type != CHAT_MSG_EMOTE) + { + TC_LOG_ERROR("network", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str()); + SendNotification(LANG_UNKNOWN_LANGUAGE); + return; + } - // no language sent with emote packet. - if (type != CHAT_MSG_EMOTE && type != CHAT_MSG_AFK && type != CHAT_MSG_DND) + // prevent talking at unknown language (cheating) + LanguageDesc const* langDesc = GetLanguageDescByID(lang); + if (!langDesc) { - recvData >> lang; + SendNotification(LANG_UNKNOWN_LANGUAGE); + return; + } - if (lang == LANG_UNIVERSAL) + if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id)) + { + // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) + Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE); + bool foundAura = false; + for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i) { - TC_LOG_ERROR("network", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str()); - SendNotification(LANG_UNKNOWN_LANGUAGE); - recvData.rfinish(); - return; + if ((*i)->GetMiscValue() == int32(lang)) + { + foundAura = true; + break; + } } - - // prevent talking at unknown language (cheating) - LanguageDesc const* langDesc = GetLanguageDescByID(lang); - if (!langDesc) + if (!foundAura) { - SendNotification(LANG_UNKNOWN_LANGUAGE); - recvData.rfinish(); + SendNotification(LANG_NOT_LEARNED_LANGUAGE); return; } + } - if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id)) - { - // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) - Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE); - bool foundAura = false; - for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i) - { - if ((*i)->GetMiscValue() == int32(lang)) - { - foundAura = true; - break; - } - } - if (!foundAura) - { - SendNotification(LANG_NOT_LEARNED_LANGUAGE); - recvData.rfinish(); - return; - } - } - - if (lang == LANG_ADDON) + // send in universal language if player in .gm on mode (ignore spell effects) + if (sender->IsGameMaster()) + lang = LANG_UNIVERSAL; + else + { + // send in universal language in two side iteration allowed mode + if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)) + lang = LANG_UNIVERSAL; + else { - // LANG_ADDON is only valid for the following message types switch (type) { case CHAT_MSG_PARTY: case CHAT_MSG_RAID: + case CHAT_MSG_RAID_WARNING: + // allow two side chat at group channel if two side group allowed + if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) + lang = LANG_UNIVERSAL; + break; case CHAT_MSG_GUILD: - case CHAT_MSG_BATTLEGROUND: - case CHAT_MSG_WHISPER: - // check if addon messages are disabled - if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL)) - { - recvData.rfinish(); - return; - } + case CHAT_MSG_OFFICER: + // allow two side chat at guild channel if two side guild allowed + if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) + lang = LANG_UNIVERSAL; break; - default: - TC_LOG_ERROR("network", "Player %s (%s) sent a chatmessage with an invalid language/message type combination", - GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str()); - - recvData.rfinish(); - return; } } - // LANG_ADDON should not be changed nor be affected by flood control - else - { - // send in universal language if player in .gm on mode (ignore spell effects) - if (sender->IsGameMaster()) - lang = LANG_UNIVERSAL; - else - { - // send in universal language in two side iteration allowed mode - if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)) - lang = LANG_UNIVERSAL; - else - { - switch (type) - { - case CHAT_MSG_PARTY: - case CHAT_MSG_PARTY_LEADER: - case CHAT_MSG_RAID: - case CHAT_MSG_RAID_LEADER: - case CHAT_MSG_RAID_WARNING: - // allow two side chat at group channel if two side group allowed - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - lang = LANG_UNIVERSAL; - break; - case CHAT_MSG_GUILD: - case CHAT_MSG_OFFICER: - // allow two side chat at guild channel if two side guild allowed - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) - lang = LANG_UNIVERSAL; - break; - } - } - - // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used) - Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE); - if (!ModLangAuras.empty()) - lang = ModLangAuras.front()->GetMiscValue(); - } - if (!sender->CanSpeak()) - { - std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); - SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); - recvData.rfinish(); // Prevent warnings - return; - } - } + // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used) + Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE); + if (!ModLangAuras.empty()) + lang = ModLangAuras.front()->GetMiscValue(); } - else - lang = LANG_UNIVERSAL; - if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER) + if (!sender->CanSpeak()) { - SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str()); - recvData.rfinish(); + std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); + SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); return; } - uint32 textLength = 0; - uint32 receiverLength = 0; - std::string to, channel, msg; - bool ignoreChecks = false; - switch (type) + if (sender->HasAura(GM_SILENCE_AURA) && type != CHAT_MSG_WHISPER) { - case CHAT_MSG_SAY: - case CHAT_MSG_EMOTE: - case CHAT_MSG_YELL: - case CHAT_MSG_PARTY: - case CHAT_MSG_GUILD: - case CHAT_MSG_OFFICER: - case CHAT_MSG_RAID: - case CHAT_MSG_RAID_WARNING: - case CHAT_MSG_BATTLEGROUND: - textLength = recvData.ReadBits(9); - msg = recvData.ReadString(textLength); - break; - case CHAT_MSG_WHISPER: - receiverLength = recvData.ReadBits(10); - textLength = recvData.ReadBits(9); - to = recvData.ReadString(receiverLength); - msg = recvData.ReadString(textLength); - break; - case CHAT_MSG_CHANNEL: - receiverLength = recvData.ReadBits(10); - textLength = recvData.ReadBits(9); - msg = recvData.ReadString(textLength); - channel = recvData.ReadString(receiverLength); - break; - case CHAT_MSG_AFK: - case CHAT_MSG_DND: - textLength = recvData.ReadBits(9); - msg = recvData.ReadString(textLength); - ignoreChecks = true; - break; + SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str()); + return; } - if (!ignoreChecks) - { - if (msg.empty()) - return; + if (msg.empty()) + return; - if (ChatHandler(this).ParseCommands(msg.c_str())) - return; + if (ChatHandler(this).ParseCommands(msg.c_str())) + return; - if (lang != LANG_ADDON) - { - // Strip invisible characters for non-addon messages - if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) - stripLineInvisibleChars(msg); + // Strip invisible characters for non-addon messages + if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); - if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str())) - { - TC_LOG_ERROR("network", "Player %s (%s) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(), - GetPlayer()->GetGUID().ToString().c_str(), msg.c_str()); + if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str())) + { + TC_LOG_ERROR("network", "Player %s (%s) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(), + GetPlayer()->GetGUID().ToString().c_str(), msg.c_str()); - if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK)) - KickPlayer(); + if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK)) + KickPlayer(); - return; - } - } + return; } switch (type) @@ -322,16 +224,19 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } case CHAT_MSG_WHISPER: { - if (!normalizePlayerName(to)) + /// @todo implement cross realm whispers (someday) + ExtendedPlayerName extName = ExtractExtendedPlayerName(target); + + if (!normalizePlayerName(extName.Name)) { - SendPlayerNotFoundNotice(to); + SendPlayerNotFoundNotice(target); break; } - Player* receiver = ObjectAccessor::FindConnectedPlayerByName(to); + Player* receiver = ObjectAccessor::FindConnectedPlayerByName(extName.Name); if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) { - SendPlayerNotFoundNotice(to); + SendPlayerNotFoundNotice(target); return; } if (!sender->IsGameMaster() && sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) && !receiver->IsInWhisperWhiteList(sender->GetGUID())) @@ -362,7 +267,6 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) break; } case CHAT_MSG_PARTY: - case CHAT_MSG_PARTY_LEADER: { // if player is in battleground, he cannot say to battleground members by /p Group* group = GetPlayer()->GetOriginalGroup(); @@ -378,9 +282,9 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); - WorldPacket data; - ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg); - group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID())); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, ChatMsg(type), Language(lang), sender, NULL, msg); + group->BroadcastPacket(packet.Write(), false, group->GetMemberGroup(GetPlayer()->GetGUID())); break; } case CHAT_MSG_GUILD: @@ -410,25 +314,19 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) break; } case CHAT_MSG_RAID: - case CHAT_MSG_RAID_LEADER: { - // if player is in battleground, he cannot say to battleground members by /ra Group* group = GetPlayer()->GetOriginalGroup(); if (!group) - { - group = GetPlayer()->GetGroup(); - if (!group || group->isBGGroup() || !group->isRaidGroup()) - return; - } + return; if (group->IsLeader(GetPlayer()->GetGUID())) type = CHAT_MSG_RAID_LEADER; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); - WorldPacket data; - ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg); - group->BroadcastPacket(&data, false); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, ChatMsg(type), Language(lang), sender, NULL, msg); + group->BroadcastPacket(packet.Write(), false); break; } case CHAT_MSG_RAID_WARNING: @@ -439,28 +337,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); - WorldPacket data; + WorldPackets::Chat::Chat packet; //in battleground, raid warning is sent only to players in battleground - code is ok - ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); - group->BroadcastPacket(&data, false); - break; - } - case CHAT_MSG_BATTLEGROUND: - case CHAT_MSG_BATTLEGROUND_LEADER: - { - // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() - Group* group = GetPlayer()->GetGroup(); - if (!group || !group->isBGGroup()) - return; - - if (group->IsLeader(GetPlayer()->GetGUID())) - type = CHAT_MSG_BATTLEGROUND_LEADER; - - sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); - - WorldPacket data; - ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg); - group->BroadcastPacket(&data, false); + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); + group->BroadcastPacket(packet.Write(), false); break; } case CHAT_MSG_CHANNEL: @@ -474,9 +354,9 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } } - if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(sender->GetTeam())) { - if (Channel* chn = cMgr->GetChannel(channel, sender)) + if (Channel* chn = cMgr->GetChannel(target, sender)) { sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn); chn->Say(sender->GetGUID(), msg.c_str(), lang); @@ -484,70 +364,18 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } break; } - case CHAT_MSG_AFK: - { - if (!sender->IsInCombat()) - { - if (sender ->isAFK()) // Already AFK - { - if (msg.empty()) - sender->ToggleAFK(); // Remove AFK - else - sender->autoReplyMsg = msg; // Update message - } - else // New AFK mode - { - sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : msg; - - if (sender->isDND()) - sender->ToggleDND(); - - sender->ToggleAFK(); - } - - sScriptMgr->OnPlayerChat(sender, type, lang, msg); - } - break; - } - case CHAT_MSG_DND: - { - if (sender->isDND()) // Already DND - { - if (msg.empty()) - sender->ToggleDND(); // Remove DND - else - sender->autoReplyMsg = msg; // Update message - } - else // New DND mode - { - sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : msg; - - if (sender->isAFK()) - sender->ToggleAFK(); - - sender->ToggleDND(); - } - - sScriptMgr->OnPlayerChat(sender, type, lang, msg); - break; - } default: TC_LOG_ERROR("network", "CHAT: unknown message type %u, lang: %u", type, lang); break; } } -void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData) +void WorldSession::HandleChatAddonMessageOpcode(WorldPackets::Chat::ChatAddonMessage& packet) { - Player* sender = GetPlayer(); ChatMsg type; - switch (recvData.GetOpcode()) + switch (packet.GetOpcode()) { - /* - case CMSG_MESSAGECHAT_ADDON_BATTLEGROUND: - type = CHAT_MSG_BATTLEGROUND; - break; case CMSG_MESSAGECHAT_ADDON_GUILD: type = CHAT_MSG_GUILD; break; @@ -560,95 +388,50 @@ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData) case CMSG_MESSAGECHAT_ADDON_RAID: type = CHAT_MSG_RAID; break; - case CMSG_MESSAGECHAT_ADDON_WHISPER: - type = CHAT_MSG_WHISPER; - break; - */ default: - TC_LOG_ERROR("network", "HandleAddonMessagechatOpcode: Unknown addon chat opcode (%u)", recvData.GetOpcode()); - recvData.hexlike(); + TC_LOG_ERROR("network", "HandleChatAddonMessageOpcode: Unknown addon chat opcode (%u)", packet.GetOpcode()); return; } - std::string message; - std::string prefix; - std::string targetName; + HandleChatAddonMessage(type, packet.Prefix, packet.Text); +} - switch (type) - { - case CHAT_MSG_WHISPER: - { - uint32 msgLen = recvData.ReadBits(9); - uint32 prefixLen = recvData.ReadBits(5); - uint32 targetLen = recvData.ReadBits(10); - message = recvData.ReadString(msgLen); - prefix = recvData.ReadString(prefixLen); - targetName = recvData.ReadString(targetLen); - break; - } - case CHAT_MSG_PARTY: - case CHAT_MSG_RAID: - case CHAT_MSG_OFFICER: - { - uint32 prefixLen = recvData.ReadBits(5); - uint32 msgLen = recvData.ReadBits(9); - prefix = recvData.ReadString(prefixLen); - message = recvData.ReadString(msgLen); - break; - } - case CHAT_MSG_GUILD: - case CHAT_MSG_BATTLEGROUND: - { - uint32 msgLen = recvData.ReadBits(9); - uint32 prefixLen = recvData.ReadBits(5); - message = recvData.ReadString(msgLen); - prefix = recvData.ReadString(prefixLen); - break; - } - default: - break; - } +void WorldSession::HandleChatAddonMessageWhisperOpcode(WorldPackets::Chat::ChatAddonMessageWhisper& packet) +{ + HandleChatAddonMessage(CHAT_MSG_WHISPER, packet.Prefix, packet.Text, packet.Target); +} + +void WorldSession::HandleChatAddonMessage(ChatMsg type, std::string prefix, std::string text, std::string target /*= ""*/) +{ + Player* sender = GetPlayer(); if (prefix.empty() || prefix.length() > 16) return; // Disabled addon channel? if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL)) - { - recvData.rfinish(); return; - } switch (type) { - case CHAT_MSG_BATTLEGROUND: - { - Group* group = sender->GetGroup(); - if (!group || !group->isBGGroup()) - return; - - WorldPacket data; - ChatHandler::BuildChatPacket(data, type, LANG_ADDON, sender, NULL, message, 0U, "", DEFAULT_LOCALE, prefix); - group->BroadcastAddonMessagePacket(&data, prefix, false); - break; - } case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: { if (sender->GetGuildId()) if (Guild* guild = sGuildMgr->GetGuildById(sender->GetGuildId())) - guild->BroadcastAddonToGuild(this, type == CHAT_MSG_OFFICER, message, prefix); + guild->BroadcastAddonToGuild(this, type == CHAT_MSG_OFFICER, text, prefix); break; } case CHAT_MSG_WHISPER: { - if (!normalizePlayerName(targetName)) + if (!normalizePlayerName(target)) break; - Player* receiver = sObjectAccessor->FindPlayerByName(targetName); + + Player* receiver = sObjectAccessor->FindPlayerByName(target); if (!receiver) break; - sender->WhisperAddon(message, prefix, receiver); + sender->WhisperAddon(text, prefix, receiver); break; } // Messages sent to "RAID" while in a party will get delivered to "PARTY" @@ -657,12 +440,12 @@ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData) { Group* group = sender->GetGroup(); - if (!group || group->isBGGroup()) + if (!group) break; - WorldPacket data; - ChatHandler::BuildChatPacket(data, type, LANG_ADDON, sender, NULL, message, 0U, "", DEFAULT_LOCALE, prefix); - group->BroadcastAddonMessagePacket(&data, prefix, true, -1, sender->GetGUID()); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, type, LANG_ADDON, sender, NULL, text, 0U, "", DEFAULT_LOCALE, prefix); + group->BroadcastAddonMessagePacket(packet.Write(), prefix, true, -1, sender->GetGUID()); break; } default: @@ -673,6 +456,72 @@ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData) } } +void WorldSession::HandleChatMessageAFKOpcode(WorldPackets::Chat::ChatMessageAFK& packet) +{ + Player* sender = GetPlayer(); + + if (sender->IsInCombat()) + return; + + if (sender->HasAura(GM_SILENCE_AURA)) + { + SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str()); + return; + } + + if (sender->isAFK()) // Already AFK + { + if (packet.Text.empty()) + sender->ToggleAFK(); // Remove AFK + else + sender->autoReplyMsg = packet.Text; // Update message + } + else // New AFK mode + { + sender->autoReplyMsg = packet.Text.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : packet.Text; + + if (sender->isDND()) + sender->ToggleDND(); + + sender->ToggleAFK(); + } + + sScriptMgr->OnPlayerChat(sender, CHAT_MSG_AFK, LANG_UNIVERSAL, packet.Text); +} + +void WorldSession::HandleChatMessageDNDOpcode(WorldPackets::Chat::ChatMessageDND& packet) +{ + Player* sender = GetPlayer(); + + if (sender->IsInCombat()) + return; + + if (sender->HasAura(GM_SILENCE_AURA)) + { + SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str()); + return; + } + + if (sender->isDND()) // Already DND + { + if (packet.Text.empty()) + sender->ToggleDND(); // Remove DND + else + sender->autoReplyMsg = packet.Text; // Update message + } + else // New DND mode + { + sender->autoReplyMsg = packet.Text.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : packet.Text; + + if (sender->isAFK()) + sender->ToggleAFK(); + + sender->ToggleDND(); + } + + sScriptMgr->OnPlayerChat(sender, CHAT_MSG_DND, LANG_UNIVERSAL, packet.Text); +} + void WorldSession::HandleEmoteOpcode(WorldPacket& recvData) { if (!GetPlayer()->IsAlive() || GetPlayer()->HasUnitState(UNIT_STATE_DIED)) @@ -689,55 +538,46 @@ namespace Trinity class EmoteChatBuilder { public: - EmoteChatBuilder(Player const& player, uint32 text_emote, uint32 emote_num, Unit const* target) - : i_player(player), i_text_emote(text_emote), i_emote_num(emote_num), i_target(target) { } + EmoteChatBuilder(Player const& player, uint32 soundIndex, uint32 emoteID, Unit const* target) + : _player(player), _soundIndex(soundIndex), _emoteID(emoteID), _target(target) { } void operator()(WorldPacket& data, LocaleConstant loc_idx) { - std::string const name(i_target ? i_target->GetNameForLocaleIdx(loc_idx) : ""); - uint32 namlen = name.size(); - - data.Initialize(SMSG_TEXT_EMOTE, 20 + namlen); - data << i_player.GetGUID(); - data << uint32(i_text_emote); - data << uint32(i_emote_num); - data << uint32(namlen); - if (namlen > 1) - data << name; - else - data << uint8(0x00); + WorldPackets::Chat::STextEmote packet; + packet.SourceGUID = _player.GetGUID(); + packet.SourceAccountGUID = _player.GetSession()->GetAccountGUID(); + if (_target) + packet.TargetGUID = _target->GetGUID(); + packet.EmoteID = _emoteID; + packet.SoundIndex = _soundIndex; + data = *packet.Write(); } private: - Player const& i_player; - uint32 i_text_emote; - uint32 i_emote_num; - Unit const* i_target; + Player const& _player; + uint32 _soundIndex; + uint32 _emoteID; + Unit const* _target; }; -} // namespace Trinity +} -void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData) +void WorldSession::HandleTextEmoteOpcode(WorldPackets::Chat::CTextEmote& packet) { - if (!GetPlayer()->IsAlive()) + Player* player = GetPlayer(); + + if (!player->IsAlive()) return; - if (!GetPlayer()->CanSpeak()) + if (!player->CanSpeak()) { std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); return; } - uint32 text_emote, emoteNum; - ObjectGuid guid; - - recvData >> text_emote; - recvData >> emoteNum; - recvData >> guid; - - sScriptMgr->OnPlayerTextEmote(GetPlayer(), text_emote, emoteNum, guid); + sScriptMgr->OnPlayerTextEmote(player, packet.SoundIndex, packet.EmoteID, packet.Target); - EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(text_emote); + EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(packet.EmoteID); if (!em) return; @@ -752,34 +592,34 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData) break; case EMOTE_STATE_DANCE: case EMOTE_STATE_READ: - GetPlayer()->SetUInt32Value(UNIT_NPC_EMOTESTATE, emote_anim); + player->SetUInt32Value(UNIT_NPC_EMOTESTATE, emote_anim); break; default: // Only allow text-emotes for "dead" entities (feign death included) - if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) + if (player->HasUnitState(UNIT_STATE_DIED)) break; - GetPlayer()->HandleEmoteCommand(emote_anim); + player->HandleEmoteCommand(emote_anim); break; } - Unit* unit = ObjectAccessor::GetUnit(*_player, guid); + Unit* unit = ObjectAccessor::GetUnit(*_player, packet.Target); - CellCoord p = Trinity::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()); + CellCoord p = Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY()); Cell cell(p); cell.SetNoCreate(); - Trinity::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit); + Trinity::EmoteChatBuilder emote_builder(*player, packet.SoundIndex, packet.EmoteID, unit); Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > emote_do(emote_builder); - Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > > emote_worker(GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), emote_do); + Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > > emote_worker(player, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), emote_do); TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder> >, WorldTypeMapContainer> message(emote_worker); - cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)); + cell.Visit(p, message, *player->GetMap(), *player, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)); - GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, 0, unit); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, packet.SoundIndex, 0, 0, unit); //Send scripted event call if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI()) - ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote); + ((Creature*)unit)->AI()->ReceiveEmote(player, packet.SoundIndex); } void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData) @@ -811,9 +651,9 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData) if (!player || !player->GetSession()) return; - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_IGNORED, LANG_UNIVERSAL, _player, _player, GetPlayer()->GetName()); - player->GetSession()->SendPacket(&data); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_IGNORED, LANG_UNIVERSAL, _player, _player, GetPlayer()->GetName()); + player->SendDirectMessage(packet.Write()); } void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket) diff --git a/src/server/game/Handlers/CombatHandler.cpp b/src/server/game/Handlers/CombatHandler.cpp index 99aae6f5d0d..deac92d1b0b 100644 --- a/src/server/game/Handlers/CombatHandler.cpp +++ b/src/server/game/Handlers/CombatHandler.cpp @@ -27,15 +27,13 @@ #include "VehicleDefines.h" #include "Player.h" #include "Opcodes.h" +#include "CombatPackets.h" -void WorldSession::HandleAttackSwingOpcode(WorldPacket& recvData) +void WorldSession::HandleAttackSwingOpcode(WorldPackets::Combat::AttackSwing& packet) { - ObjectGuid guid; - recvData >> guid; + TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_ATTACKSWING Message %s", packet.Victim.ToString().c_str()); - TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_ATTACKSWING Message %s", guid.ToString().c_str()); - - Unit* pEnemy = ObjectAccessor::GetUnit(*_player, guid); + Unit* pEnemy = ObjectAccessor::GetUnit(*_player, packet.Victim); if (!pEnemy) { @@ -68,7 +66,7 @@ void WorldSession::HandleAttackSwingOpcode(WorldPacket& recvData) _player->Attack(pEnemy, true); } -void WorldSession::HandleAttackStopOpcode(WorldPacket & /*recvData*/) +void WorldSession::HandleAttackStopOpcode(WorldPackets::Combat::AttackStop& /*recvData*/) { GetPlayer()->AttackStop(); } diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 95bcecbfdeb..54fb865c017 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -28,6 +28,8 @@ #include "ObjectAccessor.h" #include "SpellInfo.h" #include "DB2Stores.h" +#include "NPCPackets.h" +#include "ItemPackets.h" #include <vector> void WorldSession::HandleSplitItemOpcode(WorldPacket& recvData) @@ -560,18 +562,14 @@ void WorldSession::HandleBuyItemOpcode(WorldPacket& recvData) TC_LOG_DEBUG("network", "WORLD: received wrong itemType (%u) in HandleBuyItemOpcode", itemType); } -void WorldSession::HandleListInventoryOpcode(WorldPacket& recvData) +void WorldSession::HandleListInventoryOpcode(WorldPackets::NPC::Hello& packet) { - ObjectGuid guid; - - recvData >> guid; + TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_LIST_INVENTORY"); if (!GetPlayer()->IsAlive()) return; - TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_LIST_INVENTORY"); - - SendListInventory(guid); + SendListInventory(packet.Unit); } void WorldSession::SendListInventory(ObjectGuid vendorGuid) @@ -597,12 +595,10 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid) VendorItemData const* vendorItems = vendor->GetVendorItems(); uint32 rawItemCount = vendorItems ? vendorItems->GetItemCount() : 0; - //if (rawItemCount > 300), - // rawItemCount = 300; // client cap but uint8 max value is 255 + WorldPackets::NPC::VendorInventory packet; + packet.Vendor = vendor->GetGUID(); - ByteBuffer itemsData(32 * rawItemCount); - std::vector<bool> enablers; - enablers.reserve(2 * rawItemCount); + packet.Items.resize(rawItemCount); const float discountMod = _player->GetReputationPriceDiscount(vendor); uint8 count = 0; @@ -612,13 +608,15 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid) if (!vendorItem) continue; + WorldPackets::NPC::VendorItem& item = packet.Items[count]; + if (vendorItem->Type == ITEM_VENDOR_TYPE_ITEM) { ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(vendorItem->item); if (!itemTemplate) continue; - uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem); + int32 leftInStock = !vendorItem->maxcount ? -1 : vendor->GetVendorItemCurrentCount(vendorItem); if (!_player->IsGameMaster()) // ignore conditions if GM on { // Respect allowed class @@ -647,29 +645,15 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid) if (int32 priceMod = _player->GetTotalAuraModifier(SPELL_AURA_MOD_VENDOR_ITEMS_PRICES)) price -= CalculatePct(price, priceMod); - itemsData << uint32(slot + 1); // client expects counting to start at 1 - itemsData << uint32(itemTemplate->MaxDurability); + item.MuID = slot + 1; // client expects counting to start at 1 + item.Durability = itemTemplate->MaxDurability; + item.ExtendedCostID = vendorItem->ExtendedCost; + item.Type = vendorItem->Type; + item.Quantity = leftInStock; + item.StackCount = itemTemplate->BuyCount; + item.Price = price; - if (vendorItem->ExtendedCost) - { - enablers.push_back(0); - itemsData << uint32(vendorItem->ExtendedCost); - } - else - enablers.push_back(1); - - enablers.push_back(1); // item is unlocked - - itemsData << uint32(vendorItem->item); - itemsData << uint32(vendorItem->Type); // 1 is items, 2 is currency - itemsData << uint32(price); - itemsData << uint32(itemTemplate->DisplayInfoID); - // if (!unk "enabler") data << uint32(something); - itemsData << int32(leftInStock); - itemsData << uint32(itemTemplate->BuyCount); - - if (++count >= MAX_VENDOR_ITEMS) - break; + item.Item.ItemID = vendorItem->item; } else if (vendorItem->Type == ITEM_VENDOR_TYPE_CURRENCY) { @@ -680,70 +664,23 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid) if (!vendorItem->ExtendedCost) continue; // there's no price defined for currencies, only extendedcost is used - itemsData << uint32(slot + 1); // client expects counting to start at 1 - itemsData << uint32(0); // max durability - - enablers.push_back(0); - itemsData << uint32(vendorItem->ExtendedCost); - - enablers.push_back(1); // item is unlocked - - itemsData << uint32(vendorItem->item); - itemsData << uint32(vendorItem->Type); // 1 is items, 2 is currency - itemsData << uint32(0); // price, only seen currency types that have Extended cost - itemsData << uint32(0); // displayId - // if (!unk "enabler") data << uint32(something); - itemsData << int32(-1); - itemsData << uint32(vendorItem->maxcount); - - if (++count >= MAX_VENDOR_ITEMS) - break; + item.MuID = slot + 1; // client expects counting to start at 1 + item.ExtendedCostID = vendorItem->ExtendedCost; + item.Item.ItemID = vendorItem->item; + item.Type = vendorItem->Type; + item.StackCount = vendorItem->maxcount; } - // else error - } - - ObjectGuid guid = vendorGuid; - - WorldPacket data(SMSG_LIST_INVENTORY, 12 + itemsData.size()); - - data.WriteBit(guid[1]); - data.WriteBit(guid[0]); - - data.WriteBits(count, 21); // item count - - data.WriteBit(guid[3]); - data.WriteBit(guid[6]); - data.WriteBit(guid[5]); - data.WriteBit(guid[2]); - data.WriteBit(guid[7]); - - for (std::vector<bool>::const_iterator itr = enablers.begin(); itr != enablers.end(); ++itr) - data.WriteBit(*itr); - - data.WriteBit(guid[4]); + else + continue; - data.FlushBits(); - data.append(itemsData); - - data.WriteByteSeq(guid[5]); - data.WriteByteSeq(guid[4]); - data.WriteByteSeq(guid[1]); - data.WriteByteSeq(guid[0]); - data.WriteByteSeq(guid[6]); - - // It doesn't matter what value is used here (PROBABLY its full vendor size) - // What matters is that if count of items we can see is 0 and this field is 1 - // then client will open the vendor list, otherwise it won't - if (rawItemCount) - data << uint8(rawItemCount); - else - data << uint8(vendor->IsArmorer()); + if (++count >= MAX_VENDOR_ITEMS) + break; + } - data.WriteByteSeq(guid[2]); - data.WriteByteSeq(guid[3]); - data.WriteByteSeq(guid[7]); + // Resize vector to real size (some items can be skipped due to checks) + packet.Items.resize(count); - SendPacket(&data); + SendPacket(packet.Write()); } void WorldSession::HandleAutoStoreBagItemOpcode(WorldPacket& recvData) diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index ab906fa956f..3a48c29ce03 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -57,6 +57,7 @@ #include "BattlefieldMgr.h" #include "DB2Stores.h" #include "CharacterPackets.h" +#include "ClientConfigPackets.h" #include "MiscPackets.h" void WorldSession::HandleRepopRequestOpcode(WorldPacket& recvData) @@ -537,12 +538,9 @@ void WorldSession::HandleRequestCemeteryList(WorldPacket& /*recvPacket*/) SendPacket(&data); } -void WorldSession::HandleSetSelectionOpcode(WorldPacket& recvData) +void WorldSession::HandleSetSelectionOpcode(WorldPackets::Misc::SetSelection& packet) { - ObjectGuid guid; - recvData >> guid; - - _player->SetSelection(guid); + _player->SetSelection(packet.Selection); } void WorldSession::HandleStandStateChangeOpcode(WorldPacket& recvData) @@ -967,97 +965,70 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData) player->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, at->target_Orientation, TELE_TO_NOT_LEAVE_TRANSPORT); } -void WorldSession::HandleUpdateAccountData(WorldPacket& recvData) +void WorldSession::HandleUpdateAccountData(WorldPackets::ClientConfig::UserClientUpdateAccountData& packet) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_UPDATE_ACCOUNT_DATA"); - - uint32 type, timestamp, decompressedSize; - recvData >> type >> timestamp >> decompressedSize; - - TC_LOG_DEBUG("network", "UAD: type %u, time %u, decompressedSize %u", type, timestamp, decompressedSize); + TC_LOG_DEBUG("network", "WORLD: Received CMSG_UPDATE_ACCOUNT_DATA: type %u, time %u, decompressedSize %u", + packet.DataType, packet.Time, packet.Size); - if (type > NUM_ACCOUNT_DATA_TYPES) + if (packet.DataType > NUM_ACCOUNT_DATA_TYPES) return; - if (decompressedSize == 0) // erase + if (packet.Size == 0) // erase { - SetAccountData(AccountDataType(type), 0, ""); - - WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4); - data << uint32(type); - data << uint32(0); - SendPacket(&data); - + SetAccountData(AccountDataType(packet.DataType), 0, ""); return; } - if (decompressedSize > 0xFFFF) + if (packet.Size > 0xFFFF) { - recvData.rfinish(); // unnneded warning spam in this case - TC_LOG_ERROR("network", "UAD: Account data packet too big, size %u", decompressedSize); + TC_LOG_ERROR("network", "UAD: Account data packet too big, size %u", packet.Size); return; } ByteBuffer dest; - dest.resize(decompressedSize); + dest.resize(packet.Size); - uLongf realSize = decompressedSize; - if (uncompress(dest.contents(), &realSize, recvData.contents() + recvData.rpos(), recvData.size() - recvData.rpos()) != Z_OK) + uLongf realSize = packet.Size; + if (uncompress(dest.contents(), &realSize, packet.CompressedData.contents(), packet.CompressedData.size()) != Z_OK) { - recvData.rfinish(); // unnneded warning spam in this case TC_LOG_ERROR("network", "UAD: Failed to decompress account data"); return; } - recvData.rfinish(); // uncompress read (recvData.size() - recvData.rpos()) - std::string adata; dest >> adata; - SetAccountData(AccountDataType(type), timestamp, adata); - - WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4); - data << uint32(type); - data << uint32(0); - SendPacket(&data); + SetAccountData(AccountDataType(packet.DataType), packet.Time, adata); } -void WorldSession::HandleRequestAccountData(WorldPacket& recvData) +void WorldSession::HandleRequestAccountData(WorldPackets::ClientConfig::RequestAccountData& request) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_ACCOUNT_DATA"); + TC_LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_ACCOUNT_DATA: type %u", request.DataType); - uint32 type; - recvData >> type; - - TC_LOG_DEBUG("network", "RAD: type %u", type); - - if (type >= NUM_ACCOUNT_DATA_TYPES) + if (request.DataType >= NUM_ACCOUNT_DATA_TYPES) return; - AccountData* adata = GetAccountData(AccountDataType(type)); + AccountData const* adata = GetAccountData(AccountDataType(request.DataType)); - uint32 size = adata->Data.size(); + WorldPackets::ClientConfig::UpdateAccountData data; + data.Player = _player ? _player->GetGUID() : ObjectGuid::Empty; + data.Time = adata->Time; + data.Size = adata->Data.size(); + data.DataType = request.DataType; - uLongf destSize = compressBound(size); + uLongf destSize = compressBound(data.Size); - ByteBuffer dest; - dest.resize(destSize); + data.CompressedData.resize(destSize); - if (size && compress(dest.contents(), &destSize, (uint8 const*)adata->Data.c_str(), size) != Z_OK) + if (data.Size && compress(data.CompressedData.contents(), &destSize, (uint8 const*)adata->Data.c_str(), data.Size) != Z_OK) { - TC_LOG_DEBUG("network", "RAD: Failed to compress account data"); + TC_LOG_ERROR("network", "RAD: Failed to compress account data"); return; } - dest.resize(destSize); + data.CompressedData.resize(destSize); - WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA, 8+4+4+4+destSize); - data << (_player ? _player->GetGUID() : ObjectGuid::Empty); - data << uint32(type); // type (0-7) - data << uint32(adata->Time); // unix time - data << uint32(size); // decompressed length - data.append(dest); // compressed data - SendPacket(&data); + SendPacket(data.Write()); } int32 WorldSession::HandleEnableNagleAlgorithm() @@ -1522,24 +1493,21 @@ void WorldSession::HandleSetTitleOpcode(WorldPacket& recvData) GetPlayer()->SetUInt32Value(PLAYER_CHOSEN_TITLE, title); } -void WorldSession::HandleTimeSyncResp(WorldPacket& recvData) +void WorldSession::HandleTimeSyncResp(WorldPackets::Misc::TimeSyncResponse& packet) { TC_LOG_DEBUG("network", "CMSG_TIME_SYNC_RESP"); - uint32 counter, clientTicks; - recvData >> counter >> clientTicks; - - if (counter != _player->m_timeSyncQueue.front()) + if (packet.SequenceIndex != _player->m_timeSyncQueue.front()) TC_LOG_ERROR("network", "Wrong time sync counter from player %s (cheater?)", _player->GetName().c_str()); - TC_LOG_DEBUG("network", "Time sync received: counter %u, client ticks %u, time since last sync %u", counter, clientTicks, clientTicks - _player->m_timeSyncClient); + TC_LOG_DEBUG("network", "Time sync received: counter %u, client ticks %u, time since last sync %u", packet.SequenceIndex, packet.ClientTime, packet.ClientTime - _player->m_timeSyncClient); - uint32 ourTicks = clientTicks + (getMSTime() - _player->m_timeSyncServer); + uint32 ourTicks = packet.ClientTime + (getMSTime() - _player->m_timeSyncServer); // diff should be small - TC_LOG_DEBUG("network", "Our ticks: %u, diff %u, latency %u", ourTicks, ourTicks - clientTicks, GetLatency()); + TC_LOG_DEBUG("network", "Our ticks: %u, diff %u, latency %u", ourTicks, ourTicks - packet.ClientTime, GetLatency()); - _player->m_timeSyncClient = clientTicks; + _player->m_timeSyncClient = packet.ClientTime; _player->m_timeSyncQueue.pop(); } @@ -1756,9 +1724,9 @@ void WorldSession::HandleWorldStateUITimerUpdate(WorldPacket& /*recvData*/) // empty opcode TC_LOG_DEBUG("network", "WORLD: CMSG_WORLD_STATE_UI_TIMER_UPDATE"); - WorldPacket data(SMSG_WORLD_STATE_UI_TIMER_UPDATE, 4); - data << uint32(time(NULL)); - SendPacket(&data); + WorldPackets::Misc::UITime response; + response.Time = time(NULL); + SendPacket(response.Write()); } void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps, std::set<uint32> const& worldMapAreaSwaps) @@ -1896,74 +1864,6 @@ void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket) _player->SetPendingBind(0, 0); } -void WorldSession::HandleRequestHotfix(WorldPacket& recvPacket) -{ - uint32 type, count; - recvPacket >> type; - - DB2StorageBase const* store = GetDB2Storage(type); - if (!store) - { - TC_LOG_ERROR("network", "CMSG_REQUEST_HOTFIX: Received unknown hotfix type: %u", type); - recvPacket.rfinish(); - return; - } - - count = recvPacket.ReadBits(23); - - ObjectGuid* guids = new ObjectGuid[count]; - for (uint32 i = 0; i < count; ++i) - { - guids[i][0] = recvPacket.ReadBit(); - guids[i][4] = recvPacket.ReadBit(); - guids[i][7] = recvPacket.ReadBit(); - guids[i][2] = recvPacket.ReadBit(); - guids[i][5] = recvPacket.ReadBit(); - guids[i][3] = recvPacket.ReadBit(); - guids[i][6] = recvPacket.ReadBit(); - guids[i][1] = recvPacket.ReadBit(); - } - - uint32 entry; - for (uint32 i = 0; i < count; ++i) - { - recvPacket.ReadByteSeq(guids[i][5]); - recvPacket.ReadByteSeq(guids[i][6]); - recvPacket.ReadByteSeq(guids[i][7]); - recvPacket.ReadByteSeq(guids[i][0]); - recvPacket.ReadByteSeq(guids[i][1]); - recvPacket.ReadByteSeq(guids[i][3]); - recvPacket.ReadByteSeq(guids[i][4]); - recvPacket >> entry; - recvPacket.ReadByteSeq(guids[i][2]); - - if (!store->HasRecord(entry)) - { - WorldPacket data(SMSG_DB_REPLY, 4 * 4); - data << -int32(entry); - data << uint32(store->GetHash()); - data << uint32(time(NULL)); - data << uint32(0); - SendPacket(&data); - continue; - } - - WorldPacket data(SMSG_DB_REPLY); - data << int32(entry); - data << uint32(store->GetHash()); - data << uint32(sObjectMgr->GetHotfixDate(entry, store->GetHash())); - - size_t sizePos = data.wpos(); - data << uint32(0); // size of next block - store->WriteRecord(entry, uint32(GetSessionDbcLocale()), data); - data.put<uint32>(sizePos, data.wpos() - sizePos - 4); - - SendPacket(&data); - } - - delete[] guids; -} - void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket) { TC_LOG_DEBUG("network", "WORLD: CMSG_UPDATE_MISSILE_TRAJECTORY"); diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index adc2e185591..1ccd7294cc8 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -36,7 +36,7 @@ #define MOVEMENT_PACKET_TIME_DELAY 0 -void WorldSession::HandleMoveWorldportAckOpcode(WorldPacket & /*recvData*/) +void WorldSession::HandleMoveWorldportAckOpcode(WorldPackets::Movement::WorldPortAck& /*packet*/) { TC_LOG_DEBUG("network", "WORLD: got MSG_MOVE_WORLDPORT_ACK."); HandleMoveWorldportAckOpcode(); diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index cc82063e074..90af94f9754 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -37,6 +37,7 @@ #include "ScriptMgr.h" #include "CreatureAI.h" #include "SpellInfo.h" +#include "NPCPackets.h" enum StableResultCode { @@ -75,18 +76,14 @@ void WorldSession::SendTabardVendorActivate(ObjectGuid guid) SendPacket(&data); } -void WorldSession::HandleBankerActivateOpcode(WorldPacket& recvData) +void WorldSession::HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet) { - ObjectGuid guid; - TC_LOG_DEBUG("network", "WORLD: Received CMSG_BANKER_ACTIVATE"); - recvData >> guid; - - Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BANKER); + Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_BANKER); if (!unit) { - TC_LOG_DEBUG("network", "WORLD: HandleBankerActivateOpcode - %s not found or you can not interact with him.", guid.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleBankerActivateOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str()); return; } @@ -94,7 +91,7 @@ void WorldSession::HandleBankerActivateOpcode(WorldPacket& recvData) if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - SendShowBank(guid); + SendShowBank(packet.Unit); } void WorldSession::SendShowBank(ObjectGuid guid) @@ -112,12 +109,9 @@ void WorldSession::SendShowMailBox(ObjectGuid guid) SendPacket(&data); } -void WorldSession::HandleTrainerListOpcode(WorldPacket& recvData) +void WorldSession::HandleTrainerListOpcode(WorldPackets::NPC::Hello& packet) { - ObjectGuid guid; - - recvData >> guid; - SendTrainerList(guid); + SendTrainerList(packet.Unit); } void WorldSession::SendTrainerList(ObjectGuid guid) @@ -148,18 +142,16 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle) return; } - WorldPacket data(SMSG_TRAINER_LIST, 8+4+4+trainer_spells->spellList.size()*38 + strTitle.size()+1); - data << guid; - data << uint32(trainer_spells->trainerType); - data << uint32(1); // different value for each trainer, also found in CMSG_TRAINER_BUY_SPELL - - size_t count_pos = data.wpos(); - data << uint32(trainer_spells->spellList.size()); + WorldPackets::NPC::TrainerList packet; + packet.TrainerGUID = guid; + packet.TrainerType = trainer_spells->trainerType; + packet.Greeting = strTitle; // reputation discount float fDiscountMod = _player->GetReputationPriceDiscount(unit); bool can_learn_primary_prof = GetPlayer()->GetFreePrimaryProfessionPoints() > 0; + packet.Spells.resize(trainer_spells->spellList.size()); uint32 count = 0; for (TrainerSpellMap::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr) { @@ -185,22 +177,23 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle) TrainerSpellState state = _player->GetTrainerSpellState(tSpell); - data << uint32(tSpell->SpellID); // learned spell (or cast-spell in profession case) - data << uint8(state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state); - data << uint32(floor(tSpell->MoneyCost * fDiscountMod)); + WorldPackets::NPC::TrainerListSpell& spell = packet.Spells[count]; + spell.SpellID = tSpell->SpellID; + spell.MoneyCost = floor(tSpell->MoneyCost * fDiscountMod); + spell.ReqSkillLine = tSpell->ReqSkillLine; + spell.ReqSkillRank = tSpell->ReqSkillRank; + spell.ReqLevel = tSpell->ReqLevel; + spell.Usable = (state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state); - data << uint8(tSpell->ReqLevel); - data << uint32(tSpell->ReqSkillLine); - data << uint32(tSpell->ReqSkillRank); - //prev + req or req + 0 uint8 maxReq = 0; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + /// @todo Update this when new spell system is ready + /*for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (!tSpell->ReqAbility[i]) continue; if (uint32 prevSpellId = sSpellMgr->GetPrevSpellInChain(tSpell->ReqAbility[i])) { - data << uint32(prevSpellId); + spell.ReqAbility[maxReq] = prevSpellId; ++maxReq; } if (maxReq == 2) @@ -208,29 +201,25 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle) SpellsRequiringSpellMapBounds spellsRequired = sSpellMgr->GetSpellsRequiredForSpellBounds(tSpell->ReqAbility[i]); for (SpellsRequiringSpellMap::const_iterator itr2 = spellsRequired.first; itr2 != spellsRequired.second && maxReq < 3; ++itr2) { - data << uint32(itr2->second); + spell.ReqAbility[maxReq] = itr2->second; ++maxReq; } if (maxReq == 2) break; - } - while (maxReq < 2) + }*/ + while (maxReq < MAX_TRAINERSPELL_ABILITY_REQS) { - data << uint32(0); + spell.ReqAbility[maxReq] = 0; ++maxReq; } - data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0); - // primary prof. learn confirmation dialog - data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state - ++count; } - data << strTitle; + // Shrink to actual data size + packet.Spells.resize(count); - data.put<uint32>(count_pos, count); - SendPacket(&data); + SendPacket(packet.Write()); } void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData) @@ -312,17 +301,14 @@ void WorldSession::SendTrainerBuyFailed(ObjectGuid guid, uint32 spellId, uint32 SendPacket(&data); } -void WorldSession::HandleGossipHelloOpcode(WorldPacket& recvData) +void WorldSession::HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GOSSIP_HELLO"); - ObjectGuid guid; - recvData >> guid; - - Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); + Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_NONE); if (!unit) { - TC_LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - %s not found or you can not interact with him.", guid.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str()); return; } @@ -453,18 +439,15 @@ void WorldSession::SendSpiritResurrect() _player->UpdateObjectVisibility(); } -void WorldSession::HandleBinderActivateOpcode(WorldPacket& recvData) +void WorldSession::HandleBinderActivateOpcode(WorldPackets::NPC::Hello& packet) { - ObjectGuid npcGUID; - recvData >> npcGUID; - if (!GetPlayer()->IsInWorld() || !GetPlayer()->IsAlive()) return; - Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID, UNIT_NPC_FLAG_INNKEEPER); + Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_INNKEEPER); if (!unit) { - TC_LOG_DEBUG("network", "WORLD: HandleBinderActivateOpcode - %s not found or you can not interact with him.", npcGUID.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleBinderActivateOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str()); return; } diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 490097ec647..81dc9e6cec0 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -39,7 +39,7 @@ void WorldSession::SendNameQueryOpcode(ObjectGuid guid) Player* player = ObjectAccessor::FindConnectedPlayer(guid); CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(guid); - WorldPackets::Character::PlayerNameResponse response; + WorldPackets::Query::QueryPlayerNameResponse response; response.Player = guid; if (characterInfo) @@ -68,7 +68,7 @@ void WorldSession::SendNameQueryOpcode(ObjectGuid guid) SendPacket(response.Write()); } -void WorldSession::HandleNameQueryOpcode(WorldPackets::Character::QueryPlayerName& packet) +void WorldSession::HandleNameQueryOpcode(WorldPackets::Query::QueryPlayerName& packet) { SendNameQueryOpcode(packet.Player); } @@ -239,128 +239,65 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket& /*recvData*/) SendPacket(&data); } -void WorldSession::HandleNpcTextQueryOpcode(WorldPacket& recvData) +void WorldSession::HandleNpcTextQueryOpcode(WorldPackets::Query::QueryNPCText& packet) { - uint32 textID; - uint64 guid; + TC_LOG_DEBUG("network", "WORLD: CMSG_NPC_TEXT_QUERY TextId: %u", packet.TextID); - recvData >> textID; - TC_LOG_DEBUG("network", "WORLD: CMSG_NPC_TEXT_QUERY TextId: %u", textID); + GossipText const* gossip = sObjectMgr->GetGossipText(packet.TextID); - recvData >> guid; - - GossipText const* gossip = sObjectMgr->GetGossipText(textID); - - WorldPacket data(SMSG_NPC_TEXT_UPDATE, 100); // guess size - data << textID; - - if (!gossip) + WorldPackets::Query::QueryNPCTextResponse response; + response.TextID = packet.TextID; + + if (gossip) { for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) { - data << float(0); - data << "Greetings $N"; - data << "Greetings $N"; - data << uint32(0); - data << uint32(0); - data << uint32(0); - data << uint32(0); - data << uint32(0); - data << uint32(0); - data << uint32(0); + response.Probabilities[i] = gossip->Options[i].Probability; + response.BroadcastTextID[i] = gossip->Options[i].BroadcastTextID; } - } - else - { - std::string text0[MAX_GOSSIP_TEXT_OPTIONS], text1[MAX_GOSSIP_TEXT_OPTIONS]; - LocaleConstant locale = GetSessionDbLocaleIndex(); - - for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) - { - BroadcastText const* bct = sObjectMgr->GetBroadcastText(gossip->Options[i].BroadcastTextID); - if (bct) - { - text0[i] = bct->GetText(locale, GENDER_MALE, true); - text1[i] = bct->GetText(locale, GENDER_FEMALE, true); - } - else - { - text0[i] = gossip->Options[i].Text_0; - text1[i] = gossip->Options[i].Text_1; - } - - if (locale != DEFAULT_LOCALE && !bct) - { - if (NpcTextLocale const* npcTextLocale = sObjectMgr->GetNpcTextLocale(textID)) - { - ObjectMgr::GetLocaleString(npcTextLocale->Text_0[i], locale, text0[i]); - ObjectMgr::GetLocaleString(npcTextLocale->Text_1[i], locale, text1[i]); - } - } - - data << gossip->Options[i].Probability; - - if (text0[i].empty()) - data << text1[i]; - else - data << text0[i]; - - if (text1[i].empty()) - data << text0[i]; - else - data << text1[i]; - - data << gossip->Options[i].Language; - for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j) - { - data << gossip->Options[i].Emotes[j]._Delay; - data << gossip->Options[i].Emotes[j]._Emote; - } - } + response.Allow = true; } - SendPacket(&data); + SendPacket(response.Write()); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_NPC_TEXT_UPDATE"); } /// Only _static_ data is sent in this packet !!! -void WorldSession::HandlePageTextQueryOpcode(WorldPacket& recvData) +void WorldSession::HandlePageTextQueryOpcode(WorldPackets::Query::QueryPageText& packet) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_PAGE_TEXT_QUERY"); - - uint32 pageID; - recvData >> pageID; - recvData.read_skip<uint64>(); // guid + + uint32 pageID = packet.PageTextID; while (pageID) { PageText const* pageText = sObjectMgr->GetPageText(pageID); - // guess size - WorldPacket data(SMSG_PAGE_TEXT_QUERY_RESPONSE, 50); - data << pageID; + + WorldPackets::Query::QueryPageTextResponse response; + response.PageTextID = pageID; if (!pageText) { - data << "Item page missing."; - data << uint32(0); + response.Allow = false; pageID = 0; } else { - std::string Text = pageText->Text; - + response.Allow = true; + response.Info.ID = pageID; + int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) if (PageTextLocale const* player = sObjectMgr->GetPageTextLocale(pageID)) - ObjectMgr::GetLocaleString(player->Text, loc_idx, Text); + ObjectMgr::GetLocaleString(player->Text, loc_idx, response.Info.Text); - data << Text; - data << uint32(pageText->NextPageID); + response.Info.NextPageID = pageText->NextPageID; pageID = pageText->NextPageID; } - SendPacket(&data); + + SendPacket(response.Write()); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_PAGE_TEXT_QUERY_RESPONSE"); } @@ -494,3 +431,35 @@ void WorldSession::HandleQuestPOIQuery(WorldPacket& recvData) SendPacket(&data); } + +void WorldSession::HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet) +{ + DB2StorageBase const* store = GetDB2Storage(packet.TableHash); + if (!store) + { + TC_LOG_ERROR("network", "CMSG_DB_QUERY_BULK: Received unknown hotfix type: %u", packet.TableHash); + return; + } + + for (WorldPackets::Query::DBQueryRecord const& rec : packet.Queries) + { + WorldPackets::Query::DBReply response; + response.TableHash = packet.TableHash; + + if (store->HasRecord(rec.RecordID)) + { + response.RecordID = rec.RecordID; + response.Locale = GetSessionDbcLocale(); + response.Timestamp = sObjectMgr->GetHotfixDate(rec.RecordID, packet.TableHash); + response.Data = store; + } + else + { + TC_LOG_ERROR("network", "CMSG_DB_QUERY_BULK: Entry %u does not exist in datastore: %u", rec.RecordID, packet.TableHash); + response.RecordID = -rec.RecordID; + response.Timestamp = time(NULL); + } + + SendPacket(response.Write()); + } +} diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 26451751b5d..f591a5fa988 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -31,17 +31,16 @@ #include "Battleground.h" #include "ScriptMgr.h" #include "GameObjectAI.h" +#include "QuestPackets.h" -void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData) +void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPackets::Quest::QuestGiverStatusQuery& packet) { - ObjectGuid guid; - recvData >> guid; uint32 questStatus = DIALOG_STATUS_NONE; - Object* questGiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); + Object* questGiver = ObjectAccessor::GetObjectByTypeMask(*_player, packet.QuestGiverGUID, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); if (!questGiver) { - TC_LOG_INFO("network", "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for non-existing questgiver (%s)", guid.ToString().c_str()); + TC_LOG_INFO("network", "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for non-existing questgiver (%s)", packet.QuestGiverGUID.ToString().c_str()); return; } @@ -66,7 +65,7 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData) } //inform client about status of quest - _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, guid); + _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, packet.QuestGiverGUID); } void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket& recvData) @@ -639,19 +638,14 @@ void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket) } } -void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket*/) +void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPackets::Quest::QuestGiverStatusMultipleQuery& /*packet*/) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY"); - uint32 count = 0; - - WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4 + 8 + 4); - data << uint32(count); // placeholder + WorldPackets::Quest::QuestGiverStatusMultiple response; for (GuidSet::const_iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr) { - uint32 questStatus = DIALOG_STATUS_NONE; - if (itr->IsAnyTypeCreature()) { // need also pet quests case support @@ -661,11 +655,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket if (!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER)) continue; - questStatus = _player->GetQuestDialogStatus(questgiver); - - data << questgiver->GetGUID(); - data << uint32(questStatus); - ++count; + response.QuestGiver.emplace_back(questgiver->GetGUID(), _player->GetQuestDialogStatus(questgiver)); } else if (itr->IsGameObject()) { @@ -673,16 +663,11 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket if (!questgiver || questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER) continue; - questStatus = _player->GetQuestDialogStatus(questgiver); - - data << questgiver->GetGUID(); - data << uint32(questStatus); - ++count; + response.QuestGiver.emplace_back(questgiver->GetGUID(), _player->GetQuestDialogStatus(questgiver)); } } - data.put<uint32>(0, count); // write real count - SendPacket(&data); + SendPacket(response.Write()); } void WorldSession::HandleQueryQuestsCompleted(WorldPacket& /*recvData*/) diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp index ef1e9031cb9..f0c1b28117b 100644 --- a/src/server/game/Handlers/SkillHandler.cpp +++ b/src/server/game/Handlers/SkillHandler.cpp @@ -26,6 +26,7 @@ #include "UpdateMask.h" #include "WorldPacket.h" #include "WorldSession.h" +#include "TalentPackets.h" void WorldSession::HandleLearnTalentOpcode(WorldPacket& recvData) { @@ -126,3 +127,36 @@ void WorldSession::HandleUnlearnSkillOpcode(WorldPacket& recvData) GetPlayer()->SetSkill(skillId, 0, 0, 0); } + +void WorldSession::HandleSetSpecializationOpcode(WorldPackets::Talent::SetSpecialization& packet) +{ + Player* player = GetPlayer(); + + if (packet.SpecGroupIndex >= MAX_SPECIALIZATIONS) + { + TC_LOG_DEBUG("network", "WORLD: HandleSetSpecializationOpcode - specialization index %u out of range", packet.SpecGroupIndex); + return; + } + + ChrSpecializationEntry const* chrSpec = sChrSpecializationByIndexStore[player->getClass()][packet.SpecGroupIndex]; + + if (!chrSpec) + { + TC_LOG_DEBUG("network", "WORLD: HandleSetSpecializationOpcode - specialization index %u not found", packet.SpecGroupIndex); + return; + } + + if (chrSpec->ClassID != player->getClass()) + { + TC_LOG_DEBUG("network", "WORLD: HandleSetSpecializationOpcode - specialization %u does not belong to class %u", chrSpec->ID, player->getClass()); + return; + } + + if (player->getLevel() < MIN_SPECIALIZATION_LEVEL) + { + TC_LOG_DEBUG("network", "WORLD: HandleSetSpecializationOpcode - player level too low for specializations"); + return; + } + + player->LearnTalentSpecialization(chrSpec->ID); +} diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 0e243064cc2..79b213e2829 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -458,6 +458,10 @@ void WorldSession::HandleCancelAuraOpcode(WorldPacket& recvPacket) uint32 spellId; recvPacket >> spellId; + ObjectGuid guid; + recvPacket >> guid; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) return; diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index a8255d62777..1c968a495e9 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -128,7 +128,7 @@ void InstanceScript::LoadObjectData(ObjectData const* creatureData, ObjectData c if (gameObjectData) LoadObjectData(gameObjectData, _gameObjectInfo); - TC_LOG_ERROR("scripts", "InstanceScript::LoadObjectData: " SZFMTD " objects loaded.", _creatureInfo.size() + _gameObjectInfo.size()); + TC_LOG_DEBUG("scripts", "InstanceScript::LoadObjectData: " SZFMTD " objects loaded.", _creatureInfo.size() + _gameObjectInfo.size()); } void InstanceScript::LoadObjectData(ObjectData const* data, ObjectInfoMap& objectInfo) diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h index 34733613c28..ede70719652 100644 --- a/src/server/game/Maps/TransportMgr.h +++ b/src/server/game/Maps/TransportMgr.h @@ -22,6 +22,7 @@ #include "Spline.h" #include "DBCStores.h" #include "ObjectGuid.h" +#include "DB2Structure.h" struct KeyFrame; struct GameObjectTemplate; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 22bc3b079a3..7d32555e651 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -87,9 +87,10 @@ enum Expansions enum Gender { - GENDER_MALE = 0, - GENDER_FEMALE = 1, - GENDER_NONE = 2 + GENDER_UNKNOWN = -1, + GENDER_MALE = 0, + GENDER_FEMALE = 1, + GENDER_NONE = 2 }; // ChrRaces.dbc (6.0.2.18988) @@ -844,12 +845,13 @@ enum SpellAttr13 SPELL_ATTR13_UNK23 = 0x00800000 // 23 }; -#define MIN_TALENT_GROUP 0 -#define MAX_TALENT_GROUP 1 -#define MIN_TALENT_GROUPS 1 -#define MAX_TALENT_GROUPS 2 -#define MAX_GLYPH_SLOT_INDEX 9 -#define REQ_PRIMARY_TREE_TALENTS 31 +#define MIN_TALENT_GROUP 0 +#define MAX_TALENT_GROUP 1 +#define MIN_TALENT_GROUPS 1 +#define MAX_TALENT_GROUPS 2 +#define MAX_GLYPH_SLOT_INDEX 6 +#define MIN_SPECIALIZATION_LEVEL 10 +#define MAX_SPECIALIZATIONS 4 // Custom values enum SpellClickUserTypes @@ -4156,8 +4158,22 @@ enum ChatMsg CHAT_MSG_CURRENCY = 0x40 }; +#define GM_SILENCE_AURA 1852 + #define MAX_CHAT_MSG_TYPE 0x41 +enum ChatFlags +{ + CHAT_FLAG_NONE = 0x00, + CHAT_FLAG_AFK = 0x01, + CHAT_FLAG_DND = 0x02, + CHAT_FLAG_GM = 0x04, + CHAT_FLAG_COM = 0x08, // Commentator + CHAT_FLAG_DEV = 0x10, + CHAT_FLAG_BOSS_SOUND = 0x20, // Plays "RaidBossEmoteWarning" sound on raid boss emote/whisper + CHAT_FLAG_MOBILE = 0x40 +}; + enum ChatLinkColors { CHAT_LINK_COLOR_TRADE = 0xffffd000, // orange diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 749b6be4ee5..560f40143bb 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -24,6 +24,7 @@ #include "Vehicle.h" #include "WorldPacket.h" #include "Opcodes.h" +#include "MovementPackets.h" namespace Movement { @@ -115,17 +116,11 @@ namespace Movement unit->m_movementInfo.SetMovementFlags(moveFlags); move_spline.Initialize(args); - WorldPacket data(SMSG_MONSTER_MOVE, 64); - data << unit->GetPackGUID(); - if (!unit->GetTransGUID().IsEmpty()) - { - data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); - data << unit->GetTransGUID().WriteAsPacked(); - data << int8(unit->GetTransSeat()); - } - - PacketBuilder::WriteMonsterMove(move_spline, data); - unit->SendMessageToSet(&data, true); + WorldPackets::Movement::MonsterMove packet; + packet.MoverGUID = unit->GetGUID(); + packet.Pos = real_position; + PacketBuilder::WriteMonsterMove(move_spline, packet.SplineData); + unit->SendMessageToSet(packet.Write(), true); return move_spline.Duration(); } @@ -161,17 +156,18 @@ namespace Movement move_spline.onTransport = transport; move_spline.Initialize(args); - WorldPacket data(SMSG_MONSTER_MOVE, 64); - data << unit->GetPackGUID(); + WorldPackets::Movement::MonsterMove packet; + packet.MoverGUID = unit->GetGUID(); + packet.Pos = loc; + packet.SplineData.ID = move_spline.GetId(); + if (transport) { - data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); - data << unit->GetTransGUID().WriteAsPacked(); - data << int8(unit->GetTransSeat()); + packet.SplineData.Move.TransportGUID = unit->GetTransGUID(); + packet.SplineData.Move.VehicleSeat = unit->GetTransSeat(); } - PacketBuilder::WriteStopMovement(loc, args.splineId, data); - unit->SendMessageToSet(&data, true); + unit->SendMessageToSet(packet.Write(), true); } MoveSplineInit::MoveSplineInit(Unit* m) : unit(m) diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index 02fdabb3938..f13c69b97fd 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -21,132 +21,90 @@ #include "MoveSpline.h" #include "WorldPacket.h" #include "Object.h" +#include "MovementPackets.h" namespace Movement { - inline void operator << (ByteBuffer& b, const Vector3& v) + void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, WorldPackets::Movement::MovementMonsterSpline& movementMonsterSpline) { - b << v.x << v.y << v.z; - } - - inline void operator >> (ByteBuffer& b, Vector3& v) - { - b >> v.x >> v.y >> v.z; - } + movementMonsterSpline.ID = move_spline.m_Id; + WorldPackets::Movement::MovementSpline& movementSpline = movementMonsterSpline.Move; - enum MonsterMoveType - { - MonsterMoveNormal = 0, - MonsterMoveStop = 1, - MonsterMoveFacingSpot = 2, - MonsterMoveFacingTarget = 3, - MonsterMoveFacingAngle = 4 - }; - - void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data) - { MoveSplineFlag splineflags = move_spline.splineflags; + splineflags.enter_cycle = move_spline.isCyclic(); + movementSpline.Flags = uint32(splineflags & uint32(~MoveSplineFlag::Mask_No_Monster_Move)); - data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40) - data << move_spline.spline.getPoint(move_spline.spline.first()); - data << move_spline.GetId(); - - switch (splineflags & MoveSplineFlag::Mask_Final_Facing) + switch (move_spline.splineflags & MoveSplineFlag::Mask_Final_Facing) { + case MoveSplineFlag::Final_Point: + movementSpline.Face = MONSTER_MOVE_FACING_SPOT; + movementSpline.FaceSpot = move_spline.facing.f; + break; case MoveSplineFlag::Final_Target: - data << uint8(MonsterMoveFacingTarget); - data << move_spline.facing.target; + movementSpline.Face = MONSTER_MOVE_FACING_TARGET; + movementSpline.FaceGUID = move_spline.facing.target; break; case MoveSplineFlag::Final_Angle: - data << uint8(MonsterMoveFacingAngle); - data << move_spline.facing.angle; - break; - case MoveSplineFlag::Final_Point: - data << uint8(MonsterMoveFacingSpot); - data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z; + movementSpline.Face = MONSTER_MOVE_FACING_ANGLE; + movementSpline.FaceDirection = move_spline.facing.angle; break; default: - data << uint8(MonsterMoveNormal); + movementSpline.Face = MONSTER_MOVE_NORMAL; break; } - // add fake Enter_Cycle flag - needed for client-side cyclic movement (client will erase first spline vertex after first cycle done) - splineflags.enter_cycle = move_spline.isCyclic(); - data << uint32(splineflags & uint32(~MoveSplineFlag::Mask_No_Monster_Move)); - if (splineflags.animation) { - data << splineflags.getAnimationId(); - data << move_spline.effect_start_time; + movementSpline.AnimTier = splineflags.getAnimationId(); + movementSpline.TierTransStartTime = move_spline.effect_start_time; } - data << move_spline.Duration(); + movementSpline.MoveTime = move_spline.Duration(); if (splineflags.parabolic) { - data << move_spline.vertical_acceleration; - data << move_spline.effect_start_time; + movementSpline.JumpGravity = move_spline.vertical_acceleration; + movementSpline.SpecialTime = move_spline.effect_start_time; } - } - - void PacketBuilder::WriteStopMovement(Vector3 const& pos, uint32 splineId, ByteBuffer& data) - { - data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40) - data << pos; - data << splineId; - data << uint8(MonsterMoveStop); - } - - void WriteLinearPath(Spline<int32> const& spline, ByteBuffer& data) - { - uint32 last_idx = spline.getPointCount() - 3; - Vector3 const* real_path = &spline.getPoint(1); - - data << last_idx; - data << real_path[last_idx]; // destination - if (last_idx > 1) - { - Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f; - Vector3 offset; - // first and last points already appended - for (uint32 i = 1; i < last_idx; ++i) - { - offset = middle - real_path[i]; - data.appendPackXYZ(offset.x, offset.y, offset.z); - } - } - } - - void WriteUncompressedPath(Spline<int32> const& spline, ByteBuffer& data) - { - uint32 count = spline.getPointCount() - 3; - data << count; - data.append<Vector3>(&spline.getPoint(2), count); - } - - void WriteUncompressedCyclicPath(Spline<int32> const& spline, ByteBuffer& data) - { - uint32 count = spline.getPointCount() - 3; - data << uint32(count + 1); - data << spline.getPoint(1); // fake point, client will erase it from the spline after first cycle done - data.append<Vector3>(&spline.getPoint(1), count); - } - - void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, WorldPacket& data) - { - WriteCommonMonsterMovePart(move_spline, data); Spline<int32> const& spline = move_spline.spline; - MoveSplineFlag splineflags = move_spline.splineflags; + std::vector<Vector3> const& array = spline.getPoints(); + if (splineflags & MoveSplineFlag::UncompressedPath) { if (!splineflags.cyclic) - WriteUncompressedPath(spline, data); + { + uint32 count = spline.getPointCount() - 3; + for (uint32 i = 2; i < count; ++i) + movementSpline.Points.push_back(array[i]); + } else - WriteUncompressedCyclicPath(spline, data); + { + uint32 count = spline.getPointCount() - 3; + movementSpline.Points.push_back(array[1]); + for (uint32 i = 1; i < count; ++i) + movementSpline.Points.push_back(array[i]); + } } else - WriteLinearPath(spline, data); + { + uint32 last_idx = spline.getPointCount() - 3; + Vector3 const* real_path = &spline.getPoint(1); + + movementSpline.Points.push_back(real_path[last_idx]); + + if (last_idx > 1) + { + Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f; + Vector3 offset; + // first and last points already appended + for (uint32 i = 1; i < last_idx; ++i) + { + offset = middle - real_path[i]; + movementSpline.PackedDeltas.push_back(offset); + } + } + } } void PacketBuilder::WriteCreate(MoveSpline const& moveSpline, ByteBuffer& data) diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.h b/src/server/game/Movement/Spline/MovementPacketBuilder.h index 2878a330f67..83172b2c3e0 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.h +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.h @@ -22,6 +22,7 @@ #include "Define.h" // for uint32 #include "G3D/Vector3.h" +#include "MovementPackets.h" using G3D::Vector3; class ByteBuffer; @@ -35,7 +36,7 @@ namespace Movement static void WriteCommonMonsterMovePart(const MoveSpline& mov, WorldPacket& data); public: - static void WriteMonsterMove(const MoveSpline& mov, WorldPacket& data); + static void WriteMonsterMove(const MoveSpline& mov, WorldPackets::Movement::MovementMonsterSpline& movementMonsterSpline); static void WriteStopMovement(Vector3 const& loc, uint32 splineId, ByteBuffer& data); static void WriteCreate(MoveSpline const& moveSpline, ByteBuffer& data); }; diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h index a69af9e3a83..14c4e19b19b 100644 --- a/src/server/game/Movement/Spline/MovementTypedefs.h +++ b/src/server/game/Movement/Spline/MovementTypedefs.h @@ -21,6 +21,14 @@ #include "Common.h" +enum MonsterMoveType +{ + MONSTER_MOVE_NORMAL = 0, + MONSTER_MOVE_FACING_SPOT = 1, + MONSTER_MOVE_FACING_TARGET = 2, + MONSTER_MOVE_FACING_ANGLE = 3 +}; + namespace G3D { class Vector3; diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp index 359a8f3946a..3bf3464f016 100644 --- a/src/server/game/Reputation/ReputationMgr.cpp +++ b/src/server/game/Reputation/ReputationMgr.cpp @@ -18,6 +18,7 @@ #include "DatabaseEnv.h" #include "ReputationMgr.h" +#include "ReputationPackets.h" #include "DBCStores.h" #include "Player.h" #include "WorldPacket.h" @@ -199,38 +200,17 @@ void ReputationMgr::SendState(FactionState const* faction) void ReputationMgr::SendInitialReputations() { - uint16 count = 256; - WorldPacket data(SMSG_INITIALIZE_FACTIONS, 4 + count * 5); - data << uint32(count); - - RepListID a = 0; + WorldPackets::Reputation::InitializeFactions initFactions; for (FactionStateList::iterator itr = _factions.begin(); itr != _factions.end(); ++itr) { - // fill in absent fields - for (; a != itr->first; ++a) - { - data << uint8(0); - data << uint32(0); - } - - // fill in encountered data - data << uint8(itr->second.Flags); - data << uint32(itr->second.Standing); - + initFactions.FactionFlags[itr->first] = itr->second.Flags; + initFactions.FactionStandings[itr->first] = itr->second.Standing; + /// @todo faction bonus itr->second.needSend = false; - - ++a; } - // fill in absent fields - for (; a != count; ++a) - { - data << uint8(0); - data << uint32(0); - } - - _player->SendDirectMessage(&data); + _player->SendDirectMessage(initFactions.Write()); } void ReputationMgr::SendStates() diff --git a/src/server/game/Server/Packets/AuthenticationPackets.cpp b/src/server/game/Server/Packets/AuthenticationPackets.cpp index 2bb1760b31c..a69e684438f 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.cpp +++ b/src/server/game/Server/Packets/AuthenticationPackets.cpp @@ -65,20 +65,20 @@ WorldPacket const* WorldPackets::Auth::AuthResponse::Write() if (SuccessInfo.HasValue) { - _worldPacket << uint32(SuccessInfo.value.VirtualRealmAddress); - _worldPacket << uint32(SuccessInfo.value.VirtualRealms.size()); - _worldPacket << uint32(SuccessInfo.value.TimeRemain); - _worldPacket << uint32(SuccessInfo.value.TimeOptions); - _worldPacket << uint32(SuccessInfo.value.TimeRested); - _worldPacket << uint8(SuccessInfo.value.ActiveExpansionLevel); - _worldPacket << uint8(SuccessInfo.value.AccountExpansionLevel); - _worldPacket << uint32(SuccessInfo.value.TimeSecondsUntilPCKick); - _worldPacket << uint32(SuccessInfo.value.AvailableRaces->size()); - _worldPacket << uint32(SuccessInfo.value.AvailableClasses->size()); - _worldPacket << uint32(SuccessInfo.value.Templates.size()); - _worldPacket << uint32(SuccessInfo.value.CurrencyID); - - for (auto& realm : SuccessInfo.value.VirtualRealms) + _worldPacket << uint32(SuccessInfo.Value.VirtualRealmAddress); + _worldPacket << uint32(SuccessInfo.Value.VirtualRealms.size()); + _worldPacket << uint32(SuccessInfo.Value.TimeRemain); + _worldPacket << uint32(SuccessInfo.Value.TimeOptions); + _worldPacket << uint32(SuccessInfo.Value.TimeRested); + _worldPacket << uint8(SuccessInfo.Value.ActiveExpansionLevel); + _worldPacket << uint8(SuccessInfo.Value.AccountExpansionLevel); + _worldPacket << uint32(SuccessInfo.Value.TimeSecondsUntilPCKick); + _worldPacket << uint32(SuccessInfo.Value.AvailableRaces->size()); + _worldPacket << uint32(SuccessInfo.Value.AvailableClasses->size()); + _worldPacket << uint32(SuccessInfo.Value.Templates.size()); + _worldPacket << uint32(SuccessInfo.Value.CurrencyID); + + for (auto& realm : SuccessInfo.Value.VirtualRealms) { _worldPacket << uint32(realm.RealmAddress); _worldPacket.WriteBit(realm.IsLocal); @@ -89,19 +89,19 @@ WorldPacket const* WorldPackets::Auth::AuthResponse::Write() _worldPacket.WriteString(realm.RealmNameNormalized); } - for (auto& race : *SuccessInfo.value.AvailableRaces) + for (auto& race : *SuccessInfo.Value.AvailableRaces) { _worldPacket << uint8(race.first); /// the current race _worldPacket << uint8(race.second); /// the required Expansion } - for (auto& klass : *SuccessInfo.value.AvailableClasses) + for (auto& klass : *SuccessInfo.Value.AvailableClasses) { _worldPacket << uint8(klass.first); /// the current class _worldPacket << uint8(klass.second); /// the required Expansion } - for (auto& templat : SuccessInfo.value.Templates) + for (auto& templat : SuccessInfo.Value.Templates) { _worldPacket << uint32(templat.TemplateSetId); _worldPacket << uint32(templat.TemplateClasses.size()); @@ -117,23 +117,23 @@ WorldPacket const* WorldPackets::Auth::AuthResponse::Write() _worldPacket.WriteString(templat.Description); } - _worldPacket.WriteBit(SuccessInfo.value.IsExpansionTrial); - _worldPacket.WriteBit(SuccessInfo.value.ForceCharacterTemplate); - _worldPacket.WriteBit(SuccessInfo.value.NumPlayersHorde != 0); - _worldPacket.WriteBit(SuccessInfo.value.NumPlayersAlliance != 0); - _worldPacket.WriteBit(SuccessInfo.value.IsVeteranTrial); + _worldPacket.WriteBit(SuccessInfo.Value.IsExpansionTrial); + _worldPacket.WriteBit(SuccessInfo.Value.ForceCharacterTemplate); + _worldPacket.WriteBit(SuccessInfo.Value.NumPlayersHorde.HasValue); + _worldPacket.WriteBit(SuccessInfo.Value.NumPlayersAlliance.HasValue); + _worldPacket.WriteBit(SuccessInfo.Value.IsVeteranTrial); - if (SuccessInfo.value.NumPlayersHorde) - _worldPacket << uint16(SuccessInfo.value.NumPlayersHorde); + if (SuccessInfo.Value.NumPlayersHorde.HasValue) + _worldPacket << uint16(SuccessInfo.Value.NumPlayersHorde.Value); - if (SuccessInfo.value.NumPlayersAlliance) - _worldPacket << uint16(SuccessInfo.value.NumPlayersAlliance); + if (SuccessInfo.Value.NumPlayersAlliance.HasValue) + _worldPacket << uint16(SuccessInfo.Value.NumPlayersAlliance.Value); } if (WaitInfo.HasValue) { - _worldPacket << uint32(WaitInfo.value.WaitCount); - _worldPacket.WriteBit(WaitInfo.value.HasFCM); + _worldPacket << uint32(WaitInfo.Value.WaitCount); + _worldPacket.WriteBit(WaitInfo.Value.HasFCM); } _worldPacket.FlushBits(); diff --git a/src/server/game/Server/Packets/AuthenticationPackets.h b/src/server/game/Server/Packets/AuthenticationPackets.h index e24c06396e0..eb44064750a 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.h +++ b/src/server/game/Server/Packets/AuthenticationPackets.h @@ -118,8 +118,8 @@ namespace WorldPackets bool IsExpansionTrial = false; bool ForceCharacterTemplate = false; ///< forces the client to always use a character template when creating a new character. @see Templates. @todo implement - uint16 NumPlayersHorde = 0; ///< number of horde players in this realm. @todo implement - uint16 NumPlayersAlliance = 0; ///< number of alliance players in this realm. @todo implement + Optional<uint16> NumPlayersHorde; ///< number of horde players in this realm. @todo implement + Optional<uint16> NumPlayersAlliance; ///< number of alliance players in this realm. @todo implement bool IsVeteranTrial = false; ///< @todo research }; diff --git a/src/server/game/Server/Packets/ChannelPackets.cpp b/src/server/game/Server/Packets/ChannelPackets.cpp new file mode 100644 index 00000000000..2ece521b42b --- /dev/null +++ b/src/server/game/Server/Packets/ChannelPackets.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ChannelPackets.h" +#include "Channel.h" + +void WorldPackets::Channel::ChannelListRequest::Read() +{ + ChannelName = _worldPacket.ReadString(_worldPacket.ReadBits(7)); +} + +WorldPacket const* WorldPackets::Channel::ChannelListResponse::Write() +{ + _worldPacket.WriteBit(Display); + _worldPacket.WriteBits(Channel.length(), 7); + _worldPacket << uint8(ChannelFlags); + _worldPacket << uint32(Members.size()); + _worldPacket.WriteString(Channel); + + for (ChannelPlayer const& player : Members) + { + _worldPacket << player.Guid; + _worldPacket << uint32(player.VirtualRealmAddress); + _worldPacket << uint8(player.Flags); + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Channel::ChannelNotify::Write() +{ + _worldPacket.WriteBits(Type, 6); + _worldPacket.WriteBits(Channel.length(), 7); + _worldPacket.WriteBits(Sender.length(), 6); + + _worldPacket << SenderGuid; + _worldPacket << SenderAccountID; + _worldPacket << uint32(SenderVirtualRealm); + _worldPacket << TargetGuid; + _worldPacket << uint32(TargetVirtualRealm); + _worldPacket << int32(ChatChannelID); + + if (Type == CHAT_MODE_CHANGE_NOTICE) + { + _worldPacket << uint8(OldFlags); + _worldPacket << uint8(NewFlags); + } + + _worldPacket.WriteString(Channel); + _worldPacket.WriteString(Sender); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Channel::ChannelNotifyJoined::Write() +{ + _worldPacket.WriteBits(Channel.length(), 7); + _worldPacket.WriteBits(ChannelWelcomeMsg.length(), 10); + _worldPacket << uint8(ChannelFlags); + _worldPacket << int32(ChatChannelID); + _worldPacket << uint64(InstanceID); + _worldPacket.WriteString(Channel); + _worldPacket.WriteString(ChannelWelcomeMsg); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Channel::ChannelNotifyLeft::Write() +{ + _worldPacket.WriteBits(Channel.length(), 7); + _worldPacket.WriteBit(Suspended); + _worldPacket << int32(ChatChannelID); + _worldPacket.WriteString(Channel); + + return &_worldPacket; +} + +void WorldPackets::Channel::JoinChannel::Read() +{ + _worldPacket >> ChatChannelId; + CreateVoiceSession = _worldPacket.ReadBit(); + Internal = _worldPacket.ReadBit(); + uint32 channelLength = _worldPacket.ReadBits(7); + uint32 passwordLength = _worldPacket.ReadBits(7); + ChannelName = _worldPacket.ReadString(channelLength); + Password = _worldPacket.ReadString(passwordLength); +} + +void WorldPackets::Channel::LeaveChannel::Read() +{ + _worldPacket >> ZoneChannelID; + ChannelName = _worldPacket.ReadString(_worldPacket.ReadBits(7)); +} diff --git a/src/server/game/Server/Packets/ChannelPackets.h b/src/server/game/Server/Packets/ChannelPackets.h new file mode 100644 index 00000000000..36a0a516928 --- /dev/null +++ b/src/server/game/Server/Packets/ChannelPackets.h @@ -0,0 +1,137 @@ +/* +* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef ChannelPackets_h__ +#define ChannelPackets_h__ + +#include "Packet.h" +#include "ObjectGuid.h" + +namespace WorldPackets +{ + namespace Channel + { + class ChannelListRequest final : public ClientPacket + { + public: + ChannelListRequest(WorldPacket&& packet) : ClientPacket(std::move(packet)) + { + ASSERT(packet.GetOpcode() == CMSG_CHANNEL_LIST || packet.GetOpcode() == CMSG_CHANNEL_DISPLAY_LIST); + } + + void Read() override; + + std::string ChannelName; + }; + + class ChannelListResponse final : public ServerPacket + { + public: + struct ChannelPlayer + { + ChannelPlayer(ObjectGuid const& guid, uint32 realm, uint8 flags) : + Guid(guid), VirtualRealmAddress(realm), Flags(flags) { } + + ObjectGuid Guid; ///< Player Guid + uint32 VirtualRealmAddress; + uint8 Flags = 0; ///< @see enum ChannelMemberFlags + }; + + ChannelListResponse() : ServerPacket(SMSG_CHANNEL_LIST) { } + + WorldPacket const* Write() override; + + std::vector<ChannelPlayer> Members; + std::string Channel; ///< Channel Name + uint8 ChannelFlags = 0; ///< @see enum ChannelFlags + bool Display = false; + }; + + class ChannelNotify final : public ServerPacket + { + public: + ChannelNotify() : ServerPacket(SMSG_CHANNEL_NOTIFY, 80) { } + + WorldPacket const* Write() override; + + std::string Sender; + ObjectGuid SenderGuid; + ObjectGuid SenderAccountID; + uint8 Type = 0; ///< @see enum ChatNotify + uint8 OldFlags = 0; ///< @see enum ChannelMemberFlags + uint8 NewFlags = 0; ///< @see enum ChannelMemberFlags + std::string Channel; ///< Channel Name + uint32 SenderVirtualRealm = 0; + ObjectGuid TargetGuid; + uint32 TargetVirtualRealm = 0; + int32 ChatChannelID = 0; + }; + + class ChannelNotifyJoined final : public ServerPacket + { + public: + ChannelNotifyJoined() : ServerPacket(SMSG_CHANNEL_NOTIFY_JOINED, 50) { } + + WorldPacket const* Write() override; + + std::string ChannelWelcomeMsg; + int32 ChatChannelID = 0; + int32 InstanceID = 0; + uint8 ChannelFlags = 0; ///< @see enum ChannelFlags + std::string Channel; ///< Channel Name + }; + + class ChannelNotifyLeft final : public ServerPacket + { + public: + ChannelNotifyLeft() : ServerPacket(SMSG_CHANNEL_NOTIFY_LEFT, 30) { } + + WorldPacket const* Write() override; + + std::string Channel; ///< Channel Name + int32 ChatChannelID = 0; + bool Suspended = false; ///< User Leave - false, On Zone Change - true + }; + + class JoinChannel final : public ClientPacket + { + public: + JoinChannel(WorldPacket&& packet) : ClientPacket(CMSG_JOIN_CHANNEL, std::move(packet)) { } + + void Read() override; + + std::string Password; + std::string ChannelName; + bool CreateVoiceSession = false; + int32 ChatChannelId = 0; + bool Internal = false; + }; + + class LeaveChannel final : public ClientPacket + { + public: + LeaveChannel(WorldPacket&& packet) : ClientPacket(CMSG_LEAVE_CHANNEL, std::move(packet)) { } + + void Read() override; + + int32 ZoneChannelID = 0; + std::string ChannelName; + }; + } +} + +#endif // ChannelPackets_h__ diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp index 9876da54ae3..b5d26bf2968 100644 --- a/src/server/game/Server/Packets/CharacterPackets.cpp +++ b/src/server/game/Server/Packets/CharacterPackets.cpp @@ -200,7 +200,7 @@ void WorldPackets::Character::CreateChar::Read() _worldPacket >> CreateInfo->OutfitId; CreateInfo->Name = _worldPacket.ReadString(nameLength); if (CreateInfo->TemplateSet.HasValue) - _worldPacket >> CreateInfo->TemplateSet.value; + _worldPacket >> CreateInfo->TemplateSet.Value; } WorldPacket const* WorldPackets::Character::CharacterCreateResponse::Write() @@ -234,7 +234,7 @@ WorldPacket const* WorldPackets::Character::CharacterRenameResult::Write() _worldPacket.WriteBits(Name.length(), 6); if (Guid.HasValue) - _worldPacket << Guid.value; + _worldPacket << Guid.Value; _worldPacket.WriteString(Name); return &_worldPacket; @@ -274,19 +274,19 @@ void WorldPackets::Character::CharRaceOrFactionChange::Read() RaceOrFactionChangeInfo->Name = _worldPacket.ReadString(nameLength); if (RaceOrFactionChangeInfo->SkinID.HasValue) - _worldPacket >> RaceOrFactionChangeInfo->SkinID.value; + _worldPacket >> RaceOrFactionChangeInfo->SkinID.Value; if (RaceOrFactionChangeInfo->HairColorID.HasValue) - _worldPacket >> RaceOrFactionChangeInfo->HairColorID.value; + _worldPacket >> RaceOrFactionChangeInfo->HairColorID.Value; if (RaceOrFactionChangeInfo->HairStyleID.HasValue) - _worldPacket >> RaceOrFactionChangeInfo->HairStyleID.value; + _worldPacket >> RaceOrFactionChangeInfo->HairStyleID.Value; if (RaceOrFactionChangeInfo->FacialHairStyleID.HasValue) - _worldPacket >> RaceOrFactionChangeInfo->FacialHairStyleID.value; + _worldPacket >> RaceOrFactionChangeInfo->FacialHairStyleID.Value; if (RaceOrFactionChangeInfo->FaceID.HasValue) - _worldPacket >> RaceOrFactionChangeInfo->FaceID.value; + _worldPacket >> RaceOrFactionChangeInfo->FaceID.Value; } WorldPacket const* WorldPackets::Character::CharFactionChangeResult::Write() @@ -298,15 +298,15 @@ WorldPacket const* WorldPackets::Character::CharFactionChangeResult::Write() if (Display.HasValue) { - _worldPacket.WriteBits(Display.value.Name.length(), 6); - _worldPacket << uint8(Display.value.SexID); - _worldPacket << uint8(Display.value.SkinID); - _worldPacket << uint8(Display.value.HairColorID); - _worldPacket << uint8(Display.value.HairStyleID); - _worldPacket << uint8(Display.value.FacialHairStyleID); - _worldPacket << uint8(Display.value.FaceID); - _worldPacket << uint8(Display.value.RaceID); - _worldPacket.WriteString(Display.value.Name); + _worldPacket.WriteBits(Display.Value.Name.length(), 6); + _worldPacket << uint8(Display.Value.SexID); + _worldPacket << uint8(Display.Value.SkinID); + _worldPacket << uint8(Display.Value.HairColorID); + _worldPacket << uint8(Display.Value.HairStyleID); + _worldPacket << uint8(Display.Value.FacialHairStyleID); + _worldPacket << uint8(Display.Value.FaceID); + _worldPacket << uint8(Display.Value.RaceID); + _worldPacket.WriteString(Display.Value.Name); } return &_worldPacket; @@ -395,46 +395,3 @@ void WorldPackets::Character::LoadingScreenNotify::Read() _worldPacket >> MapID; Showing = _worldPacket.ReadBit(); } - -void WorldPackets::Character::QueryPlayerName::Read() -{ - _worldPacket >> Player; - - Hint.VirtualRealmAddress.HasValue = _worldPacket.ReadBit(); - Hint.NativeRealmAddress.HasValue = _worldPacket.ReadBit(); - - if (Hint.VirtualRealmAddress.HasValue) - _worldPacket >> Hint.VirtualRealmAddress.value; - - if (Hint.NativeRealmAddress.HasValue) - _worldPacket >> Hint.NativeRealmAddress.value; -} - -WorldPacket const* WorldPackets::Character::PlayerNameResponse::Write() -{ - _worldPacket << Result; - _worldPacket << Player; - - if (Result == 0) - { - _worldPacket.WriteBits(Data.Name.length(), 7); - - for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) - _worldPacket.WriteBits(Data.DeclinedNames.name[i].length(), 7); - - for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) - _worldPacket.WriteString(Data.DeclinedNames.name[i]); - - _worldPacket << Data.AccountID; - _worldPacket << Data.BnetAccountID; - _worldPacket << Data.GuidActual; - _worldPacket << Data.VirtualRealmAddress; - _worldPacket << Data.Race; - _worldPacket << Data.Sex; - _worldPacket << Data.ClassID; - _worldPacket << Data.Level; - _worldPacket.WriteString(Data.Name); - } - - return &_worldPacket; -} diff --git a/src/server/game/Server/Packets/CharacterPackets.h b/src/server/game/Server/Packets/CharacterPackets.h index 8ffd3622539..386c407b10f 100644 --- a/src/server/game/Server/Packets/CharacterPackets.h +++ b/src/server/game/Server/Packets/CharacterPackets.h @@ -473,50 +473,6 @@ namespace WorldPackets int32 MapID = -1; bool Showing = false; }; - - struct PlayerGuidLookupHint - { - Optional<uint32> VirtualRealmAddress; ///< current realm (?) (identifier made from the Index, BattleGroup and Region) - Optional<uint32> NativeRealmAddress; ///< original realm (?) (identifier made from the Index, BattleGroup and Region) - }; - - struct PlayerGuidLookupData - { - bool IsDeleted = false; - ObjectGuid AccountID; - ObjectGuid BnetAccountID; - ObjectGuid GuidActual; - std::string Name; - uint32 VirtualRealmAddress = 0; - uint8 Race = RACE_NONE; - uint8 Sex = GENDER_NONE; - uint8 ClassID = CLASS_NONE; - uint8 Level = 0; - DeclinedName DeclinedNames; - }; - - class QueryPlayerName final : public ClientPacket - { - public: - QueryPlayerName(WorldPacket&& packet) : ClientPacket(CMSG_NAME_QUERY, std::move(packet)) { } - - void Read() override; - - ObjectGuid Player; - PlayerGuidLookupHint Hint; - }; - - class PlayerNameResponse final : public ServerPacket - { - public: - PlayerNameResponse() : ServerPacket(SMSG_NAME_QUERY_RESPONSE, 60) { } - - WorldPacket const* Write() override; - - ObjectGuid Player; - uint8 Result = 0; // 0 - full packet, != 0 - only guid - PlayerGuidLookupData Data; - }; } } diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp new file mode 100644 index 00000000000..7590a092b2c --- /dev/null +++ b/src/server/game/Server/Packets/ChatPackets.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ChatPackets.h" + +void WorldPackets::Chat::ChatMessage::Read() +{ + _worldPacket >> Language; + uint32 len = _worldPacket.ReadBits(8); + Text = _worldPacket.ReadString(len); +} + +void WorldPackets::Chat::ChatMessageWhisper::Read() +{ + _worldPacket >> Language; + uint32 targetLen = _worldPacket.ReadBits(9); + uint32 textLen = _worldPacket.ReadBits(8); + Target = _worldPacket.ReadString(targetLen); + Text = _worldPacket.ReadString(textLen); +} + +void WorldPackets::Chat::ChatMessageChannel::Read() +{ + _worldPacket >> Language; + uint32 targetLen = _worldPacket.ReadBits(9); + uint32 textLen = _worldPacket.ReadBits(8); + _worldPacket.ResetBitPos(); + Target = _worldPacket.ReadString(targetLen); + Text = _worldPacket.ReadString(textLen); +} + +void WorldPackets::Chat::ChatAddonMessage::Read() +{ + uint32 prefixLen = _worldPacket.ReadBits(5); + uint32 textLen = _worldPacket.ReadBits(8); + Prefix = _worldPacket.ReadString(prefixLen); + Text = _worldPacket.ReadString(textLen); +} + +void WorldPackets::Chat::ChatAddonMessageWhisper::Read() +{ + uint32 targetLen = _worldPacket.ReadBits(9); + uint32 prefixLen = _worldPacket.ReadBits(5); + uint32 textLen = _worldPacket.ReadBits(8); + Target = _worldPacket.ReadString(targetLen); + Prefix = _worldPacket.ReadString(prefixLen); + Text = _worldPacket.ReadString(textLen); +} + +void WorldPackets::Chat::ChatMessageDND::Read() +{ + uint32 len = _worldPacket.ReadBits(8); + Text = _worldPacket.ReadString(len); +} + +void WorldPackets::Chat::ChatMessageAFK::Read() +{ + uint32 len = _worldPacket.ReadBits(8); + Text = _worldPacket.ReadString(len); +} + +void WorldPackets::Chat::ChatMessageEmote::Read() +{ + uint32 len = _worldPacket.ReadBits(8); + Text = _worldPacket.ReadString(len); +} + +WorldPacket const* WorldPackets::Chat::Chat::Write() +{ + _worldPacket << SlashCmd; + _worldPacket << Language; + _worldPacket << SenderGUID; + _worldPacket << SenderGuildGUID; + _worldPacket << SenderAccountGUID; + _worldPacket << TargetGUID; + _worldPacket << TargetVirtualAddress; + _worldPacket << SenderVirtualAddress; + _worldPacket << PartyGUID; + _worldPacket << AchievementID; + _worldPacket << DisplayTime; + _worldPacket.WriteBits(SenderName.length(), 11); + _worldPacket.WriteBits(TargetName.length(), 11); + _worldPacket.WriteBits(Prefix.length(), 5); + _worldPacket.WriteBits(Channel.length(), 7); + _worldPacket.WriteBits(ChatText.length(), 12); + _worldPacket.WriteBits(ChatFlags, 10); + _worldPacket.WriteBit(HideChatLog); + _worldPacket.WriteBit(FakeSenderName); + _worldPacket.WriteString(SenderName); + _worldPacket.WriteString(TargetName); + _worldPacket.WriteString(Prefix); + _worldPacket.WriteString(Channel); + _worldPacket.WriteString(ChatText); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Chat::Emote::Write() +{ + _worldPacket << Guid; + _worldPacket << EmoteID; + + return &_worldPacket; +} + +void WorldPackets::Chat::CTextEmote::Read() +{ + _worldPacket >> Target; + _worldPacket >> EmoteID; + _worldPacket >> SoundIndex; +} + +WorldPacket const* WorldPackets::Chat::STextEmote::Write() +{ + _worldPacket << SourceGUID; + _worldPacket << SourceAccountGUID; + _worldPacket << EmoteID; + _worldPacket << SoundIndex; + _worldPacket << TargetGUID; + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/ChatPackets.h b/src/server/game/Server/Packets/ChatPackets.h new file mode 100644 index 00000000000..3d65bb04c54 --- /dev/null +++ b/src/server/game/Server/Packets/ChatPackets.h @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ChatPackets_h__ +#define ChatPackets_h__ + +#include "Packet.h" +#include "SharedDefines.h" +#include "ObjectGuid.h" + +namespace WorldPackets +{ + namespace Chat + { + // CMSG_MESSAGECHAT_GUILD + // CMSG_MESSAGECHAT_OFFICER + // CMSG_MESSAGECHAT_YELL + // CMSG_MESSAGECHAT_SAY + // CMSG_MESSAGECHAT_PARTY + // CMSG_MESSAGECHAT_RAID + // CMSG_MESSAGECHAT_RAID_WARNING + class ChatMessage final : public ClientPacket + { + public: + ChatMessage(WorldPacket&& packet) : ClientPacket(std::move(packet)) { } + + void Read() override; + + std::string Text; + int32 Language = LANG_UNIVERSAL; + }; + + // CMSG_MESSAGECHAT_WHISPER + class ChatMessageWhisper final : public ClientPacket + { + public: + ChatMessageWhisper(WorldPacket&& packet) : ClientPacket(std::move(packet)) { } + + void Read() override; + + int32 Language = LANG_UNIVERSAL; + std::string Text; + std::string Target; + }; + + // CMSG_MESSAGECHAT_CHANNEL + class ChatMessageChannel final : public ClientPacket + { + public: + ChatMessageChannel(WorldPacket&& packet) : ClientPacket(std::move(packet)) { } + + void Read() override; + + int32 Language = LANG_UNIVERSAL; + std::string Text; + std::string Target; + }; + + // CMSG_MESSAGECHAT_ADDON_GUILD + // CMSG_MESSAGECHAT_ADDON_OFFICER + // CMSG_MESSAGECHAT_ADDON_PARTY + // CMSG_MESSAGECHAT_ADDON_RAID + class ChatAddonMessage final : public ClientPacket + { + public: + ChatAddonMessage(WorldPacket&& packet) : ClientPacket(std::move(packet)) { } + + void Read() override; + + std::string Prefix; + std::string Text; + }; + + // CMSG_MESSAGECHAT_ADDON_WHISPER + class ChatAddonMessageWhisper final : public ClientPacket + { + public: + ChatAddonMessageWhisper(WorldPacket&& packet) : ClientPacket(std::move(packet)) { } + + void Read() override; + + std::string Prefix; + std::string Target; + std::string Text; + }; + + class ChatMessageDND final : public ClientPacket + { + public: + ChatMessageDND(WorldPacket&& packet) : ClientPacket(CMSG_MESSAGECHAT_DND, std::move(packet)) { } + + void Read() override; + + std::string Text; + }; + + class ChatMessageAFK final : public ClientPacket + { + public: + ChatMessageAFK(WorldPacket&& packet) : ClientPacket(CMSG_MESSAGECHAT_AFK, std::move(packet)) { } + + void Read() override; + + std::string Text; + }; + + class ChatMessageEmote final : public ClientPacket + { + public: + ChatMessageEmote(WorldPacket&& packet) : ClientPacket(CMSG_MESSAGECHAT_EMOTE, std::move(packet)) { } + + void Read() override; + + std::string Text; + }; + + // SMSG_MESSAGECHAT + class Chat final : public ServerPacket + { + public: + Chat() : ServerPacket(SMSG_MESSAGECHAT, 100) { } + + WorldPacket const* Write() override; + + uint8 SlashCmd = 0; + uint8 Language = LANG_UNIVERSAL; + ObjectGuid SenderGUID; + ObjectGuid SenderGuildGUID; + ObjectGuid SenderAccountGUID; + ObjectGuid TargetGUID; + ObjectGuid PartyGUID; + uint32 SenderVirtualAddress; + uint32 TargetVirtualAddress; + std::string SenderName; + std::string TargetName; + std::string Prefix; + std::string Channel; + std::string ChatText; + uint32 AchievementID = 0; + uint8 ChatFlags = 0; + float DisplayTime = 0.0f; + bool HideChatLog = false; + bool FakeSenderName = false; + }; + + class Emote final : public ServerPacket + { + public: + Emote() : ServerPacket(SMSG_EMOTE, 18 + 4) { } + + WorldPacket const* Write() override; + + ObjectGuid Guid; + int32 EmoteID; + }; + + class CTextEmote final : public ClientPacket + { + public: + CTextEmote(WorldPacket&& packet) : ClientPacket(CMSG_TEXT_EMOTE, std::move(packet)) { } + + void Read() override; + + ObjectGuid Target; + int32 EmoteID; + int32 SoundIndex; + }; + + class STextEmote final : public ServerPacket + { + public: + STextEmote() : ServerPacket(SMSG_TEXT_EMOTE, 3 * 18 + 2 * 4) { } + + WorldPacket const* Write() override; + + ObjectGuid SourceGUID; + ObjectGuid SourceAccountGUID; + ObjectGuid TargetGUID; + int32 SoundIndex; + int32 EmoteID; + }; + } +} + +#endif // ChatPackets_h__ diff --git a/src/server/game/Server/Packets/ClientConfigPackets.cpp b/src/server/game/Server/Packets/ClientConfigPackets.cpp index b46288f86cb..693f8e773df 100644 --- a/src/server/game/Server/Packets/ClientConfigPackets.cpp +++ b/src/server/game/Server/Packets/ClientConfigPackets.cpp @@ -94,3 +94,36 @@ WorldPacket const* WorldPackets::ClientConfig::ClientCacheVersion::Write() return &_worldPacket; } + +void WorldPackets::ClientConfig::RequestAccountData::Read() +{ + _worldPacket >> PlayerGuid; + DataType = _worldPacket.ReadBits(3); +} + +WorldPacket const* WorldPackets::ClientConfig::UpdateAccountData::Write() +{ + _worldPacket << Player; + _worldPacket << uint32(Time); + _worldPacket << uint32(Size); + _worldPacket.WriteBits(DataType, 3); + _worldPacket << uint32(CompressedData.size()); + _worldPacket.append(CompressedData); + + return &_worldPacket; +} + +void WorldPackets::ClientConfig::UserClientUpdateAccountData::Read() +{ + _worldPacket >> PlayerGuid; + _worldPacket >> Time; + _worldPacket >> Size; + DataType = _worldPacket.ReadBits(3); + + uint32 compressedSize = _worldPacket.read<uint32>(); + if (compressedSize) + { + CompressedData.resize(compressedSize); + _worldPacket.read(CompressedData.contents(), compressedSize); + } +} diff --git a/src/server/game/Server/Packets/ClientConfigPackets.h b/src/server/game/Server/Packets/ClientConfigPackets.h index 0dbcfd7d577..8a29b1fb175 100644 --- a/src/server/game/Server/Packets/ClientConfigPackets.h +++ b/src/server/game/Server/Packets/ClientConfigPackets.h @@ -60,6 +60,45 @@ namespace WorldPackets uint32 CacheVersion = 0; }; + + class RequestAccountData final : public ClientPacket + { + public: + RequestAccountData(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_ACCOUNT_DATA, std::move(packet)) { } + + void Read() override; + + ObjectGuid PlayerGuid; + uint8 DataType = 0; ///< @see enum AccountDataType + }; + + class UpdateAccountData final : public ServerPacket + { + public: + UpdateAccountData() : ServerPacket(SMSG_UPDATE_ACCOUNT_DATA) { } + + WorldPacket const* Write() override; + + ObjectGuid Player; + uint32 Time = 0; ///< UnixTime + uint32 Size = 0; ///< decompressed size + uint8 DataType = 0; ///< @see enum AccountDataType + ByteBuffer CompressedData; + }; + + class UserClientUpdateAccountData final : public ClientPacket + { + public: + UserClientUpdateAccountData(WorldPacket&& packet) : ClientPacket(CMSG_UPDATE_ACCOUNT_DATA, std::move(packet)) { } + + void Read() override; + + ObjectGuid PlayerGuid; + uint32 Time = 0; ///< UnixTime + uint32 Size = 0; ///< decompressed size + uint8 DataType = 0; ///< @see enum AccountDataType + ByteBuffer CompressedData; + }; } } diff --git a/src/server/game/Server/Packets/CombatPackets.cpp b/src/server/game/Server/Packets/CombatPackets.cpp new file mode 100644 index 00000000000..7793ef4ae30 --- /dev/null +++ b/src/server/game/Server/Packets/CombatPackets.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "CombatPackets.h" +#include "SpellPackets.h" + +void WorldPackets::Combat::AttackSwing::Read() +{ + _worldPacket >> Victim; +} + +WorldPacket const* WorldPackets::Combat::AttackStart::Write() +{ + _worldPacket << Attacker; + _worldPacket << Victim; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Combat::SAttackStop::Write() +{ + _worldPacket << Attacker; + _worldPacket << Victim; + _worldPacket.WriteBit(Dead); + _worldPacket.FlushBits(); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Combat::ThreatUpdate::Write() +{ + _worldPacket << UnitGUID; + _worldPacket << int32(ThreatList.size()); + for (WorldPackets::Combat::ThreatInfo const& threatInfo : ThreatList) + { + _worldPacket << threatInfo.UnitGUID; + _worldPacket << threatInfo.Threat; + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Combat::HighestThreatUpdate::Write() +{ + _worldPacket << UnitGUID; + _worldPacket << HighestThreatGUID; + _worldPacket << int32(ThreatList.size()); + for (WorldPackets::Combat::ThreatInfo const& threatInfo : ThreatList) + { + _worldPacket << threatInfo.UnitGUID; + _worldPacket << threatInfo.Threat; + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Combat::ThreatRemove::Write() +{ + _worldPacket << UnitGUID; + _worldPacket << AboutGUID; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Combat::AIReaction::Write() +{ + _worldPacket << UnitGUID; + _worldPacket << Reaction; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Combat::AttackerStateUpdate::Write() +{ + if (_worldPacket.WriteBit(LogData.HasValue)) + _worldPacket << LogData.Value; + + // Placeholder for size which will be calculated at the end based on packet size + // Client uses this size to copy remaining packet to another CDataStore + _worldPacket << int32(0); + size_t pos = _worldPacket.wpos(); + + _worldPacket << HitInfo; + _worldPacket << AttackerGUID; + _worldPacket << VictimGUID; + _worldPacket << Damage; + _worldPacket << OverDamage; + if (_worldPacket.WriteBit(SubDmg.HasValue)) + { + _worldPacket << SubDmg.Value.SchoolMask; + _worldPacket << SubDmg.Value.FDamage; + _worldPacket << SubDmg.Value.Damage; + if (HitInfo & (HITINFO_FULL_ABSORB | HITINFO_PARTIAL_ABSORB)) + _worldPacket << SubDmg.Value.Absorbed; + if (HitInfo & (HITINFO_FULL_RESIST | HITINFO_PARTIAL_RESIST)) + _worldPacket << SubDmg.Value.Resisted; + } + + _worldPacket << VictimState; + _worldPacket << AttackerState; + _worldPacket << MeleeSpellID; + if (HitInfo & HITINFO_BLOCK) + _worldPacket << BlockAmount; + if (HitInfo & HITINFO_RAGE_GAIN) + _worldPacket << RageGained; + if (HitInfo & HITINFO_UNK1) + { + _worldPacket << UnkState.State1; + _worldPacket << UnkState.State2; + _worldPacket << UnkState.State3; + _worldPacket << UnkState.State4; + _worldPacket << UnkState.State5; + _worldPacket << UnkState.State6; + _worldPacket << UnkState.State7; + _worldPacket << UnkState.State8; + _worldPacket << UnkState.State9; + _worldPacket << UnkState.State10; + _worldPacket << UnkState.State11; + _worldPacket << UnkState.State12; + } + if (HitInfo & (HITINFO_BLOCK|HITINFO_UNK12)) + _worldPacket << Unk; + + // Update size placeholder + _worldPacket.put<int32>(pos - sizeof(int32), _worldPacket.wpos() - pos); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/CombatPackets.h b/src/server/game/Server/Packets/CombatPackets.h new file mode 100644 index 00000000000..14648297342 --- /dev/null +++ b/src/server/game/Server/Packets/CombatPackets.h @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef CombatPackets_h__ +#define CombatPackets_h__ + +#include "Packet.h" +#include "ObjectGuid.h" +#include "SpellPackets.h" + +namespace WorldPackets +{ + namespace Combat + { + class AttackSwing final : public ClientPacket + { + public: + AttackSwing(WorldPacket&& packet) : ClientPacket(CMSG_ATTACKSWING, std::move(packet)) { } + + void Read() override; + + ObjectGuid Victim; + }; + + class AttackStop final : public ClientPacket + { + public: + AttackStop(WorldPacket&& packet) : ClientPacket(CMSG_ATTACKSTOP, std::move(packet)) { } + + void Read() override { } + }; + + class AttackStart final : public ServerPacket + { + public: + AttackStart() : ServerPacket(SMSG_ATTACKSTART, 16) { } + + WorldPacket const* Write() override; + + ObjectGuid Attacker; + ObjectGuid Victim; + }; + + class SAttackStop final : public ServerPacket + { + public: + SAttackStop() : ServerPacket(SMSG_ATTACKSTOP, 17) { } + + WorldPacket const* Write() override; + + ObjectGuid Attacker; + ObjectGuid Victim; + bool Dead = false; + }; + + struct ThreatInfo + { + ObjectGuid UnitGUID; + int32 Threat = 0; + }; + + class ThreatUpdate final : public ServerPacket + { + public: + ThreatUpdate() : ServerPacket(SMSG_THREAT_UPDATE, 24) { } + + WorldPacket const* Write() override; + + ObjectGuid UnitGUID; + std::vector<ThreatInfo> ThreatList; + }; + + class HighestThreatUpdate final : public ServerPacket + { + public: + HighestThreatUpdate() : ServerPacket(SMSG_HIGHEST_THREAT_UPDATE, 44) { } + + WorldPacket const* Write() override; + + ObjectGuid UnitGUID; + std::vector<ThreatInfo> ThreatList; + ObjectGuid HighestThreatGUID; + }; + + class ThreatRemove final : public ServerPacket + { + public: + ThreatRemove() : ServerPacket(SMSG_THREAT_REMOVE, 16) { } + + WorldPacket const* Write() override; + + ObjectGuid AboutGUID; // Unit to remove threat from (e.g. player, pet, guardian) + ObjectGuid UnitGUID; // Unit being attacked (e.g. creature, boss) + }; + + class AIReaction final : public ServerPacket + { + public: + AIReaction() : ServerPacket(SMSG_AI_REACTION, 12) { } + + WorldPacket const* Write() override; + + ObjectGuid UnitGUID; + uint32 Reaction = 0; + }; + + struct SubDamage + { + int32 SchoolMask = 0; + float FDamage = 0.0f; // Float damage (Most of the time equals to Damage) + int32 Damage = 0; + int32 Absorbed = 0; + int32 Resisted = 0; + }; + + struct UnkAttackerState + { + int32 State1 = 0; + float State2 = 0.0f; + float State3 = 0.0f; + float State4 = 0.0f; + float State5 = 0.0f; + float State6 = 0.0f; + float State7 = 0.0f; + float State8 = 0.0f; + float State9 = 0.0f; + float State10 = 0.0f; + float State11 = 0.0f; + int32 State12 = 0; + }; + + class AttackerStateUpdate final : public ServerPacket + { + public: + AttackerStateUpdate() : ServerPacket(SMSG_ATTACKERSTATEUPDATE, 70) { } + + WorldPacket const* Write() override; + + Optional<WorldPackets::Spell::SpellCastLogData> LogData; + uint32 HitInfo = 0; // Flags + ObjectGuid AttackerGUID; + ObjectGuid VictimGUID; + int32 Damage = 0; + int32 OverDamage = -1; // (damage - health) or -1 if unit is still alive + Optional<SubDamage> SubDmg; + uint8 VictimState = 0; + int32 AttackerState = -1; + int32 MeleeSpellID = 0; + int32 BlockAmount = 0; + int32 RageGained = 0; + UnkAttackerState UnkState; + float Unk = 0.0f; + }; + } +} + +#endif // CombatPackets_h__ diff --git a/src/server/game/Server/Packets/EquipmentSetPackets.cpp b/src/server/game/Server/Packets/EquipmentSetPackets.cpp new file mode 100644 index 00000000000..07cab20debf --- /dev/null +++ b/src/server/game/Server/Packets/EquipmentSetPackets.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "EquipmentSetPackets.h" + +WorldPacket const* WorldPackets::EquipmentSet::EquipmentSetID::Write() +{ + _worldPacket << uint64(GUID); + _worldPacket << uint32(SetID); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::EquipmentSet::LoadEquipmentSet::Write() +{ + _worldPacket << uint32(SetData.size()); + + for (EquipmentSetInfo::EquipmentSetData const* equipSet : SetData) + { + _worldPacket << uint64(equipSet->Guid); + _worldPacket << uint32(equipSet->SetID); + _worldPacket << uint32(equipSet->IgnoreMask); + + for (ObjectGuid const& guid : equipSet->Pieces) + _worldPacket << guid; + + _worldPacket.WriteBits(equipSet->SetName.length(), 8); + _worldPacket.WriteBits(equipSet->SetIcon.length(), 9); + _worldPacket.WriteString(equipSet->SetName); + _worldPacket.WriteString(equipSet->SetIcon); + _worldPacket.FlushBits(); + } + + return &_worldPacket; +} + +void WorldPackets::EquipmentSet::SaveEquipmentSet::Read() +{ + _worldPacket >> Set.Guid; + _worldPacket >> Set.SetID; + _worldPacket >> Set.IgnoreMask; + + for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) + _worldPacket >> Set.Pieces[i]; + + uint32 setNameLength = _worldPacket.ReadBits(8); + uint32 setIconLength = _worldPacket.ReadBits(9); + + Set.SetName = _worldPacket.ReadString(setNameLength); + Set.SetIcon = _worldPacket.ReadString(setIconLength); +} diff --git a/src/server/game/Server/Packets/EquipmentSetPackets.h b/src/server/game/Server/Packets/EquipmentSetPackets.h new file mode 100644 index 00000000000..b01c483f5ac --- /dev/null +++ b/src/server/game/Server/Packets/EquipmentSetPackets.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "Packet.h" +#include "Player.h" + +namespace WorldPackets +{ + namespace EquipmentSet + { + class EquipmentSetID final : public ServerPacket + { + public: + EquipmentSetID() : ServerPacket(SMSG_EQUIPMENT_SET_SAVED, 8 + 4) { } + + WorldPacket const* Write() override; + + uint64 GUID = 0; ///< Set Identifier + uint32 SetID = 0; ///< Index + }; + + class LoadEquipmentSet final : public ServerPacket + { + public: + LoadEquipmentSet() : ServerPacket(SMSG_EQUIPMENT_SET_LIST, 4) { } + + WorldPacket const* Write() override; + + std::vector<EquipmentSetInfo::EquipmentSetData const*> SetData; + }; + + class SaveEquipmentSet final : public ClientPacket + { + public: + SaveEquipmentSet(WorldPacket&& packet) : ClientPacket(CMSG_EQUIPMENT_SET_SAVE, std::move(packet)) { } + + void Read() override; + + EquipmentSetInfo::EquipmentSetData Set; + }; + } +} diff --git a/src/server/game/Server/Packets/GuildPackets.cpp b/src/server/game/Server/Packets/GuildPackets.cpp index c853cf4cc19..f4159927543 100644 --- a/src/server/game/Server/Packets/GuildPackets.cpp +++ b/src/server/game/Server/Packets/GuildPackets.cpp @@ -33,16 +33,16 @@ WorldPacket const* WorldPackets::Guild::QueryGuildInfoResponse::Write() if (Info.HasValue) { - _worldPacket << Info.value.GuildGUID; - _worldPacket << uint32(Info.value.VirtualRealmAddress); - _worldPacket << uint32(Info.value.Ranks.size()); - _worldPacket << uint32(Info.value.EmblemStyle); - _worldPacket << uint32(Info.value.EmblemColor); - _worldPacket << uint32(Info.value.BorderStyle); - _worldPacket << uint32(Info.value.BorderColor); - _worldPacket << uint32(Info.value.BackgroundColor); - - for (GuildInfo::GuildInfoRank const& rank : Info.value.Ranks) + _worldPacket << Info.Value.GuildGUID; + _worldPacket << uint32(Info.Value.VirtualRealmAddress); + _worldPacket << uint32(Info.Value.Ranks.size()); + _worldPacket << uint32(Info.Value.EmblemStyle); + _worldPacket << uint32(Info.Value.EmblemColor); + _worldPacket << uint32(Info.Value.BorderStyle); + _worldPacket << uint32(Info.Value.BorderColor); + _worldPacket << uint32(Info.Value.BackgroundColor); + + for (GuildInfo::GuildInfoRank const& rank : Info.Value.Ranks) { _worldPacket << uint32(rank.RankID); _worldPacket << uint32(rank.RankOrder); @@ -51,8 +51,8 @@ WorldPacket const* WorldPackets::Guild::QueryGuildInfoResponse::Write() _worldPacket.WriteString(rank.RankName); } - _worldPacket.WriteBits(Info.value.GuildName.size(), 7); - _worldPacket.WriteString(Info.value.GuildName); + _worldPacket.WriteBits(Info.Value.GuildName.size(), 7); + _worldPacket.WriteString(Info.Value.GuildName); } _worldPacket.FlushBits(); diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp new file mode 100644 index 00000000000..924a9eec352 --- /dev/null +++ b/src/server/game/Server/Packets/ItemPackets.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ItemPackets.h" + +WorldPacket const* WorldPackets::Item::SetProficiency::Write() +{ + _worldPacket << ProficiencyMask; + _worldPacket << ProficiencyClass; + + return &_worldPacket; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData const& itemBonusInstanceData) +{ + data << itemBonusInstanceData.Context; + data << uint32(itemBonusInstanceData.BonusListIDs.size()); + for (uint32 bonusID : itemBonusInstanceData.BonusListIDs) + data << bonusID; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const& itemInstance) +{ + data << itemInstance.ItemID; + data << itemInstance.RandomPropertiesSeed; + data << itemInstance.RandomPropertiesID; + + data.WriteBit(itemInstance.ItemBonus.HasValue); + data.WriteBit(!itemInstance.Modifications.empty()); + data.FlushBits(); + + if (itemInstance.ItemBonus.HasValue) + data << itemInstance.ItemBonus.Value; + + if (!itemInstance.Modifications.empty()) + { + data << uint32(itemInstance.Modifications.size() * sizeof(uint32)); + for (uint32 itemMod : itemInstance.Modifications) + data << itemMod; + } + + return data; +} diff --git a/src/server/game/Server/Packets/ItemPackets.h b/src/server/game/Server/Packets/ItemPackets.h new file mode 100644 index 00000000000..cb87bc0c586 --- /dev/null +++ b/src/server/game/Server/Packets/ItemPackets.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ItemPackets_h__ +#define ItemPackets_h__ + +#include "Packet.h" + +namespace WorldPackets +{ + namespace Item + { + class SetProficiency final : public ServerPacket + { + public: + SetProficiency() : ServerPacket(SMSG_SET_PROFICIENCY, 5) { } + + WorldPacket const* Write() override; + + uint32 ProficiencyMask; + uint8 ProficiencyClass; + }; + + struct ItemBonusInstanceData + { + uint8 Context = 0; + std::vector<int32> BonusListIDs; + }; + + struct ItemInstance + { + uint32 ItemID = 0; + uint32 RandomPropertiesSeed = 0; + uint32 RandomPropertiesID = 0; + Optional<ItemBonusInstanceData> ItemBonus; + std::vector<int32> Modifications; + }; + } +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData const& itemBonusInstanceData); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const& itemInstance); + +#endif // ItemPackets_h__ diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index 66128354884..154ff134a6a 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -17,7 +17,101 @@ #include "MiscPackets.h" +WorldPacket const* WorldPackets::Misc::BindPointUpdate::Write() +{ + _worldPacket << float(BindPosition.x); + _worldPacket << float(BindPosition.y); + _worldPacket << float(BindPosition.z); + _worldPacket << uint32(BindMapID); + _worldPacket << uint32(BindAreaID); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Misc::InvalidatePlayer::Write() +{ + _worldPacket << Guid; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Misc::LoginSetTimeSpeed::Write() +{ + _worldPacket.AppendPackedTime(ServerTime); + _worldPacket.AppendPackedTime(GameTime); + _worldPacket << float(NewSpeed); + _worldPacket << uint32(ServerTimeHolidayOffset); + _worldPacket << uint32(GameTimeHolidayOffset); + + return &_worldPacket; +} + +void WorldPackets::Misc::SetSelection::Read() +{ + _worldPacket >> Selection; +} + void WorldPackets::Misc::ViolenceLevel::Read() { _worldPacket >> ViolenceLvl; } + +WorldPacket const* WorldPackets::Misc::TimeSyncRequest::Write() +{ + _worldPacket << SequenceIndex; + + return &_worldPacket; +} + +void WorldPackets::Misc::TimeSyncResponse::Read() +{ + _worldPacket >> SequenceIndex; + _worldPacket >> ClientTime; +} + +WorldPacket const* WorldPackets::Misc::UITime::Write() +{ + _worldPacket << Time; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Misc::TutorialFlags::Write() +{ + _worldPacket.append(TutorialData, MAX_ACCOUNT_TUTORIAL_VALUES); + + return &_worldPacket; +} + +void WorldPackets::Misc::TutorialSetFlag::Read() +{ + Action = _worldPacket.ReadBits(2); + _worldPacket >> TutorialBit; +} + +WorldPacket const* WorldPackets::Misc::WorldServerInfo::Write() +{ + _worldPacket << uint32(DifficultyID); + _worldPacket << uint8(IsTournamentRealm); + _worldPacket << uint32(WeeklyReset); + _worldPacket.WriteBit(IneligibleForLootMask.HasValue); + _worldPacket.WriteBit(InstanceGroupSize.HasValue); + _worldPacket.WriteBit(RestrictedAccountMaxLevel.HasValue); + _worldPacket.WriteBit(RestrictedAccountMaxMoney.HasValue); + + if (IneligibleForLootMask.HasValue) + _worldPacket << uint32(IneligibleForLootMask.Value); + + if (InstanceGroupSize.HasValue) + _worldPacket << uint32(InstanceGroupSize.Value); + + if (RestrictedAccountMaxLevel.HasValue) + _worldPacket << uint32(RestrictedAccountMaxLevel.Value); + + if (RestrictedAccountMaxMoney.HasValue) + _worldPacket << uint32(RestrictedAccountMaxMoney.Value); + + _worldPacket.FlushBits(); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index 8b78074090f..dfff0e331fc 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -19,11 +19,61 @@ #define MiscPackets_h__ #include "Packet.h" +#include "ObjectGuid.h" +#include "WorldSession.h" +#include "G3D/Vector3.h" +#include "Object.h" namespace WorldPackets { namespace Misc { + class BindPointUpdate final : public ServerPacket + { + public: + BindPointUpdate() : ServerPacket(SMSG_BINDPOINTUPDATE, 20) { } + + WorldPacket const* Write() override; + + uint32 BindMapID = MAPID_INVALID; + G3D::Vector3 BindPosition; + uint32 BindAreaID = 0; + }; + + class InvalidatePlayer final : public ServerPacket + { + public: + InvalidatePlayer() : ServerPacket(SMSG_INVALIDATE_PLAYER, 18) { } + + WorldPacket const* Write() override; + + ObjectGuid Guid; + }; + + class LoginSetTimeSpeed final : public ServerPacket + { + public: + LoginSetTimeSpeed() : ServerPacket(SMSG_LOGIN_SETTIMESPEED, 20) { } + + WorldPacket const* Write() override; + + float NewSpeed = 0.0f; + int32 ServerTimeHolidayOffset = 0; + uint32 GameTime = 0; + uint32 ServerTime = 0; + int32 GameTimeHolidayOffset = 0; + }; + + class SetSelection final : public ClientPacket + { + public: + SetSelection(WorldPacket&& packet) : ClientPacket(CMSG_SET_SELECTION, std::move(packet)) { } + + void Read() override; + + ObjectGuid Selection; ///< Target + }; + class ViolenceLevel final : public ClientPacket { public: @@ -33,6 +83,77 @@ namespace WorldPackets int8 ViolenceLvl = -1; ///< 0 - no combat effects, 1 - display some combat effects, 2 - blood, 3 - bloody, 4 - bloodier, 5 - bloodiest }; + + class TimeSyncRequest final : public ServerPacket + { + public: + TimeSyncRequest() : ServerPacket(SMSG_TIME_SYNC_REQ, 4) { } + + WorldPacket const* Write() override; + + uint32 SequenceIndex = 0; + }; + + class TimeSyncResponse final : public ClientPacket + { + public: + TimeSyncResponse(WorldPacket&& packet) : ClientPacket(CMSG_TIME_SYNC_RESP, std::move(packet)) { } + + void Read() override; + + uint32 ClientTime = 0; // Client ticks in ms + uint32 SequenceIndex = 0; // Same index as in request + }; + + class UITime final : public ServerPacket + { + public: + UITime() : ServerPacket(SMSG_WORLD_STATE_UI_TIMER_UPDATE, 4) { } + + WorldPacket const* Write() override; + + uint32 Time = 0; + }; + + class TutorialFlags : public ServerPacket + { + public: + TutorialFlags() : ServerPacket(SMSG_TUTORIAL_FLAGS, 32) + { + std::memset(TutorialData, 0, sizeof(TutorialData)); + } + + WorldPacket const* Write() override; + + uint32 TutorialData[MAX_ACCOUNT_TUTORIAL_VALUES]; + }; + + class TutorialSetFlag final : public ClientPacket + { + public: + TutorialSetFlag(WorldPacket&& packet) : ClientPacket(CMSG_TUTORIAL_FLAG, std::move(packet)) { } + + void Read() override; + + uint8 Action = 0; + uint32 TutorialBit = 0; + }; + + class WorldServerInfo final : public ServerPacket + { + public: + WorldServerInfo() : ServerPacket(SMSG_WORLD_SERVER_INFO, 26) { } + + WorldPacket const* Write() override; + + Optional<uint32> IneligibleForLootMask; ///< Encountermask? + uint32 WeeklyReset = 0; ///< UnixTime of last Weekly Reset Time + Optional<uint32> InstanceGroupSize; + uint8 IsTournamentRealm = 0; + Optional<uint32> RestrictedAccountMaxLevel; + Optional<uint32> RestrictedAccountMaxMoney; + uint32 DifficultyID = 0; + }; } } diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp index 487e230a4a1..972a52dc41c 100644 --- a/src/server/game/Server/Packets/MovementPackets.cpp +++ b/src/server/game/Server/Packets/MovementPackets.cpp @@ -16,162 +16,308 @@ */ #include "MovementPackets.h" +#include "MovementTypedefs.h" +#include "Unit.h" -void WorldPackets::Movement::ClientPlayerMovement::Read() +ByteBuffer& operator<<(ByteBuffer& data, G3D::Vector3 const& v) +{ + data << v.x << v.y << v.z; + return data; +} + +ByteBuffer& operator>>(ByteBuffer& data, G3D::Vector3& v) +{ + data >> v.x >> v.y >> v.z; + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, MovementInfo& movementInfo) +{ + bool hasTransportData = !movementInfo.transport.guid.IsEmpty(); + bool hasTransportPrevTime = hasTransportData && movementInfo.transport.prevTime != 0; + bool hasTransportVehicleId = hasTransportData && movementInfo.transport.vehicleId != 0; + bool hasFallDirection = movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR); + bool hasFallData = hasFallDirection || movementInfo.jump.fallTime != 0; + + data << movementInfo.guid; + data << movementInfo.time; + data << movementInfo.pos.PositionXYZOStream(); + data << movementInfo.pitch; + data << movementInfo.splineElevation; + + uint32 removeMovementForcesCount = 0; + data << removeMovementForcesCount; + + uint32 int168 = 0; + data << int168; + + /*for (uint32 i = 0; i < removeMovementForcesCount; ++i) + { + data << ObjectGuid; + }*/ + + data.WriteBits(movementInfo.flags, 30); + data.WriteBits(movementInfo.flags2, 15); + + data.WriteBit(hasTransportData); + data.WriteBit(hasFallData); + + data.WriteBit(0); // HeightChangeFailed + data.WriteBit(0); // RemoteTimeValid + + if (hasTransportData) + { + data << movementInfo.transport.guid; + data << movementInfo.transport.pos.PositionXYZOStream(); + data << movementInfo.transport.seat; + data << movementInfo.transport.time; + + data.WriteBit(hasTransportPrevTime); + data.WriteBit(hasTransportVehicleId); + + if (hasTransportPrevTime) + data << movementInfo.transport.prevTime; + + if (hasTransportVehicleId) + data << movementInfo.transport.vehicleId; + } + + if (hasFallData) + { + data << movementInfo.jump.fallTime; + data << movementInfo.jump.zspeed; + + data.WriteBit(hasFallDirection); + if (hasFallDirection) + { + data << movementInfo.jump.sinAngle; + data << movementInfo.jump.cosAngle; + data << movementInfo.jump.xyspeed; + } + } + + data.FlushBits(); + + return data; +} + +ByteBuffer& operator>>(ByteBuffer& data, MovementInfo& movementInfo) { - _worldPacket >> movementInfo.guid; - _worldPacket >> movementInfo.time; - _worldPacket >> movementInfo.pos.m_positionX; - _worldPacket >> movementInfo.pos.m_positionY; - _worldPacket >> movementInfo.pos.m_positionZ; - _worldPacket >> movementInfo.pos.m_orientation; - _worldPacket >> movementInfo.pitch; - _worldPacket >> movementInfo.splineElevation; + data >> movementInfo.guid; + data >> movementInfo.time; + data >> movementInfo.pos.PositionXYZOStream(); + data >> movementInfo.pitch; + data >> movementInfo.splineElevation; uint32 removeMovementForcesCount; - _worldPacket >> removeMovementForcesCount; + data >> removeMovementForcesCount; uint32 int168; - _worldPacket >> int168; + data >> int168; for (uint32 i = 0; i < removeMovementForcesCount; ++i) { ObjectGuid guid; - _worldPacket >> guid; + data >> guid; } - // ResetBitReader + movementInfo.flags = data.ReadBits(30); + movementInfo.flags2 = data.ReadBits(15); - movementInfo.flags = _worldPacket.ReadBits(30); - movementInfo.flags2 = _worldPacket.ReadBits(15); - - bool hasTransport = _worldPacket.ReadBit(); - bool hasFall = _worldPacket.ReadBit(); + bool hasTransport = data.ReadBit(); + bool hasFall = data.ReadBit(); - _worldPacket.ReadBit(); // HeightChangeFailed - _worldPacket.ReadBit(); // RemoteTimeValid + data.ReadBit(); // HeightChangeFailed + data.ReadBit(); // RemoteTimeValid if (hasTransport) { - _worldPacket >> movementInfo.transport.guid; - _worldPacket >> movementInfo.transport.pos.m_positionX; - _worldPacket >> movementInfo.transport.pos.m_positionY; - _worldPacket >> movementInfo.transport.pos.m_positionZ; - _worldPacket >> movementInfo.transport.pos.m_orientation; - _worldPacket >> movementInfo.transport.seat; - _worldPacket >> movementInfo.transport.time; + data >> movementInfo.transport.guid; + data >> movementInfo.transport.pos.PositionXYZOStream(); + data >> movementInfo.transport.seat; + data >> movementInfo.transport.time; - bool hasPrevTime = _worldPacket.ReadBit(); - bool hasVehicleId = _worldPacket.ReadBit(); + bool hasPrevTime = data.ReadBit(); + bool hasVehicleId = data.ReadBit(); if (hasPrevTime) - _worldPacket >> movementInfo.transport.prevTime; + data >> movementInfo.transport.prevTime; if (hasVehicleId) - _worldPacket >> movementInfo.transport.vehicleId; + data >> movementInfo.transport.vehicleId; } if (hasFall) { - _worldPacket >> movementInfo.jump.fallTime; - _worldPacket >> movementInfo.jump.zspeed; + data >> movementInfo.jump.fallTime; + data >> movementInfo.jump.zspeed; // ResetBitReader - bool hasFallDirection = _worldPacket.ReadBit(); + bool hasFallDirection = data.ReadBit(); if (hasFallDirection) { - _worldPacket >> movementInfo.jump.sinAngle; - _worldPacket >> movementInfo.jump.cosAngle; - _worldPacket >> movementInfo.jump.xyspeed; + data >> movementInfo.jump.sinAngle; + data >> movementInfo.jump.cosAngle; + data >> movementInfo.jump.xyspeed; } } + + return data; } -WorldPacket const* WorldPackets::Movement::ServerPlayerMovement::Write() +void WorldPackets::Movement::ClientPlayerMovement::Read() { - MovementInfo const movementInfo = mover->m_movementInfo; + _worldPacket >> movementInfo; +} - bool hasMovementFlags = mover->GetUnitMovementFlags() != 0; - bool hasMovementFlags2 = mover->GetExtraUnitMovementFlags() != 0; - bool hasTransportData = !mover->GetTransGUID().IsEmpty(); - bool hasSpline = mover->IsSplineEnabled(); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineFilterKey& monsterSplineFilterKey) +{ + data << monsterSplineFilterKey.Idx; + data << monsterSplineFilterKey.Speed; - bool hasTransportPrevTime = hasTransportData && movementInfo.transport.prevTime != 0; - bool hasTransportVehicleId = hasTransportData && movementInfo.transport.vehicleId != 0; - bool hasPitch = mover->HasUnitMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || mover->HasExtraUnitMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING); - bool hasFallDirection = mover->HasUnitMovementFlag(MOVEMENTFLAG_FALLING); - bool hasFallData = hasFallDirection || movementInfo.jump.fallTime != 0; - bool hasSplineElevation = mover->HasUnitMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION); + return data; +} - _worldPacket << movementInfo.guid; - _worldPacket << movementInfo.time; - _worldPacket << movementInfo.pos.m_positionX; - _worldPacket << movementInfo.pos.m_positionY; - _worldPacket << movementInfo.pos.m_positionZ; - _worldPacket << movementInfo.pos.m_orientation; - _worldPacket << movementInfo.pitch; - _worldPacket << movementInfo.splineElevation; +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineFilter& monsterSplineFilter) +{ + data << uint32(monsterSplineFilter.FilterKeys.size()); + data << monsterSplineFilter.BaseSpeed; + data << monsterSplineFilter.StartOffset; + data << monsterSplineFilter.DistToPrevFilterKey; + for (WorldPackets::Movement::MonsterSplineFilterKey& filterKey : monsterSplineFilter.FilterKeys) + data << filterKey; + data << monsterSplineFilter.AddedToStart; + data.WriteBits(monsterSplineFilter.FilterFlags, 2); + data.FlushBits(); + + return data; +} - uint32 removeMovementForcesCount = 0; - _worldPacket << removeMovementForcesCount; +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementSpline& movementSpline) +{ + data << movementSpline.Flags; + data << movementSpline.AnimTier; + data << movementSpline.TierTransStartTime; + data << movementSpline.Elapsed; + data << movementSpline.MoveTime; + data << movementSpline.JumpGravity; + data << movementSpline.SpecialTime; + data << int32(movementSpline.Points.size()); + data << movementSpline.Mode; + data << movementSpline.VehicleExitVoluntary; + data << movementSpline.TransportGUID; + data << movementSpline.VehicleSeat; + data << int32(movementSpline.PackedDeltas.size()); + for (G3D::Vector3 const& pos : movementSpline.Points) + data << pos; + for (G3D::Vector3 const& pos : movementSpline.PackedDeltas) + data.appendPackXYZ(pos.x, pos.y, pos.z); + data.WriteBits(movementSpline.Face, 2); + data.WriteBit(movementSpline.SplineFilter.HasValue); + data.FlushBits(); + + switch (movementSpline.Face) + { + case MONSTER_MOVE_FACING_SPOT: + data << movementSpline.FaceSpot; + break; + case MONSTER_MOVE_FACING_TARGET: + data << movementSpline.FaceDirection; + data << movementSpline.FaceGUID; + break; + case MONSTER_MOVE_FACING_ANGLE: + data << movementSpline.FaceDirection; + break; + } - uint32 int168 = 0; - _worldPacket << int168; + if (movementSpline.SplineFilter.HasValue) + data << movementSpline.SplineFilter.Value; - /*for (uint32 i = 0; i < removeMovementForcesCount; ++i) - { - _worldPacket << ObjectGuid; - }*/ + return data; +} - _worldPacket.FlushBits(); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementMonsterSpline& movementMonsterSpline) +{ + data << movementMonsterSpline.ID; + data << movementMonsterSpline.Destination; + data << movementMonsterSpline.Move; + data.WriteBit(movementMonsterSpline.CrzTeleport); - _worldPacket.WriteBits(movementInfo.flags, 30); - _worldPacket.WriteBits(movementInfo.flags2, 15); + // Unk bits. 0 if monster is moving, 1 or 2 if stopped + if (movementMonsterSpline.Move.Flags) + data.WriteBits(0, 2); + else + data.WriteBits(2, 2); - _worldPacket.WriteBit(hasTransportData); - _worldPacket.WriteBit(hasFallData); + data.FlushBits(); - _worldPacket.WriteBit(0); // HeightChangeFailed - _worldPacket.WriteBit(0); // RemoteTimeValid + return data; +} - if (hasTransportData) - { - _worldPacket << movementInfo.transport.guid; - _worldPacket << movementInfo.transport.pos.m_positionX; - _worldPacket << movementInfo.transport.pos.m_positionY; - _worldPacket << movementInfo.transport.pos.m_positionZ; - _worldPacket << movementInfo.transport.pos.m_orientation; - _worldPacket << movementInfo.transport.seat; - _worldPacket << movementInfo.transport.time; +WorldPacket const* WorldPackets::Movement::MonsterMove::Write() +{ + _worldPacket << MoverGUID; + _worldPacket << Pos; + _worldPacket << SplineData; + return &_worldPacket; +} - _worldPacket.WriteBit(hasTransportPrevTime); - _worldPacket.WriteBit(hasTransportVehicleId); +WorldPacket const* WorldPackets::Movement::MoveSplineSet::Write() +{ + _worldPacket << MoverGUID; + _worldPacket << Speed; + return &_worldPacket; +} - if (hasTransportPrevTime) - _worldPacket << movementInfo.transport.prevTime; +WorldPacket const* WorldPackets::Movement::MoveUpdate::Write() +{ + _worldPacket << movementInfo; + _worldPacket << Speed; + return &_worldPacket; +} - if (hasTransportVehicleId) - _worldPacket << movementInfo.transport.vehicleId; - } +WorldPacket const* WorldPackets::Movement::ServerPlayerMovement::Write() +{ + MovementInfo movementInfo = mover->m_movementInfo; - if (hasFallData) - { - _worldPacket << movementInfo.jump.fallTime; - _worldPacket << movementInfo.jump.zspeed; + _worldPacket << movementInfo; - _worldPacket.FlushBits(); + return &_worldPacket; +} - _worldPacket.WriteBit(hasFallDirection); - if (hasFallDirection) - { - _worldPacket << movementInfo.jump.sinAngle; - _worldPacket << movementInfo.jump.cosAngle; - _worldPacket << movementInfo.jump.xyspeed; - } +WorldPacket const* WorldPackets::Movement::TransferPending::Write() +{ + _worldPacket << int32(MapID); + _worldPacket.WriteBit(Ship.HasValue); + _worldPacket.WriteBit(TransferSpellID.HasValue); + if (Ship.HasValue) + { + _worldPacket << uint32(Ship.Value.ID); + _worldPacket << int32(Ship.Value.OriginMapID); } - + + if (TransferSpellID.HasValue) + _worldPacket << int32(TransferSpellID.Value); + _worldPacket.FlushBits(); return &_worldPacket; -}
\ No newline at end of file +} + +WorldPacket const* WorldPackets::Movement::TransferAborted::Write() +{ + _worldPacket << uint32(MapID); + _worldPacket << uint8(Arg); + _worldPacket.WriteBits(TransfertAbort, 5); + _worldPacket.FlushBits(); + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Movement::NewWorld::Write() +{ + _worldPacket << MapID; + _worldPacket << Pos.PositionXYZOStream(); + _worldPacket << Reason; + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h index f018757eada..6f3b19a661d 100644 --- a/src/server/game/Server/Packets/MovementPackets.h +++ b/src/server/game/Server/Packets/MovementPackets.h @@ -19,6 +19,8 @@ #define MovementPackets_h__ #include "Packet.h" +#include "Object.h" +#include <G3D/Vector3.h> namespace WorldPackets { @@ -37,13 +39,154 @@ namespace WorldPackets class ServerPlayerMovement final : public ServerPacket { public: - ServerPlayerMovement() : ServerPacket(SMSG_PLAYER_MOVE) {} + ServerPlayerMovement() : ServerPacket(SMSG_PLAYER_MOVE) { } WorldPacket const* Write() override; Unit* mover; }; + + struct MonsterSplineFilterKey + { + int16 Idx; + int16 Speed; + }; + + struct MonsterSplineFilter + { + std::vector<MonsterSplineFilterKey> FilterKeys; + uint8 FilterFlags; + float BaseSpeed; + int16 StartOffset; + float DistToPrevFilterKey; + int16 AddedToStart; + }; + + struct MovementSpline + { + uint32 Flags = 0; // Spline flags + uint8 Face = 0; // Movement direction (see MonsterMoveType enum) + uint8 AnimTier = 0; + uint32 TierTransStartTime = 0; + uint32 Elapsed = 0; + uint32 MoveTime = 0; + float JumpGravity = 0.0f; + uint32 SpecialTime = 0; + std::vector<G3D::Vector3> Points; // Spline path + uint8 Mode = 0; + uint8 VehicleExitVoluntary = 0; + ObjectGuid TransportGUID; + uint8 VehicleSeat = 255; + std::vector<G3D::Vector3> PackedDeltas; + Optional<MonsterSplineFilter> SplineFilter; + float FaceDirection = 0.0f; + ObjectGuid FaceGUID; + G3D::Vector3 FaceSpot; + }; + + struct MovementMonsterSpline + { + uint32 ID; + G3D::Vector3 Destination; + bool CrzTeleport = false; + MovementSpline Move; + }; + + class MonsterMove final : public ServerPacket + { + public: + MonsterMove() : ServerPacket(SMSG_MONSTER_MOVE) { } + + WorldPacket const* Write() override; + + MovementMonsterSpline SplineData; + ObjectGuid MoverGUID; + G3D::Vector3 Pos; + }; + + class MoveSplineSet : public ServerPacket + { + public: + MoveSplineSet(OpcodeServer opcode) : ServerPacket(opcode, 12) { } + + WorldPacket const* Write() override; + + ObjectGuid MoverGUID; + float Speed; + }; + + class MoveUpdate : public ServerPacket + { + public: + MoveUpdate(OpcodeServer opcode) : ServerPacket(opcode) { } + + WorldPacket const* Write() override; + + MovementInfo movementInfo; + float Speed; + }; + + class TransferPending final : public ServerPacket + { + struct ShipTransferPending + { + uint32 ID = 0; ///< gameobject_template.entry of the transport the player is teleporting on + int32 OriginMapID = -1; ///< Map id the player is currently on (before teleport) + }; + + public: + TransferPending() : ServerPacket(SMSG_TRANSFER_PENDING, 16) { } + + WorldPacket const* Write() override; + + int32 MapID = -1; + Optional<ShipTransferPending> Ship; + Optional<int32> TransferSpellID; + }; + + class TransferAborted final : public ServerPacket + { + public: + TransferAborted() : ServerPacket(SMSG_TRANSFER_ABORTED, 4 + 1 + 4) { } + + WorldPacket const* Write() override; + + uint32 TransfertAbort = 0; + uint8 Arg = 0; + uint32 MapID = 0; + }; + + class NewWorld final : public ServerPacket + { + public: + NewWorld() : ServerPacket(SMSG_NEW_WORLD, 24) { } + + WorldPacket const* Write() override; + + int32 MapID = 0; + uint32 Reason = 0; + Position Pos; + }; + + class WorldPortAck final : public ClientPacket + { + public: + WorldPortAck(WorldPacket&& packet) : ClientPacket(CMSG_MOVE_WORLDPORT_ACK, std::move(packet)) { } + + void Read() override { } + }; } } +ByteBuffer& operator<<(ByteBuffer& data, G3D::Vector3 const& v); +ByteBuffer& operator>>(ByteBuffer& data, G3D::Vector3& v); + +ByteBuffer& operator>>(ByteBuffer& data, MovementInfo& movementInfo); +ByteBuffer& operator<<(ByteBuffer& data, MovementInfo& movementInfo); + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineFilterKey const& monsterSplineFilterKey); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineFilter const& monsterSplineFilter); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementSpline const& movementSpline); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementMonsterSpline const& movementMonsterSpline); + #endif // MovementPackets_h__ diff --git a/src/server/game/Server/Packets/NPCPackets.cpp b/src/server/game/Server/Packets/NPCPackets.cpp new file mode 100644 index 00000000000..60dbed09f1b --- /dev/null +++ b/src/server/game/Server/Packets/NPCPackets.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "NPCPackets.h" +#include "ItemPackets.h" + +void WorldPackets::NPC::Hello::Read() +{ + _worldPacket >> Unit; +} + +WorldPacket const* WorldPackets::NPC::GossipMessage::Write() +{ + _worldPacket << GossipGUID; + _worldPacket << GossipID; + _worldPacket << FriendshipFactionID; + _worldPacket << TextID; + + _worldPacket << int32(GossipOptions.size()); + _worldPacket << int32(GossipText.size()); + + for (ClientGossipOptions const& options : GossipOptions) + { + _worldPacket << options.ClientOption; + _worldPacket << options.OptionNPC; + _worldPacket << options.OptionFlags; + _worldPacket << options.OptionCost; + + _worldPacket.WriteBits(options.Text.size(), 12); + _worldPacket.WriteBits(options.Confirm.size(), 12); + _worldPacket.FlushBits(); + + _worldPacket.WriteString(options.Text); + _worldPacket.WriteString(options.Confirm); + } + + for (ClientGossipText const& text : GossipText) + { + _worldPacket << text.QuestID; + _worldPacket << text.QuestType; + _worldPacket << text.QuestLevel; + _worldPacket << text.QuestFlags[0]; + _worldPacket << text.QuestFlags[1]; + + _worldPacket.WriteBit(text.Repeatable); + _worldPacket.WriteBits(text.QuestTitle.size(), 9); + _worldPacket.FlushBits(); + + _worldPacket.WriteString(text.QuestTitle); + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::NPC::VendorInventory::Write() +{ + _worldPacket << Vendor; + _worldPacket << Reason; + + _worldPacket << int32(Items.size()); + for (VendorItem const& item : Items) + { + _worldPacket << item.MuID; + _worldPacket << item.Type; + _worldPacket << item.Item; + _worldPacket << item.Quantity; + _worldPacket << item.Price; + _worldPacket << item.Durability; + _worldPacket << item.StackCount; + _worldPacket << item.ExtendedCostID; + _worldPacket << item.PlayerConditionFailed; + + _worldPacket.WriteBit(item.DoNotFilterOnVendor); + _worldPacket.FlushBits(); + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::NPC::TrainerList::Write() +{ + _worldPacket << TrainerGUID; + _worldPacket << TrainerType; + _worldPacket << TrainerID; + + _worldPacket << int32(Spells.size()); + for (TrainerListSpell const& spell : Spells) + { + _worldPacket << spell.SpellID; + _worldPacket << spell.MoneyCost; + _worldPacket << spell.ReqSkillLine; + _worldPacket << spell.ReqSkillRank; + + for (uint32 i = 0; i < MAX_TRAINERSPELL_ABILITY_REQS; ++i) + _worldPacket << spell.ReqAbility[i]; + + _worldPacket << spell.Usable; + _worldPacket << spell.ReqLevel; + } + + _worldPacket.WriteBits(Greeting.length(), 11); + _worldPacket.FlushBits(); + _worldPacket.WriteString(Greeting); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/NPCPackets.h b/src/server/game/Server/Packets/NPCPackets.h new file mode 100644 index 00000000000..221cb454765 --- /dev/null +++ b/src/server/game/Server/Packets/NPCPackets.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef NPCPackets_h__ +#define NPCPackets_h__ + +#include "Packet.h" +#include "ItemPackets.h" +#include "Creature.h" + +namespace WorldPackets +{ + namespace NPC + { + // CMSG_BANKER_ACTIVATE + // CMSG_BINDER_ACTIVATE + // CMSG_BINDER_CONFIRM + // CMSG_GOSSIP_HELLO + // CMSG_LIST_INVENTORY + // CMSG_TRAINER_LIST + class Hello final : public ClientPacket + { + public: + Hello(WorldPacket&& packet) : ClientPacket(std::move(packet)) { } + + void Read() override; + + ObjectGuid Unit; + }; + + struct ClientGossipOptions + { + int32 ClientOption = 0; + uint8 OptionNPC = 0; + uint8 OptionFlags = 0; + int32 OptionCost = 0; + std::string Text; + std::string Confirm; + }; + + struct ClientGossipText + { + int32 QuestID = 0; + int32 QuestType = 0; + int32 QuestLevel = 0; + bool Repeatable = false; + std::string QuestTitle; + int32 QuestFlags[2]; + }; + + class GossipMessage final : public ServerPacket + { + public: + GossipMessage() : ServerPacket(SMSG_GOSSIP_MESSAGE, 200) { } + + WorldPacket const* Write() override; + + std::vector<ClientGossipOptions> GossipOptions; + int32 FriendshipFactionID = 0; + ObjectGuid GossipGUID; + std::vector<ClientGossipText> GossipText; + int32 TextID = 0; + int32 GossipID = 0; + }; + + struct VendorItem + { + int32 MuID = 0; + int32 Type = 0; + WorldPackets::Item::ItemInstance Item; + int32 Quantity = -1; + int32 Price = 0; + int32 Durability = 0; + int32 StackCount = 0; + int32 ExtendedCostID = 0; + int32 PlayerConditionFailed = 0; + bool DoNotFilterOnVendor = false; + }; + + class VendorInventory final : public ServerPacket + { + public: + VendorInventory() : ServerPacket(SMSG_LIST_INVENTORY, 600) { } + + WorldPacket const* Write() override; + + uint8 Reason = 0; + std::vector<VendorItem> Items; + ObjectGuid Vendor; + }; + + struct TrainerListSpell + { + int32 SpellID = 0; + int32 MoneyCost = 0; + int32 ReqSkillLine = 0; + int32 ReqSkillRank = 0; + int32 ReqAbility[MAX_TRAINERSPELL_ABILITY_REQS]; + uint8 Usable = 0; + uint8 ReqLevel = 0; + }; + + class TrainerList final : public ServerPacket + { + public: + TrainerList() : ServerPacket(SMSG_TRAINER_LIST, 150) { } + + WorldPacket const* Write() override; + + std::string Greeting; + int32 TrainerType = 0; + ObjectGuid TrainerGUID; + int32 TrainerID = 1; + std::vector<TrainerListSpell> Spells; + }; + } +} + +#endif // NPCPackets_h__ diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp index 3076c221c71..335d261651a 100644 --- a/src/server/game/Server/Packets/QueryPackets.cpp +++ b/src/server/game/Server/Packets/QueryPackets.cpp @@ -88,3 +88,123 @@ WorldPacket const* WorldPackets::Query::QueryCreatureResponse::Write() return &_worldPacket; } + +void WorldPackets::Query::QueryPlayerName::Read() +{ + _worldPacket >> Player; + + Hint.VirtualRealmAddress.HasValue = _worldPacket.ReadBit(); + Hint.NativeRealmAddress.HasValue = _worldPacket.ReadBit(); + + if (Hint.VirtualRealmAddress.HasValue) + _worldPacket >> Hint.VirtualRealmAddress.Value; + + if (Hint.NativeRealmAddress.HasValue) + _worldPacket >> Hint.NativeRealmAddress.Value; +} + +WorldPacket const* WorldPackets::Query::QueryPlayerNameResponse::Write() +{ + _worldPacket << Result; + _worldPacket << Player; + + if (Result == RESPONSE_SUCCESS) + { + _worldPacket.WriteBits(Data.Name.length(), 7); + + for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + _worldPacket.WriteBits(Data.DeclinedNames.name[i].length(), 7); + + for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + _worldPacket.WriteString(Data.DeclinedNames.name[i]); + + _worldPacket << Data.AccountID; + _worldPacket << Data.BnetAccountID; + _worldPacket << Data.GuidActual; + _worldPacket << Data.VirtualRealmAddress; + _worldPacket << Data.Race; + _worldPacket << Data.Sex; + _worldPacket << Data.ClassID; + _worldPacket << Data.Level; + _worldPacket.WriteString(Data.Name); + } + + return &_worldPacket; +} + +void WorldPackets::Query::QueryPageText::Read() +{ + _worldPacket >> PageTextID; + _worldPacket >> ItemGUID; +} + +WorldPacket const* WorldPackets::Query::QueryPageTextResponse::Write() +{ + _worldPacket << PageTextID; + _worldPacket.WriteBit(Allow); + + if (Allow) + { + _worldPacket << Info.ID; + _worldPacket << Info.NextPageID; + _worldPacket.WriteBits(Info.Text.length(), 12); + _worldPacket.WriteString(Info.Text); + } + + return &_worldPacket; +} + +void WorldPackets::Query::QueryNPCText::Read() +{ + _worldPacket >> TextID; + _worldPacket >> Guid; +} + +WorldPacket const* WorldPackets::Query::QueryNPCTextResponse::Write() +{ + _worldPacket << TextID; + _worldPacket.WriteBit(Allow); + + if (Allow) + { + _worldPacket << int32(MAX_GOSSIP_TEXT_OPTIONS * (4 + 4)); + for (uint32 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) + _worldPacket << Probabilities[i]; + for (uint32 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) + _worldPacket << BroadcastTextID[i]; + } + + return &_worldPacket; +} + +void WorldPackets::Query::DBQueryBulk::Read() +{ + _worldPacket >> TableHash; + + uint32 count = _worldPacket.ReadBits(13); + _worldPacket.ResetBitPos(); + + Queries.resize(count); + for (uint32 i = 0; i < count; ++i) + { + _worldPacket >> Queries[i].GUID; + _worldPacket >> Queries[i].RecordID; + } +} + +WorldPacket const* WorldPackets::Query::DBReply::Write() +{ + _worldPacket << TableHash; + _worldPacket << RecordID; + _worldPacket << Timestamp; + + size_t sizePos = _worldPacket.wpos(); + _worldPacket << int32(0); // size of next block + + if (Data) + Data->WriteRecord(RecordID, Locale, _worldPacket); + + _worldPacket.put<int32>(sizePos, _worldPacket.wpos() - sizePos - 4); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h index 49bb5847400..b9e04ec4260 100644 --- a/src/server/game/Server/Packets/QueryPackets.h +++ b/src/server/game/Server/Packets/QueryPackets.h @@ -20,6 +20,8 @@ #include "Packet.h" #include "Creature.h" +#include "NPCHandler.h" +#include "DB2Stores.h" namespace WorldPackets { @@ -59,7 +61,7 @@ namespace WorldPackets class QueryCreatureResponse final : public ServerPacket { public: - QueryCreatureResponse() : ServerPacket(SMSG_CREATURE_QUERY_RESPONSE, 2+4+4+4+12) { } + QueryCreatureResponse() : ServerPacket(SMSG_CREATURE_QUERY_RESPONSE, 76) { } WorldPacket const* Write() override; @@ -67,6 +69,137 @@ namespace WorldPackets CreatureStats Stats; uint32 CreatureID = 0; }; + + struct PlayerGuidLookupHint + { + Optional<uint32> VirtualRealmAddress; ///< current realm (?) (identifier made from the Index, BattleGroup and Region) + Optional<uint32> NativeRealmAddress; ///< original realm (?) (identifier made from the Index, BattleGroup and Region) + }; + + class QueryPlayerName final : public ClientPacket + { + public: + QueryPlayerName(WorldPacket&& packet) : ClientPacket(CMSG_NAME_QUERY, std::move(packet)) { } + + void Read() override; + + ObjectGuid Player; + PlayerGuidLookupHint Hint; + }; + + struct PlayerGuidLookupData + { + bool IsDeleted = false; + ObjectGuid AccountID; + ObjectGuid BnetAccountID; + ObjectGuid GuidActual; + std::string Name; + uint32 VirtualRealmAddress = 0; + uint8 Race = RACE_NONE; + uint8 Sex = GENDER_NONE; + uint8 ClassID = CLASS_NONE; + uint8 Level = 0; + DeclinedName DeclinedNames; + }; + + class QueryPlayerNameResponse final : public ServerPacket + { + public: + QueryPlayerNameResponse() : ServerPacket(SMSG_NAME_QUERY_RESPONSE, 60) { } + + WorldPacket const* Write() override; + + ObjectGuid Player; + uint8 Result = 0; // 0 - full packet, != 0 - only guid + PlayerGuidLookupData Data; + }; + + class QueryPageText final : public ClientPacket + { + public: + QueryPageText(WorldPacket&& packet) : ClientPacket(CMSG_PAGE_TEXT_QUERY, std::move(packet)) { } + + void Read() override; + + ObjectGuid ItemGUID; + uint32 PageTextID = 0; + }; + + struct PageTextInfo + { + uint32 ID = 0; + uint32 NextPageID = 0; + std::string Text; + }; + + class QueryPageTextResponse final : public ServerPacket + { + public: + QueryPageTextResponse() : ServerPacket(SMSG_PAGE_TEXT_QUERY_RESPONSE, 15) { } + + WorldPacket const* Write() override; + + bool Allow = false; + PageTextInfo Info; + uint32 PageTextID = 0; + }; + + class QueryNPCText final : public ClientPacket + { + public: + QueryNPCText(WorldPacket&& packet) : ClientPacket(CMSG_NPC_TEXT_QUERY, std::move(packet)) { } + + void Read() override; + + ObjectGuid Guid; + uint32 TextID = 0; + }; + + class QueryNPCTextResponse final : public ServerPacket + { + public: + QueryNPCTextResponse() : ServerPacket(SMSG_NPC_TEXT_UPDATE, 73) { } + + WorldPacket const* Write() override; + + uint32 TextID = 0; + bool Allow = false; + float Probabilities[MAX_GOSSIP_TEXT_OPTIONS]; + uint32 BroadcastTextID[MAX_GOSSIP_TEXT_OPTIONS]; + }; + + struct DBQueryRecord + { + ObjectGuid GUID; + uint32 RecordID; + }; + + class DBQueryBulk final : public ClientPacket + { + public: + DBQueryBulk(WorldPacket&& packet) : ClientPacket(CMSG_DB_QUERY_BULK, std::move(packet)) { } + + void Read() override; + + uint32 TableHash; + std::vector<DBQueryRecord> Queries; + }; + + class DBReply final : public ServerPacket + { + public: + DBReply() : ServerPacket(SMSG_DB_REPLY, 12) { } + + WorldPacket const* Write() override; + + uint32 TableHash = 0; + uint32 Timestamp = 0; + int32 RecordID = 0; + + // These are not sent directly + uint32 Locale = 0; + DB2StorageBase const* Data = nullptr; + }; } } diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp new file mode 100644 index 00000000000..e20023d3dd2 --- /dev/null +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "QuestPackets.h" + +void WorldPackets::Quest::QuestGiverStatusQuery::Read() +{ + _worldPacket >> QuestGiverGUID; +} + +WorldPacket const* WorldPackets::Quest::QuestGiverStatus::Write() +{ + _worldPacket << QuestGiver.Guid; + _worldPacket << QuestGiver.Status; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Quest::QuestGiverStatusMultiple::Write() +{ + _worldPacket << int32(QuestGiver.size()); + for (QuestGiverInfo const& questGiver : QuestGiver) + { + _worldPacket << questGiver.Guid; + _worldPacket << questGiver.Status; + } + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h new file mode 100644 index 00000000000..12410380c3a --- /dev/null +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef QuestPackets_h__ +#define QuestPackets_h__ + +#include "Packet.h" +#include "QuestDef.h" +#include "ObjectGuid.h" + +namespace WorldPackets +{ + namespace Quest + { + class QuestGiverStatusQuery final : public ClientPacket + { + public: + QuestGiverStatusQuery(WorldPacket&& packet) : ClientPacket(CMSG_QUESTGIVER_STATUS_QUERY, std::move(packet)) { } + + void Read() override; + + ObjectGuid QuestGiverGUID; + }; + + // Empty packet, server replies with quest giver status of visible creatures + class QuestGiverStatusMultipleQuery final : public ClientPacket + { + public: + QuestGiverStatusMultipleQuery(WorldPacket&& packet) : ClientPacket(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, std::move(packet)) { } + + void Read() override { } + }; + + struct QuestGiverInfo + { + QuestGiverInfo() { } + QuestGiverInfo(ObjectGuid const& guid, uint32 status) + : Guid(guid), Status(status) { } + + ObjectGuid Guid; + uint32 Status = DIALOG_STATUS_NONE; + }; + + class QuestGiverStatus final : public ServerPacket + { + public: + QuestGiverStatus() : ServerPacket(SMSG_QUESTGIVER_STATUS, 22) { } + + WorldPacket const* Write() override; + + QuestGiverInfo QuestGiver; + }; + + class QuestGiverStatusMultiple final : public ServerPacket + { + public: + QuestGiverStatusMultiple() : ServerPacket(SMSG_QUESTGIVER_STATUS_MULTIPLE, 24) { } + + WorldPacket const* Write() override; + + std::vector<QuestGiverInfo> QuestGiver; + }; + } +} + +#endif // QuestPackets_h__ diff --git a/src/server/game/Server/Packets/ReputationPackets.cpp b/src/server/game/Server/Packets/ReputationPackets.cpp new file mode 100644 index 00000000000..4acecf851f4 --- /dev/null +++ b/src/server/game/Server/Packets/ReputationPackets.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ReputationPackets.h" + +WorldPacket const* WorldPackets::Reputation::InitializeFactions::Write() +{ + for (uint16 i = 0; i < FactionCount; ++i) + { + _worldPacket << uint8(FactionFlags[i]); + _worldPacket << int32(FactionStandings[i]); + } + + for (uint16 i = 0; i < FactionCount; ++i) + _worldPacket.WriteBit(FactionHasBonus[i]); + + _worldPacket.FlushBits(); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/ReputationPackets.h b/src/server/game/Server/Packets/ReputationPackets.h new file mode 100644 index 00000000000..387ae9b0318 --- /dev/null +++ b/src/server/game/Server/Packets/ReputationPackets.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "Packet.h" + +namespace WorldPackets +{ + namespace Reputation + { + static uint16 const FactionCount = 256; + + class InitializeFactions final : public ServerPacket + { + public: + InitializeFactions() : ServerPacket(SMSG_INITIALIZE_FACTIONS, 1312) + { + for (uint16 i = 0; i < FactionCount; ++i) + { + FactionStandings[i] = 0; + FactionHasBonus[i] = false; + FactionFlags[i] = 0; + } + } + + WorldPacket const* Write() override; + + int32 FactionStandings[FactionCount]; + bool FactionHasBonus[FactionCount]; ///< @todo: implement faction bonus + uint8 FactionFlags[FactionCount]; ///< @see enum FactionFlags + }; + } +} diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp index 9cf5bca318d..e56e73fb036 100644 --- a/src/server/game/Server/Packets/SpellPackets.cpp +++ b/src/server/game/Server/Packets/SpellPackets.cpp @@ -46,6 +46,43 @@ WorldPacket const* WorldPackets::Spell::SendKnownSpells::Write() return &_worldPacket; } +WorldPacket const* WorldPackets::Spell::UpdateActionButtons::Write() +{ + for (uint32 i = 0; i < MAX_ACTION_BUTTONS; ++i) + _worldPacket << ActionButtons[i]; + + _worldPacket << Reason; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Spell::SendUnlearnSpells::Write() +{ + _worldPacket << uint32(Spells.size()); + for (uint32 spellId : Spells) + _worldPacket << uint32(spellId); + + return &_worldPacket; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spell::SpellCastLogData& spellCastLogData) +{ + data << spellCastLogData.Health; + data << spellCastLogData.AttackPower; + data << spellCastLogData.SpellPower; + data << int32(spellCastLogData.PowerData.size()); + for (WorldPackets::Spell::SpellLogPowerData const& powerData : spellCastLogData.PowerData) + { + data << powerData.PowerType; + data << powerData.Amount; + } + data.WriteBit(false); + // data << float // Unk data if bit is true + data.FlushBits(); + + return data; +} + WorldPacket const* WorldPackets::Spell::SendAuraUpdate::Write() { return &_worldPacket; diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index 15b13f66eba..8aee276021c 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -19,6 +19,7 @@ #define SpellPackets_h__ #include "Packet.h" +#include "Player.h" #include "SpellAuras.h" namespace WorldPackets @@ -55,6 +56,50 @@ namespace WorldPackets std::vector<uint32> KnownSpells; }; + class UpdateActionButtons final : public ServerPacket + { + public: + UpdateActionButtons() : ServerPacket(SMSG_ACTION_BUTTONS, MAX_ACTION_BUTTONS * 8 + 1) + { + std::memset(ActionButtons, 0, sizeof(ActionButtons)); + } + + WorldPacket const* Write() override; + + uint64 ActionButtons[MAX_ACTION_BUTTONS]; + uint8 Reason = 0; + /* + Reason can be 0, 1, 2 + 0 - Sends initial action buttons, client does not validate if we have the spell or not + 1 - Used used after spec swaps, client validates if a spell is known. + 2 - Clears the action bars client sided. This is sent during spec swap before unlearning and before sending the new buttons + */ + }; + + class SendUnlearnSpells final : public ServerPacket + { + public: + SendUnlearnSpells() : ServerPacket(SMSG_SEND_UNLEARN_SPELLS, 4) { } + + WorldPacket const* Write() override; + + std::vector<uint32> Spells; + }; + + struct SpellLogPowerData + { + int32 PowerType = 0; + int32 Amount = 0; + }; + + struct SpellCastLogData + { + int32 Health = 0; + int32 AttackPower = 0; + int32 SpellPower = 0; + std::vector<SpellLogPowerData> PowerData; + }; + class SendAuraUpdate final : public ServerPacket { public: @@ -63,8 +108,10 @@ namespace WorldPackets WorldPacket const* Write() override; void Init(bool IsFullUpdate, ObjectGuid Target, uint32 Count); void BuildUpdatePacket(AuraApplication* aurApp, bool remove, uint16 level); - }; + }; } } +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spell::SpellCastLogData& spellCastLogData); + #endif // SpellPackets_h__ diff --git a/src/server/game/Server/Packets/SystemPackets.cpp b/src/server/game/Server/Packets/SystemPackets.cpp index 7c8ecce3db7..4a7be4ed591 100644 --- a/src/server/game/Server/Packets/SystemPackets.cpp +++ b/src/server/game/Server/Packets/SystemPackets.cpp @@ -43,22 +43,22 @@ WorldPacket const* WorldPackets::System::FeatureSystemStatus::Write() if (EuropaTicketSystemStatus.HasValue) { - _worldPacket.WriteBit(EuropaTicketSystemStatus.value.UnkBit0); - _worldPacket.WriteBit(EuropaTicketSystemStatus.value.UnkBit1); - _worldPacket.WriteBit(EuropaTicketSystemStatus.value.TicketSystemEnabled); - _worldPacket.WriteBit(EuropaTicketSystemStatus.value.SubmitBugEnabled); - - _worldPacket << uint32(EuropaTicketSystemStatus.value.ThrottleState.MaxTries); - _worldPacket << uint32(EuropaTicketSystemStatus.value.ThrottleState.PerMilliseconds); - _worldPacket << uint32(EuropaTicketSystemStatus.value.ThrottleState.TryCount); - _worldPacket << uint32(EuropaTicketSystemStatus.value.ThrottleState.LastResetTimeBeforeNow); + _worldPacket.WriteBit(EuropaTicketSystemStatus.Value.UnkBit0); + _worldPacket.WriteBit(EuropaTicketSystemStatus.Value.UnkBit1); + _worldPacket.WriteBit(EuropaTicketSystemStatus.Value.TicketSystemEnabled); + _worldPacket.WriteBit(EuropaTicketSystemStatus.Value.SubmitBugEnabled); + + _worldPacket << uint32(EuropaTicketSystemStatus.Value.ThrottleState.MaxTries); + _worldPacket << uint32(EuropaTicketSystemStatus.Value.ThrottleState.PerMilliseconds); + _worldPacket << uint32(EuropaTicketSystemStatus.Value.ThrottleState.TryCount); + _worldPacket << uint32(EuropaTicketSystemStatus.Value.ThrottleState.LastResetTimeBeforeNow); } if (SessionAlert.HasValue) { - _worldPacket << int32(SessionAlert.value.Delay); - _worldPacket << int32(SessionAlert.value.Period); - _worldPacket << int32(SessionAlert.value.DisplayTime); + _worldPacket << int32(SessionAlert.Value.Delay); + _worldPacket << int32(SessionAlert.Value.Period); + _worldPacket << int32(SessionAlert.Value.DisplayTime); } _worldPacket.FlushBits(); diff --git a/src/server/game/Server/Packets/TalentPackets.cpp b/src/server/game/Server/Packets/TalentPackets.cpp index 3410fb273f7..4855f663662 100644 --- a/src/server/game/Server/Packets/TalentPackets.cpp +++ b/src/server/game/Server/Packets/TalentPackets.cpp @@ -36,3 +36,8 @@ WorldPacket const* WorldPackets::Talent::UpdateTalentData::Write() return &_worldPacket; } + +void WorldPackets::Talent::SetSpecialization::Read() +{ + _worldPacket >> SpecGroupIndex; +} diff --git a/src/server/game/Server/Packets/TalentPackets.h b/src/server/game/Server/Packets/TalentPackets.h index c756c6962bb..21753e22c8d 100644 --- a/src/server/game/Server/Packets/TalentPackets.h +++ b/src/server/game/Server/Packets/TalentPackets.h @@ -20,7 +20,6 @@ #include "Packet.h" #include "Player.h" -#include <vector> namespace WorldPackets { @@ -48,6 +47,16 @@ namespace WorldPackets TalentInfoUpdate Info; }; + + class SetSpecialization final : public ClientPacket + { + public: + SetSpecialization(WorldPacket&& packet) : ClientPacket(CMSG_SET_SPECIALIZATION, std::move(packet)) { } + + void Read() override; + + uint32 SpecGroupIndex = 0; + }; } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 4711bf4f306..1ca8938b4eb 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -19,11 +19,19 @@ #include "Opcodes.h" #include "WorldSession.h" #include "Packets/CharacterPackets.h" +#include "Packets/ChannelPackets.h" +#include "Packets/ChatPackets.h" +#include "Packets/ClientConfigPackets.h" +#include "Packets/CombatPackets.h" +#include "Packets/EquipmentSetPackets.h" #include "Packets/GuildPackets.h" -#include "Packets/TradePackets.h" #include "Packets/MiscPackets.h" -#include "Packets/QueryPackets.h" #include "Packets/MovementPackets.h" +#include "Packets/NPCPackets.h" +#include "Packets/QueryPackets.h" +#include "Packets/QuestPackets.h" +#include "Packets/TalentPackets.h" +#include "Packets/TradePackets.h" template<class PacketClass, void(WorldSession::*HandlerFunction)(PacketClass&)> class PacketHandler : public OpcodeHandler @@ -132,8 +140,8 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_ARENA_TEAM_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamQueryOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_ARENA_TEAM_REMOVE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamRemoveOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_ARENA_TEAM_ROSTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamRosterOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_ATTACKSTOP, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleAttackStopOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_ATTACKSWING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleAttackSwingOpcode ); + DEFINE_HANDLER(CMSG_ATTACKSTOP, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Combat::AttackStop, &WorldSession::HandleAttackStopOpcode); + DEFINE_HANDLER(CMSG_ATTACKSWING, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Combat::AttackSwing, &WorldSession::HandleAttackSwingOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_HELLO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionHelloOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_LIST_BIDDER_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListBidderItems ); DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_LIST_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListItems ); @@ -151,7 +159,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOSTORE_BANK_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBankItemOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOSTORE_LOOT_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutostoreLootItemOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTO_DECLINE_GUILD_INVITES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoDeclineGuildInvites ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_BANKER_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBankerActivateOpcode ); + DEFINE_HANDLER(CMSG_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBankerActivateOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_LEAVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBattlefieldLeaveOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldListOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBfEntryInviteResponse ); @@ -167,9 +175,12 @@ void OpcodeTable::Initialize() 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_BATTLE_PAY_GET_PURCHASE_LIST_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_DELETE_PET, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_MODIFY_NAME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_NAME_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_SET_BATTLE_SLOT, 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_HANDLER(CMSG_BINDER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBinderActivateOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_BUG, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBugOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BUSY_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BUYBACK_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBuybackItem ); @@ -205,10 +216,10 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle); DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_ANNOUNCEMENTS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelAnnouncements ); DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_BAN, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelBan ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_DISPLAY_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelDisplayListQuery ); + DEFINE_HANDLER(CMSG_CHANNEL_DISPLAY_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Channel::ChannelListRequest, &WorldSession::HandleChannelList); DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_INVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelInvite ); DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_KICK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelKick ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelList ); + DEFINE_HANDLER(CMSG_CHANNEL_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Channel::ChannelListRequest, &WorldSession::HandleChannelList); DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_MODERATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_MODERATOR, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelModerator ); DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_MUTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelMute ); @@ -228,7 +239,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_CHAR_CREATE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CreateChar, &WorldSession::HandleCharCreateOpcode); DEFINE_HANDLER(CMSG_CHAR_CUSTOMIZE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharCustomize, &WorldSession::HandleCharCustomizeOpcode); DEFINE_HANDLER(CMSG_CHAR_DELETE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::DeleteChar, &WorldSession::HandleCharDeleteOpcode); - DEFINE_HANDLER(CMSG_CHAR_ENUM, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::EnumCharacters, &WorldSession::HandleCharEnumOpcode ); + DEFINE_HANDLER(CMSG_CHAR_ENUM, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::EnumCharacters, &WorldSession::HandleCharEnumOpcode); DEFINE_HANDLER(CMSG_CHAR_RACE_OR_FACTION_CHANGE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharRaceOrFactionChange, &WorldSession::HandleCharRaceOrFactionChangeOpcode); DEFINE_HANDLER(CMSG_CHAR_RENAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharacterRenameRequest, &WorldSession::HandleCharRenameOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAR_UNDELETE_ENUM, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharUndeleteEnumOpcode ); @@ -254,7 +265,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_CORPSE_MAP_POSITION_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseMapPositionQuery ); DEFINE_HANDLER(CMSG_CREATURE_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Query::QueryCreature, &WorldSession::HandleCreatureQuery); DEFINE_OPCODE_HANDLER_OLD(CMSG_DANCE_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_DB_QUERY_BULK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_DB_QUERY_BULK, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Query::DBQueryBulk, &WorldSession::HandleDBQueryBulk); 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 ); @@ -269,7 +280,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_ENABLETAXI, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes ); DEFINE_OPCODE_HANDLER_OLD(CMSG_ENABLE_NAGLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess ); DEFINE_OPCODE_HANDLER_OLD(CMSG_EQUIPMENT_SET_DELETE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetDelete ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_EQUIPMENT_SET_SAVE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetSave ); + DEFINE_HANDLER(CMSG_EQUIPMENT_SET_SAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::EquipmentSet::SaveEquipmentSet, &WorldSession::HandleEquipmentSetSave); DEFINE_OPCODE_HANDLER_OLD(CMSG_EQUIPMENT_SET_USE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetUse ); DEFINE_OPCODE_HANDLER_OLD(CMSG_FACTION_BONUS_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_FAR_SIGHT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleFarSightOpcode ); @@ -288,7 +299,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_GMTICKET_SYSTEMSTATUS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketSystemStatusOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_GMTICKET_UPDATETEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketUpdateOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GM_REPORT_LAG, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReportLag ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_GOSSIP_HELLO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipHelloOpcode ); + DEFINE_HANDLER(CMSG_GOSSIP_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleGossipHelloOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_GOSSIP_SELECT_OPTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipSelectOptionOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GRANT_LEVEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGrantLevel ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GROUP_ASSISTANT_LEADER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupAssistantLeaderOpcode); @@ -354,12 +365,12 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_ITEM_REFUND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefund ); DEFINE_OPCODE_HANDLER_OLD(CMSG_ITEM_REFUND_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefundInfoRequest ); DEFINE_OPCODE_HANDLER_OLD(CMSG_ITEM_TEXT_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleItemTextQuery ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_JOIN_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleJoinChannel ); + DEFINE_HANDLER(CMSG_JOIN_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Channel::JoinChannel, &WorldSession::HandleJoinChannel); DEFINE_OPCODE_HANDLER_OLD(CMSG_KEEP_ALIVE, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess ); DEFINE_OPCODE_HANDLER_OLD(CMSG_LEARN_PREVIEW_TALENTS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnPreviewTalents ); DEFINE_OPCODE_HANDLER_OLD(CMSG_LEARN_PREVIEW_TALENTS_PET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnPreviewTalentsPet ); DEFINE_OPCODE_HANDLER_OLD(CMSG_LEARN_TALENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnTalentOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_LEAVE_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLeaveChannel ); + DEFINE_HANDLER(CMSG_LEAVE_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Channel::LeaveChannel, &WorldSession::HandleLeaveChannel); DEFINE_OPCODE_HANDLER_OLD(CMSG_LFG_GET_STATUS, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleLfgGetStatus ); DEFINE_OPCODE_HANDLER_OLD(CMSG_LFG_JOIN, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgJoinOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_LFG_LEAVE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgLeaveOpcode ); @@ -379,7 +390,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_POST_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderPostRequest ); DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_REMOVE_RECRUIT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderRemoveRecruit ); DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_SET_GUILD_POST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderSetGuildPost ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_LIST_INVENTORY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleListInventoryOpcode ); + DEFINE_HANDLER(CMSG_LIST_INVENTORY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleListInventoryOpcode); DEFINE_HANDLER(CMSG_LOAD_SCREEN, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::LoadingScreenNotify, &WorldSession::HandleLoadScreenOpcode); DEFINE_HANDLER(CMSG_LOGOUT_CANCEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::LogoutCancel, &WorldSession::HandleLogoutCancelOpcode); DEFINE_HANDLER(CMSG_LOGOUT_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::LogoutRequest, &WorldSession::HandleLogoutRequestOpcode); @@ -397,25 +408,23 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_MAIL_RETURN_TO_SENDER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMailReturnToSender ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MAIL_TAKE_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMailTakeItem ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MAIL_TAKE_MONEY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMailTakeMoney ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_BATTLEGROUND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_GUILD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_OFFICER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_PARTY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_RAID, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_WHISPER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_AFK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_BATTLEGROUND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_DND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_EMOTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_GUILD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_OFFICER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_PARTY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_RAID, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_RAID_WARNING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_SAY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_WHISPER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_YELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_HANDLER(CMSG_MESSAGECHAT_ADDON_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_ADDON_OFFICER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_ADDON_PARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_ADDON_RAID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_ADDON_WHISPER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessageWhisper, &WorldSession::HandleChatAddonMessageWhisperOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_AFK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessageAFK, &WorldSession::HandleChatMessageAFKOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessageChannel, &WorldSession::HandleChatMessageChannelOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_DND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessageDND, &WorldSession::HandleChatMessageDNDOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessageEmote, &WorldSession::HandleChatMessageEmoteOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_OFFICER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_PARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_RAID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_RAID_WARNING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_SAY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_YELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_WHISPER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessageWhisper, &WorldSession::HandleChatMessageWhisperOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_MINIGAME_MOVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MINIMAP_PING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMinimapPingOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOUNTSPECIAL_ANIM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode ); @@ -465,19 +474,20 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_MOVE_STOP_STRAFE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); DEFINE_HANDLER(CMSG_MOVE_STOP_SWIM, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); DEFINE_HANDLER(CMSG_MOVE_STOP_TURN, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); + DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_TELEPORT_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveTeleportAck ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_TIME_SKIPPED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleMoveTimeSkippedOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_WATER_WALK_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveWaterWalkAck ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_WORLDPORT_ACK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveWorldportAckOpcode ); - DEFINE_HANDLER(CMSG_NAME_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::QueryPlayerName, &WorldSession::HandleNameQueryOpcode); + DEFINE_HANDLER(CMSG_MOVE_WORLDPORT_ACK, STATUS_TRANSFER, PROCESS_THREADUNSAFE, WorldPackets::Movement::WorldPortAck, &WorldSession::HandleMoveWorldportAckOpcode); + DEFINE_HANDLER(CMSG_NAME_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryPlayerName, &WorldSession::HandleNameQueryOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_NEXT_CINEMATIC_CAMERA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleNextCinematicCamera ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_NPC_TEXT_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleNpcTextQueryOpcode ); + DEFINE_HANDLER(CMSG_NPC_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryNPCText, &WorldSession::HandleNpcTextQueryOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_OBJECT_UPDATE_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleObjectUpdateFailedOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OBJECT_UPDATE_RESCUED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OFFER_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOfferPetitionOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OPENING_CINEMATIC, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOpeningCinematic ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OPEN_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOpenItemOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OPT_OUT_OF_LOOT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOptOutOfLootOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PAGE_TEXT_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePageTextQueryOpcode ); + DEFINE_HANDLER(CMSG_PAGE_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryPageText, &WorldSession::HandlePageTextQueryOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_SILENCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_UNSILENCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PETITION_BUY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionBuyOpcode ); @@ -517,8 +527,8 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_HELLO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverHelloOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_QUERY_QUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQueryQuestOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_REQUEST_REWARD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverRequestRewardOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverStatusMultipleQuery); - DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_STATUS_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleQuestgiverStatusQueryOpcode); + DEFINE_HANDLER(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverStatusMultipleQuery, &WorldSession::HandleQuestgiverStatusMultipleQuery); + DEFINE_HANDLER(CMSG_QUESTGIVER_STATUS_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Quest::QuestGiverStatusQuery, &WorldSession::HandleQuestgiverStatusQueryOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTLOG_REMOVE_QUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogRemoveQuest ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_CONFIRM_ACCEPT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_NPC_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestNPCQuery ); @@ -531,15 +541,15 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_REALM_NAME_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); 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 ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_RECRUIT_A_FRIEND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REFORGE_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleReforgeItemOpcode ); DEFINE_HANDLER(CMSG_REORDER_CHARACTERS, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::ReorderCharacters, &WorldSession::HandleReorderCharacters); DEFINE_OPCODE_HANDLER_OLD(CMSG_REPAIR_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRepairItemOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REPOP_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRepopRequestOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REPORT_PVP_AFK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReportPvPAFK ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_ACCOUNT_DATA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestAccountData ); + DEFINE_HANDLER(CMSG_REQUEST_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::ClientConfig::RequestAccountData, &WorldSession::HandleRequestAccountData); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_CATEGORY_COOLDOWNS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestCategoryCooldowns ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_CEMETERY_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestCemeteryList ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_HOTFIX, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestHotfix ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_INSPECT_RATED_BG_STATS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PET_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode ); @@ -584,9 +594,9 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PREFERED_CEMETERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_RELATIVE_POSITION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SAVED_INSTANCE_EXTEND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetSavedInstanceExtend ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SELECTION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleSetSelectionOpcode ); + DEFINE_HANDLER(CMSG_SET_SELECTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetSelection, &WorldSession::HandleSetSelectionOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SKILL_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SPECIALIZATION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_SET_SPECIALIZATION, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Talent::SetSpecialization, &WorldSession::HandleSetSpecializationOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_TAXI_BENCHMARK_MODE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_TITLE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTitleOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_TRADE_CURRENCY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -614,26 +624,24 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_TAXINODE_STATUS_QUERY, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleTaxiNodeStatusQueryOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TAXIQUERYAVAILABLENODES, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TELEPORT_TO_UNIT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_TEXT_EMOTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTextEmoteOpcode ); + DEFINE_HANDLER(CMSG_TEXT_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::CTextEmote, &WorldSession::HandleTextEmoteOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_TIME_ADJUSTMENT_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_TIME_SYNC_RESP, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleTimeSyncResp ); + DEFINE_HANDLER(CMSG_TIME_SYNC_RESP, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::TimeSyncResponse, &WorldSession::HandleTimeSyncResp); DEFINE_OPCODE_HANDLER_OLD(CMSG_TIME_SYNC_RESP_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TOGGLE_PVP, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTogglePvP ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TOTEM_DESTROYED, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTotemDestroyed ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TRAINER_BUY_SPELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerBuySpellOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_TRAINER_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerListOpcode ); + DEFINE_HANDLER(CMSG_TRAINER_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleTrainerListOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_TRANSMOGRIFY_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTransmogrifyItems ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TURN_IN_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTurnInPetitionOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_TUTORIAL_CLEAR, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialClear ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_TUTORIAL_FLAG, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialFlag ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_TUTORIAL_RESET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialReset ); + DEFINE_HANDLER(CMSG_TUTORIAL_FLAG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::TutorialSetFlag, &WorldSession::HandleTutorialFlag); DEFINE_OPCODE_HANDLER_OLD(CMSG_UNACCEPT_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode ); DEFINE_HANDLER(CMSG_UNDELETE_CHARACTER, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::UndeleteCharacter, &WorldSession::HandleCharUndeleteOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_UNDELETE_COOLDOWN_STATUS_QUERY, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleUndeleteCooldownStatusQuery); DEFINE_OPCODE_HANDLER_OLD(CMSG_UNLEARN_SKILL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUnlearnSkillOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_UNLEARN_SPECIALIZATION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_UNREGISTER_ALL_ADDON_PREFIXES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUnregisterAddonPrefixesOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_ACCOUNT_DATA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateAccountData ); + DEFINE_HANDLER(CMSG_UPDATE_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::ClientConfig::UserClientUpdateAccountData, &WorldSession::HandleUpdateAccountData); DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_MISSILE_TRAJECTORY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory ); DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_PROJECTILE_POSITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateProjectilePosition ); DEFINE_OPCODE_HANDLER_OLD(CMSG_USED_FOLLOW, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -649,7 +657,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_WARGAME_START, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_WHO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_WHOIS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoisOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_WORLD_STATE_UI_TIMER_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleWorldStateUITimerUpdate ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_WORLD_STATE_UI_TIMER_UPDATE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleWorldStateUITimerUpdate ); DEFINE_OPCODE_HANDLER_OLD(CMSG_WORLD_TELEPORT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleWorldTeleportOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_WRAP_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleWrapItemOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_ZONEUPDATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleZoneUpdateOpcode ); @@ -657,8 +665,6 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(MSG_INSPECT_ARENA_TEAMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectArenaTeamsOpcode ); DEFINE_OPCODE_HANDLER_OLD(MSG_LIST_STABLED_PETS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleListStabledPetsOpcode ); DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_CHARM_TELEPORT_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TELEPORT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TELEPORT_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveTeleportAck ); DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TELEPORT_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TIME_SKIPPED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TOGGLE_COLLISION_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -689,13 +695,15 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_INFO_RESPONSE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_RESTRICTED_WARNING, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_TOYS_UPDATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTION_BUTTONS, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTION_BUTTONS, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTIVATETAXIREPLY, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADDON_INFO, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADD_RUNE_POWER, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AI_REACTION, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADJUST_SPLINE_DURATION, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AI_REACTION, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_ACHIEVEMENT_DATA, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_SPIRIT_HEALER_TIME, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MESSAGE, STATUS_UNHANDLED); @@ -709,9 +717,9 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_QUERY_RESPONSE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_ROSTER, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_STATS, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKERSTATEUPDATE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSTART, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSTOP, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKERSTATEUPDATE, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSTART, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSTOP, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_BADFACING, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_CANT_ATTACK, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_DEADTARGET, STATUS_UNHANDLED); @@ -721,7 +729,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_COMMAND_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_HELLO, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_PENDING_SALES, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_RESULT, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_ITEMS_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OWNER_LIST_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OWNER_NOTIFICATION, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_REMOVED_NOTIFICATION, STATUS_UNHANDLED); @@ -753,6 +761,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_DISTRIBUTION_UPDATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_DISTRIBUTION_LIST_RESPONSE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_PRODUCT_LIST_RESPONSE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_PURCHASE_LIST_RESPONSE, STATUS_UNHANDLED); @@ -760,7 +769,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL_LOCK_ACQUIRED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_NAME_QUERY_RESPONSE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDER_CONFIRM, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDPOINTUPDATE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDPOINTUPDATE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDZONEREPLY, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BREAK_TARGET, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_BANK_SLOT_RESULT, STATUS_UNHANDLED); @@ -791,9 +800,11 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_AUTO_REPEAT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_COMBAT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CAST_FAILED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_LIST, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_LIST, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_MEMBER_COUNT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_NOTIFY, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_NOTIFY_JOINED, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_NOTIFY_LEFT, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_START, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_UPDATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHARACTER_LOGIN_FAILED, STATUS_UNHANDLED); @@ -819,6 +830,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_TARGET, 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_COIN_REMOVED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMBAT_EVENT_FAILED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_MAP_INFO, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_PARTY_INFO, STATUS_UNHANDLED); @@ -850,7 +862,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_DAMAGE_CALC_LOG, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DANCE_QUERY_RESPONSE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DANCE_STUDIO_CREATE_RESULT, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_DB_REPLY, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_DB_REPLY, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEATH_RELEASE_LOC, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEBUG_RUNE_REGEN, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEFENSE_MESSAGE, STATUS_UNHANDLED); @@ -862,6 +874,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISMOUNTRESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISPEL_FAILED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISPLAY_GAME_ERROR, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISPLAY_PROMOTION, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DONT_AUTO_PUSH_SPELLS_TO_ACTION_BAR, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DROP_NEW_CONNECTION, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_COMPLETE, STATUS_UNHANDLED); @@ -873,12 +886,12 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUMP_RIDE_TICKETS_RESPONSE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DURABILITY_DAMAGE_DEATH, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ECHO_PARTY_SQUELCH, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_EMOTE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_EMOTE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENABLE_BARBER_SHOP, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENCHANTMENTLOG, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENVIRONMENTALDAMAGELOG, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_LIST, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_SAVED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_LIST, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_SAVED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_USE_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_EXPECTED_SPAM_RECORDS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_EXPLORATION_EXPERIENCE, STATUS_UNHANDLED); @@ -896,8 +909,10 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_SET_VEHICLE_REC_ID, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORGE_MASTER_SET, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_FRIEND_STATUS, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_ACTIVATE_ANIM_KIT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_CUSTOM_ANIM, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_DESPAWN_ANIM, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_DESPAWN, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_PAGETEXT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_QUERY_RESPONSE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_RESET_STATE, STATUS_UNHANDLED); @@ -905,7 +920,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMETIME_SET, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMETIME_UPDATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_EVENT_DEBUG_LOG, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_ACTIVATE_ANIM_KIT, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_COMPLETE_MISSION_RESULT, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_REMOTE_INFO, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMRESPONSE_DB_ERROR, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMRESPONSE_RECEIVED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMRESPONSE_STATUS_UPDATE, STATUS_UNHANDLED); @@ -916,10 +932,12 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMTICKET_UPDATETEXT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_MESSAGECHAT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_PLAYER_INFO, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_TICKET_CASE_STATUS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_TICKET_STATUS_UPDATE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_TICKET_SYSTEM_STATUS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GODMODE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_COMPLETE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_MESSAGE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_MESSAGE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_POI, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUPACTION_THROTTLED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_CANCEL, STATUS_UNHANDLED); @@ -945,8 +963,10 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT_2, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DATA, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DELETED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_UPDATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_DECLINE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_BANK_MONEY_CHANGED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_LOG_QUERY_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PRESENCE_CHANGE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_FLAGGED_FOR_RENAME, STATUS_UNHANDLED); @@ -977,10 +997,10 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_XP, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_XP_GAIN, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HEALTH_UPDATE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_HIGHEST_THREAT_UPDATE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_HIGHEST_THREAT_UPDATE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_INFO, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SETUP, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SPELLS, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_CURRENCY, STATUS_UNHANDLED); @@ -989,12 +1009,13 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_RATED_BG_STATS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_RESULTS_UPDATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_TALENT, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_INFO, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_LOCK_WARNING_QUERY, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_RESET, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_RESET_FAILED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_SAVE_CREATED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALIDATE_DANCE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALIDATE_PLAYER, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALIDATE_PLAYER, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALID_PROMOTION_CODE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVENTORY_CHANGE_FAILURE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_ADD_PASSIVE, STATUS_UNHANDLED); @@ -1034,9 +1055,9 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_POST_UPDATED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_RECRUIT_LIST_UPDATED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIST_INVENTORY, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIST_INVENTORY, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGIN_SETTIMESPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGIN_SETTIMESPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGIN_VERIFY_WORLD, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGOUT_CANCEL_ACK, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGOUT_COMPLETE, STATUS_NEVER); @@ -1057,9 +1078,10 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_SLOT_CHANGED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_START_ROLL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAIL_LIST_RESULT, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAIL_QUERY_NEXT_TIME_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAP_OBJ_EVENTS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MEETINGSTONE_IN_PROGRESS, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MESSAGECHAT, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MESSAGECHAT, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MESSAGE_BOX, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIGAME_SETUP, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIGAME_STATE, STATUS_UNHANDLED); @@ -1068,7 +1090,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_MISSILE_CANCEL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MODIFY_COOLDOWN, STATUS_UNHANDLED); 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, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONSTER_MOVE_TRANSPORT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOTD, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOUNTRESULT, STATUS_UNHANDLED); @@ -1099,6 +1121,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_SWIM_SPEED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_TURN_RATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_WALK_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_TELEPORT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNROOT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_FLY, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_UNHANDLED); @@ -1107,30 +1130,30 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_SPEED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_KNOCK_BACK, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_PITCH_RATE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_BACK_SPEED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_SPEED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_BACK_SPEED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_PITCH_RATE, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_BACK_SPEED, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_SPEED, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_BACK_SPEED, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TELEPORT, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TURN_RATE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_WALK_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TURN_RATE, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_WALK_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_WATER_WALK, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MULTIPLE_PACKETS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NAME_QUERY_RESPONSE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NEW_TAXI_PATH, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_NEW_WORLD, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_NEW_WORLD, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NEW_WORLD_ABORT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFICATION, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_DANCE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_DEST_LOC_SPELL_CAST, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_NPC_TEXT_UPDATE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_NPC_TEXT_UPDATE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OFFER_PETITION_ERROR, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_CONTAINER, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_LFG_DUNGEON_FINDER, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OVERRIDE_LIGHT, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAGE_TEXT_QUERY_RESPONSE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAGE_TEXT_QUERY_RESPONSE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTYKILLLOG, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_COMMAND_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS, STATUS_UNHANDLED); @@ -1193,8 +1216,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_INVALID, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_LIST, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_REQUEST_ITEMS, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS_MULTIPLE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS_MULTIPLE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTLOG_FULL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_KILL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_PVP_KILL, STATUS_UNHANDLED); @@ -1225,6 +1248,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFER_A_FRIEND_EXPIRED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFER_A_FRIEND_FAILURE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFORGE_RESULT, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFRESH_SPELL_HISTORY, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REMOVED_SPELL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REPORT_PVP_AFK_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REQUEST_CEMETERY_LIST_RESPONSE, STATUS_UNHANDLED); @@ -1242,13 +1266,17 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_RWHOIS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SELL_ITEM, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_MAIL_RESULT, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_UNLEARN_SPELLS, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_CHARGES, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_HISTORY, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_UNLEARN_SPELLS, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVERTIME, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_INFO_RESPONSE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_MESSAGE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_PERF, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_AI_ANIM_KIT, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_ALL_TASK_PROGRESS, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_CURRENCY, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_DF_FAST_LAUNCH_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_ATWAR, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_NOT_VISIBLE, STATUS_UNHANDLED); @@ -1256,13 +1284,14 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_VISIBLE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FLAT_SPELL_MODIFIER, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FORCED_REACTIONS, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MAX_WEEKLY_QUANTITY, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MELEE_ANIM_KIT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MOVEMENT_ANIM_KIT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PCT_SPELL_MODIFIER, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PHASE_SHIFT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROJECTILE_POSITION, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_TIME_ZONE_INFORMATION, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOWTAXINODES, STATUS_UNHANDLED); @@ -1300,20 +1329,20 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_ANIM, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FEATHER_FALL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLYING, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_HOVER, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_LAND_WALK, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_NORMAL_FALL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_PITCH_RATE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_MODE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_TURN_RATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_MODE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WATER_WALK, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_START_SWIM, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_STOP_SWIM, STATUS_UNHANDLED); @@ -1322,6 +1351,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_HOVER, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_STABLE_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_STANDSTATE_UPDATE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_ELAPSED_TIMERS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_MIRROR_TIMER, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_TIMER, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_STOP_DANCE, STATUS_UNHANDLED); @@ -1334,16 +1364,16 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_COMMS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_TOKEN, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_ERROR, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INFO, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INFO, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INVOLUNTARILY_RESET, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TAXINODE_STATUS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TEST_DROP_RATE_RESULT, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_TEXT_EMOTE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_TEXT_EMOTE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_CLEAR, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_REMOVE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_UPDATE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_REMOVE, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_UPDATE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TIME_ADJUSTMENT, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_TIME_SYNC_REQ, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_TIME_SYNC_REQ, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TITLE_EARNED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TOGGLE_XP_GAIN, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TOTEM_CREATED, STATUS_UNHANDLED); @@ -1351,19 +1381,18 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRADE_STATUS_EXTENDED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_BUY_FAILED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_BUY_SUCCEEDED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_LIST, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_ABORTED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_PENDING, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_LIST, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_ABORTED, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_PENDING, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_CINEMATIC, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_MOVIE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TURN_IN_PETITION_RESULTS, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNDELETE_CHARACTER_RESPONSE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNDELETE_COOLDOWN_STATUS_RESPONSE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNIT_HEALTH_FREQUENT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNIT_SPELLCAST_START, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_ACCOUNT_DATA, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_ACCOUNT_DATA, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_COMBO_POINTS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CURRENCY, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CURRENCY_WEEK_LIMIT, STATUS_UNHANDLED); @@ -1373,6 +1402,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_LAST_INSTANCE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_OBJECT, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_SERVER_PLAYER_POSITION, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_TASK_PROGRESS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_WORLD_STATE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_ADD, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_REMOVE, STATUS_UNHANDLED); @@ -1400,8 +1430,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEEKLY_SPELL_USAGE_UPDATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_WHO, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_WHOIS, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_WORLD_SERVER_INFO, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_WORLD_STATE_UI_TIMER_UPDATE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_WORLD_SERVER_INFO, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_WORLD_STATE_UI_TIMER_UPDATE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_XP_GAIN_ABORTED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ZONE_UNDER_ATTACK, STATUS_UNHANDLED); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index be7f810eb6f..9a7c8ed8ae3 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -78,35 +78,38 @@ enum OpcodeClient : uint32 CMSG_AUCTION_SELL_ITEM = 0xBADD, CMSG_AUTH_CONTINUED_SESSION = 0x0485, CMSG_AUTH_SESSION = 0x0487, - CMSG_AUTOBANK_ITEM = 0xBADD, + CMSG_AUTOBANK_ITEM = 0x0751, CMSG_AUTOEQUIP_GROUND_ITEM = 0xBADD, - CMSG_AUTOEQUIP_ITEM = 0xBADD, + CMSG_AUTOEQUIP_ITEM = 0x0F35, CMSG_AUTOEQUIP_ITEM_SLOT = 0xBADD, - CMSG_AUTOSTORE_BAG_ITEM = 0xBADD, - CMSG_AUTOSTORE_BANK_ITEM = 0xBADD, + CMSG_AUTOSTORE_BAG_ITEM = 0x0F18, + CMSG_AUTOSTORE_BANK_ITEM = 0x0732, CMSG_AUTOSTORE_GROUND_ITEM = 0xBADD, - CMSG_AUTOSTORE_LOOT_ITEM = 0xBADD, + CMSG_AUTOSTORE_LOOT_ITEM = 0x0609, CMSG_AUTO_DECLINE_GUILD_INVITE = 0xBADD, CMSG_AUTO_DECLINE_GUILD_INVITES = 0xBADD, CMSG_BANKER_ACTIVATE = 0x1B24, CMSG_BATTLEFIELD_JOIN = 0xBADD, CMSG_BATTLEFIELD_LEAVE = 0xBADD, CMSG_BATTLEFIELD_LIST = 0x03B1, - CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE = 0xBADD, - CMSG_BATTLEFIELD_MGR_EXIT_REQUEST = 0xBADD, - CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE = 0xBADD, + CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE = 0x059A, + CMSG_BATTLEFIELD_MGR_EXIT_REQUEST = 0x1381, + CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE = 0x122A, CMSG_BATTLEFIELD_MGR_QUEUE_REQUEST = 0xBADD, - CMSG_BATTLEFIELD_PORT = 0xBADD, + CMSG_BATTLEFIELD_PORT = 0x11EB, CMSG_BATTLEFIELD_REQUEST_SCORE_DATA = 0xBADD, CMSG_BATTLEFIELD_STATUS = 0xBADD, CMSG_BATTLEGROUND_PLAYER_POSITIONS = 0xBADD, - CMSG_BATTLEMASTER_JOIN = 0xBADD, - CMSG_BATTLEMASTER_JOIN_ARENA = 0xBADD, + CMSG_BATTLEMASTER_JOIN = 0x0D2E, + CMSG_BATTLEMASTER_JOIN_ARENA = 0x0DAE, CMSG_BATTLEMASTER_JOIN_RATED = 0xBADD, CMSG_BATTLEMASTER_HELLO = 0xBADD, CMSG_BATTLE_PAY_GET_PRODUCT_LIST_QUERY = 0x1389, CMSG_BATTLE_PAY_GET_PURCHASE_LIST_QUERY = 0x120C, + CMSG_BATTLE_PET_DELETE_PET = 0x07B9, + CMSG_BATTLE_PET_MODIFY_NAME = 0x03A9, CMSG_BATTLE_PET_NAME_QUERY = 0x041C, + CMSG_BATTLE_PET_SET_BATTLE_SLOT = 0x120B, CMSG_BEGIN_TRADE = 0xBADD, CMSG_BINDER_ACTIVATE = 0x02F3, CMSG_BOT_DETECTED2 = 0xBADD, @@ -146,10 +149,10 @@ enum OpcodeClient : uint32 CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE = 0xBADD, CMSG_CHANNEL_ANNOUNCEMENTS = 0xBADD, CMSG_CHANNEL_BAN = 0xBADD, - CMSG_CHANNEL_DISPLAY_LIST = 0xBADD, + CMSG_CHANNEL_DISPLAY_LIST = 0x093B, CMSG_CHANNEL_INVITE = 0xBADD, CMSG_CHANNEL_KICK = 0xBADD, - CMSG_CHANNEL_LIST = 0xBADD, + CMSG_CHANNEL_LIST = 0x093B, CMSG_CHANNEL_MODERATE = 0xBADD, CMSG_CHANNEL_MODERATOR = 0xBADD, CMSG_CHANNEL_MUTE = 0xBADD, @@ -190,7 +193,7 @@ enum OpcodeClient : uint32 CMSG_COMPLAIN = 0xBADD, CMSG_COMPLETE_CINEMATIC = 0xBADD, CMSG_COMPLETE_MOVIE = 0xBADD, - CMSG_CONNECT_TO_FAILED = 0xBADD, + CMSG_CONNECT_TO_FAILED = 0x0135, CMSG_CONTACT_LIST = 0xBADD, CMSG_CORPSE_MAP_POSITION_QUERY = 0xBADD, CMSG_CREATURE_QUERY = 0x0505, @@ -277,7 +280,7 @@ enum OpcodeClient : uint32 CMSG_GUILD_EVENT_LOG_QUERY = 0xBADD, CMSG_GUILD_INFO = 0xBADD, CMSG_GUILD_INFO_TEXT = 0xBADD, - CMSG_GUILD_INVITE = 0xBADD, + CMSG_GUILD_INVITE = 0x19A4, CMSG_GUILD_LEAVE = 0xBADD, CMSG_GUILD_MEMBER_SEND_SOR_REQUEST = 0xBADD, CMSG_GUILD_MOTD = 0xBADD, @@ -312,7 +315,7 @@ enum OpcodeClient : uint32 CMSG_LEARN_PREVIEW_TALENTS = 0xBADD, CMSG_LEARN_PREVIEW_TALENTS_PET = 0xBADD, CMSG_LEARN_TALENT = 0xBADD, - CMSG_LEAVE_CHANNEL = 0xBADD, + CMSG_LEAVE_CHANNEL = 0x19F2, CMSG_LFG_GET_STATUS = 0xBADD, CMSG_LFG_JOIN = 0xBADD, CMSG_LFG_LEAVE = 0xBADD, @@ -332,7 +335,7 @@ enum OpcodeClient : uint32 CMSG_LF_GUILD_POST_REQUEST = 0xBADD, CMSG_LF_GUILD_REMOVE_RECRUIT = 0xBADD, CMSG_LF_GUILD_SET_GUILD_POST = 0xBADD, - CMSG_LIST_INVENTORY = 0xBADD, + CMSG_LIST_INVENTORY = 0x0B39, CMSG_LOAD_SCREEN = 0x0B08, CMSG_LOGOUT_CANCEL = 0x03C2, CMSG_LOGOUT_REQUEST = 0x1911, @@ -344,29 +347,27 @@ enum OpcodeClient : uint32 CMSG_LOOT_MONEY = 0xBADD, CMSG_LOOT_RELEASE = 0xBADD, CMSG_LOOT_ROLL = 0xBADD, - CMSG_MAIL_CREATE_TEXT_ITEM = 0xBADD, - CMSG_MAIL_DELETE = 0xBADD, + CMSG_MAIL_CREATE_TEXT_ITEM = 0x13D1, + CMSG_MAIL_DELETE = 0x068C, CMSG_MAIL_MARK_AS_READ = 0xBADD, CMSG_MAIL_RETURN_TO_SENDER = 0xBADD, CMSG_MAIL_TAKE_ITEM = 0xBADD, CMSG_MAIL_TAKE_MONEY = 0xBADD, CMSG_MEETINGSTONE_INFO = 0xBADD, - CMSG_MESSAGECHAT_ADDON_BATTLEGROUND = 0xBADD, - CMSG_MESSAGECHAT_ADDON_GUILD = 0xBADD, - CMSG_MESSAGECHAT_ADDON_OFFICER = 0xBADD, - CMSG_MESSAGECHAT_ADDON_PARTY = 0xBADD, - CMSG_MESSAGECHAT_ADDON_RAID = 0xBADD, - CMSG_MESSAGECHAT_ADDON_WHISPER = 0xBADD, + CMSG_MESSAGECHAT_ADDON_GUILD = 0x137C, + CMSG_MESSAGECHAT_ADDON_OFFICER = 0x188A, + CMSG_MESSAGECHAT_ADDON_PARTY = 0x015C, + CMSG_MESSAGECHAT_ADDON_RAID = 0x082C, + CMSG_MESSAGECHAT_ADDON_WHISPER = 0x18A2, CMSG_MESSAGECHAT_AFK = 0x1BDC, - CMSG_MESSAGECHAT_BATTLEGROUND = 0xBADD, CMSG_MESSAGECHAT_CHANNEL = 0x0913, CMSG_MESSAGECHAT_DND = 0x0AAB, CMSG_MESSAGECHAT_EMOTE = 0x113C, CMSG_MESSAGECHAT_GUILD = 0x0B1B, - CMSG_MESSAGECHAT_OFFICER = 0xBADD, + CMSG_MESSAGECHAT_OFFICER = 0x0114, CMSG_MESSAGECHAT_PARTY = 0x0134, - CMSG_MESSAGECHAT_RAID = 0xBADD, - CMSG_MESSAGECHAT_RAID_WARNING = 0xBADD, + CMSG_MESSAGECHAT_RAID = 0x0B33, + CMSG_MESSAGECHAT_RAID_WARNING = 0x0313, CMSG_MESSAGECHAT_SAY = 0x1884, CMSG_MESSAGECHAT_WHISPER = 0x1829, CMSG_MESSAGECHAT_YELL = 0x1161, @@ -423,6 +424,7 @@ enum OpcodeClient : uint32 CMSG_MOVE_STOP_STRAFE = 0x01D1, CMSG_MOVE_STOP_SWIM = 0x097C, CMSG_MOVE_STOP_TURN = 0x0964, + CMSG_MOVE_TELEPORT_ACK = 0x0D01, CMSG_MOVE_TIME_SKIPPED = 0x19C2, CMSG_MOVE_TOGGLE_COLLISION_ACK = 0xBADD, CMSG_MOVE_WATER_WALK_ACK = 0xBADD, @@ -457,7 +459,7 @@ enum OpcodeClient : uint32 CMSG_PET_SPELL_AUTOCAST = 0xBADD, CMSG_PET_STOP_ATTACK = 0xBADD, CMSG_PING = 0x0416, - CMSG_PLAYED_TIME = 0xBADD, + CMSG_PLAYED_TIME = 0x1BB2, CMSG_PLAYER_DIFFICULTY_CHANGE = 0xBADD, CMSG_PLAYER_LOGIN = 0x0B1D, CMSG_PLAYER_LOGOUT = 0xBADD, @@ -483,7 +485,7 @@ enum OpcodeClient : uint32 CMSG_QUESTGIVER_QUEST_AUTOLAUNCH = 0xBADD, CMSG_QUESTGIVER_REQUEST_REWARD = 0xBADD, CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x0131, - CMSG_QUESTGIVER_STATUS_QUERY = 0x0704, + CMSG_QUESTGIVER_STATUS_QUERY = 0x01E2, CMSG_QUESTLOG_REMOVE_QUEST = 0xBADD, CMSG_QUESTLOG_SWAP_QUEST = 0xBADD, CMSG_QUEST_CONFIRM_ACCEPT = 0xBADD, @@ -497,6 +499,7 @@ enum OpcodeClient : uint32 CMSG_REALM_NAME_QUERY = 0x1189, CMSG_REALM_SPLIT = 0xBADD, CMSG_RECLAIM_CORPSE = 0xBADD, + CMSG_RECRUIT_A_FRIEND = 0x07BA, CMSG_REFORGE_ITEM = 0xBADD, CMSG_REORDER_CHARACTERS = 0x0DAA, CMSG_REPAIR_ITEM = 0x0B54, @@ -505,8 +508,7 @@ enum OpcodeClient : uint32 CMSG_REPORT_PVP_AFK = 0xBADD, CMSG_REQUEST_ACCOUNT_DATA = 0x0F3E, CMSG_REQUEST_CATEGORY_COOLDOWNS = 0xBADD, - CMSG_REQUEST_CEMETERY_LIST = 0xBADD, - CMSG_REQUEST_HOTFIX = 0xBADD, + CMSG_REQUEST_CEMETERY_LIST = 0x10A2, CMSG_REQUEST_INSPECT_RATED_BG_STATS = 0xBADD, CMSG_REQUEST_PARTY_MEMBER_STATS = 0xBADD, CMSG_REQUEST_PET_INFO = 0xBADD, @@ -540,7 +542,7 @@ enum OpcodeClient : uint32 CMSG_SET_ACTIONBAR_TOGGLES = 0xBADD, CMSG_SET_ACTION_BUTTON = 0x0599, CMSG_SET_ACTIVE_MOVER = 0xBADD, - CMSG_SET_ACTIVE_VOICE_CHANNEL = 0xBADD, + CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x031E, CMSG_SET_ALLOW_LOW_LEVEL_RAID1 = 0xBADD, CMSG_SET_ALLOW_LOW_LEVEL_RAID2 = 0xBADD, CMSG_SET_CHANNEL_WATCH = 0xBADD, @@ -605,9 +607,7 @@ enum OpcodeClient : uint32 CMSG_TRANSMOGRIFY_ITEMS = 0x0A85, CMSG_TRIGGER_CINEMATIC_CHEAT = 0xBADD, CMSG_TURN_IN_PETITION = 0xBADD, - CMSG_TUTORIAL_CLEAR = 0xBADD, - CMSG_TUTORIAL_FLAG = 0xBADD, - CMSG_TUTORIAL_RESET = 0xBADD, + CMSG_TUTORIAL_FLAG = 0x0B16, CMSG_UNACCEPT_TRADE = 0xBADD, CMSG_UNDELETE_CHARACTER = 0x0D99, CMSG_UNDELETE_COOLDOWN_STATUS_QUERY = 0x19A9, @@ -620,7 +620,7 @@ enum OpcodeClient : uint32 CMSG_USED_FOLLOW = 0xBADD, CMSG_USE_ITEM = 0x08B6, CMSG_VIOLENCE_LEVEL = 0x098D, - CMSG_VOICE_SESSION_ENABLE = 0xBADD, + CMSG_VOICE_SESSION_ENABLE = 0x1102, CMSG_VOID_STORAGE_QUERY = 0x019E, CMSG_VOID_STORAGE_TRANSFER = 0x0463, CMSG_VOID_STORAGE_UNLOCK = 0x13BB, @@ -630,7 +630,7 @@ enum OpcodeClient : uint32 CMSG_WARGAME_START = 0xBADD, CMSG_WHO = 0x1322, CMSG_WHOIS = 0xBADD, - CMSG_WORLD_STATE_UI_TIMER_UPDATE = 0xBADD, + CMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x0302, CMSG_WORLD_TELEPORT = 0xBADD, CMSG_WRAP_ITEM = 0xBADD, CMSG_ZONEUPDATE = 0xBADD, @@ -650,8 +650,6 @@ enum OpcodeClient : uint32 MSG_MOVE_SET_SWIM_SPEED_CHEAT = 0xBADD, MSG_MOVE_SET_TURN_RATE_CHEAT = 0xBADD, MSG_MOVE_SET_WALK_SPEED_CHEAT = 0xBADD, - MSG_MOVE_TELEPORT = 0xBADD, - MSG_MOVE_TELEPORT_ACK = 0xBADD, MSG_MOVE_TELEPORT_CHEAT = 0xBADD, MSG_MOVE_TIME_SKIPPED = 0xBADD, MSG_MOVE_TOGGLE_COLLISION_CHEAT = 0xBADD, @@ -684,12 +682,14 @@ enum OpcodeServer : uint32 SMSG_ACCOUNT_INFO_RESPONSE = 0xBADD, SMSG_ACCOUNT_MOUNT_UPDATE = 0x0140, SMSG_ACCOUNT_RESTRICTED_WARNING = 0xBADD, + SMSG_ACCOUNT_TOYS_UPDATE = 0x0590, SMSG_ACHIEVEMENT_DELETED = 0xBADD, SMSG_ACHIEVEMENT_EARNED = 0xBADD, SMSG_ACTION_BUTTONS = 0x1D1F, SMSG_ACTIVATETAXIREPLY = 0xBADD, SMSG_ADDON_INFO = 0x1D9F, SMSG_ADD_RUNE_POWER = 0xBADD, + SMSG_ADJUST_SPLINE_DURATION = 0x0104, SMSG_AI_REACTION = 0x0BA1, SMSG_ALL_ACHIEVEMENT_DATA = 0xBADD, SMSG_ALL_ACHIEVEMENT_DATA_ACCOUNT = 0x0123, @@ -718,16 +718,16 @@ enum OpcodeServer : uint32 SMSG_AUCTION_COMMAND_RESULT = 0x0B2D, SMSG_AUCTION_HELLO = 0x011F, SMSG_AUCTION_LIST_PENDING_SALES = 0xBADD, - SMSG_AUCTION_LIST_RESULT = 0x19D2, + SMSG_AUCTION_LIST_ITEMS_RESULT = 0x0BA4, SMSG_AUCTION_OWNER_LIST_RESULT = 0xBADD, SMSG_AUCTION_OWNER_NOTIFICATION = 0xBADD, SMSG_AUCTION_REMOVED_NOTIFICATION = 0xBADD, SMSG_AURACASTLOG = 0xBADD, - SMSG_AURA_POINTS_DEPLETED = 0xBADD, + SMSG_AURA_POINTS_DEPLETED = 0x093B, SMSG_AURA_UPDATE = 0x091C, SMSG_AUTH_CHALLENGE = 0x1759, SMSG_AUTH_RESPONSE = 0x0DA9, - SMSG_AVAILABLE_VOICE_CHANNEL = 0xBADD, + SMSG_AVAILABLE_VOICE_CHANNEL = 0x04D4, SMSG_AVERAGE_ITEM_LEVEL_INFORM = 0xBADD, SMSG_BARBER_SHOP_RESULT = 0xBADD, SMSG_BATTLEFIELD_LIST = 0xBADD, @@ -751,6 +751,7 @@ enum OpcodeServer : uint32 SMSG_BATTLEGROUND_INFO_THROTTLED = 0xBADD, SMSG_BATTLEGROUND_PLAYER_JOINED = 0xBADD, SMSG_BATTLEGROUND_PLAYER_LEFT = 0xBADD, + SMSG_BATTLE_PAY_DISTRIBUTION_UPDATE = 0x0BE3, SMSG_BATTLE_PAY_GET_DISTRIBUTION_LIST_RESPONSE = 0x0F2A, SMSG_BATTLE_PAY_GET_PRODUCT_LIST_RESPONSE = 0x12A4, SMSG_BATTLE_PAY_GET_PURCHASE_LIST_RESPONSE = 0x168A, @@ -785,16 +786,17 @@ enum OpcodeServer : uint32 SMSG_CALENDAR_RAID_LOCKOUT_UPDATED = 0xBADD, SMSG_CALENDAR_SEND_CALENDAR = 0xBADD, SMSG_CALENDAR_SEND_EVENT = 0xBADD, - SMSG_CALENDAR_SEND_NUM_PENDING = 0xBADD, + SMSG_CALENDAR_SEND_NUM_PENDING = 0x1B3A, SMSG_CALENDAR_UPDATE_INVITE_LIST = 0xBADD, SMSG_CAMERA_SHAKE = 0xBADD, SMSG_CANCEL_AUTO_REPEAT = 0xBADD, SMSG_CANCEL_COMBAT = 0xBADD, - SMSG_CAST_FAILED = 0xBADD, - SMSG_CHANNEL_LIST = 0xBADD, + SMSG_CAST_FAILED = 0x1A89, + SMSG_CHANNEL_LIST = 0x1411, SMSG_CHANNEL_MEMBER_COUNT = 0xBADD, SMSG_CHANNEL_NOTIFY = 0x0643, SMSG_CHANNEL_NOTIFY_JOINED = 0x1602, + SMSG_CHANNEL_NOTIFY_LEFT = 0x1452, SMSG_CHANNEL_START = 0x016C, SMSG_CHANNEL_UPDATE = 0x19DB, SMSG_CHARACTER_LOGIN_FAILED = 0xBADD, @@ -822,6 +824,7 @@ enum OpcodeServer : uint32 SMSG_CLEAR_TARGET = 0xBADD, SMSG_CLIENTCACHE_VERSION = 0x080D, SMSG_CLIENT_CONTROL_UPDATE = 0xBADD, + SMSG_COIN_REMOVED = 0x0D30, SMSG_COMBAT_EVENT_FAILED = 0xBADD, SMSG_COMBAT_LOG_MULTIPLE = 0xBADD, SMSG_COMMENTATOR_MAP_INFO = 0xBADD, @@ -836,7 +839,7 @@ enum OpcodeServer : uint32 SMSG_COMSAT_CONNECT_FAIL = 0xBADD, SMSG_COMSAT_DISCONNECT = 0xBADD, SMSG_COMSAT_RECONNECT_TRY = 0xBADD, - SMSG_CONTACT_LIST = 0xBADD, + SMSG_CONTACT_LIST = 0x0210, SMSG_CONTACT_STATUS = 0x1BEA, SMSG_CONVERT_RUNE = 0xBADD, SMSG_COOLDOWN_CHEAT = 0xBADD, @@ -870,6 +873,7 @@ enum OpcodeServer : uint32 SMSG_DISMOUNTRESULT = 0xBADD, SMSG_DISPEL_FAILED = 0xBADD, SMSG_DISPLAY_GAME_ERROR = 0xBADD, + SMSG_DISPLAY_PROMOTION = 0x151D, SMSG_DONT_AUTO_PUSH_SPELLS_TO_ACTION_BAR = 0xBADD, SMSG_DROP_NEW_CONNECTION = 0xBADD, SMSG_DUEL_COMPLETE = 0xBADD, @@ -905,8 +909,10 @@ enum OpcodeServer : uint32 SMSG_FORCE_SET_VEHICLE_REC_ID = 0xBADD, SMSG_FORGE_MASTER_SET = 0xBADD, SMSG_FRIEND_STATUS = 0xBADD, - SMSG_GAMEOBJECT_CUSTOM_ANIM = 0xBADD, + SMSG_GAMEOBJECT_ACTIVATE_ANIM_KIT = 0x038C, + SMSG_GAMEOBJECT_CUSTOM_ANIM = 0x03EB, SMSG_GAMEOBJECT_DESPAWN_ANIM = 0xBADD, + SMSG_GAMEOBJECT_DESPAWN = 0x0D29, SMSG_GAMEOBJECT_PAGETEXT = 0xBADD, SMSG_GAMEOBJECT_QUERY_RESPONSE = 0xBADD, SMSG_GAMEOBJECT_RESET_STATE = 0xBADD, @@ -914,7 +920,8 @@ enum OpcodeServer : uint32 SMSG_GAMETIME_SET = 0xBADD, SMSG_GAMETIME_UPDATE = 0xBADD, SMSG_GAME_EVENT_DEBUG_LOG = 0xBADD, - SMSG_GAME_OBJECT_ACTIVATE_ANIM_KIT = 0xBADD, + SMSG_GARRISON_COMPLETE_MISSION_RESULT = 0x0952, + SMSG_GARRISON_REMOTE_INFO = 0x0151, SMSG_GMRESPONSE_DB_ERROR = 0xBADD, SMSG_GMRESPONSE_RECEIVED = 0xBADD, SMSG_GMRESPONSE_STATUS_UPDATE = 0xBADD, @@ -925,7 +932,9 @@ enum OpcodeServer : uint32 SMSG_GMTICKET_UPDATETEXT = 0xBADD, SMSG_GM_MESSAGECHAT = 0xBADD, SMSG_GM_PLAYER_INFO = 0xBADD, + SMSG_GM_TICKET_CASE_STATUS = 0x1D8D, SMSG_GM_TICKET_STATUS_UPDATE = 0xBADD, + SMSG_GM_TICKET_SYSTEM_STATUS = 0x1229, SMSG_GODMODE = 0xBADD, SMSG_GOSSIP_COMPLETE = 0x15D1, SMSG_GOSSIP_MESSAGE = 0x1746, @@ -934,7 +943,7 @@ enum OpcodeServer : uint32 SMSG_GROUP_CANCEL = 0xBADD, SMSG_GROUP_DECLINE = 0xBADD, SMSG_GROUP_DESTROYED = 0xBADD, - SMSG_GROUP_INVITE = 0xBADD, + SMSG_GROUP_INVITE = 0x0920, SMSG_GROUP_LIST = 0x15BE, SMSG_GROUP_SET_LEADER = 0xBADD, SMSG_GROUP_SET_ROLE = 0xBADD, @@ -955,8 +964,10 @@ enum OpcodeServer : uint32 SMSG_GUILD_COMMAND_RESULT_2 = 0xBADD, SMSG_GUILD_CRITERIA_DATA = 0xBADD, SMSG_GUILD_CRITERIA_DELETED = 0xBADD, + SMSG_GUILD_CRITERIA_UPDATE = 0x1208, SMSG_GUILD_DECLINE = 0xBADD, SMSG_GUILD_EVENT = 0x1027, + SMSG_GUILD_EVENT_BANK_MONEY_CHANGED = 0x1077, SMSG_GUILD_EVENT_LOG_QUERY_RESULT = 0xBADD, SMSG_GUILD_EVENT_PRESENCE_CHANGE = 0x1228, SMSG_GUILD_FLAGGED_FOR_RENAME = 0xBADD, @@ -983,7 +994,7 @@ enum OpcodeServer : uint32 SMSG_GUILD_REPUTATION_REACTION_CHANGED = 0xBADD, SMSG_GUILD_REPUTATION_WEEKLY_CAP = 0xBADD, SMSG_GUILD_RESET = 0xBADD, - SMSG_GUILD_REWARDS_LIST = 0xBADD, + SMSG_GUILD_REWARDS_LIST = 0x1818, SMSG_GUILD_ROSTER = 0x1026, SMSG_GUILD_SET_NOTE = 0xBADD, SMSG_GUILD_TRADESKILL_UPDATE = 0xBADD, @@ -1007,12 +1018,13 @@ enum OpcodeServer : uint32 SMSG_INSPECT_RATED_BG_STATS = 0xBADD, SMSG_INSPECT_RESULTS_UPDATE = 0xBADD, SMSG_INSPECT_TALENT = 0xBADD, + SMSG_INSTANCE_INFO = 0x0DA0, SMSG_INSTANCE_LOCK_WARNING_QUERY = 0xBADD, SMSG_INSTANCE_RESET = 0xBADD, SMSG_INSTANCE_RESET_FAILED = 0xBADD, SMSG_INSTANCE_SAVE_CREATED = 0xBADD, SMSG_INVALIDATE_DANCE = 0xBADD, - SMSG_INVALIDATE_PLAYER = 0xBADD, + SMSG_INVALIDATE_PLAYER = 0x0B37, SMSG_INVALID_PROMOTION_CODE = 0xBADD, SMSG_INVENTORY_CHANGE_FAILURE = 0xBADD, SMSG_ITEM_ADD_PASSIVE = 0xBADD, @@ -1078,6 +1090,7 @@ enum OpcodeServer : uint32 SMSG_LOOT_SLOT_CHANGED = 0xBADD, SMSG_LOOT_START_ROLL = 0xBADD, SMSG_MAIL_LIST_RESULT = 0x0B3F, + SMSG_MAIL_QUERY_NEXT_TIME_RESULT = 0x153D, SMSG_MAP_OBJ_EVENTS = 0xBADD, SMSG_MEETINGSTONE_COMPLETE = 0xBADD, SMSG_MEETINGSTONE_IN_PROGRESS = 0xBADD, @@ -1092,7 +1105,7 @@ enum OpcodeServer : uint32 SMSG_MISSILE_CANCEL = 0xBADD, SMSG_MODIFY_COOLDOWN = 0xBADD, SMSG_MONEY_NOTIFY = 0xBADD, - SMSG_MONSTER_MOVE = 0xBADD, + SMSG_MONSTER_MOVE = 0x0994, SMSG_MONSTER_MOVE_TRANSPORT = 0xBADD, SMSG_MOTD = 0x0442, SMSG_MOUNTRESULT = 0xBADD, @@ -1125,6 +1138,7 @@ enum OpcodeServer : uint32 SMSG_MOVE_SET_VEHICLE_REC_ID = 0xBADD, SMSG_MOVE_SET_WALK_IN_AIR = 0xBADD, SMSG_MOVE_SET_WALK_SPEED = 0xBADD, + SMSG_MOVE_TELEPORT = 0x03A6, SMSG_MOVE_UNROOT = 0xBADD, SMSG_MOVE_UNSET_CAN_FLY = 0xBADD, SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0xBADD, @@ -1134,14 +1148,14 @@ enum OpcodeServer : uint32 SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED = 0xBADD, SMSG_MOVE_UPDATE_FLIGHT_SPEED = 0xBADD, SMSG_MOVE_UPDATE_KNOCK_BACK = 0xBADD, - SMSG_MOVE_UPDATE_PITCH_RATE = 0xBADD, - SMSG_MOVE_UPDATE_RUN_BACK_SPEED = 0xBADD, - SMSG_MOVE_UPDATE_RUN_SPEED = 0xBADD, - SMSG_MOVE_UPDATE_SWIM_BACK_SPEED = 0xBADD, - SMSG_MOVE_UPDATE_SWIM_SPEED = 0xBADD, + SMSG_MOVE_UPDATE_PITCH_RATE = 0x13D9, + SMSG_MOVE_UPDATE_RUN_BACK_SPEED = 0x09DE, + SMSG_MOVE_UPDATE_RUN_SPEED = 0x09AD, + SMSG_MOVE_UPDATE_SWIM_BACK_SPEED = 0x1083, + SMSG_MOVE_UPDATE_SWIM_SPEED = 0x0B95, SMSG_MOVE_UPDATE_TELEPORT = 0x03D5, - SMSG_MOVE_UPDATE_TURN_RATE = 0xBADD, - SMSG_MOVE_UPDATE_WALK_SPEED = 0xBADD, + SMSG_MOVE_UPDATE_TURN_RATE = 0x08BE, + SMSG_MOVE_UPDATE_WALK_SPEED = 0x01E5, SMSG_MOVE_WATER_WALK = 0xBADD, SMSG_MULTIPLE_PACKETS = 0xBADD, SMSG_NAME_QUERY_RESPONSE = 0x0828, @@ -1162,7 +1176,7 @@ enum OpcodeServer : uint32 SMSG_PAGE_TEXT_QUERY_RESPONSE = 0x05A0, SMSG_PARTYKILLLOG = 0xBADD, SMSG_PARTY_COMMAND_RESULT = 0xBADD, - SMSG_PARTY_MEMBER_STATS = 0xBADD, + SMSG_PARTY_MEMBER_STATS = 0x1729, SMSG_PARTY_MEMBER_STATS_FULL = 0xBADD, SMSG_PAUSE_MIRROR_TIMER = 0xBADD, SMSG_PERIODICAURALOG = 0x0B1B, @@ -1201,7 +1215,7 @@ enum OpcodeServer : uint32 SMSG_PLAY_OBJECT_SOUND = 0xBADD, SMSG_PLAY_ONE_SHOT_ANIM_KIT = 0xBADD, SMSG_PLAY_SOUND = 0x02D2, - SMSG_PLAY_SPELL_VISUAL = 0xBADD, + SMSG_PLAY_SPELL_VISUAL = 0x1A84, SMSG_PLAY_SPELL_VISUAL_KIT = 0x0171, SMSG_PLAY_TIME_WARNING = 0xBADD, SMSG_PONG = 0x17CA, @@ -1216,7 +1230,7 @@ enum OpcodeServer : uint32 SMSG_PVP_SEASON = 0x09E3, SMSG_QUERY_QUESTS_COMPLETED_RESPONSE = 0xBADD, SMSG_QUERY_TIME_RESPONSE = 0x1DB0, - SMSG_QUESTGIVER_OFFER_REWARD = 0xBADD, + SMSG_QUESTGIVER_OFFER_REWARD = 0x17B2, SMSG_QUESTGIVER_QUEST_COMPLETE = 0x1773, SMSG_QUESTGIVER_QUEST_DETAILS = 0x15B3, SMSG_QUESTGIVER_QUEST_FAILED = 0xBADD, @@ -1227,7 +1241,7 @@ enum OpcodeServer : uint32 SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x17C6, SMSG_QUESTLOG_FULL = 0xBADD, SMSG_QUESTUPDATE_ADD_ITEM = 0xBADD, - SMSG_QUESTUPDATE_ADD_KILL = 0xBADD, + SMSG_QUESTUPDATE_ADD_KILL = 0x1515, SMSG_QUESTUPDATE_ADD_PVP_KILL = 0xBADD, SMSG_QUESTUPDATE_COMPLETE = 0xBADD, SMSG_QUESTUPDATE_FAILED = 0xBADD, @@ -1256,9 +1270,10 @@ enum OpcodeServer : uint32 SMSG_REFER_A_FRIEND_EXPIRED = 0xBADD, SMSG_REFER_A_FRIEND_FAILURE = 0xBADD, SMSG_REFORGE_RESULT = 0xBADD, + SMSG_REFRESH_SPELL_HISTORY = 0x0A2A, SMSG_REMOVED_SPELL = 0xBADD, SMSG_REPORT_PVP_AFK_RESULT = 0xBADD, - SMSG_REQUEST_CEMETERY_LIST_RESPONSE = 0xBADD, + SMSG_REQUEST_CEMETERY_LIST_RESPONSE = 0x059E, SMSG_REQUEST_PVP_REWARDS_RESPONSE = 0xBADD, SMSG_RESEARCH_COMPLETE = 0xBADD, SMSG_RESEARCH_SETUP_HISTORY = 0x0A25, @@ -1274,20 +1289,25 @@ enum OpcodeServer : uint32 SMSG_RWHOIS = 0xBADD, SMSG_SELL_ITEM = 0xBADD, SMSG_SEND_MAIL_RESULT = 0x0302, - SMSG_SEND_UNLEARN_SPELLS = 0x1A82, + SMSG_SEND_SPELL_CHARGES = 0x1A82, + SMSG_SEND_SPELL_HISTORY = 0x1933, + SMSG_SEND_UNLEARN_SPELLS = 0x0BCB, SMSG_SERVERTIME = 0xBADD, SMSG_SERVER_FIRST_ACHIEVEMENT = 0xBADD, SMSG_SERVER_INFO_RESPONSE = 0xBADD, SMSG_SERVER_MESSAGE = 0x0683, SMSG_SERVER_PERF = 0xBADD, - SMSG_SET_AI_ANIM_KIT = 0xBADD, + SMSG_SET_AI_ANIM_KIT = 0x0335, + SMSG_SET_ALL_TASK_PROGRESS = 0x1B52, + SMSG_SET_CURRENCY = 0x17BE, SMSG_SET_DF_FAST_LAUNCH_RESULT = 0xBADD, SMSG_SET_FACTION_ATWAR = 0xBADD, SMSG_SET_FACTION_NOT_VISIBLE = 0xBADD, SMSG_SET_FACTION_STANDING = 0xBADD, - SMSG_SET_FACTION_VISIBLE = 0xBADD, + SMSG_SET_FACTION_VISIBLE = 0x138B, SMSG_SET_FLAT_SPELL_MODIFIER = 0x1884, SMSG_SET_FORCED_REACTIONS = 0x09A9, + SMSG_SET_MAX_WEEKLY_QUANTITY = 0x1489, SMSG_SET_MELEE_ANIM_KIT = 0xBADD, SMSG_SET_MOVEMENT_ANIM_KIT = 0xBADD, SMSG_SET_PCT_SPELL_MODIFIER = 0x113C, @@ -1319,8 +1339,8 @@ enum OpcodeServer : uint32 SMSG_SPELL_CATEGORY_COOLDOWN = 0x082A, SMSG_SPELL_COOLDOWN = 0xBADD, SMSG_SPELL_DELAYED = 0xBADD, - SMSG_SPELL_FAILED_OTHER = 0xBADD, - SMSG_SPELL_FAILURE = 0xBADD, + SMSG_SPELL_FAILED_OTHER = 0x1A03, + SMSG_SPELL_FAILURE = 0x11DB, SMSG_SPELL_GO = 0x1161, SMSG_SPELL_START = 0x0803, SMSG_SPELL_UPDATE_CHAIN_TARGETS = 0x0374, @@ -1356,6 +1376,7 @@ enum OpcodeServer : uint32 SMSG_SPLINE_MOVE_WATER_WALK = 0xBADD, SMSG_STABLE_RESULT = 0xBADD, SMSG_STANDSTATE_UPDATE = 0x1311, + SMSG_START_ELAPSED_TIMERS = 0x093F, SMSG_START_MIRROR_TIMER = 0xBADD, SMSG_START_TIMER = 0xBADD, SMSG_STOP_DANCE = 0xBADD, @@ -1370,11 +1391,11 @@ enum OpcodeServer : uint32 SMSG_TALENTS_ERROR = 0xBADD, SMSG_TALENTS_INFO = 0x012D, SMSG_TALENTS_INVOLUNTARILY_RESET = 0xBADD, - SMSG_TAXINODE_STATUS = 0xBADD, + SMSG_TAXINODE_STATUS = 0x0338, SMSG_TEST_DROP_RATE_RESULT = 0xBADD, SMSG_TEXT_EMOTE = 0x0383, SMSG_THREAT_CLEAR = 0xBADD, - SMSG_THREAT_REMOVE = 0xBADD, + SMSG_THREAT_REMOVE = 0x0F3D, SMSG_THREAT_UPDATE = 0x03A9, SMSG_TIME_ADJUSTMENT = 0xBADD, SMSG_TIME_SYNC_REQ = 0x03B1, @@ -1386,7 +1407,7 @@ enum OpcodeServer : uint32 SMSG_TRAINER_BUY_FAILED = 0xBADD, SMSG_TRAINER_BUY_SUCCEEDED = 0xBADD, SMSG_TRAINER_LIST = 0x0BA9, - SMSG_TRANSFER_ABORTED = 0xBADD, + SMSG_TRANSFER_ABORTED = 0x03C2, SMSG_TRANSFER_PENDING = 0x172A, SMSG_TRIGGER_CINEMATIC = 0xBADD, SMSG_TRIGGER_MOVIE = 0xBADD, @@ -1397,7 +1418,6 @@ enum OpcodeServer : uint32 SMSG_UNIT_HEALTH_FREQUENT = 0xBADD, SMSG_UNIT_SPELLCAST_START = 0xBADD, SMSG_UPDATE_ACCOUNT_DATA = 0x1520, - SMSG_UPDATE_ACCOUNT_DATA_COMPLETE = 0xBADD, SMSG_UPDATE_COMBO_POINTS = 0xBADD, SMSG_UPDATE_CURRENCY = 0xBADD, SMSG_UPDATE_CURRENCY_WEEK_LIMIT = 0xBADD, @@ -1407,6 +1427,7 @@ enum OpcodeServer : uint32 SMSG_UPDATE_LAST_INSTANCE = 0xBADD, SMSG_UPDATE_OBJECT = 0x122C, SMSG_UPDATE_SERVER_PLAYER_POSITION = 0xBADD, + SMSG_UPDATE_TASK_PROGRESS = 0x1209, SMSG_UPDATE_WORLD_STATE = 0x03EC, SMSG_USERLIST_ADD = 0xBADD, SMSG_USERLIST_REMOVE = 0xBADD, @@ -1414,7 +1435,7 @@ enum OpcodeServer : uint32 SMSG_VOICESESSION_FULL = 0xBADD, SMSG_VOICE_CHAT_STATUS = 0xBADD, SMSG_VOICE_PARENTAL_CONTROLS = 0xBADD, - SMSG_VOICE_SESSION_LEAVE = 0xBADD, + SMSG_VOICE_SESSION_LEAVE = 0x0403, SMSG_VOICE_SESSION_ROSTER_UPDATE = 0xBADD, SMSG_VOICE_SET_TALKER_MUTED = 0xBADD, SMSG_VOID_ITEM_SWAP_RESPONSE = 0x1131, @@ -1422,8 +1443,8 @@ enum OpcodeServer : uint32 SMSG_VOID_STORAGE_FAILED = 0xBADD, SMSG_VOID_STORAGE_TRANSFER_CHANGES = 0x0321, SMSG_VOID_TRANSFER_RESULT = 0x0539, - SMSG_WAIT_QUEUE_FINISH = 0xBADD, - SMSG_WAIT_QUEUE_UPDATE = 0xBADD, + SMSG_WAIT_QUEUE_FINISH = 0x198A, + SMSG_WAIT_QUEUE_UPDATE = 0x00D4, SMSG_WARDEN_DATA = 0x0BEC, SMSG_WARGAME_CHECK_ENTRY = 0xBADD, SMSG_WARGAME_REQUEST_SENT = 0xBADD, @@ -1435,7 +1456,7 @@ enum OpcodeServer : uint32 SMSG_WHO = 0x0601, SMSG_WHOIS = 0xBADD, SMSG_WORLD_SERVER_INFO = 0x11AC, - SMSG_WORLD_STATE_UI_TIMER_UPDATE = 0xBADD, + SMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x0B83, SMSG_XP_GAIN_ABORTED = 0xBADD, SMSG_ZONE_UNDER_ATTACK = 0x1401 }; diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 4dcd2430642..12ba71c4423 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -50,6 +50,7 @@ #include "BattlenetServerManager.h" #include "CharacterPackets.h" #include "ClientConfigPackets.h" +#include "MiscPackets.h" namespace { @@ -120,7 +121,7 @@ WorldSession::WorldSession(uint32 id, uint32 battlenetAccountId, std::shared_ptr m_sessionDbLocaleIndex(locale), m_latency(0), m_clientTimeDelay(0), - m_TutorialsChanged(false), + _tutorialsChanged(false), _filterAddonMessages(false), recruiterId(recruiter), isRecruiter(isARecruiter), @@ -129,7 +130,7 @@ WorldSession::WorldSession(uint32 id, uint32 battlenetAccountId, std::shared_ptr forceExit(false), m_currentBankerGUID() { - memset(m_Tutorials, 0, sizeof(m_Tutorials)); + memset(_tutorials, 0, sizeof(_tutorials)); if (sock) { @@ -694,7 +695,7 @@ void WorldSession::LoadAccountData(PreparedQueryResult result, uint32 mask) { for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i) if (mask & (1 << i)) - m_accountData[i] = AccountData(); + _accountData[i] = AccountData(); if (!result) return; @@ -717,20 +718,20 @@ void WorldSession::LoadAccountData(PreparedQueryResult result, uint32 mask) continue; } - m_accountData[type].Time = time_t(fields[1].GetUInt32()); - m_accountData[type].Data = fields[2].GetString(); + _accountData[type].Time = time_t(fields[1].GetUInt32()); + _accountData[type].Data = fields[2].GetString(); } while (result->NextRow()); } -void WorldSession::SetAccountData(AccountDataType type, time_t tm, std::string const& data) +void WorldSession::SetAccountData(AccountDataType type, uint32 time, std::string const& data) { if ((1 << type) & GLOBAL_CACHE_MASK) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_ACCOUNT_DATA); stmt->setUInt32(0, GetAccountId()); stmt->setUInt8(1, type); - stmt->setUInt32(2, uint32(tm)); + stmt->setUInt32(2, time); stmt->setString(3, data); CharacterDatabase.Execute(stmt); } @@ -743,39 +744,38 @@ void WorldSession::SetAccountData(AccountDataType type, time_t tm, std::string c PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_PLAYER_ACCOUNT_DATA); stmt->setUInt64(0, m_GUIDLow); stmt->setUInt8(1, type); - stmt->setUInt32(2, uint32(tm)); + stmt->setUInt32(2, time); stmt->setString(3, data); CharacterDatabase.Execute(stmt); } - m_accountData[type].Time = tm; - m_accountData[type].Data = data; + _accountData[type].Time = time_t(time); + _accountData[type].Data = data; } void WorldSession::LoadTutorialsData() { - memset(m_Tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES); + memset(_tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_TUTORIALS); stmt->setUInt32(0, GetAccountId()); if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i) - m_Tutorials[i] = (*result)[i].GetUInt32(); + _tutorials[i] = (*result)[i].GetUInt32(); - m_TutorialsChanged = false; + _tutorialsChanged = false; } void WorldSession::SendTutorialsData() { - WorldPacket data(SMSG_TUTORIAL_FLAGS, 4 * MAX_ACCOUNT_TUTORIAL_VALUES); - for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i) - data << m_Tutorials[i]; - SendPacket(&data); + WorldPackets::Misc::TutorialFlags packet; + memcpy(packet.TutorialData, _tutorials, sizeof(_tutorials)); + SendPacket(packet.Write()); } -void WorldSession::SaveTutorialsData(SQLTransaction &trans) +void WorldSession::SaveTutorialsData(SQLTransaction& trans) { - if (!m_TutorialsChanged) + if (!_tutorialsChanged) return; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_HAS_TUTORIALS); @@ -784,11 +784,11 @@ void WorldSession::SaveTutorialsData(SQLTransaction &trans) // Modify data in DB stmt = CharacterDatabase.GetPreparedStatement(hasTutorials ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS); for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i) - stmt->setUInt32(i, m_Tutorials[i]); + stmt->setUInt32(i, _tutorials[i]); stmt->setUInt32(MAX_ACCOUNT_TUTORIAL_VALUES, GetAccountId()); trans->Append(stmt); - m_TutorialsChanged = false; + _tutorialsChanged = false; } void WorldSession::ReadAddonsInfo(ByteBuffer& data) diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 5b5cde1bc63..baeace23b40 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -94,7 +94,43 @@ namespace WorldPackets class LogoutRequest; class LogoutCancel; class LoadingScreenNotify; - class QueryPlayerName; + } + + namespace ClientConfig + { + class RequestAccountData; + class UserClientUpdateAccountData; + } + + namespace Channel + { + class ChannelListRequest; + class JoinChannel; + class LeaveChannel; + } + + namespace Chat + { + class ChatMessage; + class ChatMessageWhisper; + class ChatMessageChannel; + class ChatAddonMessage; + class ChatAddonMessageWhisper; + class ChatMessageAFK; + class ChatMessageDND; + class ChatMessageEmote; + class CTextEmote; + } + + namespace Combat + { + class AttackSwing; + class AttackStop; + } + + namespace EquipmentSet + { + class SaveEquipmentSet; } namespace Guild @@ -102,6 +138,11 @@ namespace WorldPackets class QueryGuildInfo; } + namespace Talent + { + class SetSpecialization; + } + namespace Trade { class CancelTrade; @@ -109,17 +150,36 @@ namespace WorldPackets namespace Misc { + class SetSelection; class ViolenceLevel; + class TimeSyncResponse; + class TutorialSetFlag; + } + + namespace NPC + { + class Hello; } namespace Query { class QueryCreature; + class QueryPlayerName; + class QueryPageText; + class QueryNPCText; + class DBQueryBulk; + } + + namespace Quest + { + class QuestGiverStatusQuery; + class QuestGiverStatusMultipleQuery; } namespace Movement { class ClientPlayerMovement; + class WorldPortAck; } } @@ -142,11 +202,44 @@ enum AccountDataType #define REGISTERED_ADDON_PREFIX_SOFTCAP 64 -struct AccountData +enum TutorialAction +{ + TUTORIAL_ACTION_UPDATE = 0, + TUTORIAL_ACTION_CLEAR = 1, + TUTORIAL_ACTION_RESET = 2 +}; + +/* +enum Tutorials { - AccountData() : Time(0), Data("") { } + TUTORIAL_TALENT = 0, + TUTORIAL_SPEC = 1, + TUTORIAL_GLYPH = 2, + TUTORIAL_SPELLBOOK = 3, + TUTORIAL_PROFESSIONS = 4, + TUTORIAL_CORE_ABILITITES = 5, + TUTORIAL_PET_JOURNAL = 6, + TUTORIAL_WHAT_HAS_CHANGED = 7, + TUTORIAL_GARRISON_BUILDING = 8, + TUTORIAL_GARRISON_MISSION_LIST = 9, + TUTORIAL_GARRISON_MISSION_PAGE = 10, + TUTORIAL_GARRISON_LANDING = 11, + TUTORIAL_GARRISON_ZONE_ABILITY = 12, + TUTORIAL_WORLD_MAP_FRAME = 13, + TUTORIAL_CLEAN_UP_BAGS = 14, + TUTORIAL_BAG_SETTINGS = 15, + TUTORIAL_REAGENT_BANK_UNLOCK = 16, + TUTORIAL_TOYBOX_FAVORITE = 17, + TUTORIAL_TOYBOX_MOUSEWHEEL_PAGING = 18, + TUTORIAL_LFG_LIST = 19 +}; +*/ + +#define MAX_ACCOUNT_TUTORIAL_VALUES 8 - time_t Time; +struct AccountData +{ + time_t Time = 0; std::string Data; }; @@ -285,7 +378,9 @@ class WorldSession AccountTypes GetSecurity() const { return _security; } uint32 GetAccountId() const { return _accountId; } + ObjectGuid GetAccountGUID() const { return ObjectGuid::Create<HighGuid::WowAccount>(GetAccountId()); } uint32 GetBattlenetAccountId() const { return _battlenetAccountId; } + ObjectGuid GetBattlenetAccountGUID() const { return ObjectGuid::Create<HighGuid::BNetAccount>(GetBattlenetAccountId()); } Player* GetPlayer() const { return _player; } std::string const& GetPlayerName() const; std::string GetPlayerInfo() const; @@ -360,21 +455,21 @@ class WorldSession bool CheckStableMaster(ObjectGuid guid); // Account Data - AccountData* GetAccountData(AccountDataType type) { return &m_accountData[type]; } - void SetAccountData(AccountDataType type, time_t tm, std::string const& data); + AccountData const* GetAccountData(AccountDataType type) const { return &_accountData[type]; } + void SetAccountData(AccountDataType type, uint32 time, std::string const& data); void LoadGlobalAccountData(); void LoadAccountData(PreparedQueryResult result, uint32 mask); void LoadTutorialsData(); void SendTutorialsData(); void SaveTutorialsData(SQLTransaction& trans); - uint32 GetTutorialInt(uint8 index) const { return m_Tutorials[index]; } + uint32 GetTutorialInt(uint8 index) const { return _tutorials[index]; } void SetTutorialInt(uint8 index, uint32 value) { - if (m_Tutorials[index] != value) + if (_tutorials[index] != value) { - m_Tutorials[index] = value; - m_TutorialsChanged = true; + _tutorials[index] = value; + _tutorialsChanged = true; } } //used with item_page table @@ -558,7 +653,7 @@ class WorldSession void HandleTogglePvP(WorldPacket& recvPacket); void HandleZoneUpdateOpcode(WorldPacket& recvPacket); - void HandleSetSelectionOpcode(WorldPacket& recvPacket); + void HandleSetSelectionOpcode(WorldPackets::Misc::SetSelection& packet); void HandleStandStateChangeOpcode(WorldPacket& recvPacket); void HandleEmoteOpcode(WorldPacket& recvPacket); void HandleContactListOpcode(WorldPacket& recvPacket); @@ -578,23 +673,22 @@ class WorldSession void HandleSetWatchedFactionOpcode(WorldPacket& recvData); void HandleSetFactionInactiveOpcode(WorldPacket& recvData); - void HandleUpdateAccountData(WorldPacket& recvPacket); - void HandleRequestAccountData(WorldPacket& recvPacket); + void HandleUpdateAccountData(WorldPackets::ClientConfig::UserClientUpdateAccountData& packet); + void HandleRequestAccountData(WorldPackets::ClientConfig::RequestAccountData& request); void HandleSetActionButtonOpcode(WorldPacket& recvPacket); void HandleGameObjectUseOpcode(WorldPacket& recPacket); void HandleMeetingStoneInfo(WorldPacket& recPacket); void HandleGameobjectReportUse(WorldPacket& recvPacket); - void HandleNameQueryOpcode(WorldPackets::Character::QueryPlayerName& packet); - + void HandleNameQueryOpcode(WorldPackets::Query::QueryPlayerName& packet); void HandleQueryTimeOpcode(WorldPacket& recvPacket); - void HandleCreatureQuery(WorldPackets::Query::QueryCreature& packet); + void HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet); void HandleGameObjectQueryOpcode(WorldPacket& recvPacket); - void HandleMoveWorldportAckOpcode(WorldPacket& recvPacket); + void HandleMoveWorldportAckOpcode(WorldPackets::Movement::WorldPortAck& packet); void HandleMoveWorldportAckOpcode(); // for server-side calls void HandleMovementOpcodes(WorldPackets::Movement::ClientPlayerMovement& packet); @@ -689,16 +783,16 @@ class WorldSession void SendActivateTaxiReply(ActivateTaxiReply reply); void HandleTabardVendorActivateOpcode(WorldPacket& recvPacket); - void HandleBankerActivateOpcode(WorldPacket& recvPacket); + void HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet); void HandleBuyBankSlotOpcode(WorldPacket& recvPacket); - void HandleTrainerListOpcode(WorldPacket& recvPacket); + void HandleTrainerListOpcode(WorldPackets::NPC::Hello& packet); void HandleTrainerBuySpellOpcode(WorldPacket& recvPacket); void HandlePetitionShowListOpcode(WorldPacket& recvPacket); - void HandleGossipHelloOpcode(WorldPacket& recvPacket); + void HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet); void HandleGossipSelectOptionOpcode(WorldPacket& recvPacket); void HandleSpiritHealerActivateOpcode(WorldPacket& recvPacket); - void HandleNpcTextQueryOpcode(WorldPacket& recvPacket); - void HandleBinderActivateOpcode(WorldPacket& recvPacket); + void HandleNpcTextQueryOpcode(WorldPackets::Query::QueryNPCText& packet); + void HandleBinderActivateOpcode(WorldPackets::NPC::Hello& packet); void HandleListStabledPetsOpcode(WorldPacket& recvPacket); void HandleStablePet(WorldPacket& recvPacket); void HandleStablePetCallback(PreparedQueryResult result); @@ -753,7 +847,7 @@ class WorldSession void HandleSellItemOpcode(WorldPacket& recvPacket); void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket); void HandleBuyItemOpcode(WorldPacket& recvPacket); - void HandleListInventoryOpcode(WorldPacket& recvPacket); + void HandleListInventoryOpcode(WorldPackets::NPC::Hello& packet); void HandleAutoStoreBagItemOpcode(WorldPacket& recvPacket); void HandleReadItem(WorldPacket& recvPacket); void HandleAutoEquipItemSlotOpcode(WorldPacket& recvPacket); @@ -763,8 +857,8 @@ class WorldSession void HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket); void HandleWrapItemOpcode(WorldPacket& recvPacket); - void HandleAttackSwingOpcode(WorldPacket& recvPacket); - void HandleAttackStopOpcode(WorldPacket& recvPacket); + void HandleAttackSwingOpcode(WorldPackets::Combat::AttackSwing& packet); + void HandleAttackStopOpcode(WorldPackets::Combat::AttackStop& packet); void HandleSetSheathedOpcode(WorldPacket& recvPacket); void HandleUseItemOpcode(WorldPacket& recvPacket); @@ -779,9 +873,10 @@ class WorldSession void HandleLearnPreviewTalents(WorldPacket& recvPacket); void HandleTalentWipeConfirmOpcode(WorldPacket& recvPacket); void HandleUnlearnSkillOpcode(WorldPacket& recvPacket); + void HandleSetSpecializationOpcode(WorldPackets::Talent::SetSpecialization& packet); - void HandleQuestgiverStatusQueryOpcode(WorldPacket& recvPacket); - void HandleQuestgiverStatusMultipleQuery(WorldPacket& recvPacket); + void HandleQuestgiverStatusQueryOpcode(WorldPackets::Quest::QuestGiverStatusQuery& packet); + void HandleQuestgiverStatusMultipleQuery(WorldPackets::Quest::QuestGiverStatusMultipleQuery& packet); void HandleQuestgiverHelloOpcode(WorldPacket& recvPacket); void HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvPacket); void HandleQuestgiverQueryQuestOpcode(WorldPacket& recvPacket); @@ -797,13 +892,21 @@ class WorldSession void HandlePushQuestToParty(WorldPacket& recvPacket); void HandleQuestPushResult(WorldPacket& recvPacket); - void HandleMessagechatOpcode(WorldPacket& recvPacket); - void HandleAddonMessagechatOpcode(WorldPacket& recvPacket); + void HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage& packet); + void HandleChatMessageWhisperOpcode(WorldPackets::Chat::ChatMessageWhisper& packet); + void HandleChatMessageChannelOpcode(WorldPackets::Chat::ChatMessageChannel& packet); + void HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, std::string target = ""); + void HandleChatAddonMessageOpcode(WorldPackets::Chat::ChatAddonMessage& packet); + void HandleChatAddonMessageWhisperOpcode(WorldPackets::Chat::ChatAddonMessageWhisper& packet); + void HandleChatAddonMessage(ChatMsg type, std::string prefix, std::string text, std::string target = ""); + void HandleChatMessageAFKOpcode(WorldPackets::Chat::ChatMessageAFK& packet); + void HandleChatMessageDNDOpcode(WorldPackets::Chat::ChatMessageDND& packet); + void HandleChatMessageEmoteOpcode(WorldPackets::Chat::ChatMessageEmote& packet); void SendPlayerNotFoundNotice(std::string const& name); void SendPlayerAmbiguousNotice(std::string const& name); void SendWrongFactionNotice(); void SendChatRestrictedNotice(ChatRestrictionType restriction); - void HandleTextEmoteOpcode(WorldPacket& recvPacket); + void HandleTextEmoteOpcode(WorldPackets::Chat::CTextEmote& packet); void HandleChatIgnoredOpcode(WorldPacket& recvPacket); void HandleUnregisterAddonPrefixesOpcode(WorldPacket& recvPacket); @@ -815,9 +918,9 @@ class WorldSession void HandleResurrectResponseOpcode(WorldPacket& recvPacket); void HandleSummonResponseOpcode(WorldPacket& recvData); - void HandleJoinChannel(WorldPacket& recvPacket); - void HandleLeaveChannel(WorldPacket& recvPacket); - void HandleChannelList(WorldPacket& recvPacket); + void HandleJoinChannel(WorldPackets::Channel::JoinChannel& packet); + void HandleLeaveChannel(WorldPackets::Channel::LeaveChannel& packet); + void HandleChannelList(WorldPackets::Channel::ChannelListRequest& packet); void HandleChannelPassword(WorldPacket& recvPacket); void HandleChannelSetOwner(WorldPacket& recvPacket); void HandleChannelOwner(WorldPacket& recvPacket); @@ -832,18 +935,15 @@ class WorldSession void HandleChannelAnnouncements(WorldPacket& recvPacket); void HandleChannelModerate(WorldPacket& recvPacket); void HandleChannelDeclineInvite(WorldPacket& recvPacket); - void HandleChannelDisplayListQuery(WorldPacket& recvPacket); void HandleGetChannelMemberCount(WorldPacket& recvPacket); void HandleSetChannelWatch(WorldPacket& recvPacket); void HandleCompleteCinematic(WorldPacket& recvPacket); void HandleNextCinematicCamera(WorldPacket& recvPacket); - void HandlePageTextQueryOpcode(WorldPacket& recvPacket); + void HandlePageTextQueryOpcode(WorldPackets::Query::QueryPageText& packet); - void HandleTutorialFlag (WorldPacket& recvData); - void HandleTutorialClear(WorldPacket& recvData); - void HandleTutorialReset(WorldPacket& recvData); + void HandleTutorialFlag(WorldPackets::Misc::TutorialSetFlag& packet); //Pet void HandlePetAction(WorldPacket& recvData); @@ -899,7 +999,7 @@ class WorldSession void HandleMoveSetCanFlyAckOpcode(WorldPacket& recvData); void HandleSetTitleOpcode(WorldPacket& recvData); void HandleRealmSplitOpcode(WorldPacket& recvData); - void HandleTimeSyncResp(WorldPacket& recvData); + void HandleTimeSyncResp(WorldPackets::Misc::TimeSyncResponse& packet); void HandleWhoisOpcode(WorldPacket& recvData); void HandleResetInstancesOpcode(WorldPacket& recvData); void HandleHearthAndResurrect(WorldPacket& recvData); @@ -1028,7 +1128,7 @@ class WorldSession void HandleRemoveGlyph(WorldPacket& recvData); void HandleQueryInspectAchievements(WorldPacket& recvData); void HandleGuildAchievementProgressQuery(WorldPacket& recvData); - void HandleEquipmentSetSave(WorldPacket& recvData); + void HandleEquipmentSetSave(WorldPackets::EquipmentSet::SaveEquipmentSet& packet); void HandleEquipmentSetDelete(WorldPacket& recvData); void HandleEquipmentSetUse(WorldPacket& recvData); void HandleWorldStateUITimerUpdate(WorldPacket& recvData); @@ -1038,7 +1138,6 @@ class WorldSession void HandleEjectPassenger(WorldPacket& data); void HandleEnterPlayerVehicle(WorldPacket& data); void HandleUpdateProjectilePosition(WorldPacket& recvPacket); - void HandleRequestHotfix(WorldPacket& recvPacket); void HandleUpdateMissileTrajectory(WorldPacket& recvPacket); void HandleViolenceLevel(WorldPackets::Misc::ViolenceLevel& violenceLevel); void HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket); @@ -1147,9 +1246,9 @@ class WorldSession LocaleConstant m_sessionDbLocaleIndex; std::atomic<uint32> m_latency; std::atomic<uint32> m_clientTimeDelay; - AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES]; - uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES]; - bool m_TutorialsChanged; + AccountData _accountData[NUM_ACCOUNT_DATA_TYPES]; + uint32 _tutorials[MAX_ACCOUNT_TUTORIAL_VALUES]; + bool _tutorialsChanged; AddonsList m_addonsList; std::vector<std::string> _registeredAddonPrefixes; bool _filterAddonMessages; diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 5729cea131d..aa1426d5fd2 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -440,7 +440,6 @@ uint32 WorldSocket::CompressPacket(uint8* buffer, WorldPacket const& packet) return 0; } - return bufferSize - _compressionStream->avail_out; } diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 819af225fe4..6451111d0b8 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -273,6 +273,9 @@ Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint32 tryEffMa uint32 effMask = Aura::BuildEffectMaskForOwner(spellproto, tryEffMask, owner); if (!effMask) return NULL; + + TC_LOG_ERROR("spells", "TryRefreshStackOrCreate spell %u tryEffMask %u effMask %u", spellproto->Id, tryEffMask, effMask); + if (Aura* foundAura = owner->ToUnit()->_TryStackingOrRefreshingExistingAura(spellproto, effMask, caster, baseAmount, castItem, casterGUID)) { // we've here aura, which script triggered removal after modding stack amount diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index bd577af2b5a..65eb54122f9 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5618,21 +5618,13 @@ void Spell::EffectBind(SpellEffIndex effIndex) homeLoc = player->GetWorldLocation(); player->SetHomebind(homeLoc, areaId); - - // binding - WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4); - data << float(homeLoc.GetPositionX()); - data << float(homeLoc.GetPositionY()); - data << float(homeLoc.GetPositionZ()); - data << uint32(homeLoc.GetMapId()); - data << uint32(areaId); - player->SendDirectMessage(&data); + player->SendBindPointUpdate(); TC_LOG_DEBUG("spells", "EffectBind: New homebind X: %f, Y: %f, Z: %f, MapId: %u, AreaId: %u", homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId); // zone update - data.Initialize(SMSG_PLAYERBOUND, 8 + 4); + WorldPacket data(SMSG_PLAYERBOUND, 8 + 4); data << m_caster->GetGUID(); data << uint32(areaId); player->SendDirectMessage(&data); @@ -5709,4 +5701,4 @@ void Spell::EffectCreateAreaTrigger(SpellEffIndex effIndex) AreaTrigger * areaTrigger = new AreaTrigger; if (!areaTrigger->CreateAreaTrigger(sObjectMgr->GetGenerator<HighGuid::AreaTrigger>()->Generate(), triggerEntry, GetCaster(), GetSpellInfo(), pos)) delete areaTrigger; -}
\ No newline at end of file +} diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index bcca2203cb8..85ad4a67d3f 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -358,6 +358,7 @@ SpellEffectInfo::SpellEffectInfo(SpellEntry const* /*spellEntry*/, SpellInfo con MiscValue = _effect ? _effect->EffectMiscValue : 0; MiscValueB = _effect ? _effect->EffectMiscValueB : 0; Mechanic = Mechanics(_effect ? _effect->EffectMechanic : 0); + PositionFacing = _effect ? _effect->EffectPosFacing : 0.0f; TargetA = SpellImplicitTargetInfo(_effect ? _effect->ImplicitTarget[0] : 0); TargetB = SpellImplicitTargetInfo(_effect ? _effect->ImplicitTarget[1] : 0); RadiusEntry = _effect && _effect->EffectRadiusIndex ? sSpellRadiusStore.LookupEntry(_effect->EffectRadiusIndex) : NULL; @@ -511,19 +512,6 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const value = caster->ApplyEffectModifiers(_spellInfo, EffectIndex, value); // amount multiplication based on caster's level -/* REVIEW - MERGE <<<<<<< HEAD - if (!_spellInfo->GetSpellScaling() && !basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION && _spellInfo->SpellLevel) && - Effect != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE && - Effect != SPELL_EFFECT_KNOCK_BACK && - Effect != SPELL_EFFECT_ADD_EXTRA_ATTACKS && - ApplyAuraName != SPELL_AURA_MOD_SPEED_ALWAYS && - ApplyAuraName != SPELL_AURA_MOD_SPEED_NOT_STACK && - ApplyAuraName != SPELL_AURA_MOD_INCREASE_SPEED && - ApplyAuraName != SPELL_AURA_MOD_DECREASE_SPEED) - //there are many more: slow speed, -healing pct - value *= 0.25f * exp(caster->getLevel() * (70 - _spellInfo->SpellLevel) / 1000.0f); - //value = int32(value * (int32)getLevel() / (int32)(_spellInfo->spellLevel ? _spellInfo->spellLevel : 1)); -======= */ if (!caster->IsControlledByPlayer() && _spellInfo->SpellLevel && _spellInfo->SpellLevel != caster->getLevel() && !basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION)) @@ -574,7 +562,6 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const value *= casterScaler->ratio / spellScaler->ratio; } } -// REVIEW - MERGE >>>>>>> master } return int32(value); @@ -3104,4 +3091,4 @@ SpellEffectInfo const* SpellInfo::GetEffect(uint32 difficulty, uint32 index) con return nullptr; return effects[index]; -}
\ No newline at end of file +} diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 632f2ce639e..a49f956bc57 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -245,6 +245,7 @@ public: int32 MiscValue; int32 MiscValueB; Mechanics Mechanic; + float PositionFacing; SpellImplicitTargetInfo TargetA; SpellImplicitTargetInfo TargetB; SpellRadiusEntry const* RadiusEntry; @@ -261,8 +262,8 @@ public: SpellEffectInfo() : _spellInfo(NULL), EffectIndex(0), Effect(0), ApplyAuraName(0), ApplyAuraPeriod(0), DieSides(0), RealPointsPerLevel(0), BasePoints(0), PointsPerResource(0), Amplitude(0), ChainAmplitude(0), - BonusCoefficient(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), RadiusEntry(NULL), ChainTargets(0), - ItemType(0), TriggerSpell(0), ImplicitTargetConditions(NULL) {} + BonusCoefficient(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), PositionFacing(0), + RadiusEntry(NULL), ChainTargets(0), ItemType(0), TriggerSpell(0), ImplicitTargetConditions(NULL) { } SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex, SpellEffectEntry const* effect); bool IsEffect() const; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 28ff52e4926..3211ff389e8 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1600,8 +1600,8 @@ void SpellMgr::LoadSpellTargetPositions() mSpellTargetPositions.clear(); // need for reload case - // 0 1 2 3 4 5 6 - QueryResult result = WorldDatabase.Query("SELECT id, effIndex, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM spell_target_position"); + // 0 1 2 3 4 5 + QueryResult result = WorldDatabase.Query("SELECT ID, EffectIndex, MapID, PositionX, PositionY, PositionZ FROM spell_target_position"); if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 spell target coordinates. DB table `spell_target_position` is empty."); @@ -1622,36 +1622,46 @@ void SpellMgr::LoadSpellTargetPositions() st.target_X = fields[3].GetFloat(); st.target_Y = fields[4].GetFloat(); st.target_Z = fields[5].GetFloat(); - st.target_Orientation = fields[6].GetFloat(); MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId); if (!mapEntry) { - TC_LOG_ERROR("sql.sql", "Spell (Id: %u, effIndex: %u) target map (ID: %u) does not exist in `Map.dbc`.", Spell_ID, effIndex, st.target_mapId); + TC_LOG_ERROR("sql.sql", "Spell (ID: %u, EffectIndex: %u) is using a non-existant MapID (ID: %u).", Spell_ID, effIndex, st.target_mapId); continue; } - if (st.target_X==0 && st.target_Y==0 && st.target_Z==0) + if (st.target_X == 0 && st.target_Y == 0 && st.target_Z == 0) { - TC_LOG_ERROR("sql.sql", "Spell (Id: %u, effIndex: %u) target coordinates not provided.", Spell_ID, effIndex); + TC_LOG_ERROR("sql.sql", "Spell (ID: %u, EffectIndex: %u): target coordinates not provided.", Spell_ID, effIndex); continue; } SpellInfo const* spellInfo = GetSpellInfo(Spell_ID); if (!spellInfo) { - TC_LOG_ERROR("sql.sql", "Spell (Id: %u) listed in `spell_target_position` does not exist.", Spell_ID); + TC_LOG_ERROR("sql.sql", "Spell (ID: %u) listed in `spell_target_position` does not exist.", Spell_ID); continue; } SpellEffectInfo const* effect = spellInfo->GetEffect(effIndex); - if (!effect) { TC_LOG_ERROR("sql.sql", "Spell (Id: %u, effIndex: %u) listed in `spell_target_position` does not have an effect at index %u.", Spell_ID, effIndex, effIndex); continue; } + // target facing is in degrees for 6484 & 9268... (blizz sucks) + if (effect->PositionFacing > 2 * M_PI) + st.target_Orientation = effect->PositionFacing * M_PI / 180; + else + st.target_Orientation = effect->PositionFacing; + + if (effect->TargetA.GetTarget() == TARGET_DEST_DB || effect->TargetB.GetTarget() == TARGET_DEST_DB) + { + TC_LOG_ERROR("sql.sql", "Spell (Id: %u, effIndex: %u) listed in `spell_target_position` does not have TARGET_DEST_DB as target at index %u.", Spell_ID, effIndex, effIndex); + continue; + } + if (effect->TargetA.GetTarget() == TARGET_DEST_DB || effect->TargetB.GetTarget() == TARGET_DEST_DB) { std::pair<uint32, SpellEffIndex> key = std::make_pair(Spell_ID, effIndex); diff --git a/src/server/game/Texts/ChatTextBuilder.h b/src/server/game/Texts/ChatTextBuilder.h index 72f80bb07a3..a4834d555d3 100644 --- a/src/server/game/Texts/ChatTextBuilder.h +++ b/src/server/game/Texts/ChatTextBuilder.h @@ -20,6 +20,7 @@ #include "Chat.h" #include "ObjectMgr.h" +#include "Packets/ChatPackets.h" namespace Trinity { @@ -32,13 +33,9 @@ namespace Trinity void operator()(WorldPacket& data, LocaleConstant locale) { BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId); - ChatHandler::BuildChatPacket(data, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale); - } - - size_t operator()(WorldPacket* data, LocaleConstant locale) const - { - BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId); - return ChatHandler::BuildChatPacket(*data, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale); + data = *packet.Write(); } private: @@ -57,7 +54,9 @@ namespace Trinity void operator()(WorldPacket& data, LocaleConstant locale) { - ChatHandler::BuildChatPacket(data, _msgType, _language, _source, _target, _text, 0, "", locale); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, _msgType, _language, _source, _target, _text, 0, "", locale); + data = *packet.Write(); } private: diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index 77819b87ec0..07d0bd53629 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -24,6 +24,7 @@ #include "GridNotifiers.h" #include "GridNotifiersImpl.h" #include "CreatureTextMgr.h" +#include "ChatPackets.h" class CreatureTextBuilder { @@ -31,11 +32,12 @@ class CreatureTextBuilder CreatureTextBuilder(WorldObject const* obj, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject const* target) : _source(obj), _gender(gender), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { } - size_t operator()(WorldPacket* data, LocaleConstant locale) const + void operator()(WorldPacket& data, LocaleConstant locale) const { std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale); - - return ChatHandler::BuildChatPacket(*data, _msgType, Language(_language), _source, _target, text, 0, "", locale); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, _msgType, Language(_language), _source, _target, text, 0, "", locale); + data = *packet.Write(); } private: @@ -54,11 +56,12 @@ class PlayerTextBuilder PlayerTextBuilder(WorldObject const* obj, WorldObject const* speaker, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject const* target) : _source(obj), _talker(speaker), _gender(gender), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { } - size_t operator()(WorldPacket* data, LocaleConstant locale) const + void operator()(WorldPacket& data, LocaleConstant locale) const { std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale); - - return ChatHandler::BuildChatPacket(*data, _msgType, Language(_language), _talker, _target, text, 0, "", locale); + WorldPackets::Chat::Chat packet; + return ChatHandler::BuildChatPacket(&packet, _msgType, Language(_language), _talker, _target, text, 0, "", locale); + data = *packet.Write(); } private: diff --git a/src/server/game/Texts/CreatureTextMgr.h b/src/server/game/Texts/CreatureTextMgr.h index 06efadb1dc7..647d8249e68 100644 --- a/src/server/game/Texts/CreatureTextMgr.h +++ b/src/server/game/Texts/CreatureTextMgr.h @@ -24,6 +24,7 @@ #include "SharedDefines.h" #include "Opcodes.h" #include "Group.h" +#include "Packets/ChatPackets.h" enum CreatureTextRange { @@ -133,50 +134,38 @@ class CreatureTextLocalizer ~CreatureTextLocalizer() { for (size_t i = 0; i < _packetCache.size(); ++i) - { - if (_packetCache[i]) - delete _packetCache[i]->first; delete _packetCache[i]; - } } void operator()(Player* player) { LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex(); - WorldPacket* messageTemplate; - size_t whisperGUIDpos; + WorldPackets::Chat::Chat* messageTemplate; // create if not cached yet if (!_packetCache[loc_idx]) { - messageTemplate = new WorldPacket(); - whisperGUIDpos = _builder(messageTemplate, loc_idx); - ASSERT(messageTemplate->GetOpcode() != NULL_OPCODE); - _packetCache[loc_idx] = new std::pair<WorldPacket*, size_t>(messageTemplate, whisperGUIDpos); + messageTemplate = new WorldPackets::Chat::Chat(); + _packetCache[loc_idx] = messageTemplate; } else - { - messageTemplate = _packetCache[loc_idx]->first; - whisperGUIDpos = _packetCache[loc_idx]->second; - } + messageTemplate = _packetCache[loc_idx]; - WorldPacket data(*messageTemplate); switch (_msgType) { case CHAT_MSG_MONSTER_WHISPER: case CHAT_MSG_RAID_BOSS_WHISPER: - // TODO: Fix this. GUIDs are now always written packed and can have different packed lengths - //data.put<uint64>(whisperGUIDpos, player->GetGUID().GetRawValue()); + messageTemplate->TargetGUID = player->GetGUID(); break; default: break; } - player->SendDirectMessage(&data); + player->SendDirectMessage(messageTemplate->Write()); } private: - std::vector<std::pair<WorldPacket*, size_t>* > _packetCache; + std::vector<WorldPackets::Chat::Chat*> _packetCache; Builder const& _builder; ChatMsg _msgType; }; diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index 6f42d41c694..43d4374c544 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -519,10 +519,10 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s if (!changenth(line, 2, chraccount)) // characters.account update ROLLBACK(DUMP_FILE_BROKEN); - race = uint8(atol(getnth(line, 4).c_str())); - playerClass = uint8(atol(getnth(line, 5).c_str())); - gender = uint8(atol(getnth(line, 6).c_str())); - level = uint8(atol(getnth(line, 7).c_str())); + race = uint8(atoul(getnth(line, 4).c_str())); + playerClass = uint8(atoul(getnth(line, 5).c_str())); + gender = uint8(atoul(getnth(line, 6).c_str())); + level = uint8(atoul(getnth(line, 7).c_str())); if (name.empty()) { // check if the original name already exists diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 098181c76a1..a9d12fd11f8 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -46,6 +46,7 @@ #include "LFGMgr.h" #include "MapManager.h" #include "Memory.h" +#include "MiscPackets.h" #include "MMapFactory.h" #include "ObjectMgr.h" #include "OutdoorPvPMgr.h" @@ -64,6 +65,7 @@ #include "WaypointMovementGenerator.h" #include "WeatherMgr.h" #include "WorldSession.h" +#include "ChatPackets.h" #include <boost/algorithm/string.hpp> @@ -2287,7 +2289,9 @@ namespace Trinity while (char* line = lineFromMessage(pos)) { WorldPacket* data = new WorldPacket(); - ChatHandler::BuildChatPacket(*data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + *data = *packet.Write(); data_list.push_back(data); } } @@ -2345,16 +2349,15 @@ void World::SendGMText(uint32 string_id, ...) /// DEPRECATED, only for debug purpose. Send a System Message to all players (except self if mentioned) void World::SendGlobalText(const char* text, WorldSession* self) { - WorldPacket data; - // need copy to prevent corruption by strtok call in LineFromMessage original string char* buf = strdup(text); char* pos = buf; while (char* line = ChatHandler::LineFromMessage(pos)) { - ChatHandler::BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); - SendGlobalMessage(&data, self); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + SendGlobalMessage(packet.Write(), self); } free(buf); @@ -2386,9 +2389,9 @@ bool World::SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession /// Send a System Message to all players in the zone (except self if mentioned) void World::SendZoneText(uint32 zone, const char* text, WorldSession* self, uint32 team) { - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, text); - SendZoneMessage(zone, &data, self, team); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, text); + SendZoneMessage(zone, packet.Write(), self, team); } /// Kick (and save) all players @@ -3305,9 +3308,9 @@ void World::UpdateCharacterInfo(ObjectGuid const& guid, std::string const& name, if (race != RACE_NONE) itr->second.Race = race; - WorldPacket data(SMSG_INVALIDATE_PLAYER, 8); - data << guid; - SendGlobalMessage(&data); + WorldPackets::Misc::InvalidatePlayer data; + data.Guid = guid; + SendGlobalMessage(data.Write()); } void World::UpdateCharacterInfoLevel(ObjectGuid const& guid, uint8 level) diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 0c37b1491c3..22a8fcb67f0 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -481,15 +481,15 @@ public: char const* msg = "testtest"; uint8 type = atoi(args); - WorldPacket data; - ChatHandler::BuildChatPacket(data, ChatMsg(type), LANG_UNIVERSAL, handler->GetSession()->GetPlayer(), handler->GetSession()->GetPlayer(), msg, 0, "chan"); - handler->GetSession()->SendPacket(&data); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, ChatMsg(type), LANG_UNIVERSAL, handler->GetSession()->GetPlayer(), handler->GetSession()->GetPlayer(), msg, 0, "chan"); + handler->GetSession()->SendPacket(packet.Write()); return true; } static bool HandleDebugSendQuestPartyMsgCommand(ChatHandler* handler, char const* args) { - uint32 msg = atol((char*)args); + uint32 msg = atoul(args); handler->GetSession()->GetPlayer()->SendPushToPartyResponse(handler->GetSession()->GetPlayer(), msg); return true; } @@ -508,7 +508,7 @@ public: static bool HandleDebugSendQuestInvalidMsgCommand(ChatHandler* handler, char const* args) { - QuestFailedReason msg = static_cast<QuestFailedReason>(atol((char*)args)); + QuestFailedReason msg = static_cast<QuestFailedReason>(atoul(args)); handler->GetSession()->GetPlayer()->SendCanTakeQuestResponse(msg); return true; } diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 5a00267d6aa..d802d5a496d 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -118,7 +118,7 @@ public: if (!id) return false; - uint32 objectId = atol(id); + uint32 objectId = atoul(id); if (!objectId) return false; @@ -241,7 +241,7 @@ public: if (!id) return false; - uint32 objectId = atol(id); + uint32 objectId = atoul(id); if (objectId) result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, phaseMask, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1", @@ -675,12 +675,8 @@ public: if (objectType < 4) object->SetByteValue(GAMEOBJECT_BYTES_1, objectType, objectState); else if (objectType == 4) - { - WorldPacket data(SMSG_GAMEOBJECT_CUSTOM_ANIM, 8+4); - data << object->GetGUID(); - data << (uint32)(objectState); - object->SendMessageToSet(&data, true); - } + object->SendCustomAnim(objectState); + handler->PSendSysMessage("Set gobject type %d state %d", objectType, objectState); return true; } diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp index 46929e3967c..7721fed3fba 100644 --- a/src/server/scripts/Commands/cs_list.cpp +++ b/src/server/scripts/Commands/cs_list.cpp @@ -65,7 +65,7 @@ public: if (!id) return false; - uint32 creatureId = atol(id); + uint32 creatureId = atoul(id); if (!creatureId) { handler->PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, creatureId); @@ -82,7 +82,7 @@ public: } char* countStr = strtok(NULL, " "); - uint32 count = countStr ? atol(countStr) : 10; + uint32 count = countStr ? atoul(countStr) : 10; if (count == 0) return false; @@ -133,11 +133,11 @@ public: if (!*args) return false; - char* id = handler->extractKeyFromLink((char*)args, "Hitem"); + char const* id = handler->extractKeyFromLink((char*)args, "Hitem"); if (!id) return false; - uint32 itemId = atol(id); + uint32 itemId = atoul(id); if (!itemId) { handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); @@ -154,7 +154,7 @@ public: } char* countStr = strtok(NULL, " "); - uint32 count = countStr ? atol(countStr) : 10; + uint32 count = countStr ? atoul(countStr) : 10; if (count == 0) return false; @@ -354,7 +354,7 @@ public: if (!id) return false; - uint32 gameObjectId = atol(id); + uint32 gameObjectId = atoul(id); if (!gameObjectId) { handler->PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, gameObjectId); @@ -371,7 +371,7 @@ public: } char* countStr = strtok(NULL, " "); - uint32 count = countStr ? atol(countStr) : 10; + uint32 count = countStr ? atoul(countStr) : 10; if (count == 0) return false; diff --git a/src/server/scripts/Commands/cs_message.cpp b/src/server/scripts/Commands/cs_message.cpp index 715487eff99..664c8f3d216 100644 --- a/src/server/scripts/Commands/cs_message.cpp +++ b/src/server/scripts/Commands/cs_message.cpp @@ -74,7 +74,7 @@ public: Player* player = handler->GetSession()->GetPlayer(); Channel* channcel = NULL; - if (ChannelMgr* cMgr = ChannelMgr::forTeam(player->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(player->GetTeam())) channcel = cMgr->GetChannel(channelStr, player); if (strcmp(argStr, "on") == 0) diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 0c8dd5813f2..f8c3f43d144 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1135,7 +1135,7 @@ public: char const* id = handler->extractKeyFromLink((char*)args, "Hitem"); if (!id) return false; - itemId = uint32(atol(id)); + itemId = atoul(id); } char const* ccount = strtok(NULL, " "); @@ -1217,7 +1217,7 @@ public: if (!id) return false; - uint32 itemSetId = atol(id); + uint32 itemSetId = atoul(id); // prevent generation all items with itemset field value '0' if (itemSetId == 0) @@ -1358,7 +1358,7 @@ public: return false; } - int32 level = uint32(atol(levelStr)); + int32 level = atol(levelStr); Player* target = handler->getSelectedPlayer(); if (!target) @@ -1380,7 +1380,7 @@ public: // If our target does not yet have the skill they are trying to add to them, the chosen level also becomes // the max level of the new profession. - uint16 max = maxPureSkill ? atol(maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level); + uint16 max = maxPureSkill ? atoul(maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level); if (level <= 0 || level > max || max <= 0) return false; @@ -1779,7 +1779,7 @@ public: uint32 totalmail = uint32(fields[1].GetUInt64()); // ... we have to convert it from Char to int. We can use totalmail as it is - rmailint = atol(readmail.c_str()); + rmailint = atoul(readmail.c_str()); // Output XXI. LANG_INFO_CHR_MAILS if at least one mail is given if (totalmail >= 1) diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 7d42609a2a0..eb64c2f3eaa 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -1004,7 +1004,7 @@ public: if (strchr(args, 'g') || strchr(args, 's') || strchr(args, 'c')) moneyToAdd = MoneyStringToMoney(std::string(args)); else - moneyToAdd = atol(args); + moneyToAdd = atoll(args); uint64 targetMoney = target->GetMoney(); diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 9d64ba60bc4..3e841f45f59 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -332,15 +332,15 @@ public: char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0 uint32 maxcount = 0; if (fmaxcount) - maxcount = atol(fmaxcount); + maxcount = atoul(fmaxcount); char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0 uint32 incrtime = 0; if (fincrtime) - incrtime = atol(fincrtime); + incrtime = atoul(fincrtime); char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0 - uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0; + uint32 extendedcost = fextendedcost ? atoul(fextendedcost) : 0; Creature* vendor = handler->getSelectedCreature(); if (!vendor) { @@ -570,7 +570,7 @@ public: handler->SetSentErrorMessage(true); return false; } - uint32 itemId = atol(pitem); + uint32 itemId = atoul(pitem); const uint8 type = 1; // FIXME: make type (1 item, 2 currency) an argument diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp index b5186bdb948..8138a755f87 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -67,7 +67,7 @@ public: if (!cId) return false; - uint32 entry = atol(cId); + uint32 entry = atoul(cId); Quest const* quest = sObjectMgr->GetQuestTemplate(entry); @@ -112,7 +112,7 @@ public: if (!cId) return false; - uint32 entry = atol(cId); + uint32 entry = atoul(cId); Quest const* quest = sObjectMgr->GetQuestTemplate(entry); @@ -165,7 +165,7 @@ public: if (!cId) return false; - uint32 entry = atol(cId); + uint32 entry = atoul(cId); Quest const* quest = sObjectMgr->GetQuestTemplate(entry); @@ -269,7 +269,7 @@ public: if (!cId) return false; - uint32 entry = atol(cId); + uint32 entry = atoul(cId); Quest const* quest = sObjectMgr->GetQuestTemplate(entry); diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp index 4a58a7f7e5d..01a0094bfc7 100644 --- a/src/server/scripts/Commands/cs_reset.cpp +++ b/src/server/scripts/Commands/cs_reset.cpp @@ -204,9 +204,10 @@ public: Player* target; ObjectGuid targetGuid; std::string targetName; - /* TODO: 6.x remove/update pet talents + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) { + /* TODO: 6.x remove/update pet talents // Try reset talents as Hunter Pet Creature* creature = handler->getSelectedCreature(); if (!*args && creature && creature->IsPet()) @@ -223,12 +224,12 @@ public: } return true; } + */ handler->SendSysMessage(LANG_NO_CHAR_SELECTED); handler->SetSentErrorMessage(true); return false; } - */ if (target) { diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp index 176c24f6707..bf28ccbb17e 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp @@ -31,6 +31,7 @@ EndScriptData */ #include "WorldPacket.h" #include "Chat.h" #include "WorldSession.h" +#include "Packets/ChatPackets.h" /* Battle of Mount Hyjal encounters: 0 - Rage Winterchill event @@ -173,10 +174,9 @@ public: { if (Player* player = i->GetSource()) { - WorldPacket packet; - - ChatHandler::BuildChatPacket(packet, CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, unit, player, YELL_EFFORTS); - player->SendDirectMessage(&packet); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, unit, player, YELL_EFFORTS); + player->SendDirectMessage(packet.Write()); player->PlayDirectSound(10986, player); } } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp index b84d24d66d3..794496382c2 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp @@ -292,6 +292,7 @@ public: break; } player->CLOSE_GOSSIP_MENU(); + ai->SetDespawnAtFar(false); creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); return true; } diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp index 53fbf8f0cf7..1f55abf8a11 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp @@ -21,8 +21,14 @@ DoorData const doorData[] = { - { GO_IKISS_DOOR, DATA_TALON_KING_IKISS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, - { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END + { GO_IKISS_DOOR, DATA_TALON_KING_IKISS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END +}; + +ObjectData const gameObjectData[] = +{ + { GO_TALON_KING_COFFER, DATA_TALON_KING_COFFER }, + { 0, 0 } // END }; class instance_sethekk_halls : public InstanceMapScript @@ -37,6 +43,7 @@ class instance_sethekk_halls : public InstanceMapScript SetHeaders(DataHeader); SetBossNumber(EncounterCount); LoadDoorData(doorData); + LoadObjectData(nullptr, gameObjectData); } void OnCreatureCreate(Creature* creature) override @@ -50,16 +57,27 @@ class instance_sethekk_halls : public InstanceMapScript } } - void OnGameObjectCreate(GameObject* go) override + bool SetBossState(uint32 type, EncounterState state) override { - if (go->GetEntry() == GO_IKISS_DOOR) - AddDoor(go, true); - } + if (!InstanceScript::SetBossState(type, state)) + return false; - void OnGameObjectRemove(GameObject* go) override - { - if (go->GetEntry() == GO_IKISS_DOOR) - AddDoor(go, false); + switch (type) + { + case DATA_TALON_KING_IKISS: + if (state == DONE) + { + /// @workaround: GO_FLAG_INTERACT_COND remains on the gob, but it is not handled correctly in this case + /// gameobject should have GO_DYNFLAG_LO_ACTIVATE too, which makes gobs interactable with GO_FLAG_INTERACT_COND + /// so just removed GO_FLAG_INTERACT_COND + if (GameObject* coffer = GetGameObject(DATA_TALON_KING_COFFER)) + coffer->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND | GO_FLAG_NOT_SELECTABLE); + } + break; + default: + break; + } + return true; } }; diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h b/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h index 4b6bfab46cb..8cf01fb4635 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h @@ -28,7 +28,10 @@ enum DataTypes // Encounter States/Boss GUIDs DATA_DARKWEAVER_SYTH = 0, DATA_TALON_KING_IKISS = 1, - DATA_ANZU = 2 + DATA_ANZU = 2, + + // Additional Data + DATA_TALON_KING_COFFER = 3 }; enum CreatureIds @@ -39,7 +42,8 @@ enum CreatureIds enum GameObjectIds { - GO_IKISS_DOOR = 177203 + GO_IKISS_DOOR = 177203, + GO_TALON_KING_COFFER = 187372 }; template<class AI> diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp index f0884e83baa..794d3a490f6 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp @@ -31,21 +31,25 @@ class go_main_chambers_access_panel : public GameObjectScript return false; if (go->GetEntry() == GO_ACCESS_PANEL_HYDRO && (instance->GetBossState(DATA_HYDROMANCER_THESPIA) == DONE || instance->GetBossState(DATA_HYDROMANCER_THESPIA) == SPECIAL)) - { instance->SetBossState(DATA_HYDROMANCER_THESPIA, SPECIAL); - go->SetGoState(GO_STATE_ACTIVE); - } if (go->GetEntry() == GO_ACCESS_PANEL_MEK && (instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == DONE || instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == SPECIAL)) - { instance->SetBossState(DATA_MEKGINEER_STEAMRIGGER, SPECIAL); - go->SetGoState(GO_STATE_ACTIVE); - } + + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + go->SetGoState(GO_STATE_ACTIVE); return true; } }; +ObjectData const gameObjectData[] = +{ + { GO_ACCESS_PANEL_HYDRO, DATA_ACCESS_PANEL_HYDRO }, + { GO_ACCESS_PANEL_MEK, DATA_ACCESS_PANEL_MEK }, + { 0, 0 } // END +}; + class instance_steam_vault : public InstanceMapScript { public: @@ -57,6 +61,7 @@ class instance_steam_vault : public InstanceMapScript { SetHeaders(DataHeader); SetBossNumber(EncounterCount); + LoadObjectData(nullptr, gameObjectData); DistillerState = 0; } @@ -89,6 +94,8 @@ class instance_steam_vault : public InstanceMapScript default: break; } + + InstanceScript::OnGameObjectCreate(go); } ObjectGuid GetGuidData(uint32 type) const override @@ -128,6 +135,9 @@ class instance_steam_vault : public InstanceMapScript switch (type) { case DATA_HYDROMANCER_THESPIA: + if (state == DONE) + if (GameObject* panel = GetGameObject(DATA_ACCESS_PANEL_HYDRO)) + panel->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); if (state == SPECIAL) { if (GetBossState(DATA_MEKGINEER_STEAMRIGGER) == SPECIAL) @@ -137,6 +147,9 @@ class instance_steam_vault : public InstanceMapScript } break; case DATA_MEKGINEER_STEAMRIGGER: + if (state == DONE) + if (GameObject* panel = GetGameObject(DATA_ACCESS_PANEL_MEK)) + panel->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); if (state == SPECIAL) { if (GetBossState(DATA_HYDROMANCER_THESPIA) == SPECIAL) diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h index 58f71b047ef..d18d0406dea 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h +++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h @@ -28,7 +28,11 @@ enum DataTypes DATA_HYDROMANCER_THESPIA = 0, DATA_MEKGINEER_STEAMRIGGER = 1, DATA_WARLORD_KALITHRESH = 2, - DATA_DISTILLER = 3 + DATA_DISTILLER = 3, + + // Additional Data + DATA_ACCESS_PANEL_HYDRO = 4, + DATA_ACCESS_PANEL_MEK = 5 }; enum CreatureIds diff --git a/src/server/scripts/World/action_ip_logger.cpp b/src/server/scripts/World/action_ip_logger.cpp index 9d2aa868234..c82459d0599 100644 --- a/src/server/scripts/World/action_ip_logger.cpp +++ b/src/server/scripts/World/action_ip_logger.cpp @@ -16,13 +16,10 @@ */ #include "ScriptMgr.h" -#include "Channel.h" -#include "Guild.h" -#include "Group.h" +#include "Player.h" enum IPLoggingTypes { - // AccountActionIpLogger(); ACCOUNT_LOGIN = 0, ACCOUNT_FAIL_LOGIN = 1, diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index 4e23b4a4770..578bc7aa61f 100644 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -79,6 +79,9 @@ inline float finiteAlways(float f) { return std::isfinite(f) ? f : 0.0f; } +inline unsigned long atoul(char const* str) { return strtoul(str, nullptr, 10); } +inline unsigned long long atoull(char const* str) { return strtoull(str, nullptr, 10); } + #define STRINGIZE(a) #a enum TimeConstants @@ -118,7 +121,6 @@ const uint8 TOTAL_LOCALES = 9; #define DEFAULT_LOCALE LOCALE_enUS #define MAX_LOCALES 8 -#define MAX_ACCOUNT_TUTORIAL_VALUES 8 extern char const* localeNames[TOTAL_LOCALES]; diff --git a/src/server/shared/Networking/SocketMgr.h b/src/server/shared/Networking/SocketMgr.h index 92c16d96882..c004295bc1a 100644 --- a/src/server/shared/Networking/SocketMgr.h +++ b/src/server/shared/Networking/SocketMgr.h @@ -47,7 +47,16 @@ public: return false; } - _acceptor = new AsyncAcceptor(service, bindIp, port); + try + { + _acceptor = new AsyncAcceptor(service, bindIp, port); + } + catch (boost::system::system_error const& err) + { + TC_LOG_ERROR("network", "Exception caught in SocketMgr.StartNetwork (%s:%u): %s", bindIp.c_str(), port, err.what()); + return false; + } + _threads = CreateThreads(); ASSERT(_threads); diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 069b783a537..67e940e263c 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -303,7 +303,7 @@ class ByteBuffer { if (size_t len = value.length()) append((uint8 const*)value.c_str(), len); - append((uint8)0); + append<uint8>(0); return *this; } @@ -311,7 +311,7 @@ class ByteBuffer { if (size_t len = (str ? strlen(str) : 0)) append((uint8 const*)str, len); - append((uint8)0); + append<uint8>(0); return *this; } @@ -475,7 +475,7 @@ class ByteBuffer void read(uint8 *dest, size_t len) { - if (_rpos + len > size()) + if (_rpos + len > size()) throw ByteBufferPositionException(false, _rpos, len, size()); ResetBitPos(); diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index 8a4f7325add..5aaedfb8ffe 100644 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -33,21 +33,21 @@ template<typename T> struct Optional { - Optional() : value(), HasValue(false) { } + Optional() : Value(), HasValue(false) { } - T value; + T Value; bool HasValue; inline void Set(T const& v) { HasValue = true; - value = v; + Value = v; } inline void Clear() { HasValue = false; - value = T(); + Value = T(); } }; |
