aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/DataStores/DBCStores.cpp11
-rw-r--r--src/server/game/DataStores/DBCStores.h2
-rw-r--r--src/server/game/DataStores/DBCStructure.h6
-rw-r--r--src/server/game/DataStores/DBCfmt.h1
-rw-r--r--src/server/game/Entities/Player/Player.cpp99
-rw-r--r--src/server/game/Entities/Player/Player.h5
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp14
-rw-r--r--src/server/game/Server/Packets/CharacterPackets.cpp13
-rw-r--r--src/server/game/Server/Packets/CharacterPackets.h17
-rw-r--r--src/server/game/Server/Packets/QuestPackets.cpp23
-rw-r--r--src/server/game/Server/Packets/QuestPackets.h32
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp7
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h3
-rw-r--r--src/server/game/Server/WorldSession.cpp1
-rw-r--r--src/server/game/Server/WorldSession.h1
15 files changed, 203 insertions, 32 deletions
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index ec97b871ee9..20788fde81d 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -183,6 +183,7 @@ DBCStorage <PowerDisplayEntry> sPowerDisplayStore(PowerDisplayfmt);
DBCStorage <PvPDifficultyEntry> sPvPDifficultyStore(PvPDifficultyfmt);
DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);
+DBCStorage <QuestV2Entry> sQuestV2Store(QuestV2fmt);
DBCStorage <QuestXPEntry> sQuestXPStore(QuestXPfmt);
DBCStorage <QuestFactionRewEntry> sQuestFactionRewardStore(QuestFactionRewardfmt);
DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore(RandomPropertiesPointsfmt);
@@ -528,6 +529,7 @@ void LoadDBCStores(const std::string& dataPath)
if (entry->BracketID > MAX_BATTLEGROUND_BRACKETS)
ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sQuestV2Store, dbcPath, "QuestV2.dbc");//19342
LoadDBC(availableDbcLocales, bad_dbc_files, sQuestXPStore, dbcPath, "QuestXP.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sQuestFactionRewardStore, dbcPath, "QuestFactionReward.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc");//19116
@@ -1216,3 +1218,12 @@ uint32 GetTalentSpellCost(uint32 spellId)
return 0;
return 1;
}
+
+uint32 GetQuestUniqueBitFlag(uint32 questId)
+{
+ QuestV2Entry const* v2 = sQuestV2Store.LookupEntry(questId);
+ if (!v2)
+ return 0;
+
+ return v2->UniqueBitFlag;
+}
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index e0d58baa442..7c20baf5e55 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -87,6 +87,8 @@ LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty);
uint32 GetDefaultMapLight(uint32 mapId);
+uint32 GetQuestUniqueBitFlag(uint32 questId);
+
typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap;
typedef std::pair<SkillRaceClassInfoMap::iterator, SkillRaceClassInfoMap::iterator> SkillRaceClassInfoBounds;
SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_);
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 0b76ada0b96..8451c955fc2 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -1347,6 +1347,12 @@ struct QuestSortEntry
//char* SortName_lang; // 1
};
+struct QuestV2Entry
+{
+ uint32 ID; // 0
+ uint32 UniqueBitFlag; // 1
+};
+
struct QuestXPEntry
{
uint32 ID; // 0
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index 7b4e1d00ac6..3999ec61675 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -123,6 +123,7 @@ char const NameGenfmt[] = "dsii";
char const NumTalentsAtLevelfmt[] = "df";
char const QuestFactionRewardfmt[] = "niiiiiiiiii";
char const QuestSortEntryfmt[] = "nx";
+char const QuestV2fmt[] = "ni";
char const QuestXPfmt[] = "niiiiiiiiii";
char const PowerDisplayfmt[] = "nixXXX";
char const PvPDifficultyfmt[] = "diiii";
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 35a8020c40a..39dae59dcf4 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -867,10 +867,9 @@ Player::Player(WorldSession* session): Unit(true)
isDebugAreaTriggers = false;
+ _completedQuestBits.resize(QUESTS_COMPLETED_BITS_SIZE * 8);
m_WeeklyQuestChanged = false;
-
m_MonthlyQuestChanged = false;
-
m_SeasonalQuestChanged = false;
SetPendingBind(0, 0);
@@ -14849,7 +14848,6 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
RemoveActiveQuest(quest_id, false);
m_RewardedQuests.insert(quest_id);
m_RewardedQuestsSave[quest_id] = QUEST_DEFAULT_SAVE_TYPE;
-
// StoreNewItem, mail reward, etc. save data directly to the database
// to prevent exploitable data desynchronisation we save the quest status to the database too
// (to prevent rewarding this quest another time while rewards were already given out)
@@ -14888,6 +14886,16 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId());
+ if (uint32 questBit = GetQuestUniqueBitFlag(quest_id))
+ {
+ _completedQuestBits.set(questBit - 1);
+
+ WorldPackets::Quest::SetQuestCompletedBit setCompletedBit;
+ setCompletedBit.QuestID = quest_id;
+ setCompletedBit.Bit = questBit;
+ SendDirectMessage(setCompletedBit.Write());
+ }
+
if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
{
pvpInfo.IsHostile = pvpInfo.IsInHostileArea || HasPvPForcingQuest();
@@ -15517,6 +15525,16 @@ void Player::RemoveRewardedQuest(uint32 questId, bool update /*= true*/)
m_RewardedQuestsSave[questId] = QUEST_FORCE_DELETE_SAVE_TYPE;
}
+ if (uint32 questBit = GetQuestUniqueBitFlag(questId))
+ {
+ _completedQuestBits.reset(questBit - 1);
+
+ WorldPackets::Quest::ClearQuestCompletedBit clearCompletedBit;
+ clearCompletedBit.QuestID = questId;
+ clearCompletedBit.Bit = questBit;
+ SendDirectMessage(clearCompletedBit.Write());
+ }
+
if (update)
SendQuestUpdate(questId);
}
@@ -18140,10 +18158,14 @@ void Player::_LoadQuestStatusRewarded(PreparedQueryResult result)
// set rewarded title if any
if (quest->GetRewTitle())
- {
if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(quest->GetRewTitle()))
SetTitle(titleEntry);
- }
+
+ // Skip loading special quests - they are also added to rewarded quests but only once and remain there forever
+ // instead add them separately from load daily/weekly/monthly/seasonal
+ if (!quest->IsDailyOrWeekly() && !quest->IsMonthly() && !quest->IsSeasonal())
+ if (uint32 questBit = GetQuestUniqueBitFlag(quest_id))
+ _completedQuestBits.set(questBit - 1);
}
m_RewardedQuests.insert(quest_id);
@@ -18182,6 +18204,8 @@ void Player::_LoadDailyQuestStatus(PreparedQueryResult result)
continue;
AddDynamicValue(PLAYER_DYNAMIC_FIELD_DAILY_QUESTS, quest_id);
+ if (uint32 questBit = GetQuestUniqueBitFlag(quest_id))
+ _completedQuestBits.set(questBit - 1);
TC_LOG_DEBUG("entities.player.loading", "Daily quest (%u) cooldown for player (%s)", quest_id, GetGUID().ToString().c_str());
}
@@ -18206,6 +18230,9 @@ void Player::_LoadWeeklyQuestStatus(PreparedQueryResult result)
continue;
m_weeklyquests.insert(quest_id);
+ if (uint32 questBit = GetQuestUniqueBitFlag(quest_id))
+ _completedQuestBits.set(questBit - 1);
+
TC_LOG_DEBUG("entities.player.loading", "Weekly quest {%u} cooldown for player (%s)", quest_id, GetGUID().ToString().c_str());
}
while (result->NextRow());
@@ -18230,6 +18257,9 @@ void Player::_LoadSeasonalQuestStatus(PreparedQueryResult result)
continue;
m_seasonalquests[event_id].insert(quest_id);
+ if (uint32 questBit = GetQuestUniqueBitFlag(quest_id))
+ _completedQuestBits.set(questBit - 1);
+
TC_LOG_DEBUG("entities.player.loading", "Seasonal quest {%u} cooldown for player (%s)", quest_id, GetGUID().ToString().c_str());
}
while (result->NextRow());
@@ -18253,6 +18283,9 @@ void Player::_LoadMonthlyQuestStatus(PreparedQueryResult result)
continue;
m_monthlyquests.insert(quest_id);
+ if (uint32 questBit = GetQuestUniqueBitFlag(quest_id))
+ _completedQuestBits.set(questBit - 1);
+
TC_LOG_DEBUG("entities.player.loading", "Monthly quest {%u} cooldown for player (%s)", quest_id, GetGUID().ToString().c_str());
}
while (result->NextRow());
@@ -22876,10 +22909,13 @@ void Player::SendInitialPacketsBeforeAddToMap()
worldServerInfo.DifficultyID = GetMap()->GetDifficultyID();
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
+ // SMSG_ACCOUNT_MOUNT_UPDATE
+ // SMSG_ACCOUNT_TOYS_UPDATE
+
+ WorldPackets::Character::InitialSetup initialSetup;
+ initialSetup.ServerExpansionLevel = sWorld->getIntConfig(CONFIG_EXPANSION);
+ boost::to_block_range(_completedQuestBits, std::back_inserter(initialSetup.QuestsCompleted));
+ SendDirectMessage(initialSetup.Write());
SetMover(this);
}
@@ -23378,6 +23414,18 @@ void Player::SetMonthlyQuestStatus(uint32 quest_id)
void Player::ResetDailyQuestStatus()
{
+ std::vector<uint32> dailies = GetDynamicValues(PLAYER_DYNAMIC_FIELD_DAILY_QUESTS);
+ if (!dailies.empty())
+ {
+ WorldPackets::Quest::ClearQuestCompletedBits clearCompletedBits;
+ for (uint32 questId : dailies)
+ if (uint32 questBit = GetQuestUniqueBitFlag(questId))
+ clearCompletedBits.Qbits.push_back(questBit);
+
+ if (!clearCompletedBits.Qbits.empty())
+ SendDirectMessage(clearCompletedBits.Write());
+ }
+
ClearDynamicValue(PLAYER_DYNAMIC_FIELD_DAILY_QUESTS);
m_DFQuests.clear(); // Dungeon Finder Quests.
@@ -23392,18 +23440,37 @@ void Player::ResetWeeklyQuestStatus()
if (m_weeklyquests.empty())
return;
+ WorldPackets::Quest::ClearQuestCompletedBits clearCompletedBits;
+ for (uint32 questId : m_weeklyquests)
+ if (uint32 questBit = GetQuestUniqueBitFlag(questId))
+ clearCompletedBits.Qbits.push_back(questBit);
+
+ if (!clearCompletedBits.Qbits.empty())
+ SendDirectMessage(clearCompletedBits.Write());
+
m_weeklyquests.clear();
// DB data deleted in caller
m_WeeklyQuestChanged = false;
-
}
void Player::ResetSeasonalQuestStatus(uint16 event_id)
{
- if (m_seasonalquests.empty() || m_seasonalquests[event_id].empty())
+ auto eventItr = m_seasonalquests.find(event_id);
+ if (eventItr == m_seasonalquests.end())
+ return;
+
+ if (eventItr->second.empty())
return;
- m_seasonalquests.erase(event_id);
+ WorldPackets::Quest::ClearQuestCompletedBits clearCompletedBits;
+ for (uint32 questId : eventItr->second)
+ if (uint32 questBit = GetQuestUniqueBitFlag(questId))
+ clearCompletedBits.Qbits.push_back(questBit);
+
+ if (!clearCompletedBits.Qbits.empty())
+ SendDirectMessage(clearCompletedBits.Write());
+
+ m_seasonalquests.erase(eventItr);
// DB data deleted in caller
m_SeasonalQuestChanged = false;
}
@@ -23413,6 +23480,14 @@ void Player::ResetMonthlyQuestStatus()
if (m_monthlyquests.empty())
return;
+ WorldPackets::Quest::ClearQuestCompletedBits clearCompletedBits;
+ for (uint32 questId : m_monthlyquests)
+ if (uint32 questBit = GetQuestUniqueBitFlag(questId))
+ clearCompletedBits.Qbits.push_back(questBit);
+
+ if (!clearCompletedBits.Qbits.empty())
+ SendDirectMessage(clearCompletedBits.Write());
+
m_monthlyquests.clear();
// DB data deleted in caller
m_MonthlyQuestChanged = false;
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 8f78dc28b9a..e7e6de95746 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -35,6 +35,7 @@
#include <limits>
#include <string>
#include <vector>
+#include <boost/dynamic_bitset.hpp>
struct CreatureTemplate;
struct Mail;
@@ -630,6 +631,8 @@ enum QuestSaveType
// quest
typedef std::map<uint32, QuestSaveType> QuestStatusSaveMap;
+// Size (in bytes) of client completed quests bit map
+#define QUESTS_COMPLETED_BITS_SIZE 2500
enum QuestSlotOffsets
{
@@ -2780,6 +2783,8 @@ class Player : public Unit, public GridObject<Player>
RewardedQuestSet m_RewardedQuests;
QuestStatusSaveMap m_RewardedQuestsSave;
+ boost::dynamic_bitset<uint8> _completedQuestBits;
+
SkillStatusMap mSkillStatus;
ObjectGuid::LowType m_GuildIdInvited;
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index 6a8e28125b5..57abbfeeaa2 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -655,17 +655,3 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPackets::Quest::Ques
SendPacket(response.Write());
}
-
-void WorldSession::HandleQueryQuestsCompleted(WorldPacket& /*recvData*/)
-{
- size_t rew_count = _player->GetRewardedQuestCount();
-
- WorldPacket data(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, 4 + 4 * rew_count);
- data << uint32(rew_count);
-
- const RewardedQuestSet &rewQuests = _player->getRewardedQuests();
- for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr)
- data << uint32(*itr);
-
- SendPacket(&data);
-}
diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp
index 0ab03092b4c..00eda24524c 100644
--- a/src/server/game/Server/Packets/CharacterPackets.cpp
+++ b/src/server/game/Server/Packets/CharacterPackets.cpp
@@ -377,3 +377,16 @@ void WorldPackets::Character::LoadingScreenNotify::Read()
_worldPacket >> MapID;
Showing = _worldPacket.ReadBit();
}
+
+WorldPacket const* WorldPackets::Character::InitialSetup::Write()
+{
+ _worldPacket << uint32(QuestsCompleted.size());
+ _worldPacket << uint8(ServerExpansionLevel);
+ _worldPacket << uint8(ServerExpansionTier);
+ _worldPacket << int32(ServerRegionID);
+ _worldPacket << uint32(RaidOrigin);
+ if (!QuestsCompleted.empty())
+ _worldPacket.append(QuestsCompleted.data(), QuestsCompleted.size());
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/CharacterPackets.h b/src/server/game/Server/Packets/CharacterPackets.h
index c32620f5a89..c65de450e6c 100644
--- a/src/server/game/Server/Packets/CharacterPackets.h
+++ b/src/server/game/Server/Packets/CharacterPackets.h
@@ -473,6 +473,23 @@ namespace WorldPackets
int32 MapID = -1;
bool Showing = false;
};
+
+ class InitialSetup final : public ServerPacket
+ {
+ public:
+ InitialSetup() : ServerPacket(SMSG_INITIAL_SETUP, 1 + 1 + 4 + QUESTS_COMPLETED_BITS_SIZE + 4)
+ {
+ QuestsCompleted.reserve(QUESTS_COMPLETED_BITS_SIZE);
+ }
+
+ WorldPacket const* Write() override;
+
+ uint8 ServerExpansionTier = 0;
+ uint8 ServerExpansionLevel = 0;
+ time_t RaidOrigin = time_t(1135753200); // 28/12/2005 07:00:00
+ std::vector<uint8> QuestsCompleted;
+ int32 ServerRegionID = 3; // Cfg_Regions.dbc, EU
+ };
}
}
diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp
index 471d4846f16..db30e8d2ec0 100644
--- a/src/server/game/Server/Packets/QuestPackets.cpp
+++ b/src/server/game/Server/Packets/QuestPackets.cpp
@@ -426,3 +426,26 @@ void WorldPackets::Quest::QuestGiverQueryQuest::Read()
_worldPacket >> QuestID;
RespondToGiver = _worldPacket.ReadBit();
}
+
+WorldPacket const* WorldPackets::Quest::SetQuestCompletedBit::Write()
+{
+ _worldPacket << int32(Bit);
+ _worldPacket << int32(QuestID);
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Quest::ClearQuestCompletedBit::Write()
+{
+ _worldPacket << int32(Bit);
+ _worldPacket << int32(QuestID);
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Quest::ClearQuestCompletedBits::Write()
+{
+ _worldPacket << uint32(Qbits.size());
+ if (!Qbits.empty())
+ _worldPacket.append(Qbits.data(), Qbits.size());
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h
index c7d901aff01..8776e680775 100644
--- a/src/server/game/Server/Packets/QuestPackets.h
+++ b/src/server/game/Server/Packets/QuestPackets.h
@@ -405,6 +405,38 @@ namespace WorldPackets
int32 QuestID = 0;
bool RespondToGiver = false;
};
+
+ class SetQuestCompletedBit final : public ServerPacket
+ {
+ public:
+ SetQuestCompletedBit() : ServerPacket(SMSG_SET_QUEST_COMPLETED_BIT, 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ int32 Bit = 0;
+ int32 QuestID = 0;
+ };
+
+ class ClearQuestCompletedBit final : public ServerPacket
+ {
+ public:
+ ClearQuestCompletedBit() : ServerPacket(SMSG_CLEAR_QUEST_COMPLETED_BIT, 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ int32 Bit = 0;
+ int32 QuestID = 0;
+ };
+
+ class ClearQuestCompletedBits final : public ServerPacket
+ {
+ public:
+ ClearQuestCompletedBits() : ServerPacket(SMSG_CLEAR_QUEST_COMPLETED_BITS, 4) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<int32> Qbits;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 8b86f917b6b..cde74e849f8 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -537,7 +537,6 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_GUILD_XP, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryXPOpcode ); // STATUS_AUTHED
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_INSPECT_ACHIEVEMENTS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryInspectAchievements );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_NEXT_MAIL_TIME, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryNextMailTime );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_QUESTS_COMPLETED, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryQuestsCompleted );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_TIME, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryTimeOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_ACCEPT_QUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverAcceptQuestOpcode);
DEFINE_HANDLER(CMSG_QUESTGIVER_CHOOSE_REWARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverChooseReward, &WorldSession::HandleQuestgiverChooseRewardOpcode);
@@ -842,7 +841,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWNS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_QUEST_COMPLETED_BITS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_QUEST_COMPLETED_BIT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_QUEST_COMPLETED_BITS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_TARGET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLIENTCACHE_VERSION, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLIENT_CONTROL_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1020,7 +1020,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY_BLOB, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SETUP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SETUP, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_WORLD_STATES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1318,6 +1318,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROJECTILE_POSITION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_QUEST_COMPLETED_BIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_RAID_DIFFICULTY, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_TIME_ZONE_INFORMATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SETUP_CURRENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index c3cbcb1dfa1..241a6656c42 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -475,7 +475,6 @@ enum OpcodeClient : uint32
CMSG_QUERY_GUILD_XP = 0xBADD,
CMSG_QUERY_INSPECT_ACHIEVEMENTS = 0xBADD,
CMSG_QUERY_NEXT_MAIL_TIME = 0x0B31,
- CMSG_QUERY_QUESTS_COMPLETED = 0xBADD,
CMSG_QUERY_TIME = 0xBADD,
CMSG_QUESTGIVER_ACCEPT_QUEST = 0x13D3,
CMSG_QUESTGIVER_CANCEL = 0xBADD,
@@ -819,6 +818,7 @@ enum OpcodeServer : uint32
SMSG_CLEAR_COOLDOWN = 0xBADD,
SMSG_CLEAR_COOLDOWNS = 0xBADD,
SMSG_CLEAR_FAR_SIGHT_IMMEDIATE = 0xBADD,
+ SMSG_CLEAR_QUEST_COMPLETED_BIT = 0xBADD,
SMSG_CLEAR_QUEST_COMPLETED_BITS = 0x1D47,
SMSG_CLEAR_TARGET = 0xBADD,
SMSG_CLIENTCACHE_VERSION = 0x080D,
@@ -1320,6 +1320,7 @@ enum OpcodeServer : uint32
SMSG_SET_PLAY_HOVER_ANIM = 0x02D4,
SMSG_SET_PROFICIENCY = 0x00D3,
SMSG_SET_PROJECTILE_POSITION = 0xBADD,
+ SMSG_SET_QUEST_COMPLETED_BIT = 0x15D3,
SMSG_SET_RAID_DIFFICULTY = 0x051F,
SMSG_SET_TIME_ZONE_INFORMATION = 0x153E,
SMSG_SET_VIGNETTE = 0x09AC,
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 1efb67c46e7..4e96d829554 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -1209,7 +1209,6 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co
case CMSG_PET_NAME_QUERY: // 0 1
case CMSG_NPC_TEXT_QUERY: // 0 1
case CMSG_ATTACKSTOP: // 0 1
- //case CMSG_QUERY_QUESTS_COMPLETED: // 0 1
//case CMSG_QUERY_TIME: // 0 1
//case CMSG_CORPSE_MAP_POSITION_QUERY: // 0 1
case CMSG_MOVE_TIME_SKIPPED: // 0 1
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 43b22a33f95..baf5232cd9b 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -1165,7 +1165,6 @@ class WorldSession
void HandleEquipmentSetDelete(WorldPacket& recvData);
void HandleEquipmentSetUse(WorldPacket& recvData);
void HandleWorldStateUITimerUpdate(WorldPacket& recvData);
- void HandleQueryQuestsCompleted(WorldPacket& recvData);
void HandleQuestNPCQuery(WorldPacket& recvData);
void HandleQuestPOIQuery(WorldPacket& recvData);
void HandleEjectPassenger(WorldPacket& data);