From 580b6d7c61dcb6a0cf88c97fc116adecd3195c9a Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Fri, 28 May 2021 23:44:58 -0700 Subject: [PATCH] Add OnDoorUse hook/event in GetDataHandlers --- CHANGELOG.md | 1 + TShockAPI/GetDataHandlers.cs | 68 +++++++++++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a51eda7..ff87ee84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Moved the emoji player index check into a new class of handlers called `IllegalPerSe`, which is designed to help isolate parts of TShock and make it so that "protocol violations" are treated separately from heuristic based anti-cheat checks. (@hakusaro) * Changed `TSPlayer.FindByNameOrID` so that it will continue searching for players and return a list of many players whem ambiguous matches exist in all cases. Specifically, this avoids a scenario where a griefer names themselves `1` and is difficult to enact justice on, because their name will not be found by the matching system used to kick players. To help with ambiguity, this method now processes requests with prefixes `tsi:` and `tsn:`. `tsi:[number]` will process the search as looking for an exact player by ID. `tsn:` will process the search as looking for an exact name, case sensitive. In both cases, the system will return an exact result in the "old-style" result, i.e., a `List` with exactly one result. For example, `/kick tsid:1` will match the player with the ID `1`. `/kick tsn:1` will match the username `1`. In addition, players who attempt to join the server with the name prefixes `tsn:` and `tsi:` will be rejected for having invalid names. (@hakusaro, @Onusai) * Added warnings for conditions where a password is set at runtime but can be bypassed. The thinking is that if a user sets a password when they're booting the server, that's what they expect to be the password. The only thing is that sometimes, other config options can basically defeat this as a security feature. The goal is just to communicate more and make things clearer. The server also warns users when UUID login is enabled, because it can be confusing and insecure. (@hakusaro, @Onusai) +* Added hook for `OnDoorUse` (`DoorUse`) and associated `DoorUseEventArgs` fired when a door is used. Also added `GetDataHandlers.DoorAction` enum for determining the action of a door. (@hakusaro) ## TShock 4.5.3 * Added permissions for using Teleportation Potions, Magic Conch, and Demon Conch. (@drunderscore) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 27173d4a..dfcb1c3b 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -493,6 +493,50 @@ namespace TShockAPI return args.Handled; } + /// + /// DoorUseEventArgs - the arguments for a DoorUse event + /// + public class DoorUseEventArgs : GetDataHandledEventArgs + { + /// + /// X - The x position of the door being used + /// + public short X { get; set; } + /// + /// Y - The y position of the door being used + /// + public short Y { get; set; } + /// + /// Direction - Information about which way the door opens or where the player is relative to the door + /// + public byte Direction { get; set; } + /// + /// Action - The type of thing happening to the door + /// + public DoorAction Action { get; set; } + } + + /// + /// DoorUse - called when a door is opened or closed (normal or trap) + /// + public static HandlerList DoorUse = new HandlerList(); + private static bool OnDoorUse(TSPlayer ply, MemoryStream data, short x, short y, byte direction, DoorAction action) + { + if (DoorUse == null) + return false; + + var args = new DoorUseEventArgs + { + Player = ply, + X = x, + Y = y, + Direction = direction, + Action = action + }; + DoorUse.Invoke(null, args); + return args.Handled; + } + /// /// For use in a SendTileRect event /// @@ -2618,10 +2662,17 @@ namespace TShockAPI private static bool HandleDoorUse(GetDataHandlerArgs args) { - byte type = (byte)args.Data.ReadByte(); + byte action = (byte)args.Data.ReadByte(); short x = args.Data.ReadInt16(); short y = args.Data.ReadInt16(); - args.Data.ReadByte(); //Ignore direction + byte direction = (byte)args.Data.ReadByte(); //Ignore direction + + DoorAction doorAction = (DoorAction)action; + + if (OnDoorUse(args.Player, args.Data, x, y, direction, doorAction)) + return true; + + ushort tileType = Main.tile[x, y].type; if (x >= Main.maxTilesX || y >= Main.maxTilesY || x < 0 || y < 0) // Check for out of range { @@ -2629,13 +2680,12 @@ namespace TShockAPI return true; } - if (type < 0 || type > 5) + if (action < 0 || action > 5) { TShock.Log.ConsoleDebug("GetDataHandlers / HandleDoorUse rejected type 0 5 check {0}", args.Player.Name); return true; } - ushort tileType = Main.tile[x, y].type; if (tileType != TileID.ClosedDoor && tileType != TileID.OpenDoor && tileType != TileID.TallGateClosed && tileType != TileID.TallGateOpen @@ -3995,6 +4045,16 @@ namespace TShockAPI return true; } + public enum DoorAction + { + OpenDoor = 0, + CloseDoor, + OpenTrapdoor, + CloseTrapdoor, + OpenTallGate, + CloseTallGate + } + public enum EditAction { KillTile = 0,