diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index 2145b373..d7797fed 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -105,6 +105,7 @@ namespace TShockAPI GetDataHandlers.NPCAddBuff += OnNPCAddBuff; GetDataHandlers.NPCHome += OnUpdateNPCHome; GetDataHandlers.HealOtherPlayer += OnHealOtherPlayer; + GetDataHandlers.ReleaseNPC += OnReleaseNPC; GetDataHandlers.PlaceObject += OnPlaceObject; GetDataHandlers.PlaceTileEntity += OnPlaceTileEntity; GetDataHandlers.PlaceItemFrame += OnPlaceItemFrame; @@ -1829,6 +1830,52 @@ namespace TShockAPI return; } + /// + /// A bouncer for checking NPC released by player + /// + /// The object that triggered the event. + /// The packet arguments that the event has. + internal void OnReleaseNPC(object sender, GetDataHandlers.ReleaseNpcEventArgs args) + { + int x = args.X; + int y = args.Y; + short type = args.Type; + byte style = args.Style; + + // if npc released outside allowed tile + if ( x >= Main.maxTilesX * 16 - 16 || x < 0 || y >= Main.maxTilesY * 16 - 16 || y < 0) + { + TShock.Log.ConsoleDebug("Bouncer / OnReleaseNPC rejected out of bounds from {0}", args.Player.Name); + args.Handled = true; + return; + } + + // if player disabled + if (args.Player.IsBeingDisabled()) + { + TShock.Log.ConsoleDebug("Bouncer / OnReleaseNPC rejected npc release from {0}", args.Player.Name); + args.Handled = true; + return; + } + + // if released npc not from its item (from crafted packet) + // e.g. using bunny item to release golden bunny + if(args.Player.TPlayer.lastVisualizedSelectedItem.makeNPC != type) + { + TShock.Log.ConsoleDebug("Bouncer / OnReleaseNPC rejected npc release from {0}", args.Player.Name); + args.Player.Kick("Trying to release different critter exploit!", true); + args.Handled = true; + return; + } + + if (args.Player.IsBouncerThrottled()) + { + TShock.Log.ConsoleDebug("Bouncer / OnReleaseNPC rejected throttle from {0}", args.Player.Name); + args.Handled = true; + return; + } + } + /// Bouncer's PlaceObject hook reverts malicious tile placement. /// The object that triggered the event. /// The packet arguments that the event has.