From 11e8c2f4f20221a3d73366f0b41b08fa57eda67b Mon Sep 17 00:00:00 2001 From: hondacrx Date: Thu, 2 Jun 2022 17:00:58 -0400 Subject: [PATCH] Fixes loading, *Command system is broke* Will fix in the coming days. --- Source/Framework/Database/DatabaseUpdater.cs | 2 +- Source/Framework/Database/SQLResult.cs | 66 +++++++- Source/Framework/Dynamic/FlagArray.cs | 87 +++++++--- Source/Game/AuctionHouse/AuctionManager.cs | 2 +- .../DataStorage/AreaTriggerDataStorage.cs | 2 +- Source/Game/DataStorage/CliDB.cs | 6 +- .../DataStorage/ClientReader/DB6Storage.cs | 3 + .../Game/DataStorage/ClientReader/DBReader.cs | 20 +-- Source/Game/DataStorage/DB2Manager.cs | 4 +- Source/Game/DataStorage/Structs/S_Records.cs | 2 +- Source/Game/DataStorage/Structs/T_Records.cs | 2 +- Source/Game/Entities/Player/Player.cs | 2 +- Source/Game/Entities/Transport.cs | 2 +- Source/Game/Globals/ObjectManager.cs | 153 +++++++++++------- Source/Game/Handlers/TaxiHandler.cs | 2 +- Source/Game/Maps/Map.cs | 2 +- .../Networking/Packets/AuctionHousePackets.cs | 2 +- .../Networking/Packets/BattleGroundPackets.cs | 2 +- .../Game/Networking/Packets/QueryPackets.cs | 12 +- Source/Game/Scripting/ScriptManager.cs | 2 + Source/Game/Server/WorldManager.cs | 6 +- Source/Game/Spells/Spell.cs | 4 +- Source/Game/Spells/SpellInfo.cs | 8 +- Source/Game/Spells/SpellManager.cs | 8 +- Source/Scripts/Spells/Paladin.cs | 2 +- Source/WorldServer/Server.cs | 2 - 26 files changed, 268 insertions(+), 137 deletions(-) diff --git a/Source/Framework/Database/DatabaseUpdater.cs b/Source/Framework/Database/DatabaseUpdater.cs index d543611fc..42b82e8b6 100644 --- a/Source/Framework/Database/DatabaseUpdater.cs +++ b/Source/Framework/Database/DatabaseUpdater.cs @@ -60,7 +60,7 @@ namespace Framework.Database if (!File.Exists(path + fileName)) { - Log.outError(LogFilter.SqlUpdates, $"File \"{path + fileName}\" is missing, download it from \"http://www.trinitycore.org/f/files/category/1-database/\"" + + Log.outError(LogFilter.SqlUpdates, $"File \"{path + fileName}\" is missing, download it from \"https://github.com/TrinityCore/TrinityCore/releases\"" + " and place it in your sql directory."); return false; } diff --git a/Source/Framework/Database/SQLResult.cs b/Source/Framework/Database/SQLResult.cs index 8e4e7ce15..e31756e17 100644 --- a/Source/Framework/Database/SQLResult.cs +++ b/Source/Framework/Database/SQLResult.cs @@ -17,6 +17,7 @@ using MySqlConnector; using System; +using System.Runtime.CompilerServices; namespace Framework.Database { @@ -39,15 +40,68 @@ namespace Framework.Database public T Read(int column) { - var value = _reader[column]; - - if (value == DBNull.Value) + if (_reader.IsDBNull(column)) return default; - if (value.GetType() != typeof(T)) - return (T)Convert.ChangeType(value, typeof(T));//todo remove me when all fields are the right type this is super slow + var columnType = _reader.GetFieldType(column); + if (columnType == typeof(T)) + return _reader.GetFieldValue(column); - return (T)value; + switch (Type.GetTypeCode(columnType)) + { + case TypeCode.SByte: + { + var value = _reader.GetSByte(column); + return Unsafe.As(ref value); + } + case TypeCode.Byte: + { + var value = _reader.GetByte(column); + return Unsafe.As(ref value); + } + case TypeCode.Int16: + { + var value = _reader.GetInt16(column); + return Unsafe.As(ref value); + } + case TypeCode.UInt16: + { + var value = _reader.GetUInt16(column); + return Unsafe.As(ref value); + } + case TypeCode.Int32: + { + var value = _reader.GetInt32(column); + return Unsafe.As(ref value); + } + case TypeCode.UInt32: + { + var value = _reader.GetUInt32(column); + return Unsafe.As(ref value); + } + case TypeCode.Int64: + { + var value = _reader.GetInt64(column); + return Unsafe.As(ref value); + } + case TypeCode.UInt64: + { + var value = _reader.GetUInt64(column); + return Unsafe.As(ref value); + } + case TypeCode.Single: + { + var value = _reader.GetFloat(column); + return Unsafe.As(ref value); + } + case TypeCode.Double: + { + var value = _reader.GetDouble(column); + return Unsafe.As(ref value); + } + } + + return default; } public T[] ReadValues(int startIndex, int numColumns) diff --git a/Source/Framework/Dynamic/FlagArray.cs b/Source/Framework/Dynamic/FlagArray.cs index e4ffa1313..a6906b44c 100644 --- a/Source/Framework/Dynamic/FlagArray.cs +++ b/Source/Framework/Dynamic/FlagArray.cs @@ -28,7 +28,7 @@ namespace Framework.Dynamic _storage = new dynamic[length]; } - public FlagsArray(params T[] parts) + public FlagsArray(T[] parts) { _storage = new dynamic[parts.Length]; for (var i = 0; i < parts.Length; ++i) @@ -37,65 +37,68 @@ namespace Framework.Dynamic public FlagsArray(T[] parts, uint length) { - _storage = new dynamic[length]; - for (var i = 0; i < length && i < parts.Length; ++i) + for (var i = 0; i < parts.Length; ++i) _storage[i] = parts[i]; } public static bool operator <(FlagsArray left, FlagsArray right) { - for (var i = left._storage.Length; i > 0; --i) + for (int i = (int)left.GetSize(); i > 0; --i) { - if ((dynamic)left._storage[i - 1] < right._storage[i - 1]) + if ((dynamic)left[i - 1] < right[i - 1]) return true; - else if ((dynamic)left._storage[i - 1] > right._storage[i - 1]) + else if ((dynamic)left[i - 1] > right[i - 1]) return false; } return false; } public static bool operator >(FlagsArray left, FlagsArray right) { - for (var i = left._storage.Length; i > 0; --i) + for (int i = (int)left.GetSize(); i > 0; --i) { - if ((dynamic)left._storage[i - 1] > right._storage[i - 1]) + if ((dynamic)left[i - 1] > right[i - 1]) return true; - else if ((dynamic)left._storage[i - 1] < right._storage[i - 1]) + else if ((dynamic)left[i - 1] < right[i - 1]) return false; } return false; } - public static FlagArray128 operator &(FlagsArray left, FlagsArray right) + public static FlagsArray operator &(FlagsArray left, FlagsArray right) { - FlagArray128 fl = new(); - for (var i = 0; i < left._storage.Length; ++i) - fl[i] = left._storage[i] & right._storage[i]; + FlagsArray fl = new(left.GetSize()); + for (var i = 0; i < left.GetSize(); ++i) + fl[i] = (dynamic)left[i] & right[i]; + return fl; } - public static FlagArray128 operator |(FlagsArray left, FlagsArray right) + public static FlagsArray operator |(FlagsArray left, FlagsArray right) { - FlagArray128 fl = new(); - for (var i = 0; i < left._storage.Length; ++i) - fl[i] = left._storage[i] | right._storage[i]; + FlagsArray fl = new(left.GetSize()); + for (var i = 0; i < left.GetSize(); ++i) + fl[i] = (dynamic)left[i] | right[i]; + return fl; } - public static FlagArray128 operator ^(FlagsArray left, FlagsArray right) + public static FlagsArray operator ^(FlagsArray left, FlagsArray right) { - FlagArray128 fl = new(); - for (var i = 0; i < left._storage.Length; ++i) - fl[i] = left._storage[i] ^ right._storage[i]; + FlagsArray fl = new(left.GetSize()); + for (var i = 0; i < left.GetSize(); ++i) + fl[i] = (dynamic)left[i] ^ right[i]; return fl; } public static implicit operator bool(FlagsArray left) { - for (var i = 0; i < left._storage.Length; ++i) - if (left._storage[i] != 0) + for (var i = 0; i < left.GetSize(); ++i) + if ((dynamic)left[i] != 0) return true; return false; } + public uint GetSize() => (uint)_storage.Length; + public T this[int i] { get @@ -111,7 +114,21 @@ namespace Framework.Dynamic public class FlagArray128 : FlagsArray { - public FlagArray128(params uint[] parts) : base(parts, 4) { } + public FlagArray128(uint p1 = 0, uint p2 = 0, uint p3 = 0, uint p4 = 0) : base(4) + { + _storage[0] = p1; + _storage[1] = p2; + _storage[2] = p3; + _storage[3] = p4; + } + + public FlagArray128(uint[] parts) : base(4) + { + _storage[0] = parts[0]; + _storage[1] = parts[1]; + _storage[2] = parts[2]; + _storage[3] = parts[3]; + } public bool IsEqual(params uint[] parts) { @@ -132,6 +149,28 @@ namespace Framework.Dynamic for (var i = 0; i < parts.Length; ++i) _storage[i] = parts[i]; } + + public static FlagArray128 operator &(FlagArray128 left, FlagArray128 right) + { + FlagArray128 fl = new(); + for (var i = 0; i < left._storage.Length; ++i) + fl[i] = left._storage[i] & right._storage[i]; + return fl; + } + public static FlagArray128 operator |(FlagArray128 left, FlagArray128 right) + { + FlagArray128 fl = new(); + for (var i = 0; i < left._storage.Length; ++i) + fl[i] = left._storage[i] | right._storage[i]; + return fl; + } + public static FlagArray128 operator ^(FlagArray128 left, FlagArray128 right) + { + FlagArray128 fl = new(); + for (var i = 0; i < left._storage.Length; ++i) + fl[i] = left._storage[i] ^ right._storage[i]; + return fl; + } } public class FlaggedArray where T : struct diff --git a/Source/Game/AuctionHouse/AuctionManager.cs b/Source/Game/AuctionHouse/AuctionManager.cs index e7b8f9b5f..27d3cf6ef 100644 --- a/Source/Game/AuctionHouse/AuctionManager.cs +++ b/Source/Game/AuctionHouse/AuctionManager.cs @@ -829,7 +829,7 @@ namespace Game { knownAppearanceIds = player.GetSession().GetCollectionMgr().GetAppearanceIds(); //todo fix me - //if (knownPetSpecies.size() < CliDB.BattlePetSpeciesStorage.GetNumRows()) + //if (knownPetSpecies.Length < CliDB.BattlePetSpeciesStorage.GetNumRows()) //knownPetSpecies.resize(CliDB.BattlePetSpeciesStorage.GetNumRows()); } diff --git a/Source/Game/DataStorage/AreaTriggerDataStorage.cs b/Source/Game/DataStorage/AreaTriggerDataStorage.cs index 948ca9d30..743d6591b 100644 --- a/Source/Game/DataStorage/AreaTriggerDataStorage.cs +++ b/Source/Game/DataStorage/AreaTriggerDataStorage.cs @@ -222,7 +222,7 @@ namespace Game.DataStorage } // 0 1 2 3 4 5 6 7 - SQLResult circularMovementInfos = DB.World.Query("SELECT AreaTriggerCreatePropertiesId, StartDelay, CircleRadius, BlendFromRadius, InitialAngle, ZOffset, CounterClockwise, CanLoop FROM `areatrigger_create_properties_orbit` ORDER BY `SpellMiscId`"); + SQLResult circularMovementInfos = DB.World.Query("SELECT AreaTriggerCreatePropertiesId, StartDelay, CircleRadius, BlendFromRadius, InitialAngle, ZOffset, CounterClockwise, CanLoop FROM `areatrigger_create_properties_orbit`"); if (!circularMovementInfos.IsEmpty()) { do diff --git a/Source/Game/DataStorage/CliDB.cs b/Source/Game/DataStorage/CliDB.cs index 05bbe36eb..6c0e242cd 100644 --- a/Source/Game/DataStorage/CliDB.cs +++ b/Source/Game/DataStorage/CliDB.cs @@ -354,13 +354,13 @@ namespace Game.DataStorage TaxiPathSetBySource[entry.FromTaxiNode][entry.ToTaxiNode] = new TaxiPathBySourceAndDestination(entry.Id, entry.Cost); } - uint pathCount = TaxiPathStorage.Keys.Max() + 1; + uint pathCount = TaxiPathStorage.GetNumRows(); // Calculate path nodes count uint[] pathLength = new uint[pathCount]; // 0 and some other indexes not used foreach (TaxiPathNodeRecord entry in TaxiPathNodeStorage.Values) if (pathLength[entry.PathID] < entry.NodeIndex + 1) - pathLength[entry.PathID] = entry.NodeIndex + 1u; + pathLength[entry.PathID] = (uint)entry.NodeIndex + 1u; // Set path length for (uint i = 0; i < pathCount; ++i) @@ -370,7 +370,7 @@ namespace Game.DataStorage foreach (var entry in TaxiPathNodeStorage.Values) TaxiPathNodesByPath[entry.PathID][entry.NodeIndex] = entry; - var taxiMaskSize = ((TaxiNodesStorage.Count - 1) / 8) + 1; + var taxiMaskSize = TaxiNodesStorage.GetNumRows() + 1; TaxiNodesMask = new byte[taxiMaskSize]; OldContinentsNodesMask = new byte[taxiMaskSize]; HordeTaxiNodesMask = new byte[taxiMaskSize]; diff --git a/Source/Game/DataStorage/ClientReader/DB6Storage.cs b/Source/Game/DataStorage/ClientReader/DB6Storage.cs index cdda9bddf..a90dfaf51 100644 --- a/Source/Game/DataStorage/ClientReader/DB6Storage.cs +++ b/Source/Game/DataStorage/ClientReader/DB6Storage.cs @@ -22,6 +22,7 @@ using Framework.IO; using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Numerics; using System.Reflection; @@ -389,6 +390,8 @@ namespace Game.DataStorage public uint GetTableHash() { return _header.TableHash; } + public uint GetNumRows() { return Keys.Max() + 1; } + public string GetName() { return _tableName; diff --git a/Source/Game/DataStorage/ClientReader/DBReader.cs b/Source/Game/DataStorage/ClientReader/DBReader.cs index ce2056c31..5f2e3554e 100644 --- a/Source/Game/DataStorage/ClientReader/DBReader.cs +++ b/Source/Game/DataStorage/ClientReader/DBReader.cs @@ -219,7 +219,7 @@ namespace Game.DataStorage if (Header.HasIndexTable() && indexData.Length != sparseIndexData.Length) throw new Exception("indexData.Length != sparseIndexData.Length"); - //indexData = sparseIndexData; + indexData = sparseIndexData; } BitReader bitReader = new(recordsData); @@ -328,7 +328,7 @@ namespace Game.DataStorage else return columnMeta.Common.DefaultValue.As(); case DB2ColumnCompression.Pallet: - case DB2ColumnCompression.PalletArray: //need for SummonProperties.db2 + case DB2ColumnCompression.PalletArray: uint palletIndex = _data.Read(columnMeta.Pallet.BitWidth); return _palletData[fieldIndex][palletIndex].As(); } @@ -363,12 +363,12 @@ namespace Game.DataStorage return arr2; case DB2ColumnCompression.SignedImmediate: - T[] arr4 = new T[arraySize]; + T[] arr3 = new T[arraySize]; - for (int i = 0; i < arr4.Length; i++) - arr4[i] = _data.ReadSigned(columnMeta.Immediate.BitWidth); + for (int i = 0; i < arr3.Length; i++) + arr3[i] = _data.ReadSigned(columnMeta.Immediate.BitWidth); - return arr4; + return arr3; case DB2ColumnCompression.PalletArray: int cardinality = columnMeta.Pallet.Cardinality; @@ -377,12 +377,12 @@ namespace Game.DataStorage uint palletArrayIndex = _data.Read(columnMeta.Pallet.BitWidth); - T[] arr3 = new T[cardinality]; + T[] arr4 = new T[cardinality]; - for (int i = 0; i < arr3.Length; i++) - arr3[i] = _palletData[fieldIndex][i + cardinality * (int)palletArrayIndex].As(); + for (int i = 0; i < arr4.Length; i++) + arr4[i] = _palletData[fieldIndex][i + cardinality * (int)palletArrayIndex].As(); - return arr3; + return arr4; } throw new Exception(string.Format("Unexpected compression type {0}", columnMeta.CompressionType)); } diff --git a/Source/Game/DataStorage/DB2Manager.cs b/Source/Game/DataStorage/DB2Manager.cs index 3ad2ed0a5..6043137b2 100644 --- a/Source/Game/DataStorage/DB2Manager.cs +++ b/Source/Game/DataStorage/DB2Manager.cs @@ -853,7 +853,7 @@ namespace Game.DataStorage public uint GetEmptyAnimStateID() { - return (uint)AnimationDataStorage.Count; + return AnimationDataStorage.GetNumRows(); } public List GetAreasForGroup(uint areaGroupId) @@ -943,7 +943,7 @@ namespace Game.DataStorage return levels[tier]; } - return (uint)AzeriteLevelInfoStorage.Count; + return AzeriteLevelInfoStorage.GetNumRows(); } public string GetBroadcastTextValue(BroadcastTextRecord broadcastText, Locale locale = Locale.enUS, Gender gender = Gender.Male, bool forceGender = false) diff --git a/Source/Game/DataStorage/Structs/S_Records.cs b/Source/Game/DataStorage/Structs/S_Records.cs index 335afece6..dd78127de 100644 --- a/Source/Game/DataStorage/Structs/S_Records.cs +++ b/Source/Game/DataStorage/Structs/S_Records.cs @@ -281,7 +281,7 @@ namespace Game.DataStorage public uint Id; public short EffectAura; public uint DifficultyID; - public uint EffectIndex; + public int EffectIndex; public uint Effect; public float EffectAmplitude; public SpellEffectAttributes EffectAttributes; diff --git a/Source/Game/DataStorage/Structs/T_Records.cs b/Source/Game/DataStorage/Structs/T_Records.cs index bb6ca52cb..411d65c95 100644 --- a/Source/Game/DataStorage/Structs/T_Records.cs +++ b/Source/Game/DataStorage/Structs/T_Records.cs @@ -72,7 +72,7 @@ namespace Game.DataStorage public Vector3 Loc; public uint Id; public ushort PathID; - public uint NodeIndex; + public int NodeIndex; public ushort ContinentID; public TaxiPathNodeFlags Flags; public uint Delay; diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 881c79421..52d314eef 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -5983,7 +5983,7 @@ namespace Game.Entities SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ManaCostModifier, i), 0); // Reset no reagent cost field - SetNoRegentCostMask(new Framework.Dynamic.FlagArray128()); + SetNoRegentCostMask(new FlagArray128()); // Init data for form but skip reapply item mods for form InitDataForForm(reapplyMods); diff --git a/Source/Game/Entities/Transport.cs b/Source/Game/Entities/Transport.cs index ed71b086d..a45f2bee9 100644 --- a/Source/Game/Entities/Transport.cs +++ b/Source/Game/Entities/Transport.cs @@ -215,7 +215,7 @@ namespace Game.Entities MoveToNextWaypoint(); - Global.ScriptMgr.OnRelocate(this, _currentFrame.Node.NodeIndex, _currentFrame.Node.ContinentID, _currentFrame.Node.Loc.X, _currentFrame.Node.Loc.Y, _currentFrame.Node.Loc.Z); + Global.ScriptMgr.OnRelocate(this, (uint)_currentFrame.Node.NodeIndex, _currentFrame.Node.ContinentID, _currentFrame.Node.Loc.X, _currentFrame.Node.Loc.Y, _currentFrame.Node.Loc.Z); Log.outDebug(LogFilter.Transport, "Transport {0} ({1}) moved to node {2} {3} {4} {5} {6}", GetEntry(), GetName(), _currentFrame.Node.NodeIndex, _currentFrame.Node.ContinentID, _currentFrame.Node.Loc.X, _currentFrame.Node.Loc.Y, _currentFrame.Node.Loc.Z); diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index 058d88eda..72ed30403 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -578,7 +578,7 @@ namespace Game uint oldMSTime = Time.GetMSTime(); gossipMenuItemsStorage.Clear(); - + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 SQLResult result = DB.World.Query("SELECT MenuID, OptionID, OptionIcon, OptionText, OptionBroadcastTextID, OptionType, OptionNpcFlag, Language, ActionMenuID, ActionPoiID, BoxCoded, BoxMoney, BoxText, BoxBroadcastTextID " + "FROM gossip_menu_option ORDER BY MenuID, OptionID"); @@ -1024,48 +1024,6 @@ namespace Game } //Scripts - public void LoadScriptNames() - { - uint oldMSTime = Time.GetMSTime(); - - scriptNamesStorage.Add(""); - SQLResult result = DB.World.Query( - "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM conversation_template WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM creature WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM criteria_data WHERE ScriptName <> '' AND type = 11 " + - "UNION SELECT DISTINCT(ScriptName) FROM gameobject WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM item_script_names WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM areatrigger_template WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM scene_template WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(ScriptName) FROM quest_template_addon WHERE ScriptName <> '' " + - "UNION SELECT DISTINCT(script) FROM instance_template WHERE script <> ''"); - - if (result.IsEmpty()) - { - Log.outError(LogFilter.ServerLoading, "Loaded empty set of Script Names!"); - return; - } - - uint count = 1; - do - { - scriptNamesStorage.Add(result.Read(0)); - ++count; - } - while (result.NextRow()); - - scriptNamesStorage.Sort(); - Log.outInfo(LogFilter.ServerLoading, "Loaded {0} Script Names in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); - } public void LoadAreaTriggerScripts() { uint oldMSTime = Time.GetMSTime(); @@ -1658,25 +1616,34 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, "Validated {0} scripts in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); } + public List GetSpellScriptsBounds(uint spellId) { return spellScriptsStorage.LookupByKey(spellId); } + public List GetAllDBScriptNames() + { + return _scriptNamesStorage.GetAllDBScriptNames(); + } public string GetScriptName(uint id) { - return id < scriptNamesStorage.Count ? scriptNamesStorage[(int)id] : ""; + var entry = _scriptNamesStorage.Find(id); + if (entry != null) + return entry.Name; + + return ""; } - public uint GetScriptId(string name) + bool IsScriptDatabaseBound(uint id) { - // use binary search to find the script name in the sorted vector - // assume "" is the first element - if (string.IsNullOrEmpty(name)) - return 0; + var entry = _scriptNamesStorage.Find(id); + if (entry != null) + return entry.IsScriptDatabaseBound; - if (!scriptNamesStorage.Contains(name)) - return 0; - - return (uint)scriptNamesStorage.IndexOf(name); + return false; + } + public uint GetScriptId(string name, bool isDatabaseBound = true) + { + return _scriptNamesStorage.Insert(name, isDatabaseBound); } public uint GetAreaTriggerScriptId(uint triggerid) { @@ -3236,7 +3203,7 @@ namespace Game _creatureDefaultTrainers.Clear(); - SQLResult result = DB.World.Query("SELECT CreatureId, TrainerId, MenuId, OptionIndex FROM creature_trainer"); + SQLResult result = DB.World.Query("SELECT CreatureID, TrainerID, MenuID, OptionID FROM creature_trainer"); if (!result.IsEmpty()) { do @@ -7980,7 +7947,7 @@ namespace Game uint count = 0; - SQLResult result = DB.World.Query($"SELECT id, quest FROM {table} qr LEFT JOIN pool_quest pq ON qr.quest = pq.entry"); + SQLResult result = DB.World.Query($"SELECT id, quest FROM {table}"); if (result.IsEmpty()) { @@ -8828,7 +8795,7 @@ namespace Game _gossipMenuItemsLocaleStorage.Clear(); // need for reload case // 0 1 2 3 4 - SQLResult result = DB.World.Query("SELECT MenuId, OptionIndex, Locale, OptionText, BoxText FROM gossip_menu_option_locale"); + SQLResult result = DB.World.Query("SELECT MenuId, OptionID, Locale, OptionText, BoxText FROM gossip_menu_option_locale"); if (result.IsEmpty()) return; @@ -10803,7 +10770,7 @@ namespace Game Dictionary[] _questGreetingLocaleStorage = new Dictionary[2]; //Scripts - List scriptNamesStorage = new(); + ScriptNameContainer _scriptNamesStorage = new(); MultiMap spellScriptsStorage = new(); public Dictionary> sSpellScripts = new(); public Dictionary> sEventScripts = new(); @@ -11957,4 +11924,76 @@ namespace Game return Contains(questId) && (!_onlyActive || Quest.IsTakingQuestEnabled(questId)); } } + + class ScriptNameContainer + { + Dictionary NameToIndex = new(); + List IndexToName = new(); + + public ScriptNameContainer() + { + // We insert an empty placeholder here so we can use the + // script id 0 as dummy for "no script found". + uint id = Insert("", false); + + Cypher.Assert(id == 0); + } + + public uint Insert(string scriptName, bool isScriptNameBound) + { + Entry entry = new((uint)NameToIndex.Count, isScriptNameBound, scriptName); + var result = NameToIndex.TryAdd(scriptName, entry); + if (result) + { + Cypher.Assert(NameToIndex.Count <= int.MaxValue); + IndexToName.Add(entry); + } + + return entry.Id; + } + + public int GetSize() + { + return IndexToName.Count; + } + + public Entry Find(uint index) + { + return index < IndexToName.Count ? IndexToName[(int)index] : null; + } + + public Entry Find(string name) + { + // assume "" is the first element + if (name.IsEmpty()) + return null; + + return NameToIndex.LookupByKey(name); + } + + public List GetAllDBScriptNames() + { + List scriptNames = new(); + + foreach (var (name, entry) in NameToIndex) + if (entry.IsScriptDatabaseBound) + scriptNames.Add(name); + + return scriptNames; + } + + public class Entry + { + public uint Id; + public bool IsScriptDatabaseBound; + public string Name; + + public Entry(uint id, bool isScriptDatabaseBound, string name) + { + Id = id; + IsScriptDatabaseBound = isScriptDatabaseBound; + Name = name; + } + } + } } diff --git a/Source/Game/Handlers/TaxiHandler.cs b/Source/Game/Handlers/TaxiHandler.cs index 866645544..b2962e555 100644 --- a/Source/Game/Handlers/TaxiHandler.cs +++ b/Source/Game/Handlers/TaxiHandler.cs @@ -240,7 +240,7 @@ namespace Game { if (GetPlayer().m_taxi.RequestEarlyLanding()) { - flight.LoadPath(GetPlayer(), flight.GetPath()[(int)flight.GetCurrentNode()].NodeIndex); + flight.LoadPath(GetPlayer(), (uint)flight.GetPath()[(int)flight.GetCurrentNode()].NodeIndex); flight.Reset(GetPlayer()); } } diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index 4bc03ba2b..8ac0332af 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -2580,7 +2580,7 @@ namespace Game.Maps return; var respawnInfo = spawnMap.LookupByKey(info.spawnId); - Cypher.Assert(respawnInfo != info, $"Respawn stores inconsistent for map {GetId()}, spawnid {info.spawnId} (type {info.type})"); + Cypher.Assert(respawnInfo != null, $"Respawn stores inconsistent for map {GetId()}, spawnid {info.spawnId} (type {info.type})"); spawnMap.Remove(info.spawnId); // respawn heap diff --git a/Source/Game/Networking/Packets/AuctionHousePackets.cs b/Source/Game/Networking/Packets/AuctionHousePackets.cs index 7444dc636..886d3a25d 100644 --- a/Source/Game/Networking/Packets/AuctionHousePackets.cs +++ b/Source/Game/Networking/Packets/AuctionHousePackets.cs @@ -48,7 +48,7 @@ namespace Game.Networking.Packets uint knownPetSize = _worldPacket.ReadUInt32(); MaxPetLevel = _worldPacket.ReadInt8(); - int sizeLimit = CliDB.BattlePetSpeciesStorage.Count / 8 +1; + uint sizeLimit = CliDB.BattlePetSpeciesStorage.GetNumRows() / 8 + 1; if (knownPetSize >= sizeLimit) throw new System.Exception($"Attempted to read more array elements from packet {knownPetSize} than allowed {sizeLimit}"); diff --git a/Source/Game/Networking/Packets/BattleGroundPackets.cs b/Source/Game/Networking/Packets/BattleGroundPackets.cs index 83bba08e9..7986ab7cc 100644 --- a/Source/Game/Networking/Packets/BattleGroundPackets.cs +++ b/Source/Game/Networking/Packets/BattleGroundPackets.cs @@ -776,7 +776,7 @@ namespace Game.Networking.Packets public sbyte ArenaSlot; } - struct BattlegroundCapturePointInfo + class BattlegroundCapturePointInfo { public ObjectGuid Guid; public Vector2 Pos; diff --git a/Source/Game/Networking/Packets/QueryPackets.cs b/Source/Game/Networking/Packets/QueryPackets.cs index a880aa742..935efce21 100644 --- a/Source/Game/Networking/Packets/QueryPackets.cs +++ b/Source/Game/Networking/Packets/QueryPackets.cs @@ -680,7 +680,7 @@ namespace Game.Networking.Packets public DeclinedName DeclinedNames = new(); } - public struct NameCacheUnused920 + public class NameCacheUnused920 { public uint Unused1; public ObjectGuid Unused2; @@ -700,23 +700,23 @@ namespace Game.Networking.Packets public struct NameCacheLookupResult { public ObjectGuid Player; - public byte Result = 0; // 0 - full packet, != 0 - only guid + public byte Result; // 0 - full packet, != 0 - only guid public PlayerGuidLookupData Data; - public NameCacheUnused920? Unused920; + public NameCacheUnused920 Unused920; public void Write(WorldPacket data) { data.WriteUInt8(Result); data.WritePackedGuid(Player); data.WriteBit(Data != null); - data.WriteBit(Unused920.HasValue); + data.WriteBit(Unused920 != null); data.FlushBits(); if (Data != null) Data.Write(data); - if (Unused920.HasValue) - Unused920.Value.Write(data); + if (Unused920 != null) + Unused920.Write(data); } } diff --git a/Source/Game/Scripting/ScriptManager.cs b/Source/Game/Scripting/ScriptManager.cs index e2657db36..629c48194 100644 --- a/Source/Game/Scripting/ScriptManager.cs +++ b/Source/Game/Scripting/ScriptManager.cs @@ -165,6 +165,8 @@ namespace Game.Scripting case "SceneScript": case "QuestScript": case "ConversationScript": + case "AchievementScript": + case "BattlefieldScript": if (!attribute.Name.IsEmpty()) name = attribute.Name; diff --git a/Source/Game/Server/WorldManager.cs b/Source/Game/Server/WorldManager.cs index 751bffebc..02a859ed2 100644 --- a/Source/Game/Server/WorldManager.cs +++ b/Source/Game/Server/WorldManager.cs @@ -400,8 +400,7 @@ namespace Game || (WorldConfig.GetIntValue(WorldCfg.Expansion) != 0 && (!Global.MapMgr.ExistMapAndVMap(530, 10349.6f, -6357.29f) || !Global.MapMgr.ExistMapAndVMap(530, -3961.64f, -13931.2f)))) { Log.outError(LogFilter.ServerLoading, "Unable to load critical files - server shutting down !!!"); - ShutdownServ(0, 0, ShutdownExitCode.Error); - return; + Environment.Exit(1); } // Initialize pool manager @@ -499,9 +498,6 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, "Loading GameObject models..."); GameObjectModel.LoadGameObjectModelList(); - Log.outInfo(LogFilter.ServerLoading, "Loading Script Names..."); - Global.ObjectMgr.LoadScriptNames(); - Log.outInfo(LogFilter.ServerLoading, "Loading Instance Template..."); Global.ObjectMgr.LoadInstanceTemplate(); diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index 5dba32e29..728f2f5af 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -9320,12 +9320,12 @@ namespace Game.Spells public bool HasFlag(ProcFlags procFlags) { - return (_storage[0] & procFlags) != 0; + return (_storage[0] & (int)procFlags) != 0; } public bool HasFlag(ProcFlags2 procFlags) { - return (_storage[1] & procFlags) != 0; + return (_storage[1] & (int)procFlags) != 0; } } } \ No newline at end of file diff --git a/Source/Game/Spells/SpellInfo.cs b/Source/Game/Spells/SpellInfo.cs index af027b1af..8111be4da 100644 --- a/Source/Game/Spells/SpellInfo.cs +++ b/Source/Game/Spells/SpellInfo.cs @@ -41,7 +41,7 @@ namespace Game.Spells if (spellEffect == null) continue; - _effects.EnsureWritableListIndex(spellEffect.EffectIndex, new SpellEffectInfo(this)); + _effects.EnsureWritableListIndex((uint)spellEffect.EffectIndex, new SpellEffectInfo(this)); _effects[(int)spellEffect.EffectIndex] = new SpellEffectInfo(this, spellEffect); } @@ -259,7 +259,7 @@ namespace Game.Spells foreach (SpellEffectRecord spellEffect in effects) { - _effects.EnsureWritableListIndex(spellEffect.EffectIndex, new SpellEffectInfo(this)); + _effects.EnsureWritableListIndex((uint)spellEffect.EffectIndex, new SpellEffectInfo(this)); _effects[(int)spellEffect.EffectIndex] = new SpellEffectInfo(this, spellEffect); } @@ -4026,7 +4026,7 @@ namespace Game.Spells _spellInfo = spellInfo; if (effect != null) { - EffectIndex = effect.EffectIndex; + EffectIndex = (uint)effect.EffectIndex; Effect = (SpellEffectName)effect.Effect; ApplyAuraName = (AuraType)effect.EffectAura; ApplyAuraPeriod = effect.EffectAuraPeriod; @@ -4205,7 +4205,7 @@ namespace Game.Spells { RandPropPointsRecord randPropPoints = CliDB.RandPropPointsStorage.LookupByKey(effectiveItemLevel); if (randPropPoints == null) - randPropPoints = CliDB.RandPropPointsStorage.LookupByKey(CliDB.RandPropPointsStorage.Count - 1); + randPropPoints = CliDB.RandPropPointsStorage.LookupByKey(CliDB.RandPropPointsStorage.GetNumRows() - 1); tempValue = Scaling.Class == -8 ? randPropPoints.DamageReplaceStatF : randPropPoints.DamageSecondaryF; } diff --git a/Source/Game/Spells/SpellManager.cs b/Source/Game/Spells/SpellManager.cs index 838fff483..13684057f 100644 --- a/Source/Game/Spells/SpellManager.cs +++ b/Source/Game/Spells/SpellManager.cs @@ -1417,7 +1417,7 @@ namespace Game.Entities } if ((procEntry.AttributesMask & ~ProcAttributes.AllAllowed) != 0) { - Log.outError(LogFilter.Sql, $"The `spell_proc` table entry for spellId {spellInfo.Id} has `AttributesMask` value specifying invalid attributes 0x{procEntry.AttributesMask & ~ProcAttributes.AllAllowed:X2}."); + Log.outError(LogFilter.Sql, $"The `spell_proc` table entry for spellId {spellInfo.Id} has `AttributesMask` value specifying invalid attributes 0x{(procEntry.AttributesMask & ~ProcAttributes.AllAllowed):X}."); procEntry.AttributesMask &= ProcAttributes.AllAllowed; } @@ -1448,7 +1448,7 @@ namespace Game.Entities continue; // Nothing to do if no flags set - if (!spellInfo.ProcFlags) + if (spellInfo.ProcFlags == null) continue; bool addTriggerFlag = false; @@ -2369,7 +2369,7 @@ namespace Game.Entities uint spellId = effectsResult.Read(0); Difficulty difficulty = (Difficulty)effectsResult.Read(2); SpellEffectRecord effect = new(); - effect.EffectIndex = effectsResult.Read(1); + effect.EffectIndex = effectsResult.Read(1); effect.Effect = effectsResult.Read(3); effect.EffectAura = effectsResult.Read(4); effect.EffectAmplitude = effectsResult.Read(5); @@ -4822,7 +4822,7 @@ namespace Game.Entities { public SpellSchoolMask SchoolMask { get; set; } // if nonzero - bitmask for matching proc condition based on spell's school public SpellFamilyNames SpellFamilyName { get; set; } // if nonzero - for matching proc condition based on candidate spell's SpellFamilyName - public FlagArray128 SpellFamilyMask { get; set; } = new FlagArray128(); // if nonzero - bitmask for matching proc condition based on candidate spell's SpellFamilyFlags + public FlagArray128 SpellFamilyMask { get; set; } = new(4); // if nonzero - bitmask for matching proc condition based on candidate spell's SpellFamilyFlags public ProcFlagsInit ProcFlags { get; set; } // if nonzero - owerwrite procFlags field for given Spell.dbc entry, bitmask for matching proc condition, see enum ProcFlags public ProcFlagsSpellType SpellTypeMask { get; set; } // if nonzero - bitmask for matching proc condition based on candidate spell's damage/heal effects, see enum ProcFlagsSpellType public ProcFlagsSpellPhase SpellPhaseMask { get; set; } // if nonzero - bitmask for matching phase of a spellcast on which proc occurs, see enum ProcFlagsSpellPhase diff --git a/Source/Scripts/Spells/Paladin.cs b/Source/Scripts/Spells/Paladin.cs index 22d292afe..4b0d6a7fe 100644 --- a/Source/Scripts/Spells/Paladin.cs +++ b/Source/Scripts/Spells/Paladin.cs @@ -650,7 +650,7 @@ namespace Scripts.Spells.Paladin [Script] // 54149 - Infusion of Light class spell_pal_infusion_of_light : AuraScript { - static FlagArray128 HolyLightSpellClassMask = new FlagArray128(0, 0, 0x400); + static FlagArray128 HolyLightSpellClassMask = new(0, 0, 0x400); public override bool Validate(SpellInfo spellInfo) { diff --git a/Source/WorldServer/Server.cs b/Source/WorldServer/Server.cs index 5f229730c..700c08e22 100644 --- a/Source/WorldServer/Server.cs +++ b/Source/WorldServer/Server.cs @@ -31,8 +31,6 @@ namespace WorldServer { public class Server { - const uint WorldSleep = 1; - static void Main() { //Set Culture