diff --git a/CHANGELOG.md b/CHANGELOG.md index 7286ea27..5149a73e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Added `TSPlayer.CheckIgnores()` and removed `TShock.CheckIgnores(TSPlayer)`. (@hakusaro) * Hooks inside TShock can now be registered with their `Register` method and can be prioritized according to the TShock HandlerList system. (@hakusaro) * Fix message requiring login not using the command specifier set in the config file. (@hakusaro) +* Fix stack hack detection being inconsistent between two different check points. Moved `TShock.HackedInventory` to `TSPlayer.HasHackedItemStacks`. Added `GetDataHandlers.GetDataHandledEventArgs` which is where most hooks will inherit from in the future. (@hakusaro) ## TShock 4.3.25 * Fixed a critical exploit in the Terraria protocol that could cause massive unpreventable world corruption as well as a number of other problems. Thanks to @bartico6 for reporting. Fixed by the efforts of @QuiCM, @hakusaro, and tips in the right directioon from @bartico6. diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index 8e81d802..b0b6a427 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -42,6 +42,7 @@ namespace TShockAPI { // Setup hooks + GetDataHandlers.GetSection += OnGetSection; GetDataHandlers.PlaceItemFrame += OnPlaceItemFrame; GetDataHandlers.GemLockToggle += OnGemLockToggle; GetDataHandlers.PlaceTileEntity += OnPlaceTileEntity; @@ -64,6 +65,28 @@ namespace TShockAPI GetDataHandlers.TileEdit += OnTileEdit; } + internal void OnGetSection(object sender, GetDataHandlers.GetSectionEventArgs args) + { + if (args.Player.RequestedSection) + { + args.Handled = true; + return; + } + args.Player.RequestedSection = true; + + if (String.IsNullOrEmpty(args.Player.Name)) + { + TShock.Utils.ForceKick(args.Player, "Blank name.", true); + args.Handled = true; + return; + } + + if (!args.Player.HasPermission(Permissions.ignorestackhackdetection)) + { + args.Player.IsDisabledForStackDetection = args.Player.HasHackedItemStacks(true); + } + } + /// Fired when an item frame is placed for anti-cheat detection. /// The object that triggered the event. /// The packet arguments that the event has. diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 9162acd2..83bcb26d 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -58,6 +58,19 @@ namespace TShockAPI } } + /// + /// A custom HandledEventArgs that contains TShock's TSPlayer for the triggering uesr and the Terraria MP data stream. + /// Differentiated by GetDataHandlerArgs because it can be handled and responds to being handled. + /// + public class GetDataHandledEventArgs : HandledEventArgs + { + /// The TSPlayer that triggered the event. + public TSPlayer Player { get; set; } + + /// The raw MP packet data associated with the event. + public MemoryStream Data { get; set; } + } + public static class GetDataHandlers { private static Dictionary GetDataHandlerDelegates; @@ -1903,21 +1916,46 @@ namespace TShockAPI return true; } + /// The arguments to a GetSection packet. + public class GetSectionEventArgs : GetDataHandledEventArgs + { + /// The X position requested. Or -1 for spawn. + public int X { get; set; } + + /// The Y position requested. Or -1 for spawn. + public int Y { get; set; } + } + + /// The hook for a GetSection event. + public static HandlerList GetSection = new HandlerList(); + + /// Fires a GetSection event. + /// The TSPlayer that caused the GetSection. + /// The raw MP protocol data. + /// The x coordinate requested or -1 for spawn. + /// The y coordinate requested or -1 for spawn. + /// bool + private static bool OnGetSection(TSPlayer player, MemoryStream data, int x, int y) + { + if (GetSection == null) + return false; + + var args = new GetSectionEventArgs + { + Player = player, + Data = data, + X = x, + Y = y, + }; + + GetSection.Invoke(null, args); + return args.Handled; + } + private static bool HandleGetSection(GetDataHandlerArgs args) { - if (args.Player.RequestedSection) + if (OnGetSection(args.Player, args.Data, args.Data.ReadInt32(), args.Data.ReadInt32())) return true; - args.Player.RequestedSection = true; - if (String.IsNullOrEmpty(args.Player.Name)) - { - TShock.Utils.ForceKick(args.Player, "Blank name.", true); - return true; - } - - if (!args.Player.HasPermission(Permissions.ignorestackhackdetection)) - { - args.Player.IsDisabledForStackDetection = args.Player.HasHackedItemStacks(true); - } if (TShock.Utils.ActivePlayers() + 1 > TShock.Config.MaxSlots && !args.Player.HasPermission(Permissions.reservedslot))