diff --git a/CHANGELOG.md b/CHANGELOG.md
index 44dda4f3..b110aaad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
* Fixed the ability to spawn Zenith projectile with non-original items. (@AgaSpace)
* Added hook `GetDataHandlers.OnNpcTalk` for NpcTalk and a handler for it that stops unregistered and logged out players from interacting with NPCs, preventing them from smuggling or duplicating items via NPC item slots. (@tru321)
* Fixed the ability to create custom messages with your death (or the death of another player) (@AgaSpace)
+* Added the `OnSignRead` handler in `GetDataHandler`, and added the `SignRead` event. Added check to ensure the sign being read is within world bounds `(x >= 0 && y >= 0 && x < Main.maxTilesX && y < Main.maxTilesY)`. (@drunderscore)
## TShock 4.5.11
* Add the new allowed buff TentacleSpike to NPC buff cheat detection bouncer. (@sgkoishi)
diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs
index bf0fb54e..5998ad18 100644
--- a/TShockAPI/GetDataHandlers.cs
+++ b/TShockAPI/GetDataHandlers.cs
@@ -122,6 +122,7 @@ namespace TShockAPI
{ PacketTypes.PlayerAnimation, HandlePlayerAnimation },
{ PacketTypes.PlayerMana, HandlePlayerMana },
{ PacketTypes.PlayerTeam, HandlePlayerTeam },
+ { PacketTypes.SignRead, HandleSignRead },
{ PacketTypes.SignNew, HandleSign },
{ PacketTypes.LiquidSet, HandleLiquidSet },
{ PacketTypes.PlayerBuff, HandlePlayerBuffList },
@@ -1187,6 +1188,43 @@ namespace TShockAPI
return args.Handled;
}
+ ///
+ /// For use in a SignRead event
+ ///
+ public class SignReadEventArgs : GetDataHandledEventArgs
+ {
+ ///
+ /// X location of the sign
+ ///
+ public int X { get; set; }
+
+ ///
+ /// Y location of the sign
+ ///
+ public int Y { get; set; }
+ }
+
+ ///
+ /// Sign - Called when a sign is read
+ ///
+ public static HandlerList SignRead = new HandlerList();
+
+ private static bool OnSignRead(TSPlayer player, MemoryStream data, int x, int y)
+ {
+ if (SignRead == null)
+ return false;
+
+ var args = new SignReadEventArgs
+ {
+ Player = player,
+ Data = data,
+ X = x,
+ Y = y,
+ };
+ SignRead.Invoke(null, args);
+ return args.Handled;
+ }
+
///
/// For use in a Sign event
///
@@ -3217,6 +3255,23 @@ namespace TShockAPI
return false;
}
+ private static bool HandleSignRead(GetDataHandlerArgs args)
+ {
+ var x = args.Data.ReadInt16();
+ var y = args.Data.ReadInt16();
+
+ if (OnSignRead(args.Player, args.Data, x, y))
+ return true;
+
+ if (x < 0 || y < 0 || x >= Main.maxTilesX || y >= Main.maxTilesY)
+ {
+ TShock.Log.ConsoleDebug("GetDataHandlers / HandleSignRead rejected out of bounds {0}", args.Player.Name);
+ return true;
+ }
+
+ return false;
+ }
+
private static bool HandleSign(GetDataHandlerArgs args)
{
var id = args.Data.ReadInt16();