diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 5dca63e7f4..fed9b9ba7a 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -16,6 +16,7 @@ */ #include "WorldSession.h" +#include "ArchaeologyPackets.h" #include "AccountMgr.h" #include "AchievementMgr.h" #include "Battlefield.h" @@ -1833,10 +1834,9 @@ void WorldSession::SendStreamingMovie() SendPacket(packet.Write()); } -void WorldSession::HandleRequestResearchHistory(WorldPacket & /*recv_data*/) +void WorldSession::HandleRequestResearchHistory(WorldPackets::Archaeology::RequestResearchHistory& /*packet*/) { - if (Player* player = GetPlayer()) - player->NotifyRequestResearchHistory(); + _player->NotifyRequestResearchHistory(); } void WorldSession::HandleOpeningCinematic(WorldPackets::Misc::OpeningCinematic& /*packet*/) diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h index 2905786abd..aecfd6f269 100644 --- a/src/server/game/Server/Packets/AllPackets.h +++ b/src/server/game/Server/Packets/AllPackets.h @@ -18,6 +18,7 @@ #ifndef AllPackets_h__ #define AllPackets_h__ +#include "ArchaeologyPackets.h" #include "AuthenticationPackets.h" #include "BattlegroundPackets.h" #include "CharacterPackets.h" diff --git a/src/server/game/Server/Packets/ArchaeologyPackets.cpp b/src/server/game/Server/Packets/ArchaeologyPackets.cpp new file mode 100644 index 0000000000..d32e179776 --- /dev/null +++ b/src/server/game/Server/Packets/ArchaeologyPackets.cpp @@ -0,0 +1,47 @@ +/* +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information +* +* 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 . +*/ + +#include "ArchaeologyPackets.h" + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Archaeology::ResearchHistory const& researchHistory) +{ + data << int32(researchHistory.ProjectID); + data << int32(researchHistory.CompletionCount); + data << uint32(researchHistory.FirstCompleted); + + return data; +} + +WorldPacket const* WorldPackets::Archaeology::SetupResearchHistory::Write() +{ + _worldPacket.WriteBits(History.size(), 22); + _worldPacket.FlushBits(); + + for (WorldPackets::Archaeology::ResearchHistory const& history : History) + _worldPacket << history; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Archaeology::ResearchComplete::Write() +{ + _worldPacket << Research.FirstCompleted; + _worldPacket << Research.CompletionCount; + _worldPacket << Research.ProjectID; + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/ArchaeologyPackets.h b/src/server/game/Server/Packets/ArchaeologyPackets.h new file mode 100644 index 0000000000..a31d694b41 --- /dev/null +++ b/src/server/game/Server/Packets/ArchaeologyPackets.h @@ -0,0 +1,68 @@ +/* +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information +* +* 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 . +*/ + +#ifndef ArchaeologyPackets_h__ +#define ArchaeologyPackets_h__ + +#include "Packet.h" + +namespace WorldPackets +{ + namespace Archaeology + { + class RequestResearchHistory final : public ClientPacket + { + public: + RequestResearchHistory(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_RESEARCH_HISTORY, std::move(packet)) { } + + void Read() override { } + }; + + struct ResearchHistory + { + ResearchHistory() { } + ResearchHistory(int32 projectId, int32 completionCount, uint32 firstCompleted) : + ProjectID(projectId), CompletionCount(completionCount), FirstCompleted(firstCompleted) { } + + int32 ProjectID = 0; + int32 CompletionCount = 0; + uint32 FirstCompleted = 0; + }; + + class SetupResearchHistory final : public ServerPacket + { + public: + SetupResearchHistory() : ServerPacket(SMSG_SETUP_RESEARCH_HISTORY, 3) { } + + WorldPacket const* Write() override; + + std::vector History; + }; + + class ResearchComplete final : public ServerPacket + { + public: + ResearchComplete() : ServerPacket(SMSG_RESEARCH_COMPLETE, 12) { } + + WorldPacket const* Write() override; + + ResearchHistory Research; + }; + } +} + +#endif // ArchaeologyPackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 881013de0e..21413067cb 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -936,6 +936,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_KNOWN_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SETUP_CURRENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SETUP_RESEARCH_HISTORY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_WORLD_STATES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_RATED_BG_STATS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1175,7 +1176,6 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_REQUEST_CEMETERY_LIST_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REQUEST_PVP_REWARDS_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESEARCH_COMPLETE, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESEARCH_SETUP_HISTORY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_COMPRESSION_CONTEXT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_FAILED_NOTIFY, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_NEVER, CONNECTION_TYPE_REALM); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index d2966a8bc4..2e496ac050 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -880,6 +880,7 @@ enum OpcodeServer SMSG_INITIALIZE_FACTIONS = 0x4634, SMSG_SEND_KNOWN_SPELLS = 0x0104, SMSG_SETUP_CURRENCY = 0x15A5, + SMSG_SETUP_RESEARCH_HISTORY = 0x10B6, SMSG_INIT_WORLD_STATES = 0x4C15, SMSG_INSPECT = 0x0000, SMSG_INSPECT_HONOR_STATS = 0x79A5, @@ -1133,7 +1134,6 @@ enum OpcodeServer SMSG_REQUEST_CEMETERY_LIST_RESPONSE = 0x30A7, SMSG_REQUEST_PVP_REWARDS_RESPONSE = 0x5DA4, SMSG_RESEARCH_COMPLETE = 0x35A6, - SMSG_RESEARCH_SETUP_HISTORY = 0x10B6, SMSG_RESET_COMPRESSION_CONTEXT = 0x0142, SMSG_RESET_FAILED_NOTIFY = 0x4616, SMSG_RESISTLOG = 0x0000, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index fd46a8a352..e0ab0f3827 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -75,6 +75,11 @@ class RBACData; namespace WorldPackets { + namespace Archaeology + { + class RequestResearchHistory; + } + namespace Auth { enum class ConnectToSerial : uint32; @@ -1191,7 +1196,7 @@ class TC_GAME_API WorldSession void HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket); void HandleRequestCategoryCooldowns(WorldPacket& recvPacket); void SendStreamingMovie(); - void HandleRequestResearchHistory(WorldPacket& recv_data); + void HandleRequestResearchHistory(WorldPackets::Archaeology::RequestResearchHistory& packet); int32 HandleEnableNagleAlgorithm(); // Query diff --git a/src/server/game/Skills/Archaeology/ArchaeologyProjects.cpp b/src/server/game/Skills/Archaeology/ArchaeologyProjects.cpp index 47cb97688a..991dc530f0 100644 --- a/src/server/game/Skills/Archaeology/ArchaeologyProjects.cpp +++ b/src/server/game/Skills/Archaeology/ArchaeologyProjects.cpp @@ -16,6 +16,7 @@ */ #include "Archaeology.h" +#include "ArchaeologyPackets.h" #include "DatabaseEnv.h" #include "DBCStores.h" #include "GameTime.h" @@ -188,6 +189,12 @@ void Archaeology::CompleteProject(uint16 projectId) _player->ModifyCurrency(_archData->FragId, -int32(_archData->FragCount), false, true); _player->DestroyItemCount(_archData->KeyId, _archData->KeyCount, true, false); + WorldPackets::Archaeology::ResearchComplete packet; + packet.Research.CompletionCount = 1; + packet.Research.FirstCompleted = GameTime::GetGameTime(); + packet.Research.ProjectID = projectId; + _player->SendDirectMessage(packet.Write()); + if (_completedProjects.find(projectId) == _completedProjects.end()) { _completedProjects[projectId].first = GameTime::GetGameTime(); @@ -216,18 +223,9 @@ void Archaeology::SetArchData(ArchData const& data) void Archaeology::SendResearchHistory() { - uint32 count = _completedProjects.size(); - WorldPacket packet(SMSG_RESEARCH_SETUP_HISTORY, 4 + 4 + (4 + 4 + 4) * count); - packet.WriteBits(count, 22); + WorldPackets::Archaeology::SetupResearchHistory packet; + for (std::pair> itr : _completedProjects) + packet.History.emplace_back(itr.first, itr.second.second, itr.second.first); - packet.FlushBits(); - - for (std::map >::iterator itr = _completedProjects.begin(); itr != _completedProjects.end(); ++itr) - { - packet << int32(itr->first); - packet << int32(itr->second.second); - packet << uint32(itr->second.first); - } - - _player->SendDirectMessage(&packet); + _player->SendDirectMessage(packet.Write()); }