From 1106aa3659906aa66d27c1532784d7ec315e45ec Mon Sep 17 00:00:00 2001 From: hondacrx Date: Fri, 27 Apr 2018 15:09:38 -0400 Subject: [PATCH] Core/Quests: Ported quest greeting locales Core/Misc: Misc fixes --- .../RecastDetour/Detour/DetourNode.cs | 1 - Source/Game/Chat/Commands/ReloadCommand.cs | 2 + Source/Game/Entities/Creature/Gossip.cs | 27 ++-- Source/Game/Entities/Player/Player.Quest.cs | 17 ++- Source/Game/Entities/Player/Player.cs | 4 +- Source/Game/Globals/ObjectManager.cs | 115 ++++++++++++------ Source/Game/Quest/Quest.cs | 23 ++++ Source/Game/Server/WorldManager.cs | 14 +-- Source/Game/Spells/SpellManager.cs | 2 +- Source/WorldServer/Server.cs | 6 + 10 files changed, 144 insertions(+), 67 deletions(-) diff --git a/Source/Framework/RecastDetour/Detour/DetourNode.cs b/Source/Framework/RecastDetour/Detour/DetourNode.cs index bbc602bda..51b1709aa 100644 --- a/Source/Framework/RecastDetour/Detour/DetourNode.cs +++ b/Source/Framework/RecastDetour/Detour/DetourNode.cs @@ -19,7 +19,6 @@ public partial class Detour public partial class Detour { - public enum dtNodeFlags { DT_NODE_OPEN = 0x01, diff --git a/Source/Game/Chat/Commands/ReloadCommand.cs b/Source/Game/Chat/Commands/ReloadCommand.cs index 45d308895..fdc825fee 100644 --- a/Source/Game/Chat/Commands/ReloadCommand.cs +++ b/Source/Game/Chat/Commands/ReloadCommand.cs @@ -591,10 +591,12 @@ namespace Game.Chat Log.outInfo(LogFilter.Server, "Re-Loading Quest Locale ... "); Global.ObjectMgr.LoadQuestTemplateLocale(); Global.ObjectMgr.LoadQuestObjectivesLocale(); + Global.ObjectMgr.LoadQuestGreetingLocales(); Global.ObjectMgr.LoadQuestOfferRewardLocale(); Global.ObjectMgr.LoadQuestRequestItemsLocale(); handler.SendGlobalGMSysMessage("DB table `quest_template_locale` reloaded."); handler.SendGlobalGMSysMessage("DB table `quest_objectives_locale` reloaded."); + handler.SendGlobalGMSysMessage("DB table `quest_greeting_locale` reloaded."); handler.SendGlobalGMSysMessage("DB table `quest_offer_reward_locale` reloaded."); handler.SendGlobalGMSysMessage("DB table `quest_request_items_locale` reloaded."); return true; diff --git a/Source/Game/Entities/Creature/Gossip.cs b/Source/Game/Entities/Creature/Gossip.cs index a4e6225cb..f03810f6a 100644 --- a/Source/Game/Entities/Creature/Gossip.cs +++ b/Source/Game/Entities/Creature/Gossip.cs @@ -339,20 +339,28 @@ namespace Game.Misc _session.SendPacket(packet); } - public void SendQuestGiverQuestListMessage(ObjectGuid guid) + public void SendQuestGiverQuestListMessage(WorldObject questgiver) { + ObjectGuid guid = questgiver.GetGUID(); + LocaleConstant localeConstant = _session.GetSessionDbLocaleIndex(); + QuestGiverQuestListMessage questList = new QuestGiverQuestListMessage(); questList.QuestGiverGUID = guid; - QuestGreeting questGreeting = Global.ObjectMgr.GetQuestGreeting(guid); + QuestGreeting questGreeting = Global.ObjectMgr.GetQuestGreeting(questgiver.GetTypeId(), questgiver.GetEntry()); if (questGreeting != null) { - questList.GreetEmoteDelay = questGreeting.greetEmoteDelay; - questList.GreetEmoteType = questGreeting.greetEmoteType; - questList.Greeting = questGreeting.greeting; + questList.GreetEmoteDelay = questGreeting.EmoteDelay; + questList.GreetEmoteType = questGreeting.EmoteType; + questList.Greeting = questGreeting.Text; + + if (localeConstant != LocaleConstant.enUS) + { + QuestGreetingLocale questGreetingLocale = Global.ObjectMgr.GetQuestGreetingLocale(questgiver.GetTypeId(), questgiver.GetEntry()); + if (questGreetingLocale != null) + ObjectManager.GetLocaleString(questGreetingLocale.Greeting, localeConstant, ref questList.Greeting); + } } - else - Log.outError(LogFilter.Server, "Guid: {0} - No quest greeting found.", guid.ToString()); for (var i = 0; i < _questMenu.GetMenuItemCount(); ++i) { @@ -364,12 +372,11 @@ namespace Game.Misc { string title = quest.LogTitle; - LocaleConstant locale = _session.GetSessionDbLocaleIndex(); - if (locale != LocaleConstant.enUS) + if (localeConstant != LocaleConstant.enUS) { QuestTemplateLocale localeData = Global.ObjectMgr.GetQuestLocale(quest.Id); if (localeData != null) - ObjectManager.GetLocaleString(localeData.LogTitle, locale, ref title); + ObjectManager.GetLocaleString(localeData.LogTitle, localeConstant, ref title); } GossipText text = new GossipText(); diff --git a/Source/Game/Entities/Player/Player.Quest.cs b/Source/Game/Entities/Player/Player.Quest.cs index 5b0a67c08..3d7865819 100644 --- a/Source/Game/Entities/Player/Player.Quest.cs +++ b/Source/Game/Entities/Player/Player.Quest.cs @@ -280,7 +280,7 @@ namespace Game.Entities } } - public void SendPreparedQuest(ObjectGuid guid) + public void SendPreparedQuest(WorldObject source) { QuestMenu questMenu = PlayerTalkClass.GetQuestMenu(); if (questMenu.IsEmpty()) @@ -298,36 +298,35 @@ namespace Game.Entities { if (qmi0.QuestIcon == 4) { - PlayerTalkClass.SendQuestGiverRequestItems(quest, guid, CanRewardQuest(quest, false), true); + PlayerTalkClass.SendQuestGiverRequestItems(quest, source.GetGUID(), CanRewardQuest(quest, false), true); return; } // Send completable on repeatable and autoCompletable quest if player don't have quest // @todo verify if check for !quest.IsDaily() is really correct (possibly not) else { - WorldObject obj = Global.ObjAccessor.GetObjectByTypeMask(this, guid, TypeMask.Unit | TypeMask.GameObject | TypeMask.Item); - if (!obj || (!obj.hasQuest(questId) && !obj.hasInvolvedQuest(questId))) + if (!source.hasQuest(questId) && !source.hasInvolvedQuest(questId)) { PlayerTalkClass.SendCloseGossip(); return; } - if (!obj.IsTypeId(TypeId.Unit) || obj.HasFlag64(UnitFields.NpcFlags, NPCFlags.Gossip)) + if (!source.IsTypeId(TypeId.Unit) || source.HasFlag64(UnitFields.NpcFlags, NPCFlags.Gossip)) { if (quest.IsAutoAccept() && CanAddQuest(quest, true) && CanTakeQuest(quest, true)) - AddQuestAndCheckCompletion(quest, obj); + AddQuestAndCheckCompletion(quest, source); if (quest.IsAutoComplete() && quest.IsRepeatable() && !quest.IsDailyOrWeekly()) - PlayerTalkClass.SendQuestGiverRequestItems(quest, guid, CanCompleteRepeatableQuest(quest), true); + PlayerTalkClass.SendQuestGiverRequestItems(quest, source.GetGUID(), CanCompleteRepeatableQuest(quest), true); else - PlayerTalkClass.SendQuestGiverQuestDetails(quest, guid, true, false); + PlayerTalkClass.SendQuestGiverQuestDetails(quest, source.GetGUID(), true, false); return; } } } } - PlayerTalkClass.SendQuestGiverQuestListMessage(guid); + PlayerTalkClass.SendQuestGiverQuestListMessage(source); } public bool IsActiveQuest(uint quest_id) diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 0c5c99da0..809295ee6 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -2443,7 +2443,7 @@ namespace Game.Entities { if (PlayerTalkClass.GetGossipMenu().IsEmpty() && !PlayerTalkClass.GetQuestMenu().IsEmpty()) { - SendPreparedQuest(source.GetGUID()); + SendPreparedQuest(source); return; } } @@ -2518,7 +2518,7 @@ namespace Game.Entities break; case GossipOption.Questgiver: PrepareQuestMenu(guid); - SendPreparedQuest(guid); + SendPreparedQuest(source); break; case GossipOption.Vendor: case GossipOption.Armorer: diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index da19ebb75..e34d49afc 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -7317,9 +7317,10 @@ namespace Game { uint oldMSTime = Time.GetMSTime(); - _questGreetingStorage.Clear(); // need for reload case + for (var i = 0; i < 2; ++i) + _questGreetingStorage[i] = new Dictionary(); - // 0 1 2 3 + // 0 1 2 3 SQLResult result = DB.World.Query("SELECT ID, type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting"); if (result.IsEmpty()) { @@ -7327,15 +7328,15 @@ namespace Game return; } + uint count = 0; do { uint id = result.Read(0); byte type = result.Read(1); - // overwrite + switch (type) { case 0: // Creature - type = (byte)TypeId.Unit; if (Global.ObjectMgr.GetCreatureTemplate(id) == null) { Log.outError(LogFilter.Sql, "Table `quest_greeting`: creature template entry {0} does not exist.", id); @@ -7343,7 +7344,6 @@ namespace Game } break; case 1: // GameObject - type = (byte)TypeId.GameObject; if (Global.ObjectMgr.GetGameObjectTemplate(id) == null) { Log.outError(LogFilter.Sql, "Table `quest_greeting`: gameobject template entry {0} does not exist.", id); @@ -7358,14 +7358,12 @@ namespace Game uint greetEmoteDelay = result.Read(3); string greeting = result.Read(4); - if (!_questGreetingStorage.ContainsKey(type)) - _questGreetingStorage[type] = new Dictionary(); - _questGreetingStorage[type][id] = new QuestGreeting(greetEmoteType, greetEmoteDelay, greeting); + count++; } while (result.NextRow()); - Log.outInfo(LogFilter.ServerLoading, "Loaded {0} quest_greeting in {1} ms", _questGreetingStorage.Count, Time.GetMSTimeDiffToNow(oldMSTime)); + Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} quest_greeting in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); } public Quest GetQuestTemplate(uint questId) @@ -7424,17 +7422,29 @@ namespace Game { return _questAreaTriggerStorage.LookupByKey(triggerId); } - public QuestGreeting GetQuestGreeting(ObjectGuid guid) + public QuestGreeting GetQuestGreeting(TypeId type, uint id) { - var dic = _questGreetingStorage.LookupByKey(guid.GetTypeId()); - if (dic.Empty()) + byte typeIndex; + if (type == TypeId.Unit) + typeIndex = 0; + else if (type == TypeId.GameObject) + typeIndex = 1; + else return null; - var greeting = dic.LookupByKey(guid.GetEntry()); - if (greeting == null) + return _questGreetingStorage[typeIndex].LookupByKey(id); + } + public QuestGreetingLocale GetQuestGreetingLocale(TypeId type, uint id) + { + byte typeIndex; + if (type == TypeId.Unit) + typeIndex = 0; + else if (type == TypeId.GameObject) + typeIndex = 1; + else return null; - return greeting; + return _questGreetingLocaleStorage[typeIndex].LookupByKey(id); } //Spells /Skills / Phases @@ -7890,6 +7900,60 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, "Loaded {0} Quest Objectives locale strings in {1} ms", _questObjectivesLocaleStorage.Count, Time.GetMSTimeDiffToNow(oldMSTime)); } + public void LoadQuestGreetingLocales() + { + uint oldMSTime = Time.GetMSTime(); + + for (var i = 0; i < 2; ++i) + _questGreetingLocaleStorage[i] = new Dictionary(); + + // 0 1 2 3 + SQLResult result = DB.World.Query("SELECT Id, type, locale, Greeting FROM quest_greeting_locale"); + if (result.IsEmpty()) + return; + + uint count = 0; + do + { + uint id = result.Read(0); + byte type = result.Read(1); + switch (type) + { + case 0: // Creature + if (GetCreatureTemplate(id) == null) + { + Log.outError(LogFilter.Sql, $"Table `quest_greeting_locale`: creature template entry {id} does not exist."); + continue; + } + break; + case 1: // GameObject + if (GetGameObjectTemplate(id) == null) + { + Log.outError(LogFilter.Sql, $"Table `quest_greeting_locale`: gameobject template entry {id} does not exist."); + continue; + } + break; + default: + continue; + } + + string localeName = result.Read(2); + + LocaleConstant locale = localeName.ToEnum(); + if (locale == LocaleConstant.enUS) + continue; + + if (!_questGreetingLocaleStorage[type].ContainsKey(id)) + _questGreetingLocaleStorage[type][id] = new QuestGreetingLocale(); + + QuestGreetingLocale data = _questGreetingLocaleStorage[type][id]; + AddLocaleString(result.Read(3), locale, data.Greeting); + ++count; + } + while (result.NextRow()); + + Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} Quest Greeting locale strings in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); + } public void LoadQuestOfferRewardLocale() { uint oldMSTime = Time.GetMSTime(); @@ -9580,7 +9644,8 @@ namespace Game MultiMap _questPOIStorage = new MultiMap(); MultiMap _questAreaTriggerStorage = new MultiMap(); Dictionary _questObjectives = new Dictionary(); - Dictionary> _questGreetingStorage = new Dictionary>(); + Dictionary[] _questGreetingStorage = new Dictionary[2]; + Dictionary[] _questGreetingLocaleStorage = new Dictionary[2]; //Scripts List scriptNamesStorage = new List(); @@ -10106,24 +10171,6 @@ namespace Game public int Y; } - public class QuestGreeting - { - public QuestGreeting() - { - greeting = ""; - } - public QuestGreeting(ushort _greetEmoteType, uint _greetEmoteDelay, string _greeting) - { - greetEmoteType = _greetEmoteType; - greetEmoteDelay = _greetEmoteDelay; - greeting = _greeting; - } - - public ushort greetEmoteType; - public uint greetEmoteDelay; - public string greeting; - } - public class AreaTriggerStruct { public uint target_mapId; diff --git a/Source/Game/Quest/Quest.cs b/Source/Game/Quest/Quest.cs index 9161af8c8..620a0aff9 100644 --- a/Source/Game/Quest/Quest.cs +++ b/Source/Game/Quest/Quest.cs @@ -545,6 +545,29 @@ namespace Game public int[] ObjectiveData; } + public class QuestGreeting + { + public QuestGreeting() + { + Text = ""; + } + public QuestGreeting(ushort emoteType, uint emoteDelay, string text) + { + EmoteType = emoteType; + EmoteDelay = emoteDelay; + Text = text; + } + + public ushort EmoteType; + public uint EmoteDelay; + public string Text; + } + + public class QuestGreetingLocale + { + public StringArray Greeting = new StringArray((int)LocaleConstant.Total); + } + public class QuestTemplateLocale { public StringArray LogTitle = new StringArray((int)LocaleConstant.Total); diff --git a/Source/Game/Server/WorldManager.cs b/Source/Game/Server/WorldManager.cs index 0cdf9d507..05954dab9 100644 --- a/Source/Game/Server/WorldManager.cs +++ b/Source/Game/Server/WorldManager.cs @@ -304,9 +304,6 @@ namespace Game public void SetInitialWorldSettings() { - // Server startup begin - uint startupBegin = Time.GetMSTime(); - LoadRealmInfo(); LoadConfigSettings(); @@ -411,6 +408,7 @@ namespace Game Global.ObjectMgr.LoadCreatureLocales(); Global.ObjectMgr.LoadGameObjectLocales(); Global.ObjectMgr.LoadQuestTemplateLocale(); + Global.ObjectMgr.LoadQuestGreetingLocales(); Global.ObjectMgr.LoadQuestOfferRewardLocale(); Global.ObjectMgr.LoadQuestRequestItemsLocale(); Global.ObjectMgr.LoadQuestObjectivesLocale(); @@ -967,10 +965,6 @@ namespace Game }); } - uint startupDuration = Time.GetMSTimeDiffToNow(startupBegin); - - Log.outInfo(LogFilter.Server, "World initialized in {0} minutes {1} seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000)); - Log.SetRealmId(_realm.Id.Realm); } @@ -1765,7 +1759,7 @@ namespace Game AddSession_(sess); // Then send an update signal to remaining ones - foreach (var pair in m_sessions.ToList()) + foreach (var pair in m_sessions) { WorldSession session = pair.Value; WorldSessionFilter updater = new WorldSessionFilter(session); @@ -1775,7 +1769,7 @@ namespace Game m_disconnects[session.GetAccountId()] = Time.UnixTime; RemoveQueuedPlayer(session); - m_sessions.Remove(pair.Key); + m_sessions.TryRemove(pair.Key, out WorldSession tempSession); session.Dispose(); } } @@ -2422,7 +2416,7 @@ namespace Game uint m_updateTimeCount; uint m_currentTime; - Dictionary m_sessions = new Dictionary(); + ConcurrentDictionary m_sessions = new ConcurrentDictionary(); Dictionary m_disconnects = new Dictionary(); uint m_maxActiveSessionCount; uint m_maxQueuedSessionCount; diff --git a/Source/Game/Spells/SpellManager.cs b/Source/Game/Spells/SpellManager.cs index 3153bf765..4bfda4c2b 100644 --- a/Source/Game/Spells/SpellManager.cs +++ b/Source/Game/Spells/SpellManager.cs @@ -3132,7 +3132,7 @@ namespace Game.Entities public uint GetModelForTotem(uint spellId, Race race) { - return mSpellTotemModel.LookupByKey(Tuple.Create(spellId, race)); + return mSpellTotemModel.LookupByKey(Tuple.Create(spellId, (byte)race)); } #region Fields diff --git a/Source/WorldServer/Server.cs b/Source/WorldServer/Server.cs index 8c63736db..eb50803a2 100644 --- a/Source/WorldServer/Server.cs +++ b/Source/WorldServer/Server.cs @@ -45,6 +45,9 @@ namespace WorldServer if (!StartDB()) ExitNow(); + // Server startup begin + uint startupBegin = Time.GetMSTime(); + // set server offline (not connectable) DB.Login.Execute("UPDATE realmlist SET flag = (flag & ~{0}) | {1} WHERE id = '{2}'", (uint)RealmFlags.VersionMismatch, (uint)RealmFlags.Offline, Global.WorldMgr.GetRealm().Id.Realm); @@ -87,6 +90,9 @@ namespace WorldServer GC.WaitForPendingFinalizers(); GC.Collect(); + uint startupDuration = Time.GetMSTimeDiffToNow(startupBegin); + Log.outInfo(LogFilter.Server, "World initialized in {0} minutes {1} seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000)); + WorldUpdateLoop(); try