diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 68 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 35 | ||||
-rw-r--r-- | src/server/game/Handlers/QueryHandler.cpp | 89 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QueryPackets.cpp | 48 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QueryPackets.h | 50 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 3 |
7 files changed, 204 insertions, 93 deletions
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index feb419a011a..de6adc04fb1 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6802,45 +6802,45 @@ void ObjectMgr::LoadQuestPOI() { uint32 oldMSTime = getMSTime(); - _questPOIStore.clear(); // need for reload case + _questPOIStore.clear(); // need for reload case uint32 count = 0; - // 0 1 2 3 4 5 6 7 - QueryResult result = WorldDatabase.Query("SELECT questId, id, objIndex, mapid, WorldMapAreaId, FloorId, unk3, unk4 FROM quest_poi order by questId"); - + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + QueryResult result = WorldDatabase.Query("SELECT QuestID, BlobIndex, Idx1, ObjectiveIndex, QuestObjectiveID, QuestObjectID, MapID, WorldMapAreaId, Floor, Priority, Flags, WorldEffectID, PlayerConditionID, WoDUnk1 FROM quest_poi order by QuestID, Idx1"); if (!result) { TC_LOG_ERROR("server.loading", ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty."); return; } - // 0 1 2 3 - QueryResult points = WorldDatabase.Query("SELECT questId, id, x, y FROM quest_poi_points ORDER BY questId DESC, idx"); + // 0 1 2 3 4 + QueryResult points = WorldDatabase.Query("SELECT QuestID, BlobIndex, Idx1, X, Y FROM quest_poi_points ORDER BY QuestID DESC, Idx1, Idx2"); - std::vector<std::vector<std::vector<QuestPOIPoint> > > POIs; + std::vector<std::vector<std::vector<QuestPOIPoint>>> POIs; if (points) { // The first result should have the highest questId Field* fields = points->Fetch(); - uint32 questIdMax = fields[0].GetUInt32(); + uint32 questIdMax = fields[0].GetInt32(); POIs.resize(questIdMax + 1); do { fields = points->Fetch(); - uint32 questId = fields[0].GetUInt32(); - uint32 id = fields[1].GetUInt32(); - int32 x = fields[2].GetInt32(); - int32 y = fields[3].GetInt32(); + int32 QuestID = fields[0].GetInt32(); + int32 BlobIndex = fields[1].GetInt32(); + int32 Idx1 = fields[2].GetInt32(); + int32 X = fields[3].GetInt32(); + int32 Y = fields[4].GetInt32(); - if (POIs[questId].size() <= id + 1) - POIs[questId].resize(id + 10); + if (POIs[QuestID].size() <= Idx1 + 1) + POIs[QuestID].resize(Idx1 + 10); - QuestPOIPoint point(x, y); - POIs[questId][id].push_back(point); + QuestPOIPoint point(X, Y); + POIs[QuestID][Idx1].push_back(point); } while (points->NextRow()); } @@ -6848,23 +6848,29 @@ void ObjectMgr::LoadQuestPOI() { Field* fields = result->Fetch(); - uint32 questId = fields[0].GetUInt32(); - uint32 id = fields[1].GetUInt32(); - int32 objIndex = fields[2].GetInt32(); - uint32 mapId = fields[3].GetUInt32(); - uint32 WorldMapAreaId = fields[4].GetUInt32(); - uint32 FloorId = fields[5].GetUInt32(); - uint32 unk3 = fields[6].GetUInt32(); - uint32 unk4 = fields[7].GetUInt32(); - - QuestPOI POI(id, objIndex, mapId, WorldMapAreaId, FloorId, unk3, unk4); - if (questId < POIs.size() && id < POIs[questId].size()) - { - POI.points = POIs[questId][id]; - _questPOIStore[questId].push_back(POI); + int32 QuestID = fields[0].GetInt32(); + int32 BlobIndex = fields[1].GetInt32(); + int32 Idx1 = fields[2].GetInt32(); + int32 ObjectiveIndex = fields[3].GetInt32(); + int32 QuestObjectiveID = fields[4].GetInt32(); + int32 QuestObjectID = fields[5].GetInt32(); + int32 MapID = fields[6].GetInt32(); + int32 WorldMapAreaId = fields[7].GetInt32(); + int32 Floor = fields[8].GetInt32(); + int32 Priority = fields[8].GetInt32(); + int32 Flags = fields[9].GetInt32(); + int32 WorldEffectID = fields[10].GetInt32(); + int32 PlayerConditionID = fields[12].GetInt32(); + int32 WoDUnk1 = fields[13].GetInt32(); + + QuestPOI POI(BlobIndex, ObjectiveIndex, QuestObjectiveID, QuestObjectID, MapID, WorldMapAreaId, Floor, Priority, Flags, WorldEffectID, PlayerConditionID, WoDUnk1); + if (QuestID < POIs.size() && Idx1 < POIs[QuestID].size()) + { + POI.points = POIs[QuestID][Idx1]; + _questPOIStore[QuestID].push_back(POI); } else - TC_LOG_ERROR("server.loading", "Table quest_poi references unknown quest points for quest %u POI id %u", questId, id); + TC_LOG_ERROR("server.loading", "Table quest_poi references unknown quest points for quest %i POI id %i", QuestID, BlobIndex); ++count; } while (result->NextRow()); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index dca58857f9c..07ff1971a40 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -546,26 +546,33 @@ typedef std::pair<GossipMenuItemsContainer::iterator, GossipMenuItemsContainer:: struct QuestPOIPoint { - int32 x; - int32 y; + int32 X; + int32 Y; - QuestPOIPoint() : x(0), y(0) { } - QuestPOIPoint(int32 _x, int32 _y) : x(_x), y(_y) { } + QuestPOIPoint() : X(0), Y(0) { } + QuestPOIPoint(int32 _X, int32 _Y) : X(_X), Y(_Y) { } }; struct QuestPOI { - uint32 Id; + int32 BlobIndex; int32 ObjectiveIndex; - uint32 MapId; - uint32 AreaId; - uint32 FloorId; - uint32 Unk3; - uint32 Unk4; + int32 QuestObjectiveID; + int32 QuestObjectID; + int32 MapID; + int32 WorldMapAreaID; + int32 Floor; + int32 Priority; + int32 Flags; + int32 WorldEffectID; + int32 PlayerConditionID; + int32 UnkWoD1; std::vector<QuestPOIPoint> points; - QuestPOI() : Id(0), ObjectiveIndex(0), MapId(0), AreaId(0), FloorId(0), Unk3(0), Unk4(0) { } - QuestPOI(uint32 id, int32 objIndex, uint32 mapId, uint32 areaId, uint32 floorId, uint32 unk3, uint32 unk4) : Id(id), ObjectiveIndex(objIndex), MapId(mapId), AreaId(areaId), FloorId(floorId), Unk3(unk3), Unk4(unk4) { } + QuestPOI() : BlobIndex(0), ObjectiveIndex(0), QuestObjectiveID(0), QuestObjectID(0), MapID(0), WorldMapAreaID(0), Floor(0), Priority(0), Flags(0), WorldEffectID(0), PlayerConditionID(0), UnkWoD1(0) { } + QuestPOI(int32 _BlobIndex, int32 _ObjectiveIndex, int32 _QuestObjectiveID, int32 _QuestObjectID, int32 _MapID, int32 _WorldMapAreaID, int32 _Foor, int32 _Priority, int32 _Flags, int32 _WorldEffectID, int32 _PlayerConditionID, int32 _UnkWoD1) : + BlobIndex(_BlobIndex), ObjectiveIndex(_ObjectiveIndex), QuestObjectiveID(_QuestObjectiveID), QuestObjectID(_QuestObjectID), MapID(_MapID), WorldMapAreaID(_WorldMapAreaID), + Floor(_Foor), Priority(_Priority), Flags(_Flags), WorldEffectID(_WorldEffectID), PlayerConditionID(_PlayerConditionID), UnkWoD1(_UnkWoD1) { } }; typedef std::vector<QuestPOI> QuestPOIVector; @@ -832,9 +839,9 @@ class ObjectMgr return NULL; } - QuestPOIVector const* GetQuestPOIVector(uint32 questId) + QuestPOIVector const* GetQuestPOIVector(uint32 QuestID) { - QuestPOIContainer::const_iterator itr = _questPOIStore.find(questId); + QuestPOIContainer::const_iterator itr = _questPOIStore.find(QuestID); if (itr != _questPOIStore.end()) return &itr->second; return NULL; diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 6c79b1e9632..a102123c349 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -324,77 +324,76 @@ void WorldSession::HandleQuestNPCQuery(WorldPacket& recvData) SendPacket(&data); } -void WorldSession::HandleQuestPOIQuery(WorldPacket& recvData) +void WorldSession::HandleQuestPOIQuery(WorldPackets::Query::QuestPOIQuery& packet) { - uint32 count; - recvData >> count; // quest count, max=25 - - if (count > MAX_QUEST_LOG_SIZE) - { - recvData.rfinish(); + if (packet.MissingQuestCount > MAX_QUEST_LOG_SIZE) return; - } // Read quest ids and add the in a unordered_set so we don't send POIs for the same quest multiple times - std::unordered_set<uint32> questIds; - for (uint32 i = 0; i < count; ++i) - questIds.insert(recvData.read<uint32>()); // quest id + std::unordered_set<int32> questIds; + for (int32 i = 0; i < packet.MissingQuestCount; ++i) + questIds.insert(packet.MissingQuestPOIs[i]); // QuestID - WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4 + (4 + 4)*questIds.size()); - data << uint32(questIds.size()); // count + WorldPackets::Query::QuestPOIQueryResponse response; for (auto itr = questIds.begin(); itr != questIds.end(); ++itr) { - uint32 questId = *itr; + int32 QuestID = *itr; bool questOk = false; - uint16 questSlot = _player->FindQuestSlot(questId); + uint16 questSlot = _player->FindQuestSlot(QuestID); if (questSlot != MAX_QUEST_LOG_SIZE) - questOk =_player->GetQuestSlotQuestId(questSlot) == questId; + questOk = _player->GetQuestSlotQuestId(questSlot) == QuestID; if (questOk) { - QuestPOIVector const* POI = sObjectMgr->GetQuestPOIVector(questId); - - if (POI) + QuestPOIVector const* poiData = sObjectMgr->GetQuestPOIVector(QuestID); + if (poiData) { - data << uint32(questId); // quest ID - data << uint32(POI->size()); // POI count + WorldPackets::Query::QuestPOIData questPOIData; - for (QuestPOIVector::const_iterator itr = POI->begin(); itr != POI->end(); ++itr) + questPOIData.QuestID = QuestID; + + for (auto data = poiData->begin(); data != poiData->end(); ++data) { - data << uint32(itr->Id); // POI index - data << int32(itr->ObjectiveIndex); // objective index - data << uint32(itr->MapId); // mapid - data << uint32(itr->AreaId); // areaid - data << uint32(itr->FloorId); // floorid - data << uint32(itr->Unk3); // unknown - data << uint32(itr->Unk4); // unknown - data << uint32(itr->points.size()); // POI points count - - for (std::vector<QuestPOIPoint>::const_iterator itr2 = itr->points.begin(); itr2 != itr->points.end(); ++itr2) + WorldPackets::Query::QuestPOIBlobData questPOIBlobData; + + questPOIBlobData.BlobIndex = data->BlobIndex; + questPOIBlobData.ObjectiveIndex = data->ObjectiveIndex; + questPOIBlobData.QuestObjectiveID = data->QuestObjectiveID; + questPOIBlobData.QuestObjectID = data->QuestObjectID; + questPOIBlobData.MapID = data->MapID; + questPOIBlobData.WorldMapAreaID = data->WorldMapAreaID; + questPOIBlobData.Floor = data->Floor; + questPOIBlobData.Priority = data->Priority; + questPOIBlobData.Flags = data->Flags; + questPOIBlobData.WorldEffectID = data->WorldEffectID; + questPOIBlobData.PlayerConditionID = data->PlayerConditionID; + questPOIBlobData.UnkWoD1 = data->UnkWoD1; + + for (auto points = data->points.begin(); points != data->points.end(); ++points) { - data << int32(itr2->x); // POI point x - data << int32(itr2->y); // POI point y + WorldPackets::Query::QuestPOIBlobPoint questPOIBlobPoint; + + questPOIBlobPoint.X = points->X; + questPOIBlobPoint.Y = points->Y; + + TC_LOG_ERROR("misc", "Quest: %i BlobIndex: %i X/Y: %i/%i", QuestID, data->BlobIndex, points->X, points->Y); + + questPOIBlobData.QuestPOIBlobPointStats.push_back(questPOIBlobPoint); } + + questPOIData.QuestPOIBlobDataStats.push_back(questPOIBlobData); } - } - else - { - data << uint32(questId); // quest ID - data << uint32(0); // POI count + + response.QuestPOIDataStats.push_back(questPOIData); } } - else - { - data << uint32(questId); // quest ID - data << uint32(0); // POI count - } } - SendPacket(&data); + SendPacket(response.Write()); } void WorldSession::HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet) diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp index 99a00be56e3..2cbd3078f60 100644 --- a/src/server/game/Server/Packets/QueryPackets.cpp +++ b/src/server/game/Server/Packets/QueryPackets.cpp @@ -357,3 +357,51 @@ WorldPacket const* WorldPackets::Query::QueryTimeResponse::Write() return &_worldPacket; } + +void WorldPackets::Query::QuestPOIQuery::Read() +{ + _worldPacket >> MissingQuestCount; + + for (uint8 i = 0; i < 50; ++i) + _worldPacket >> MissingQuestPOIs[i]; +} + +WorldPacket const* WorldPackets::Query::QuestPOIQueryResponse::Write() +{ + _worldPacket << int32(QuestPOIDataStats.size()); + _worldPacket << int32(QuestPOIDataStats.size()); + + for (QuestPOIData const& questPOIData : QuestPOIDataStats) + { + _worldPacket << int32(questPOIData.QuestID); + + _worldPacket << int32(questPOIData.QuestPOIBlobDataStats.size()); + _worldPacket << int32(questPOIData.QuestPOIBlobDataStats.size()); + + for (QuestPOIBlobData const& questPOIBlobData : questPOIData.QuestPOIBlobDataStats) + { + _worldPacket << int32(questPOIBlobData.BlobIndex); + _worldPacket << int32(questPOIBlobData.ObjectiveIndex); + _worldPacket << int32(questPOIBlobData.QuestObjectiveID); + _worldPacket << int32(questPOIBlobData.QuestObjectID); + _worldPacket << int32(questPOIBlobData.MapID); + _worldPacket << int32(questPOIBlobData.WorldMapAreaID); + _worldPacket << int32(questPOIBlobData.Floor); + _worldPacket << int32(questPOIBlobData.Priority); + _worldPacket << int32(questPOIBlobData.Flags); + _worldPacket << int32(questPOIBlobData.WorldEffectID); + _worldPacket << int32(questPOIBlobData.PlayerConditionID); + _worldPacket << int32(questPOIBlobData.QuestPOIBlobPointStats.size()); + _worldPacket << int32(questPOIBlobData.UnkWoD1); + _worldPacket << int32(questPOIBlobData.QuestPOIBlobPointStats.size()); + + for (QuestPOIBlobPoint const& questPOIBlobPoint : questPOIBlobData.QuestPOIBlobPointStats) + { + _worldPacket << int32(questPOIBlobPoint.X); + _worldPacket << int32(questPOIBlobPoint.Y); + } + } + } + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h index 1910eeeb1e7..1c3310b9621 100644 --- a/src/server/game/Server/Packets/QueryPackets.h +++ b/src/server/game/Server/Packets/QueryPackets.h @@ -316,6 +316,56 @@ namespace WorldPackets time_t CurrentTime = time_t(0); int32 TimeOutRequest = 0; }; + + class QuestPOIQuery final : public ClientPacket + { + public: + QuestPOIQuery(WorldPacket&& packet) : ClientPacket(CMSG_QUEST_POI_QUERY, std::move(packet)) { } + + void Read() override; + + int32 MissingQuestCount = 0; + int32 MissingQuestPOIs[50]; + }; + + struct QuestPOIBlobPoint + { + int32 X = 0; + int32 Y = 0; + }; + + struct QuestPOIBlobData + { + int32 BlobIndex = 0; + int32 ObjectiveIndex = 0; + int32 QuestObjectiveID = 0; + int32 QuestObjectID = 0; + int32 MapID = 0; + int32 WorldMapAreaID = 0; + int32 Floor = 0; + int32 Priority = 0; + int32 Flags = 0; + int32 WorldEffectID = 0; + int32 PlayerConditionID = 0; + int32 UnkWoD1 = 0; + std::vector<QuestPOIBlobPoint> QuestPOIBlobPointStats; + }; + + struct QuestPOIData + { + int32 QuestID = 0; + std::vector<QuestPOIBlobData> QuestPOIBlobDataStats; + }; + + class QuestPOIQueryResponse final : public ServerPacket + { + public: + QuestPOIQueryResponse() : ServerPacket(SMSG_QUEST_POI_QUERY_RESPONSE, 4 + 4) { } + + WorldPacket const* Write() override; + + std::vector<QuestPOIData> QuestPOIDataStats; + }; } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 15ca609368d..b09bcc64d4c 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -643,7 +643,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_QUEST_GIVER_STATUS_MULTIPLE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverStatusMultipleQuery, &WorldSession::HandleQuestgiverStatusMultipleQuery); DEFINE_HANDLER(CMSG_QUEST_GIVER_STATUS_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Quest::QuestGiverStatusQuery, &WorldSession::HandleQuestgiverStatusQueryOpcode); DEFINE_HANDLER(CMSG_QUEST_LOG_REMOVE_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestLogRemoveQuest, &WorldSession::HandleQuestLogRemoveQuest); - DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_POI_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQuery ); + DEFINE_HANDLER(CMSG_QUEST_POI_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QuestPOIQuery, &WorldSession::HandleQuestPOIQuery); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_PUSH_RESULT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEUED_MESSAGES_END, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_RANDOM_ROLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::RandomRollClient, &WorldSession::HandleRandomRollOpcode); @@ -1513,7 +1513,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_STATUS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_STATUS_MULTIPLE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_LOG_FULL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_POI_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_POI_QUERY_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_PUSH_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_ADD_CREDIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_ADD_CREDIT_SIMPLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index f4faa7a3b11..9067ebe491c 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -332,6 +332,7 @@ namespace WorldPackets class QueryCorpseLocationFromClient; class QueryCorpseTransport; class QueryTime; + class QuestPOIQuery; } namespace Quest @@ -1347,7 +1348,7 @@ class WorldSession void HandleEquipmentSetUse(WorldPacket& recvData); void HandleUITimeRequest(WorldPackets::Misc::UITimeRequest& /*request*/); void HandleQuestNPCQuery(WorldPacket& recvData); - void HandleQuestPOIQuery(WorldPacket& recvData); + void HandleQuestPOIQuery(WorldPackets::Query::QuestPOIQuery& packet); void HandleEjectPassenger(WorldPacket& data); void HandleEnterPlayerVehicle(WorldPacket& data); void HandleUpdateProjectilePosition(WorldPacket& recvPacket); |