diff --git a/CHANGELOG.md b/CHANGELOG.md index 83383492..574c1962 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,7 @@ Putting this stuff down here so things don't conflict as often. * Added `TSPlayer` and `PlayerDeathReason` to `GetDataHandlers.PlayerDamage`. (@hakusaro) * Added `TSPlayer` to `GetDataHandlers.NPCStrike`. (@hakusaro) * Added `TSPlayer` to `GetDataHandlers.PlayerAnimation`. (@hakusaro) +* Added `GetDataHandlers.MassWireOperation` hook and related arguments. (@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 ab291c3a..f7e1628e 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -60,6 +60,43 @@ namespace TShockAPI GetDataHandlers.TileEdit.Register(OnTileEdit); } + internal void OnMassWireOperation(object sender, GetDataHandlers.MassWireOperationEventArgs args) + { + short startX = args.StartX; + short startY = args.StartY; + short endX = args.EndX; + short endY = args.EndY; + + List points = Utils.Instance.GetMassWireOperationRange( + new Point(startX, startY), + new Point(endX, endY), + args.Player.TPlayer.direction == 1); + + int x; + int y; + foreach (Point p in points) + { + /* Perform similar checks to TileKill + * The server-side nature of this packet removes the need to use SendTileSquare + * Range checks are currently ignored here as the items that send this seem to have infinite range */ + + x = p.X; + y = p.Y; + + if (!TShock.Utils.TilePlacementValid(x, y) || (args.Player.Dead && TShock.Config.PreventDeadModification)) + args.Handled = true; + return; + + if (TShock.CheckIgnores(args.Player)) + args.Handled = true; + return; + + if (TShock.CheckTilePermission(args.Player, x, y)) + args.Handled = true; + return; + } + } + /// Handles basic animation throttling for disabled players. /// sender /// args diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index b6d182b7..eb7aa572 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -1260,6 +1260,50 @@ namespace TShockAPI return args.Handled; } + /// The arguments to the MassWireOperation event. + public class MassWireOperationEventArgs : HandledEventArgs + { + /// The TSPlayer that triggered the event. + public TSPlayer Player { get; set; } + + /// The start X point in the operation. + public short StartX { get; set; } + + /// The start Y point in the operation. + public short StartY { get; set; } + + /// The end X point in the operation. + public short EndX { get; set; } + + /// The end Y point in the operation. + public short EndY { get; set; } + + /// ToolMode + public byte ToolMode { get; set; } + } + + /// Fired on a mass wire edit operation. + public static HandlerList MassWireOperation; + + private static bool OnMassWireOperation(TSPlayer player, short startX, short startY, short endX, short endY, byte toolMode) + { + if (MassWireOperation == null) + return false; + + var args = new MassWireOperationEventArgs + { + Player = player, + StartX = startX, + StartY = startY, + EndX = endX, + EndY = endY, + ToolMode = toolMode, + }; + + MassWireOperation.Invoke(null, args); + return args.Handled; + } + /// /// For use with a NPCSpecial event /// @@ -2987,33 +3031,10 @@ namespace TShockAPI short startY = args.Data.ReadInt16(); short endX = args.Data.ReadInt16(); short endY = args.Data.ReadInt16(); - args.Data.ReadByte(); // Ignore toolmode + byte toolMode = (byte) args.Data.ReadByte(); - List points = Utils.Instance.GetMassWireOperationRange( - new Point(startX, startY), - new Point(endX, endY), - args.Player.TPlayer.direction == 1); - - int x; - int y; - foreach (Point p in points) - { - /* Perform similar checks to TileKill - * The server-side nature of this packet removes the need to use SendTileSquare - * Range checks are currently ignored here as the items that send this seem to have infinite range */ - - x = p.X; - y = p.Y; - - if (!TShock.Utils.TilePlacementValid(x, y) || (args.Player.Dead && TShock.Config.PreventDeadModification)) - return true; - - if (TShock.CheckIgnores(args.Player)) - return true; - - if (TShock.CheckTilePermission(args.Player, x, y)) - return true; - } + if (OnMassWireOperation(args.Player, startX, startY, endX, endY, toolMode)) + return true; return false; }