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());
}