From 966c1fff33ec606e5301d95ebc6691690fecdf3d Mon Sep 17 00:00:00 2001 From: hondacrx Date: Sat, 31 Aug 2019 10:06:35 -0400 Subject: [PATCH] Core/Cache: Implement QueryCache system Ideas/Port From (https://github.com/TrinityCore/TrinityCore/commit/b4d30bb92cbfc8411d8d91b0f4f2981f2cecc148) --- Source/Framework/Constants/SharedConst.cs | 12 ++ Source/Game/Chat/Commands/GoCommands.cs | 8 +- Source/Game/Chat/Commands/ReloadCommand.cs | 3 + Source/Game/Entities/Creature/CreatureData.cs | 56 ++++++ Source/Game/Entities/Creature/Gossip.cs | 143 ++------------ .../Entities/GameObject/GameObjectData.cs | 40 ++++ Source/Game/Globals/ObjectManager.cs | 140 ++++++++++--- Source/Game/Handlers/QueryHandler.cs | 184 +++++------------- Source/Game/Network/Packets/QueryPackets.cs | 69 +------ Source/Game/Quest/Quest.cs | 116 +++++++++++ Source/Game/Server/WorldConfig.cs | 3 + Source/Game/Server/WorldManager.cs | 3 + Source/WorldServer/WorldServer.conf.dist | 11 ++ 13 files changed, 430 insertions(+), 358 deletions(-) diff --git a/Source/Framework/Constants/SharedConst.cs b/Source/Framework/Constants/SharedConst.cs index 73dc57529..80cf3c04c 100644 --- a/Source/Framework/Constants/SharedConst.cs +++ b/Source/Framework/Constants/SharedConst.cs @@ -1065,6 +1065,7 @@ namespace Framework.Constants BlackmarketEnabled, BlackmarketMaxAuctions, BlackmarketUpdatePeriod, + CacheDataQueries, CalculateCreatureZoneAreaData, CalculateGameobjectZoneAreaData, CastUnstuck, @@ -2447,4 +2448,15 @@ namespace Framework.Constants { Lootable = 0x0001 } + + public enum QueryDataGroup + { + Creatures = 0x01, + Gameobjects = 0x02, + Items = 0x04, + Quests = 0x08, + POIs = 0x10, + + All = 0xFF + } } diff --git a/Source/Game/Chat/Commands/GoCommands.cs b/Source/Game/Chat/Commands/GoCommands.cs index f94276432..81d3de16c 100644 --- a/Source/Game/Chat/Commands/GoCommands.cs +++ b/Source/Game/Chat/Commands/GoCommands.cs @@ -265,15 +265,15 @@ namespace Game.Chat.Commands float x, y, z = 0; uint mapId = 0; - var poiData = Global.ObjectMgr.GetQuestPOIList(questID); + var poiData = Global.ObjectMgr.GetQuestPOIData(questID); if (poiData != null) { - var data = poiData[0]; + var data = poiData.QuestPOIBlobDataStats[0]; mapId = (uint)data.MapID; - x = data.points[0].X; - y = data.points[0].Y; + x = data.QuestPOIBlobPointStats[0].X; + y = data.QuestPOIBlobPointStats[0].Y; } else { diff --git a/Source/Game/Chat/Commands/ReloadCommand.cs b/Source/Game/Chat/Commands/ReloadCommand.cs index 518482d18..a810e5010 100644 --- a/Source/Game/Chat/Commands/ReloadCommand.cs +++ b/Source/Game/Chat/Commands/ReloadCommand.cs @@ -238,6 +238,7 @@ namespace Game.Chat Global.ObjectMgr.CheckCreatureTemplate(cInfo); } + Global.ObjectMgr.InitializeQueriesData(QueryDataGroup.Creatures); handler.SendGlobalGMSysMessage("Creature template reloaded."); return true; } @@ -607,6 +608,7 @@ namespace Game.Chat { Log.outInfo(LogFilter.Server, "Re-Loading Quest POI ..."); Global.ObjectMgr.LoadQuestPOI(); + Global.ObjectMgr.InitializeQueriesData(QueryDataGroup.POIs); handler.SendGlobalGMSysMessage("DB Table `quest_poi` and `quest_poi_points` reloaded."); return true; } @@ -616,6 +618,7 @@ namespace Game.Chat { Log.outInfo(LogFilter.Server, "Re-Loading Quest Templates..."); Global.ObjectMgr.LoadQuests(); + Global.ObjectMgr.InitializeQueriesData(QueryDataGroup.Quests); handler.SendGlobalGMSysMessage("DB table `quest_template` (quest definitions) reloaded."); // dependent also from `gameobject` but this table not reloaded anyway diff --git a/Source/Game/Entities/Creature/CreatureData.cs b/Source/Game/Entities/Creature/CreatureData.cs index 1d9414f7f..c7045524d 100644 --- a/Source/Game/Entities/Creature/CreatureData.cs +++ b/Source/Game/Entities/Creature/CreatureData.cs @@ -20,6 +20,8 @@ using Framework.Constants; using System; using System.Collections.Generic; using Framework.Dynamic; +using Game.Network.Packets; +using Game.Network; namespace Game.Entities { @@ -91,6 +93,8 @@ namespace Game.Entities public CreatureFlagsExtra FlagsExtra; public uint ScriptID; + public QueryCreatureResponse QueryData; + public CreatureModel GetModelByIdx(int idx) { return idx < Models.Count ? Models[idx] : null; @@ -210,6 +214,58 @@ namespace Game.Entities return -1; } } + + public void InitializeQueryData() + { + QueryData = new QueryCreatureResponse(); + + QueryData.CreatureID = Entry; + QueryData.Allow = true; + + CreatureStats stats = new CreatureStats(); + stats.Leader = RacialLeader; + + stats.Name[0] = Name; + stats.NameAlt[0] = FemaleName; + + stats.Flags[0] = (uint)TypeFlags; + stats.Flags[1] = TypeFlags2; + + stats.CreatureType = (int)CreatureType; + stats.CreatureFamily = (int)Family; + stats.Classification = (int)Rank; + + for (uint i = 0; i < SharedConst.MaxCreatureKillCredit; ++i) + stats.ProxyCreatureID[i] = KillCredit[i]; + + foreach (var model in Models) + { + stats.Display.TotalProbability += model.Probability; + stats.Display.CreatureDisplay.Add(new CreatureXDisplay(model.CreatureDisplayID, model.DisplayScale, model.Probability)); + } + + stats.HpMulti = ModHealth; + stats.EnergyMulti = ModMana; + + stats.CreatureMovementInfoID = MovementId; + stats.RequiredExpansion = RequiredExpansion; + stats.HealthScalingExpansion = HealthScalingExpansion; + stats.VignetteID = VignetteID; + stats.Class = (int)UnitClass; + stats.FadeRegionRadius = FadeRegionRadius; + stats.WidgetSetID = WidgetSetID; + stats.WidgetSetUnitConditionID = WidgetSetUnitConditionID; + + stats.Title = SubName; + stats.TitleAlt = TitleAlt; + stats.CursorName = IconName; + + var items = Global.ObjectMgr.GetCreatureQuestItemList(Entry); + if (items != null) + stats.QuestItems.AddRange(items); + + QueryData.Stats = stats; + } } public class CreatureBaseStats diff --git a/Source/Game/Entities/Creature/Gossip.cs b/Source/Game/Entities/Creature/Gossip.cs index 0982f33b1..6e4595dd8 100644 --- a/Source/Game/Entities/Creature/Gossip.cs +++ b/Source/Game/Entities/Creature/Gossip.cs @@ -467,145 +467,38 @@ namespace Game.Misc public void SendQuestQueryResponse(Quest quest) { - QueryQuestInfoResponse packet = new QueryQuestInfoResponse(); + if (!WorldConfig.GetBoolValue(WorldCfg.CacheDataQueries)) + quest.InitializeQueryData(); - packet.Allow = true; - packet.QuestID = quest.Id; + QueryQuestInfoResponse queryQuestInfoResponse = quest.QueryData; - packet.Info.LogTitle = quest.LogTitle; - packet.Info.LogDescription = quest.LogDescription; - packet.Info.QuestDescription = quest.QuestDescription; - packet.Info.AreaDescription = quest.AreaDescription; - packet.Info.QuestCompletionLog = quest.QuestCompletionLog; - packet.Info.PortraitGiverText = quest.PortraitGiverText; - packet.Info.PortraitGiverName = quest.PortraitGiverName; - packet.Info.PortraitTurnInText = quest.PortraitTurnInText; - packet.Info.PortraitTurnInName = quest.PortraitTurnInName; - - LocaleConstant locale = _session.GetSessionDbLocaleIndex(); - if (locale != LocaleConstant.enUS) + LocaleConstant loc = _session.GetSessionDbLocaleIndex(); + if (loc != LocaleConstant.enUS) { - QuestTemplateLocale questTemplateLocale = Global.ObjectMgr.GetQuestLocale(quest.Id); + QuestTemplateLocale questTemplateLocale = Global.ObjectMgr.GetQuestLocale(queryQuestInfoResponse.QuestID); if (questTemplateLocale != null) { - ObjectManager.GetLocaleString(questTemplateLocale.LogTitle, locale, ref packet.Info.LogTitle); - ObjectManager.GetLocaleString(questTemplateLocale.LogDescription, locale, ref packet.Info.LogDescription); - ObjectManager.GetLocaleString(questTemplateLocale.QuestDescription, locale, ref packet.Info.QuestDescription); - ObjectManager.GetLocaleString(questTemplateLocale.AreaDescription, locale, ref packet.Info.AreaDescription); - ObjectManager.GetLocaleString(questTemplateLocale.QuestCompletionLog, locale, ref packet.Info.QuestCompletionLog); - ObjectManager.GetLocaleString(questTemplateLocale.PortraitGiverText, locale, ref packet.Info.PortraitGiverText); - ObjectManager.GetLocaleString(questTemplateLocale.PortraitGiverName, locale, ref packet.Info.PortraitGiverName); - ObjectManager.GetLocaleString(questTemplateLocale.PortraitTurnInText, locale, ref packet.Info.PortraitTurnInText); - ObjectManager.GetLocaleString(questTemplateLocale.PortraitTurnInName, locale, ref packet.Info.PortraitTurnInName); + ObjectManager.GetLocaleString(questTemplateLocale.LogTitle, loc, ref queryQuestInfoResponse.Info.LogTitle); + ObjectManager.GetLocaleString(questTemplateLocale.LogDescription, loc, ref queryQuestInfoResponse.Info.LogDescription); + ObjectManager.GetLocaleString(questTemplateLocale.QuestDescription, loc, ref queryQuestInfoResponse.Info.QuestDescription); + ObjectManager.GetLocaleString(questTemplateLocale.AreaDescription, loc, ref queryQuestInfoResponse.Info.AreaDescription); + ObjectManager.GetLocaleString(questTemplateLocale.QuestCompletionLog, loc, ref queryQuestInfoResponse.Info.QuestCompletionLog); + ObjectManager.GetLocaleString(questTemplateLocale.PortraitGiverText, loc, ref queryQuestInfoResponse.Info.PortraitGiverText); + ObjectManager.GetLocaleString(questTemplateLocale.PortraitGiverName, loc, ref queryQuestInfoResponse.Info.PortraitGiverName); + ObjectManager.GetLocaleString(questTemplateLocale.PortraitTurnInText, loc, ref queryQuestInfoResponse.Info.PortraitTurnInText); + ObjectManager.GetLocaleString(questTemplateLocale.PortraitTurnInName, loc, ref queryQuestInfoResponse.Info.PortraitTurnInName); } - } - packet.Info.QuestID = quest.Id; - packet.Info.QuestType = (int)quest.Type; - packet.Info.QuestLevel = quest.Level; - packet.Info.QuestScalingFactionGroup = quest.ScalingFactionGroup; - packet.Info.QuestMaxScalingLevel = quest.MaxScalingLevel; - packet.Info.QuestPackageID = quest.PackageID; - packet.Info.QuestMinLevel = quest.MinLevel; - packet.Info.QuestSortID = quest.QuestSortID; - packet.Info.QuestInfoID = quest.QuestInfoID; - packet.Info.SuggestedGroupNum = quest.SuggestedPlayers; - packet.Info.RewardNextQuest = quest.NextQuestInChain; - packet.Info.RewardXPDifficulty = quest.RewardXPDifficulty; - packet.Info.RewardXPMultiplier = quest.RewardXPMultiplier; - - if (!quest.HasFlag(QuestFlags.HiddenRewards)) - packet.Info.RewardMoney = quest.RewardMoney < 0 ? quest.RewardMoney : (int)_session.GetPlayer().GetQuestMoneyReward(quest); - - packet.Info.RewardMoneyDifficulty = quest.RewardMoneyDifficulty; - packet.Info.RewardMoneyMultiplier = quest.RewardMoneyMultiplier; - packet.Info.RewardBonusMoney = quest.RewardBonusMoney; - for (byte i = 0; i < SharedConst.QuestRewardDisplaySpellCount; ++i) - packet.Info.RewardDisplaySpell[i] = quest.RewardDisplaySpell[i]; - - packet.Info.RewardSpell = quest.RewardSpell; - - packet.Info.RewardHonor = quest.RewardHonor; - packet.Info.RewardKillHonor = quest.RewardKillHonor; - - packet.Info.RewardArtifactXPDifficulty = (int)quest.RewardArtifactXPDifficulty; - packet.Info.RewardArtifactXPMultiplier = quest.RewardArtifactXPMultiplier; - packet.Info.RewardArtifactCategoryID = (int)quest.RewardArtifactCategoryID; - - packet.Info.StartItem = quest.SourceItemId; - packet.Info.Flags = (uint)quest.Flags; - packet.Info.FlagsEx = (uint)quest.FlagsEx; - packet.Info.FlagsEx2 = (uint)quest.FlagsEx2; - packet.Info.RewardTitle = quest.RewardTitleId; - packet.Info.RewardArenaPoints = quest.RewardArenaPoints; - packet.Info.RewardSkillLineID = quest.RewardSkillId; - packet.Info.RewardNumSkillUps = quest.RewardSkillPoints; - packet.Info.RewardFactionFlags = quest.RewardReputationMask; - packet.Info.PortraitGiver = quest.QuestGiverPortrait; - packet.Info.PortraitGiverMount = quest.QuestGiverPortraitMount; - packet.Info.PortraitTurnIn = quest.QuestTurnInPortrait; - - for (byte i = 0; i < SharedConst.QuestItemDropCount; ++i) - { - packet.Info.ItemDrop[i] = (int)quest.ItemDrop[i]; - packet.Info.ItemDropQuantity[i] = (int)quest.ItemDropQuantity[i]; - } - - if (!quest.HasFlag(QuestFlags.HiddenRewards)) - { - for (byte i = 0; i < SharedConst.QuestRewardItemCount; ++i) - { - packet.Info.RewardItems[i] = quest.RewardItemId[i]; - packet.Info.RewardAmount[i] = quest.RewardItemCount[i]; - } - for (byte i = 0; i < SharedConst.QuestRewardChoicesCount; ++i) - { - packet.Info.UnfilteredChoiceItems[i].ItemID = quest.RewardChoiceItemId[i]; - packet.Info.UnfilteredChoiceItems[i].Quantity = quest.RewardChoiceItemCount[i]; - } - } - - for (byte i = 0; i < SharedConst.QuestRewardReputationsCount; ++i) - { - packet.Info.RewardFactionID[i] = quest.RewardFactionId[i]; - packet.Info.RewardFactionValue[i] = quest.RewardFactionValue[i]; - packet.Info.RewardFactionOverride[i] = quest.RewardFactionOverride[i]; - packet.Info.RewardFactionCapIn[i] = (int)quest.RewardFactionCapIn[i]; - } - - packet.Info.POIContinent = quest.POIContinent; - packet.Info.POIx = quest.POIx; - packet.Info.POIy = quest.POIy; - packet.Info.POIPriority = quest.POIPriority; - - packet.Info.AllowableRaces = quest.AllowableRaces; - packet.Info.TreasurePickerID = (int)quest.TreasurePickerID; - packet.Info.Expansion = quest.Expansion; - - foreach (QuestObjective questObjective in quest.Objectives) - { - if (locale != LocaleConstant.enUS) + foreach (QuestObjective questObjective in queryQuestInfoResponse.Info.Objectives) { QuestObjectivesLocale questObjectivesLocaleData = Global.ObjectMgr.GetQuestObjectivesLocale(questObjective.ID); if (questObjectivesLocaleData != null) - ObjectManager.GetLocaleString(questObjectivesLocaleData.Description, locale, ref questObjective.Description); + ObjectManager.GetLocaleString(questObjectivesLocaleData.Description, loc, ref questObjective.Description); } - packet.Info.Objectives.Add(questObjective); } - for (int i = 0; i < SharedConst.QuestRewardCurrencyCount; ++i) - { - packet.Info.RewardCurrencyID[i] = quest.RewardCurrencyId[i]; - packet.Info.RewardCurrencyQty[i] = quest.RewardCurrencyCount[i]; - } - - packet.Info.AcceptedSoundKitID = quest.SoundAccept; - packet.Info.CompleteSoundKitID = quest.SoundTurnIn; - packet.Info.AreaGroupID = quest.AreaGroupID; - packet.Info.TimeAllowed = quest.LimitTime; - - _session.SendPacket(packet); + _session.SendPacket(queryQuestInfoResponse); } public void SendQuestGiverOfferReward(Quest quest, ObjectGuid npcGUID, bool autoLaunched) diff --git a/Source/Game/Entities/GameObject/GameObjectData.cs b/Source/Game/Entities/GameObject/GameObjectData.cs index da6560842..86c6aeffb 100644 --- a/Source/Game/Entities/GameObject/GameObjectData.cs +++ b/Source/Game/Entities/GameObject/GameObjectData.cs @@ -20,6 +20,8 @@ using Framework.Constants; using Framework.GameMath; using System.Collections.Generic; using System.Runtime.InteropServices; +using Game.Network; +using Game.Network.Packets; namespace Game.Entities { @@ -209,6 +211,9 @@ namespace Game.Entities [FieldOffset(68)] public raw Raw; + [FieldOffset(208)] + public QueryGameObjectResponse QueryData; + // helpers public bool IsDespawnAtAction() { @@ -513,6 +518,41 @@ namespace Game.Entities } } + public void InitializeQueryData() + { + QueryData = new QueryGameObjectResponse(); + + QueryData.GameObjectID = entry; + QueryData.Allow = true; + + GameObjectStats stats = new GameObjectStats(); + stats.Type = (uint)type; + stats.DisplayID = displayId; + + stats.Name[0] = name; + stats.IconName = IconName; + stats.CastBarCaption = castBarCaption; + stats.UnkString = unk1; + + stats.Size = size; + + var items = Global.ObjectMgr.GetGameObjectQuestItemList(entry); + foreach (uint item in items) + stats.QuestItems.Add(item); + + unsafe + { + fixed (int* ptr = Raw.data) + { + for (int i = 0; i < SharedConst.MaxGOData; i++) + stats.Data[i] = ptr[i]; + } + } + stats.RequiredLevel = (uint)RequiredLevel; + + QueryData.Stats = stats; + } + #region TypeStructs public unsafe struct raw { diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index 7159865a9..f5ad6a1e7 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -32,6 +32,8 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using Framework.Dynamic; +using Framework.IO; +using Game.Network; namespace Game { @@ -1422,7 +1424,7 @@ namespace Game List evt_scripts = new List(); // Load all possible script entries from gameobjects - foreach (var go in gameObjectTemplateStorage) + foreach (var go in _gameObjectTemplateStorage) { uint eventId = go.Value.GetEventScriptId(); if (eventId != 0) @@ -1720,10 +1722,10 @@ namespace Game LoadCreatureTemplateModels(); // Checking needs to be done after loading because of the difficulty self referencing - foreach (var template in creatureTemplateStorage.Values) + foreach (var template in _creatureTemplateStorage.Values) CheckCreatureTemplate(template); - Log.outInfo(LogFilter.ServerLoading, "Loaded {0} creature definitions in {1} ms", creatureTemplateStorage.Count, Time.GetMSTimeDiffToNow(time)); + Log.outInfo(LogFilter.ServerLoading, "Loaded {0} creature definitions in {1} ms", _creatureTemplateStorage.Count, Time.GetMSTimeDiffToNow(time)); } public void LoadCreatureTemplate(SQLFields fields) { @@ -1804,7 +1806,7 @@ namespace Game creature.FlagsExtra = (CreatureFlagsExtra)fields.Read(76); creature.ScriptID = GetScriptId(fields.Read(77)); - creatureTemplateStorage.Add(entry, creature); + _creatureTemplateStorage.Add(entry, creature); } void LoadCreatureTemplateModels() @@ -2095,7 +2097,7 @@ namespace Game uint item = result.Read(1); uint idx = result.Read(2); - if (!creatureTemplateStorage.ContainsKey(entry)) + if (!_creatureTemplateStorage.ContainsKey(entry)) { Log.outError(LogFilter.Sql, "Table `creature_questitem` has data for nonexistent creature (entry: {0}, idx: {1}), skipped", entry, idx); continue; @@ -2246,7 +2248,7 @@ namespace Game ++count; } while (result.NextRow()); - foreach (var creatureTemplate in creatureTemplateStorage.Values) + foreach (var creatureTemplate in _creatureTemplateStorage.Values) { for (short lvl = creatureTemplate.Minlevel; lvl <= creatureTemplate.Maxlevel; ++lvl) { @@ -2339,7 +2341,7 @@ namespace Game { uint entry = result.Read(0); - var template = creatureTemplateStorage.LookupByKey(entry); + var template = _creatureTemplateStorage.LookupByKey(entry); if (template == null) { Log.outError(LogFilter.Sql, $"Creature template (Entry: {entry}) does not exist but has a record in `creature_template_scaling`"); @@ -3465,7 +3467,7 @@ namespace Game } public CreatureTemplate GetCreatureTemplate(uint entry) { - return creatureTemplateStorage.LookupByKey(entry); + return _creatureTemplateStorage.LookupByKey(entry); } public CreatureAddon GetCreatureTemplateAddon(uint entry) { @@ -3477,7 +3479,7 @@ namespace Game } public Dictionary GetCreatureTemplates() { - return creatureTemplateStorage; + return _creatureTemplateStorage; } public CreatureData GetCreatureData(ulong guid) { @@ -3627,7 +3629,7 @@ namespace Game go.RequiredLevel = 0; go.ScriptId = 0; - gameObjectTemplateStorage[db2go.Id] = go; + _gameObjectTemplateStorage[db2go.Id] = go; } // 0 1 2 3 4 5 6 7 @@ -3796,7 +3798,7 @@ namespace Game break; } - gameObjectTemplateStorage[entry] = got; + _gameObjectTemplateStorage[entry] = got; ++count; } while (result.NextRow()); @@ -4184,7 +4186,7 @@ namespace Game uint item = result.Read(1); uint idx = result.Read(2); - if (!gameObjectTemplateStorage.ContainsKey(entry)) + if (!_gameObjectTemplateStorage.ContainsKey(entry)) { Log.outError(LogFilter.Sql, "Table `gameobject_questitem` has data for nonexistent gameobject (entry: {0}, idx: {1}), skipped", entry, idx); continue; @@ -4362,7 +4364,7 @@ namespace Game } public GameObjectTemplate GetGameObjectTemplate(uint entry) { - return gameObjectTemplateStorage.LookupByKey(entry); + return _gameObjectTemplateStorage.LookupByKey(entry); } public GameObjectTemplateAddon GetGameObjectTemplateAddon(uint entry) { @@ -4370,7 +4372,7 @@ namespace Game } public Dictionary GetGameObjectTemplates() { - return gameObjectTemplateStorage; + return _gameObjectTemplateStorage; } public bool IsGameObjectForQuests(uint entry) { @@ -7185,7 +7187,7 @@ namespace Game // 0 1 2 3 SQLResult points = DB.World.Query("SELECT QuestID, Idx1, X, Y FROM quest_poi_points ORDER BY QuestID DESC, Idx1, Idx2"); - Dictionary> POIs = new Dictionary>(); + Dictionary> POIs = new Dictionary>(); if (!points.IsEmpty()) { @@ -7197,9 +7199,9 @@ namespace Game int y = points.Read(3); if (!POIs.ContainsKey(questId)) - POIs[questId] = new MultiMap(); + POIs[questId] = new MultiMap(); - QuestPOIPoint point = new QuestPOIPoint(x, y); + QuestPOIBlobPoint point = new QuestPOIBlobPoint(x, y); POIs[questId].Add(Idx1, point); } while (points.NextRow()); } @@ -7224,14 +7226,17 @@ namespace Game if (Global.ObjectMgr.GetQuestTemplate(questID) == null) Log.outError(LogFilter.Sql, "`quest_poi` quest id ({0}) Idx1 ({1}) does not exist in `quest_template`", questID, idx1); - QuestPOI POI = new QuestPOI(blobIndex, objectiveIndex, questObjectiveID, questObjectID, mapID, uiMapId, priority, flags, worldEffectID, playerConditionID, spawnTrackingID, alwaysAllowMergingBlobs); if (!POIs.ContainsKey(questID) || !POIs[questID].ContainsKey(idx1)) { Log.outError(LogFilter.Sql, "Table quest_poi references unknown quest points for quest {0} POI id {1}", questID, blobIndex); continue; } - POI.points = POIs[questID][idx1]; - _questPOIStorage.Add(questID, POI); + + if (!_questPOIStorage.ContainsKey(questID)) + _questPOIStorage[questID] = new QuestPOIData(questID); + + QuestPOIData poiData = _questPOIStorage[questID]; + poiData.QuestPOIBlobDataStats.Add(new QuestPOIBlobData(blobIndex, objectiveIndex, questObjectiveID, questObjectID, mapID, uiMapId, priority, flags, worldEffectID, playerConditionID, spawnTrackingID, POIs[questID][idx1], alwaysAllowMergingBlobs)); ++count; } while (result.NextRow()); @@ -7395,7 +7400,7 @@ namespace Game { return _creatureQuestInvolvedRelationsReverse.LookupByKey(questId); } - public List GetQuestPOIList(uint questId) + public QuestPOIData GetQuestPOIData(uint questId) { return _questPOIStorage.LookupByKey(questId); } @@ -9123,6 +9128,32 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} Player Choice Response locale strings in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); } } + public void InitializeQueriesData(QueryDataGroup mask) + { + // cache disabled + if (!WorldConfig.GetBoolValue(WorldCfg.CacheDataQueries)) + return; + + // Initialize Query data for creatures + if (mask.HasAnyFlag(QueryDataGroup.Creatures)) + foreach (var creaturePair in _creatureTemplateStorage) + creaturePair.Value.InitializeQueryData(); + + // Initialize Query Data for gameobjects + if (mask.HasAnyFlag(QueryDataGroup.Gameobjects)) + foreach (var gameobjectPair in _gameObjectTemplateStorage) + gameobjectPair.Value.InitializeQueryData(); + + // Initialize Query Data for quests + if (mask.HasAnyFlag(QueryDataGroup.Quests)) + foreach (var questPair in _questTemplates) + questPair.Value.InitializeQueryData(); + + // Initialize Quest POI data + if (mask.HasAnyFlag(QueryDataGroup.POIs)) + foreach (var poiPair in _questPOIStorage) + poiPair.Value.InitializeQueryData(); + } public MailLevelReward GetMailLevelReward(uint level, ulong raceMask) { @@ -9644,7 +9675,7 @@ namespace Game MultiMap _creatureQuestInvolvedRelations = new MultiMap(); MultiMap _creatureQuestInvolvedRelationsReverse = new MultiMap(); public MultiMap _exclusiveQuestGroups = new MultiMap(); - MultiMap _questPOIStorage = new MultiMap(); + Dictionary _questPOIStorage = new Dictionary(); MultiMap _questAreaTriggerStorage = new MultiMap(); Dictionary _questObjectives = new Dictionary(); Dictionary[] _questGreetingStorage = new Dictionary[2]; @@ -9680,7 +9711,7 @@ namespace Game Dictionary pointsOfInterestStorage = new Dictionary(); //Creature - Dictionary creatureTemplateStorage = new Dictionary(); + Dictionary _creatureTemplateStorage = new Dictionary(); Dictionary creatureModelStorage = new Dictionary(); Dictionary creatureDataStorage = new Dictionary(); Dictionary creatureAddonStorage = new Dictionary(); @@ -9697,7 +9728,7 @@ namespace Game Dictionary _npcTextStorage = new Dictionary(); //GameObject - Dictionary gameObjectTemplateStorage = new Dictionary(); + Dictionary _gameObjectTemplateStorage = new Dictionary(); Dictionary gameObjectDataStorage = new Dictionary(); Dictionary _gameObjectTemplateAddonStore = new Dictionary(); Dictionary _gameObjectAddonStorage = new Dictionary(); @@ -10126,10 +10157,10 @@ namespace Game public uint team; } - public class QuestPOI + public class QuestPOIBlobData { - public QuestPOI(int blobIndex, int objectiveIndex, int questObjectiveID, int questObjectID, int mapID, int uiMapID, int priority, int flags, - int worldEffectID, int playerConditionID, int spawnTrackingID, bool alwaysAllowMergingBlobs) + public QuestPOIBlobData(int blobIndex, int objectiveIndex, int questObjectiveID, int questObjectID, int mapID, int uiMapID, int priority, int flags, + int worldEffectID, int playerConditionID, int spawnTrackingID, List questPOIBlobPointStats, bool alwaysAllowMergingBlobs) { BlobIndex = blobIndex; ObjectiveIndex = objectiveIndex; @@ -10142,6 +10173,7 @@ namespace Game WorldEffectID = worldEffectID; PlayerConditionID = playerConditionID; SpawnTrackingID = spawnTrackingID; + QuestPOIBlobPointStats = questPOIBlobPointStats; AlwaysAllowMergingBlobs = alwaysAllowMergingBlobs; } @@ -10156,13 +10188,13 @@ namespace Game public int WorldEffectID; public int PlayerConditionID; public int SpawnTrackingID; - public List points = new List(); + public List QuestPOIBlobPointStats; public bool AlwaysAllowMergingBlobs; } - public class QuestPOIPoint + public class QuestPOIBlobPoint { - public QuestPOIPoint(int _x, int _y) + public QuestPOIBlobPoint(int _x, int _y) { X = _x; Y = _y; @@ -10172,6 +10204,54 @@ namespace Game public int Y; } + public class QuestPOIData + { + public uint QuestID; + public List QuestPOIBlobDataStats = new List(); + public ByteBuffer QueryDataBuffer = new ByteBuffer(); + + public QuestPOIData(uint questId) + { + QuestID = questId; + } + + public void InitializeQueryData() + { + Write(QueryDataBuffer); + } + + public void Write(ByteBuffer data) + { + data.WriteUInt32(QuestID); + data.WriteInt32(QuestPOIBlobDataStats.Count); + + foreach (QuestPOIBlobData questPOIBlobData in QuestPOIBlobDataStats) + { + data.WriteInt32(questPOIBlobData.BlobIndex); + data.WriteInt32(questPOIBlobData.ObjectiveIndex); + data.WriteInt32(questPOIBlobData.QuestObjectiveID); + data.WriteInt32(questPOIBlobData.QuestObjectID); + data.WriteInt32(questPOIBlobData.MapID); + data.WriteInt32(questPOIBlobData.UiMapID); + data.WriteInt32(questPOIBlobData.Priority); + data.WriteInt32(questPOIBlobData.Flags); + data.WriteInt32(questPOIBlobData.WorldEffectID); + data.WriteInt32(questPOIBlobData.PlayerConditionID); + data.WriteInt32(questPOIBlobData.SpawnTrackingID); + data.WriteInt32(questPOIBlobData.QuestPOIBlobPointStats.Count); + + foreach (QuestPOIBlobPoint questPOIBlobPoint in questPOIBlobData.QuestPOIBlobPointStats) + { + data.WriteInt32(questPOIBlobPoint.X); + data.WriteInt32(questPOIBlobPoint.Y); + } + + data.WriteBit(questPOIBlobData.AlwaysAllowMergingBlobs); + data.FlushBits(); + } + } + } + public class AreaTriggerStruct { public uint target_mapId; diff --git a/Source/Game/Handlers/QueryHandler.cs b/Source/Game/Handlers/QueryHandler.cs index a1c983026..838426749 100644 --- a/Source/Game/Handlers/QueryHandler.cs +++ b/Source/Game/Handlers/QueryHandler.cs @@ -67,128 +67,76 @@ namespace Game [WorldPacketHandler(ClientOpcodes.QueryGameObject, Processing = PacketProcessing.Inplace)] void HandleGameObjectQuery(QueryGameObject packet) { - QueryGameObjectResponse response = new QueryGameObjectResponse(); - response.GameObjectID = packet.GameObjectID; - - GameObjectTemplate gameObjectInfo = Global.ObjectMgr.GetGameObjectTemplate(packet.GameObjectID); - if (gameObjectInfo != null) + GameObjectTemplate info = Global.ObjectMgr.GetGameObjectTemplate(packet.GameObjectID); + if (info != null) { - response.Allow = true; - GameObjectStats stats = new GameObjectStats(); + if (!WorldConfig.GetBoolValue(WorldCfg.CacheDataQueries)) + info.InitializeQueryData(); - stats.Type = (uint)gameObjectInfo.type; - stats.DisplayID = gameObjectInfo.displayId; + QueryGameObjectResponse queryGameObjectResponse = info.QueryData; - stats.Name[0] = gameObjectInfo.name; - stats.IconName = gameObjectInfo.IconName; - stats.CastBarCaption = gameObjectInfo.castBarCaption; - stats.UnkString = gameObjectInfo.unk1; - - LocaleConstant localeConstant = GetSessionDbLocaleIndex(); - if (localeConstant != LocaleConstant.enUS) + LocaleConstant loc = GetSessionDbLocaleIndex(); + if (loc != LocaleConstant.enUS) { - GameObjectLocale gameObjectLocale = Global.ObjectMgr.GetGameObjectLocale(packet.GameObjectID); + GameObjectLocale gameObjectLocale = Global.ObjectMgr.GetGameObjectLocale(queryGameObjectResponse.GameObjectID); if (gameObjectLocale != null) { - ObjectManager.GetLocaleString(gameObjectLocale.Name, localeConstant, ref stats.Name[0]); - ObjectManager.GetLocaleString(gameObjectLocale.CastBarCaption, localeConstant, ref stats.CastBarCaption); - ObjectManager.GetLocaleString(gameObjectLocale.Unk1, localeConstant, ref stats.UnkString); + ObjectManager.GetLocaleString(gameObjectLocale.Name, loc, ref queryGameObjectResponse.Stats.Name[0]); + ObjectManager.GetLocaleString(gameObjectLocale.CastBarCaption, loc, ref queryGameObjectResponse.Stats.CastBarCaption); + ObjectManager.GetLocaleString(gameObjectLocale.Unk1, loc, ref queryGameObjectResponse.Stats.UnkString); } } - var items = Global.ObjectMgr.GetGameObjectQuestItemList(packet.GameObjectID); - foreach (uint item in items) - stats.QuestItems.Add(item); - - unsafe - { - fixed (int* ptr = gameObjectInfo.Raw.data) - { - for (int i = 0; i < SharedConst.MaxGOData; i++) - stats.Data[i] = ptr[i]; - } - } - stats.RequiredLevel = (uint)gameObjectInfo.RequiredLevel; - response.Stats = stats; + SendPacket(queryGameObjectResponse); } + else + { + Log.outDebug(LogFilter.Network, $"WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (ENTRY: {packet.GameObjectID})"); - SendPacket(response); + QueryGameObjectResponse response = new QueryGameObjectResponse(); + response.GameObjectID = packet.GameObjectID; + SendPacket(response); + } } [WorldPacketHandler(ClientOpcodes.QueryCreature, Processing = PacketProcessing.Inplace)] void HandleCreatureQuery(QueryCreature packet) { - QueryCreatureResponse response = new QueryCreatureResponse(); - - response.CreatureID = packet.CreatureID; - - CreatureTemplate creatureInfo = Global.ObjectMgr.GetCreatureTemplate(packet.CreatureID); - if (creatureInfo != null) + CreatureTemplate ci = Global.ObjectMgr.GetCreatureTemplate(packet.CreatureID); + if (ci != null) { - response.Allow = true; + if (!WorldConfig.GetBoolValue(WorldCfg.CacheDataQueries)) + ci.InitializeQueryData(); - CreatureStats stats = new CreatureStats(); + QueryCreatureResponse queryCreatureResponse = ci.QueryData; - stats.Leader = creatureInfo.RacialLeader; - - string name = creatureInfo.Name; - string nameAlt = creatureInfo.FemaleName; - - stats.Flags[0] = (uint)creatureInfo.TypeFlags; - stats.Flags[1] = creatureInfo.TypeFlags2; - - stats.CreatureType = (int)creatureInfo.CreatureType; - stats.CreatureFamily = (int)creatureInfo.Family; - stats.Classification = (int)creatureInfo.Rank; - - for (uint i = 0; i < SharedConst.MaxCreatureKillCredit; ++i) - stats.ProxyCreatureID[i] = creatureInfo.KillCredit[i]; - - foreach (var model in creatureInfo.Models) + LocaleConstant loc = GetSessionDbLocaleIndex(); + if (loc != LocaleConstant.enUS) { - stats.Display.TotalProbability += model.Probability; - stats.Display.CreatureDisplay.Add(new CreatureXDisplay(model.CreatureDisplayID, model.DisplayScale, model.Probability)); - } - - stats.HpMulti = creatureInfo.ModHealth; - stats.EnergyMulti = creatureInfo.ModMana; - - stats.CreatureMovementInfoID = creatureInfo.MovementId; - stats.RequiredExpansion = creatureInfo.RequiredExpansion; - stats.HealthScalingExpansion = creatureInfo.HealthScalingExpansion; - stats.VignetteID = creatureInfo.VignetteID; - stats.Class = (int)creatureInfo.UnitClass; - stats.FadeRegionRadius = creatureInfo.FadeRegionRadius; - stats.WidgetSetID = creatureInfo.WidgetSetID; - stats.WidgetSetUnitConditionID = creatureInfo.WidgetSetUnitConditionID; - - stats.Title = creatureInfo.SubName; - stats.TitleAlt = creatureInfo.TitleAlt; - stats.CursorName = creatureInfo.IconName; - - var items = Global.ObjectMgr.GetCreatureQuestItemList(packet.CreatureID); - foreach (uint item in items) - stats.QuestItems.Add(item); - - LocaleConstant localeConstant = GetSessionDbLocaleIndex(); - if (localeConstant != LocaleConstant.enUS) - { - CreatureLocale creatureLocale = Global.ObjectMgr.GetCreatureLocale(packet.CreatureID); + CreatureLocale creatureLocale = Global.ObjectMgr.GetCreatureLocale(ci.Entry); if (creatureLocale != null) { - ObjectManager.GetLocaleString(creatureLocale.Name, localeConstant, ref name); - ObjectManager.GetLocaleString(creatureLocale.NameAlt, localeConstant, ref nameAlt); - ObjectManager.GetLocaleString(creatureLocale.Title, localeConstant, ref stats.Title); - ObjectManager.GetLocaleString(creatureLocale.TitleAlt, localeConstant, ref stats.TitleAlt); + string name = queryCreatureResponse.Stats.Name[0]; + string nameAlt = queryCreatureResponse.Stats.NameAlt[0]; + + ObjectManager.GetLocaleString(creatureLocale.Name, loc, ref name); + ObjectManager.GetLocaleString(creatureLocale.NameAlt, loc, ref nameAlt); + ObjectManager.GetLocaleString(creatureLocale.Title, loc, ref queryCreatureResponse.Stats.Title); + ObjectManager.GetLocaleString(creatureLocale.TitleAlt, loc, ref queryCreatureResponse.Stats.TitleAlt); + + queryCreatureResponse.Stats.Name[0] = name; + queryCreatureResponse.Stats.NameAlt[0] = nameAlt; } } - stats.Name[0] = name; - stats.NameAlt[0] = nameAlt; - - response.Stats = stats; } + else + { + Log.outDebug(LogFilter.Network, $"WORLD: CMSG_QUERY_CREATURE - NO CREATURE INFO! (ENTRY: {packet.CreatureID})"); - SendPacket(response); + QueryCreatureResponse response = new QueryCreatureResponse(); + response.CreatureID = packet.CreatureID; + SendPacket(response); + } } [WorldPacketHandler(ClientOpcodes.QueryNpcText)] @@ -368,49 +316,13 @@ namespace Game QuestPOIQueryResponse response = new QuestPOIQueryResponse(); - foreach (var QuestID in questIds) + foreach (uint questId in questIds) { - bool questOk = false; - - ushort questSlot = GetPlayer().FindQuestSlot(QuestID); - - if (questSlot != SharedConst.MaxQuestLogSize) - questOk = GetPlayer().GetQuestSlotQuestId(questSlot) == QuestID; - - if (questOk) + if (_player.FindQuestSlot(questId) != SharedConst.MaxQuestLogSize) { - var poiData = Global.ObjectMgr.GetQuestPOIList(QuestID); + QuestPOIData poiData = Global.ObjectMgr.GetQuestPOIData(questId); if (poiData != null) - { - QuestPOIData questPOIData = new QuestPOIData(); - - questPOIData.QuestID = QuestID; - - foreach (var data in poiData) - { - QuestPOIBlobData questPOIBlobData = new QuestPOIBlobData(); - - questPOIBlobData.BlobIndex = data.BlobIndex; - questPOIBlobData.ObjectiveIndex = data.ObjectiveIndex; - questPOIBlobData.QuestObjectiveID = data.QuestObjectiveID; - questPOIBlobData.QuestObjectID = data.QuestObjectID; - questPOIBlobData.MapID = data.MapID; - questPOIBlobData.UiMapID = data.UiMapID; - questPOIBlobData.Priority = data.Priority; - questPOIBlobData.Flags = data.Flags; - questPOIBlobData.WorldEffectID = data.WorldEffectID; - questPOIBlobData.PlayerConditionID = data.PlayerConditionID; - questPOIBlobData.SpawnTrackingID = data.SpawnTrackingID; - questPOIBlobData.AlwaysAllowMergingBlobs = data.AlwaysAllowMergingBlobs; - - foreach (var point in data.points) - questPOIBlobData.QuestPOIBlobPointStats.Add(new QuestPOIBlobPoint(point.X, point.Y)); - - questPOIData.QuestPOIBlobDataStats.Add(questPOIBlobData); - } - - response.QuestPOIDataStats.Add(questPOIData); - } + response.QuestPOIDataStats.Add(poiData); } } diff --git a/Source/Game/Network/Packets/QueryPackets.cs b/Source/Game/Network/Packets/QueryPackets.cs index ae7e98415..814b3d83f 100644 --- a/Source/Game/Network/Packets/QueryPackets.cs +++ b/Source/Game/Network/Packets/QueryPackets.cs @@ -421,36 +421,14 @@ namespace Game.Network.Packets _worldPacket.WriteInt32(QuestPOIDataStats.Count); _worldPacket.WriteInt32(QuestPOIDataStats.Count); + bool useCache = WorldConfig.GetBoolValue(WorldCfg.CacheDataQueries); + foreach (QuestPOIData questPOIData in QuestPOIDataStats) { - _worldPacket.WriteUInt32(questPOIData.QuestID); - - _worldPacket.WriteInt32(questPOIData.QuestPOIBlobDataStats.Count); - - foreach (QuestPOIBlobData questPOIBlobData in questPOIData.QuestPOIBlobDataStats) - { - _worldPacket.WriteInt32(questPOIBlobData.BlobIndex); - _worldPacket.WriteInt32(questPOIBlobData.ObjectiveIndex); - _worldPacket.WriteInt32(questPOIBlobData.QuestObjectiveID); - _worldPacket.WriteInt32(questPOIBlobData.QuestObjectID); - _worldPacket.WriteInt32(questPOIBlobData.MapID); - _worldPacket.WriteInt32(questPOIBlobData.UiMapID); - _worldPacket.WriteInt32(questPOIBlobData.Priority); - _worldPacket.WriteInt32(questPOIBlobData.Flags); - _worldPacket.WriteInt32(questPOIBlobData.WorldEffectID); - _worldPacket.WriteInt32(questPOIBlobData.PlayerConditionID); - _worldPacket.WriteInt32(questPOIBlobData.SpawnTrackingID); - _worldPacket.WriteInt32(questPOIBlobData.QuestPOIBlobPointStats.Count); - - foreach (QuestPOIBlobPoint questPOIBlobPoint in questPOIBlobData.QuestPOIBlobPointStats) - { - _worldPacket.WriteInt32(questPOIBlobPoint.X); - _worldPacket.WriteInt32(questPOIBlobPoint.Y); - } - - _worldPacket.WriteBit(questPOIBlobData.AlwaysAllowMergingBlobs); - _worldPacket.FlushBits(); - } + if (useCache) + _worldPacket.WriteBytes(questPOIData.QueryDataBuffer); + else + questPOIData.Write(_worldPacket); } } @@ -771,41 +749,6 @@ namespace Game.Network.Packets public uint RequiredLevel; } - public struct QuestPOIBlobPoint - { - public QuestPOIBlobPoint(int x, int y) - { - X = x; - Y = y; - } - - public int X; - public int Y; - } - - public class QuestPOIBlobData - { - public int BlobIndex; - public int ObjectiveIndex; - public int QuestObjectiveID; - public int QuestObjectID; - public int MapID; - public int UiMapID; - public int Priority; - public int Flags; - public int WorldEffectID; - public int PlayerConditionID; - public int SpawnTrackingID; - public List QuestPOIBlobPointStats = new List(); - public bool AlwaysAllowMergingBlobs; - } - - public class QuestPOIData - { - public uint QuestID; - public List QuestPOIBlobDataStats = new List(); - } - class QuestCompletionNPC { public uint QuestID; diff --git a/Source/Game/Quest/Quest.cs b/Source/Game/Quest/Quest.cs index 7e759b0b8..28183d6cf 100644 --- a/Source/Game/Quest/Quest.cs +++ b/Source/Game/Quest/Quest.cs @@ -23,6 +23,7 @@ using Game.Entities; using Game.Network.Packets; using System; using System.Collections.Generic; +using Game.Network; namespace Game { @@ -402,6 +403,120 @@ namespace Game return (!IsDFQuest() && !IsDaily() && (!IsRepeatable() || IsWeekly() || IsMonthly() || IsSeasonal())); } + public void InitializeQueryData() + { + QueryData = new QueryQuestInfoResponse(); + + QueryData.Allow = true; + QueryData.QuestID = Id; + + QueryData.Info.LogTitle = LogTitle; + QueryData.Info.LogDescription = LogDescription; + QueryData.Info.QuestDescription = QuestDescription; + QueryData.Info.AreaDescription = AreaDescription; + QueryData.Info.QuestCompletionLog = QuestCompletionLog; + QueryData.Info.PortraitGiverText = PortraitGiverText; + QueryData.Info.PortraitGiverName = PortraitGiverName; + QueryData.Info.PortraitTurnInText = PortraitTurnInText; + QueryData.Info.PortraitTurnInName = PortraitTurnInName; + + QueryData.Info.QuestID = Id; + QueryData.Info.QuestType = (int)Type; + QueryData.Info.QuestLevel = Level; + QueryData.Info.QuestScalingFactionGroup = ScalingFactionGroup; + QueryData.Info.QuestMaxScalingLevel = MaxScalingLevel; + QueryData.Info.QuestPackageID = PackageID; + QueryData.Info.QuestMinLevel = MinLevel; + QueryData.Info.QuestSortID = QuestSortID; + QueryData.Info.QuestInfoID = QuestInfoID; + QueryData.Info.SuggestedGroupNum = SuggestedPlayers; + QueryData.Info.RewardNextQuest = NextQuestInChain; + QueryData.Info.RewardXPDifficulty = RewardXPDifficulty; + QueryData.Info.RewardXPMultiplier = RewardXPMultiplier; + + if (!HasFlag(QuestFlags.HiddenRewards)) + QueryData.Info.RewardMoney = RewardMoney; + + QueryData.Info.RewardMoneyDifficulty = RewardMoneyDifficulty; + QueryData.Info.RewardMoneyMultiplier = RewardMoneyMultiplier; + QueryData.Info.RewardBonusMoney = RewardBonusMoney; + for (byte i = 0; i < SharedConst.QuestRewardDisplaySpellCount; ++i) + QueryData.Info.RewardDisplaySpell[i] = RewardDisplaySpell[i]; + + QueryData.Info.RewardSpell = RewardSpell; + + QueryData.Info.RewardHonor = RewardHonor; + QueryData.Info.RewardKillHonor = RewardKillHonor; + + QueryData.Info.RewardArtifactXPDifficulty = (int)RewardArtifactXPDifficulty; + QueryData.Info.RewardArtifactXPMultiplier = RewardArtifactXPMultiplier; + QueryData.Info.RewardArtifactCategoryID = (int)RewardArtifactCategoryID; + + QueryData.Info.StartItem = SourceItemId; + QueryData.Info.Flags = (uint)Flags; + QueryData.Info.FlagsEx = (uint)FlagsEx; + QueryData.Info.FlagsEx2 = (uint)FlagsEx2; + QueryData.Info.RewardTitle = RewardTitleId; + QueryData.Info.RewardArenaPoints = RewardArenaPoints; + QueryData.Info.RewardSkillLineID = RewardSkillId; + QueryData.Info.RewardNumSkillUps = RewardSkillPoints; + QueryData.Info.RewardFactionFlags = RewardReputationMask; + QueryData.Info.PortraitGiver = QuestGiverPortrait; + QueryData.Info.PortraitGiverMount = QuestGiverPortraitMount; + QueryData.Info.PortraitTurnIn = QuestTurnInPortrait; + + for (byte i = 0; i < SharedConst.QuestItemDropCount; ++i) + { + QueryData.Info.ItemDrop[i] = (int)ItemDrop[i]; + QueryData.Info.ItemDropQuantity[i] = (int)ItemDropQuantity[i]; + } + + if (!HasFlag(QuestFlags.HiddenRewards)) + { + for (byte i = 0; i < SharedConst.QuestRewardItemCount; ++i) + { + QueryData.Info.RewardItems[i] = RewardItemId[i]; + QueryData.Info.RewardAmount[i] = RewardItemCount[i]; + } + for (byte i = 0; i < SharedConst.QuestRewardChoicesCount; ++i) + { + QueryData.Info.UnfilteredChoiceItems[i].ItemID = RewardChoiceItemId[i]; + QueryData.Info.UnfilteredChoiceItems[i].Quantity = RewardChoiceItemCount[i]; + } + } + + for (byte i = 0; i < SharedConst.QuestRewardReputationsCount; ++i) + { + QueryData.Info.RewardFactionID[i] = RewardFactionId[i]; + QueryData.Info.RewardFactionValue[i] = RewardFactionValue[i]; + QueryData.Info.RewardFactionOverride[i] = RewardFactionOverride[i]; + QueryData.Info.RewardFactionCapIn[i] = (int)RewardFactionCapIn[i]; + } + + QueryData.Info.POIContinent = POIContinent; + QueryData.Info.POIx = POIx; + QueryData.Info.POIy = POIy; + QueryData.Info.POIPriority = POIPriority; + + QueryData.Info.AllowableRaces = AllowableRaces; + QueryData.Info.TreasurePickerID = (int)TreasurePickerID; + QueryData.Info.Expansion = Expansion; + + foreach (QuestObjective questObjective in Objectives) + QueryData.Info.Objectives.Add(questObjective); + + for (int i = 0; i < SharedConst.QuestRewardCurrencyCount; ++i) + { + QueryData.Info.RewardCurrencyID[i] = RewardCurrencyId[i]; + QueryData.Info.RewardCurrencyQty[i] = RewardCurrencyCount[i]; + } + + QueryData.Info.AcceptedSoundKitID = SoundAccept; + QueryData.Info.CompleteSoundKitID = SoundTurnIn; + QueryData.Info.AreaGroupID = AreaGroupID; + QueryData.Info.TimeAllowed = LimitTime; + } + public bool HasFlag(QuestFlags flag) { return (Flags & flag) != 0; } public bool HasFlagEx(QuestFlagsEx flag) { return (FlagsEx & flag) != 0; } public bool HasFlagEx(QuestFlagsEx2 flag) { return (FlagsEx2 & flag) != 0; } @@ -541,6 +656,7 @@ namespace Game public List prevQuests = new List(); public List prevChainQuests = new List(); + public QueryQuestInfoResponse QueryData; uint _rewChoiceItemsCount; uint _rewItemsCount; diff --git a/Source/Game/Server/WorldConfig.cs b/Source/Game/Server/WorldConfig.cs index 620e4290a..be1ea11ed 100644 --- a/Source/Game/Server/WorldConfig.cs +++ b/Source/Game/Server/WorldConfig.cs @@ -910,6 +910,9 @@ namespace Game // Allow 5-man parties to use raid warnings Values[WorldCfg.ChatPartyRaidWarnings] = GetDefaultValue("PartyRaidWarnings", false); + // Allow to cache data queries + Values[WorldCfg.CacheDataQueries] = GetDefaultValue("CacheDataQueries", true); + // Check Invalid Position Values[WorldCfg.CreatureCheckInvalidPostion] = GetDefaultValue("Creature.CheckInvalidPosition", false); Values[WorldCfg.GameobjectCheckInvalidPostion] = GetDefaultValue("GameObject.CheckInvalidPosition", false); diff --git a/Source/Game/Server/WorldManager.cs b/Source/Game/Server/WorldManager.cs index 38b944de8..91564375a 100644 --- a/Source/Game/Server/WorldManager.cs +++ b/Source/Game/Server/WorldManager.cs @@ -836,6 +836,9 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, "Loading Calendar data..."); Global.CalendarMgr.LoadFromDB(); + Log.outInfo(LogFilter.ServerLoading, "Initialize query data..."); + Global.ObjectMgr.InitializeQueriesData(QueryDataGroup.All); + // Initialize game time and timers Log.outInfo(LogFilter.ServerLoading, "Initialize game time and timers"); m_gameTime = Time.UnixTime; diff --git a/Source/WorldServer/WorldServer.conf.dist b/Source/WorldServer/WorldServer.conf.dist index 40d33e5cc..d3940acd1 100644 --- a/Source/WorldServer/WorldServer.conf.dist +++ b/Source/WorldServer/WorldServer.conf.dist @@ -1198,6 +1198,17 @@ Account.PasswordChangeSecurity = 0 BirthdayTime = 1222964635 +# +# CacheDataQueries +# Description: Server caches data queries at startup. +# Can be disabled if not enough memory is available. +# Default: 1 - (Enabled) +# 0 - (Disabled) +# +# + + CacheDataQueries = 1 + # # FeatureSystem.BpayStore.Enabled # Description: Not yet implemented