Core/Cache: Implement QueryCache system
Ideas/Port From (https://github.com/TrinityCore/TrinityCore/commit/b4d30bb92cbfc8411d8d91b0f4f2981f2cecc148)
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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<uint> evt_scripts = new List<uint>();
|
||||
// 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<uint>(76);
|
||||
creature.ScriptID = GetScriptId(fields.Read<string>(77));
|
||||
|
||||
creatureTemplateStorage.Add(entry, creature);
|
||||
_creatureTemplateStorage.Add(entry, creature);
|
||||
}
|
||||
|
||||
void LoadCreatureTemplateModels()
|
||||
@@ -2095,7 +2097,7 @@ namespace Game
|
||||
uint item = result.Read<uint>(1);
|
||||
uint idx = result.Read<uint>(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<uint>(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<uint, CreatureTemplate> 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<uint>(1);
|
||||
uint idx = result.Read<uint>(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<uint, GameObjectTemplate> 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<uint, MultiMap<int, QuestPOIPoint>> POIs = new Dictionary<uint, MultiMap<int, QuestPOIPoint>>();
|
||||
Dictionary<uint, MultiMap<int, QuestPOIBlobPoint>> POIs = new Dictionary<uint, MultiMap<int, QuestPOIBlobPoint>>();
|
||||
|
||||
if (!points.IsEmpty())
|
||||
{
|
||||
@@ -7197,9 +7199,9 @@ namespace Game
|
||||
int y = points.Read<int>(3);
|
||||
|
||||
if (!POIs.ContainsKey(questId))
|
||||
POIs[questId] = new MultiMap<int, QuestPOIPoint>();
|
||||
POIs[questId] = new MultiMap<int, QuestPOIBlobPoint>();
|
||||
|
||||
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<QuestPOI> 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<uint, uint> _creatureQuestInvolvedRelations = new MultiMap<uint, uint>();
|
||||
MultiMap<uint, uint> _creatureQuestInvolvedRelationsReverse = new MultiMap<uint, uint>();
|
||||
public MultiMap<int, uint> _exclusiveQuestGroups = new MultiMap<int, uint>();
|
||||
MultiMap<uint, QuestPOI> _questPOIStorage = new MultiMap<uint, QuestPOI>();
|
||||
Dictionary<uint, QuestPOIData> _questPOIStorage = new Dictionary<uint, QuestPOIData>();
|
||||
MultiMap<uint, uint> _questAreaTriggerStorage = new MultiMap<uint, uint>();
|
||||
Dictionary<uint, QuestObjective> _questObjectives = new Dictionary<uint, QuestObjective>();
|
||||
Dictionary<uint, QuestGreeting>[] _questGreetingStorage = new Dictionary<uint, QuestGreeting>[2];
|
||||
@@ -9680,7 +9711,7 @@ namespace Game
|
||||
Dictionary<uint, PointOfInterest> pointsOfInterestStorage = new Dictionary<uint, PointOfInterest>();
|
||||
|
||||
//Creature
|
||||
Dictionary<uint, CreatureTemplate> creatureTemplateStorage = new Dictionary<uint, CreatureTemplate>();
|
||||
Dictionary<uint, CreatureTemplate> _creatureTemplateStorage = new Dictionary<uint, CreatureTemplate>();
|
||||
Dictionary<uint, CreatureModelInfo> creatureModelStorage = new Dictionary<uint, CreatureModelInfo>();
|
||||
Dictionary<ulong, CreatureData> creatureDataStorage = new Dictionary<ulong, CreatureData>();
|
||||
Dictionary<ulong, CreatureAddon> creatureAddonStorage = new Dictionary<ulong, CreatureAddon>();
|
||||
@@ -9697,7 +9728,7 @@ namespace Game
|
||||
Dictionary<uint, NpcText> _npcTextStorage = new Dictionary<uint, NpcText>();
|
||||
|
||||
//GameObject
|
||||
Dictionary<uint, GameObjectTemplate> gameObjectTemplateStorage = new Dictionary<uint, GameObjectTemplate>();
|
||||
Dictionary<uint, GameObjectTemplate> _gameObjectTemplateStorage = new Dictionary<uint, GameObjectTemplate>();
|
||||
Dictionary<ulong, GameObjectData> gameObjectDataStorage = new Dictionary<ulong, GameObjectData>();
|
||||
Dictionary<ulong, GameObjectTemplateAddon> _gameObjectTemplateAddonStore = new Dictionary<ulong, GameObjectTemplateAddon>();
|
||||
Dictionary<ulong, GameObjectAddon> _gameObjectAddonStorage = new Dictionary<ulong, GameObjectAddon>();
|
||||
@@ -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<QuestPOIBlobPoint> 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<QuestPOIPoint> points = new List<QuestPOIPoint>();
|
||||
public List<QuestPOIBlobPoint> 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<QuestPOIBlobData> QuestPOIBlobDataStats = new List<QuestPOIBlobData>();
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<QuestPOIBlobPoint> QuestPOIBlobPointStats = new List<QuestPOIBlobPoint>();
|
||||
public bool AlwaysAllowMergingBlobs;
|
||||
}
|
||||
|
||||
public class QuestPOIData
|
||||
{
|
||||
public uint QuestID;
|
||||
public List<QuestPOIBlobData> QuestPOIBlobDataStats = new List<QuestPOIBlobData>();
|
||||
}
|
||||
|
||||
class QuestCompletionNPC
|
||||
{
|
||||
public uint QuestID;
|
||||
|
||||
@@ -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<int> prevQuests = new List<int>();
|
||||
public List<uint> prevChainQuests = new List<uint>();
|
||||
public QueryQuestInfoResponse QueryData;
|
||||
|
||||
uint _rewChoiceItemsCount;
|
||||
uint _rewItemsCount;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user