From da793a8e20c20e9635f03bc75424aacf9fc36cbb Mon Sep 17 00:00:00 2001 From: ratkosrb Date: Fri, 27 May 2022 05:34:24 +0300 Subject: [PATCH 1/4] Use Environment.TickCount for packet time since its faster. --- .../Client/PacketHandlers/MovementHandler.cs | 2 +- .../World/Client/PacketHandlers/UpdateHandler.cs | 15 ++++++++++----- HermesProxy/World/Client/WorldClient.cs | 2 +- .../World/Server/PacketHandlers/SpellHandler.cs | 14 +++++++------- HermesProxy/World/Server/WorldSocket.cs | 11 ----------- HermesProxy/World/SniffFile.cs | 2 +- 6 files changed, 20 insertions(+), 26 deletions(-) diff --git a/HermesProxy/World/Client/PacketHandlers/MovementHandler.cs b/HermesProxy/World/Client/PacketHandlers/MovementHandler.cs index bfcec93f..9dca35aa 100644 --- a/HermesProxy/World/Client/PacketHandlers/MovementHandler.cs +++ b/HermesProxy/World/Client/PacketHandlers/MovementHandler.cs @@ -466,7 +466,7 @@ void HandleMonsterMove(WorldPacket packet) bool isTaxiFlight = (hasTaxiFlightFlags && (GetSession().GameState.IsWaitingForTaxiStart || - GetSession().GameState.CurrentPlayerCreateTime == packet.GetReceivedTime()) && + Math.Abs(packet.GetReceivedTime() - GetSession().GameState.CurrentPlayerCreateTime) <= 1000) && GetSession().GameState.CurrentPlayerGuid == guid); if (isTaxiFlight) diff --git a/HermesProxy/World/Client/PacketHandlers/UpdateHandler.cs b/HermesProxy/World/Client/PacketHandlers/UpdateHandler.cs index 455fb695..3d529ac1 100644 --- a/HermesProxy/World/Client/PacketHandlers/UpdateHandler.cs +++ b/HermesProxy/World/Client/PacketHandlers/UpdateHandler.cs @@ -1,4 +1,6 @@ -using Framework.GameMath; +//#define DEBUG_UPDATES + +using Framework.GameMath; using Framework.Logging; using Framework.Util; using HermesProxy.Enums; @@ -345,16 +347,19 @@ private string GetIndexString(params object[] values) } private const bool DebugUpdates = false; + private void PrintString(string txt, params object[] indexes) { - if (DebugUpdates) - Console.WriteLine("{0}{1}", GetIndexString(indexes), txt); +#if DEBUG_UPDATES + Console.WriteLine("{0}{1}", GetIndexString(indexes), txt); +#endif } private T PrintValue(string name, T obj, params object[] indexes) { - if (DebugUpdates) - Console.WriteLine("{0}{1}: {2}", GetIndexString(indexes), name, obj); +#if DEBUG_UPDATES + Console.WriteLine("{0}{1}: {2}", GetIndexString(indexes), name, obj); +#endif return obj; } diff --git a/HermesProxy/World/Client/WorldClient.cs b/HermesProxy/World/Client/WorldClient.cs index 7703c5a6..c5b818c1 100644 --- a/HermesProxy/World/Client/WorldClient.cs +++ b/HermesProxy/World/Client/WorldClient.cs @@ -185,7 +185,7 @@ private void ReceiveCallback(IAsyncResult AR) } WorldPacket packet = new WorldPacket(buffer); - packet.SetReceiveTime(Time.UnixTime); + packet.SetReceiveTime(Environment.TickCount); HandlePacket(packet); } else diff --git a/HermesProxy/World/Server/PacketHandlers/SpellHandler.cs b/HermesProxy/World/Server/PacketHandlers/SpellHandler.cs index 6f570a30..c9bcc214 100644 --- a/HermesProxy/World/Server/PacketHandlers/SpellHandler.cs +++ b/HermesProxy/World/Server/PacketHandlers/SpellHandler.cs @@ -108,7 +108,7 @@ void HandleCastSpell(CastSpell cast) GameData.AutoRepeatSpells.Contains(cast.Cast.SpellID)) { ClientCastRequest castRequest = new ClientCastRequest(); - castRequest.Timestamp = Time.UnixTime; + castRequest.Timestamp = Environment.TickCount; castRequest.SpellId = cast.Cast.SpellID; castRequest.SpellXSpellVisualId = cast.Cast.SpellXSpellVisualID; castRequest.ClientGUID = cast.Cast.CastID; @@ -134,7 +134,7 @@ void HandleCastSpell(CastSpell cast) else { ClientCastRequest castRequest = new ClientCastRequest(); - castRequest.Timestamp = Time.UnixTime; + castRequest.Timestamp = Environment.TickCount; castRequest.SpellId = cast.Cast.SpellID; castRequest.SpellXSpellVisualId = cast.Cast.SpellXSpellVisualID; castRequest.ClientGUID = cast.Cast.CastID; @@ -148,7 +148,7 @@ void HandleCastSpell(CastSpell cast) } else { - if (GetSession().GameState.CurrentClientNormalCast.Timestamp + 10 < castRequest.Timestamp) + if (GetSession().GameState.CurrentClientNormalCast.Timestamp + 10000 < castRequest.Timestamp) { SendCastRequestFailed(GetSession().GameState.CurrentClientNormalCast, false); GetSession().GameState.CurrentClientNormalCast = null; @@ -191,7 +191,7 @@ void HandleCastSpell(CastSpell cast) void HandlePetCastSpell(PetCastSpell cast) { ClientCastRequest castRequest = new ClientCastRequest(); - castRequest.Timestamp = Time.UnixTime; + castRequest.Timestamp = Environment.TickCount; castRequest.SpellId = cast.Cast.SpellID; castRequest.SpellXSpellVisualId = cast.Cast.SpellXSpellVisualID; castRequest.ClientGUID = cast.Cast.CastID; @@ -205,7 +205,7 @@ void HandlePetCastSpell(PetCastSpell cast) } else { - if (GetSession().GameState.CurrentClientPetCast.Timestamp + 10 < castRequest.Timestamp) + if (GetSession().GameState.CurrentClientPetCast.Timestamp + 10000 < castRequest.Timestamp) { SendCastRequestFailed(GetSession().GameState.CurrentClientPetCast, true); GetSession().GameState.CurrentClientPetCast = null; @@ -238,7 +238,7 @@ void HandlePetCastSpell(PetCastSpell cast) void HandleUseItem(UseItem use) { ClientCastRequest castRequest = new ClientCastRequest(); - castRequest.Timestamp = Time.UnixTime; + castRequest.Timestamp = Environment.TickCount; castRequest.SpellId = use.Cast.SpellID; castRequest.SpellXSpellVisualId = use.Cast.SpellXSpellVisualID; castRequest.ClientGUID = use.Cast.CastID; @@ -253,7 +253,7 @@ void HandleUseItem(UseItem use) } else { - if (GetSession().GameState.CurrentClientNormalCast.Timestamp + 10 < castRequest.Timestamp) + if (GetSession().GameState.CurrentClientNormalCast.Timestamp + 10000 < castRequest.Timestamp) { SendCastRequestFailed(GetSession().GameState.CurrentClientNormalCast, false); GetSession().GameState.CurrentClientNormalCast = null; diff --git a/HermesProxy/World/Server/WorldSocket.cs b/HermesProxy/World/Server/WorldSocket.cs index 18a5b7ec..4117ac5c 100644 --- a/HermesProxy/World/Server/WorldSocket.cs +++ b/HermesProxy/World/Server/WorldSocket.cs @@ -60,8 +60,6 @@ public partial class WorldSocket : SocketBase ConnectToKey _instanceConnectKey; RealmId _realmId; - long _LastPingTime; - ZLib.z_stream _compressionStream; ConcurrentDictionary _clientPacketTable = new(); GlobalSessionData _globalSession; @@ -1021,15 +1019,6 @@ public void SendServerTimeOffset() void HandlePing(Ping ping) { - if (_LastPingTime == 0) - _LastPingTime = Time.UnixTime; // for 1st ping - else - { - long now = Time.UnixTime; - long diff = now - _LastPingTime; - _LastPingTime = now; - } - SendPacket(new Pong(ping.Serial)); } diff --git a/HermesProxy/World/SniffFile.cs b/HermesProxy/World/SniffFile.cs index bec3d7ec..f8cfb22c 100644 --- a/HermesProxy/World/SniffFile.cs +++ b/HermesProxy/World/SniffFile.cs @@ -50,7 +50,7 @@ public void WritePacket(uint opcode, bool isFromClient, byte[] data) uint unixtime = (uint)Time.UnixTime; _fileWriter.Write(unixtime); - _fileWriter.Write(unixtime); // tick count + _fileWriter.Write(Environment.TickCount); if (isFromClient) { From c14eadeb34cfa8b869f0a76ba2215f264fb31c02 Mon Sep 17 00:00:00 2001 From: ratkosrb Date: Fri, 27 May 2022 05:37:10 +0300 Subject: [PATCH 2/4] Remove unused constant. --- HermesProxy/World/Client/PacketHandlers/UpdateHandler.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/HermesProxy/World/Client/PacketHandlers/UpdateHandler.cs b/HermesProxy/World/Client/PacketHandlers/UpdateHandler.cs index 3d529ac1..7fca0a77 100644 --- a/HermesProxy/World/Client/PacketHandlers/UpdateHandler.cs +++ b/HermesProxy/World/Client/PacketHandlers/UpdateHandler.cs @@ -346,8 +346,6 @@ private string GetIndexString(params object[] values) }); } - private const bool DebugUpdates = false; - private void PrintString(string txt, params object[] indexes) { #if DEBUG_UPDATES From 3271212d8aa9bb5d4545418f15e5671ec64f0a69 Mon Sep 17 00:00:00 2001 From: ratkosrb Date: Fri, 27 May 2022 07:23:21 +0300 Subject: [PATCH 3/4] Add an opcodes dictionary to speed up conversion. --- HermesProxy/VersionChecker.cs | 102 +++++++++++++++++++++++- HermesProxy/World/Client/WorldClient.cs | 2 +- HermesProxy/World/Enums/Opcodes.cs | 61 ++++++-------- HermesProxy/World/Packet.cs | 15 ++-- HermesProxy/World/Server/WorldSocket.cs | 2 +- 5 files changed, 136 insertions(+), 46 deletions(-) diff --git a/HermesProxy/VersionChecker.cs b/HermesProxy/VersionChecker.cs index 8b7751c9..8aa7ad00 100644 --- a/HermesProxy/VersionChecker.cs +++ b/HermesProxy/VersionChecker.cs @@ -29,7 +29,56 @@ static LegacyVersion() UpdateFieldDictionary = new Dictionary>(); UpdateFieldNameDictionary = new Dictionary>(); if (!LoadUFDictionariesInto(UpdateFieldDictionary, UpdateFieldNameDictionary)) - Log.Print(LogType.Error, "Could not load update fields for current server version."); + Log.Print(LogType.Error, "Could not load update fields for current legacy version."); + if (!LoadOpcodeDictionaries()) + Log.Print(LogType.Error, "Could not load opcodes for current legacy version."); + } + + private static readonly Dictionary CurrentToUniversalOpcodeDictionary = new(); + private static readonly Dictionary UniversalToCurrentOpcodeDictionary = new(); + + private static bool LoadOpcodeDictionaries() + { + Type enumType = Opcodes.GetOpcodesEnumForVersion(Build); + if (enumType == null) + return false; + + foreach (var item in Enum.GetValues(enumType)) + { + string oldOpcodeName = Enum.GetName(enumType, item); + Opcode universalOpcode = Opcodes.GetUniversalOpcode(oldOpcodeName); + if (universalOpcode == Opcode.MSG_NULL_ACTION && + oldOpcodeName != "MSG_NULL_ACTION") + { + Log.Print(LogType.Error, $"Opcode {oldOpcodeName} is missing from the universal opcode enum!"); + continue; + } + + CurrentToUniversalOpcodeDictionary.Add((uint)item, universalOpcode); + UniversalToCurrentOpcodeDictionary.Add(universalOpcode, (uint)item); + } + + if (CurrentToUniversalOpcodeDictionary.Count < 1) + return false; + + Log.Print(LogType.Server, $"Loaded {CurrentToUniversalOpcodeDictionary.Count} legacy opcodes."); + return true; + } + + public static Opcode GetUniversalOpcode(uint opcode) + { + Opcode universalOpcode; + if (CurrentToUniversalOpcodeDictionary.TryGetValue(opcode, out universalOpcode)) + return universalOpcode; + return Opcode.MSG_NULL_ACTION; + } + + public static uint GetCurrentOpcode(Opcode universalOpcode) + { + uint opcode; + if (UniversalToCurrentOpcodeDictionary.TryGetValue(universalOpcode, out opcode)) + return opcode; + return 0; } private static readonly Dictionary> UpdateFieldDictionary; @@ -284,7 +333,56 @@ static ModernVersion() UpdateFieldDictionary = new Dictionary>(); UpdateFieldNameDictionary = new Dictionary>(); if (!LoadUFDictionariesInto(UpdateFieldDictionary, UpdateFieldNameDictionary)) - Log.Print(LogType.Error, "Could not load update fields for current server version."); + Log.Print(LogType.Error, "Could not load update fields for current modern version."); + if (!LoadOpcodeDictionaries()) + Log.Print(LogType.Error, "Could not load opcodes for current modern version."); + } + + private static readonly Dictionary CurrentToUniversalOpcodeDictionary = new(); + private static readonly Dictionary UniversalToCurrentOpcodeDictionary = new(); + + private static bool LoadOpcodeDictionaries() + { + Type enumType = Opcodes.GetOpcodesEnumForVersion(Build); + if (enumType == null) + return false; + + foreach (var item in Enum.GetValues(enumType)) + { + string oldOpcodeName = Enum.GetName(enumType, item); + Opcode universalOpcode = Opcodes.GetUniversalOpcode(oldOpcodeName); + if (universalOpcode == Opcode.MSG_NULL_ACTION && + oldOpcodeName != "MSG_NULL_ACTION") + { + Log.Print(LogType.Error, $"Opcode {oldOpcodeName} is missing from the universal opcode enum!"); + continue; + } + + CurrentToUniversalOpcodeDictionary.Add((uint)item, universalOpcode); + UniversalToCurrentOpcodeDictionary.Add(universalOpcode, (uint)item); + } + + if (CurrentToUniversalOpcodeDictionary.Count < 1) + return false; + + Log.Print(LogType.Server, $"Loaded {CurrentToUniversalOpcodeDictionary.Count} modern opcodes."); + return true; + } + + public static Opcode GetUniversalOpcode(uint opcode) + { + Opcode universalOpcode; + if (CurrentToUniversalOpcodeDictionary.TryGetValue(opcode, out universalOpcode)) + return universalOpcode; + return Opcode.MSG_NULL_ACTION; + } + + public static uint GetCurrentOpcode(Opcode universalOpcode) + { + uint opcode; + if (UniversalToCurrentOpcodeDictionary.TryGetValue(universalOpcode, out opcode)) + return opcode; + return 0; } private static readonly Dictionary> UpdateFieldDictionary; diff --git a/HermesProxy/World/Client/WorldClient.cs b/HermesProxy/World/Client/WorldClient.cs index c5b818c1..71e52f54 100644 --- a/HermesProxy/World/Client/WorldClient.cs +++ b/HermesProxy/World/Client/WorldClient.cs @@ -241,7 +241,7 @@ private void SendPacket(WorldPacket packet) header.Opcode = packet.GetOpcode(); header.Write(buffer); - Log.Print(LogType.Debug, $"Sending opcode {Opcodes.GetOpcodeNameForVersion(header.Opcode, Settings.ServerBuild)} ({header.Opcode}) with size {header.Size}."); + Log.Print(LogType.Debug, $"Sending opcode {LegacyVersion.GetUniversalOpcode(header.Opcode)} ({header.Opcode}) with size {header.Size}."); byte[] headerArray = buffer.GetData(); if (_worldCrypt != null) diff --git a/HermesProxy/World/Enums/Opcodes.cs b/HermesProxy/World/Enums/Opcodes.cs index 0aaec850..12e9cbb8 100644 --- a/HermesProxy/World/Enums/Opcodes.cs +++ b/HermesProxy/World/Enums/Opcodes.cs @@ -44,52 +44,41 @@ public static ClientVersionBuild GetOpcodesDefiningBuild(ClientVersionBuild vers } return ClientVersionBuild.Zero; } - public static uint GetOpcodeValueForVersion(Opcode opcode, ClientVersionBuild version) + + public static Type GetOpcodesEnumForVersion(ClientVersionBuild version) { switch (GetOpcodesDefiningBuild(version)) { case ClientVersionBuild.V1_12_1_5875: - return FindOpcodeValueInEnum(opcode.ToString()); + return typeof(V1_12_1_5875.Opcode); case ClientVersionBuild.V2_4_3_8606: - return FindOpcodeValueInEnum(opcode.ToString()); + return typeof(V2_4_3_8606.Opcode); case ClientVersionBuild.V3_3_5a_12340: - return FindOpcodeValueInEnum(opcode.ToString()); + return typeof(V3_3_5_12340.Opcode); case ClientVersionBuild.V2_5_2_39570: - return FindOpcodeValueInEnum(opcode.ToString()); + return typeof(V2_5_2_39570.Opcode); } - return 0; + return null; } - public static uint GetOpcodeValueForVersion(string opcode, ClientVersionBuild version) + public static uint GetOpcodeValueForVersion(Opcode opcode, ClientVersionBuild version) { - switch (GetOpcodesDefiningBuild(version)) - { - case ClientVersionBuild.V1_12_1_5875: - return FindOpcodeValueInEnum(opcode); - case ClientVersionBuild.V2_4_3_8606: - return FindOpcodeValueInEnum(opcode); - case ClientVersionBuild.V3_3_5a_12340: - return FindOpcodeValueInEnum(opcode); - case ClientVersionBuild.V2_5_2_39570: - return FindOpcodeValueInEnum(opcode); - } + return GetOpcodeValueForVersion(opcode.ToString(), version); + } + + public static uint GetOpcodeValueForVersion(string opcodeName, ClientVersionBuild version) + { + object opcode; + if (Enum.TryParse(GetOpcodesEnumForVersion(version), opcodeName, out opcode)) + return (uint)opcode; + return 0; } public static string GetOpcodeNameForVersion(uint opcode, ClientVersionBuild version) { - switch (GetOpcodesDefiningBuild(version)) - { - case ClientVersionBuild.V1_12_1_5875: - return FindOpcodeNameInEnum(opcode); - case ClientVersionBuild.V2_4_3_8606: - return FindOpcodeNameInEnum(opcode); - case ClientVersionBuild.V3_3_5a_12340: - return FindOpcodeNameInEnum(opcode); - case ClientVersionBuild.V2_5_2_39570: - return FindOpcodeNameInEnum(opcode); - } - return "UNKNOWN"; + Type enumType = GetOpcodesEnumForVersion(version); + return Enum.ToObject(enumType, opcode).ToString(); } public static Opcode GetUniversalOpcode(uint opcode, ClientVersionBuild version) @@ -100,11 +89,10 @@ public static Opcode GetUniversalOpcode(uint opcode, ClientVersionBuild version) public static Opcode GetUniversalOpcode(string name) { - foreach (var item in Enum.GetValues(typeof(Opcode))) - { - if (Enum.GetName(typeof(Opcode), item) == name) - return (Opcode)item; - } + object opcode; + if (Enum.TryParse(typeof(Opcode), name, out opcode)) + return (Opcode)opcode; + return Opcode.MSG_NULL_ACTION; } @@ -129,7 +117,7 @@ private static string FindOpcodeNameInEnum(uint value) where T : System.Enum } } - public enum Opcode + public enum Opcode : uint { /* Generic opcode enumeration * Every opcode _name_ should be here (any version) @@ -3235,6 +3223,7 @@ public enum Opcode SMSG_UNKNOWN_8, SMSG_UNLEARNED_SPELLS, SMSG_UNLOAD_CHILD_MAP, + SMSG_UPDATE_AADC_STATUS_RESPONSE, SMSG_UPDATE_ACCOUNT_DATA, SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, SMSG_UPDATE_ACTION_BUTTONS, diff --git a/HermesProxy/World/Packet.cs b/HermesProxy/World/Packet.cs index 4d5a07d5..b16e4130 100644 --- a/HermesProxy/World/Packet.cs +++ b/HermesProxy/World/Packet.cs @@ -42,7 +42,7 @@ public void Dispose() public uint GetOpcode() { return _worldPacket.GetOpcode(); } public Opcode GetUniversalOpcode() { - return Opcodes.GetUniversalOpcode(GetOpcode(), Framework.Settings.ClientBuild); + return ModernVersion.GetUniversalOpcode(GetOpcode()); } public void LogPacket(ref SniffFile sniffFile) @@ -67,7 +67,7 @@ protected ServerPacket(Opcode universalOpcode) { connectionType = ConnectionType.Realm; - uint opcode = Opcodes.GetOpcodeValueForVersion(universalOpcode, Framework.Settings.ClientBuild); + uint opcode = ModernVersion.GetCurrentOpcode(universalOpcode); System.Diagnostics.Trace.Assert(opcode != 0); _worldPacket = new WorldPacket(opcode); } @@ -76,7 +76,7 @@ protected ServerPacket(Opcode universalOpcode, ConnectionType type = ConnectionT { connectionType = type; - uint opcode = Opcodes.GetOpcodeValueForVersion(universalOpcode, Framework.Settings.ClientBuild); + uint opcode = ModernVersion.GetCurrentOpcode(universalOpcode); System.Diagnostics.Trace.Assert(opcode != 0); _worldPacket = new WorldPacket(opcode); } @@ -93,7 +93,7 @@ public uint GetOpcode() } public Opcode GetUniversalOpcode() { - return Opcodes.GetUniversalOpcode(GetOpcode(), Framework.Settings.ClientBuild); + return ModernVersion.GetUniversalOpcode(GetOpcode()); } public byte[] GetData() @@ -143,7 +143,7 @@ public WorldPacket(uint opcode = 0) public WorldPacket(Opcode opcode) { - this.opcode = Opcodes.GetOpcodeValueForVersion(opcode, Framework.Settings.ServerBuild); + this.opcode = LegacyVersion.GetCurrentOpcode(opcode); System.Diagnostics.Trace.Assert(this.opcode != 0); } @@ -305,7 +305,10 @@ public void WriteBytes(WorldPacket data) public uint GetOpcode() { return opcode; } public Opcode GetUniversalOpcode(bool isModern) { - return Opcodes.GetUniversalOpcode(GetOpcode(), isModern ? Framework.Settings.ClientBuild : Framework.Settings.ServerBuild); + if (isModern) + return ModernVersion.GetUniversalOpcode(GetOpcode()); + else + return LegacyVersion.GetUniversalOpcode(GetOpcode()); } public long GetReceivedTime() { return m_receivedTime; } diff --git a/HermesProxy/World/Server/WorldSocket.cs b/HermesProxy/World/Server/WorldSocket.cs index 4117ac5c..b41440cc 100644 --- a/HermesProxy/World/Server/WorldSocket.cs +++ b/HermesProxy/World/Server/WorldSocket.cs @@ -371,7 +371,7 @@ public void SendPacket(ServerPacket packet) buffer.WriteBytes(compressedData, compressedSize); packetSize = (int)(compressedSize + 12); - opcode = (ushort)Opcodes.GetOpcodeValueForVersion(Opcode.SMSG_COMPRESSED_PACKET, Framework.Settings.ClientBuild); + opcode = (ushort)ModernVersion.GetCurrentOpcode(Opcode.SMSG_COMPRESSED_PACKET); System.Diagnostics.Trace.Assert(opcode != 0); data = buffer.GetData(); From 69c259cf8bd32dd2c4f288b36470b700a0df5208 Mon Sep 17 00:00:00 2001 From: ratkosrb Date: Fri, 27 May 2022 07:52:40 +0300 Subject: [PATCH 4/4] Fix possible crash on vanilla because of missing packet. --- HermesProxy/World/Server/PacketHandlers/SpellHandler.cs | 3 +++ HermesProxy/World/Server/Packets/SpellPackets.cs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/HermesProxy/World/Server/PacketHandlers/SpellHandler.cs b/HermesProxy/World/Server/PacketHandlers/SpellHandler.cs index d2818b6f..ad955afb 100644 --- a/HermesProxy/World/Server/PacketHandlers/SpellHandler.cs +++ b/HermesProxy/World/Server/PacketHandlers/SpellHandler.cs @@ -370,6 +370,9 @@ void HandleSelfRes(SelfRes revive) [PacketHandler(Opcode.CMSG_TOTEM_DESTROYED)] void HandleTotemDestroyed(TotemDestroyed totem) { + if (LegacyVersion.RemovedInVersion(ClientVersionBuild.V2_0_1_6180)) + return; + WorldPacket packet = new WorldPacket(Opcode.CMSG_TOTEM_DESTROYED); packet.WriteUInt8(totem.Slot); SendPacketToServer(packet); diff --git a/HermesProxy/World/Server/Packets/SpellPackets.cs b/HermesProxy/World/Server/Packets/SpellPackets.cs index 38426e87..548c0aa9 100644 --- a/HermesProxy/World/Server/Packets/SpellPackets.cs +++ b/HermesProxy/World/Server/Packets/SpellPackets.cs @@ -1555,8 +1555,10 @@ public TotemDestroyed(WorldPacket packet) : base(packet) { } public override void Read() { Slot = _worldPacket.ReadUInt8(); + Guid = _worldPacket.ReadPackedGuid128(); } public byte Slot; + public WowGuid Guid; } public class SetSpellModifier : ServerPacket