From c5f9a518023bd1d3f2803a38b0f87b8d9cfe871b Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Sun, 10 Dec 2017 23:05:50 -0700 Subject: [PATCH] Move most of HandleProjectileKill to Bouncer Added GetDataHandlers.ProjectileKill hook and related arguments. Fired when a projectile kill packet is accepted by the server. --- CHANGELOG.md | 1 + TShockAPI/Bouncer.cs | 28 ++++++++++++++++++ TShockAPI/GetDataHandlers.cs | 56 +++++++++++++++++++++++++++--------- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 010e16e7..7359fbfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Added `GetDataHandlers.HealOtherPlayer` hook. (@hakusaro) * Added `GetDataHandlers.PlaceObject` hook. (@hakusaro) * `GetDataHandlers.KillMe` now sends a `TSPlayer` and a `PlayerDeathReason`. (@hakusaro) +* Added `GetDataHandlers.ProjectileKill` hook. (@hakusaro) ## TShock 4.3.24 * Updated OpenTerraria API to 1.3.5.3 (@DeathCradle) diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index e99233a9..87ea3c72 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -42,6 +42,7 @@ namespace TShockAPI { // Setup hooks + GetDataHandlers.ProjectileKill.Register(OnProjectileKill); GetDataHandlers.PlayerUpdate.Register(OnPlayerUpdate); GetDataHandlers.KillMe.Register(OnKillMe); GetDataHandlers.NewProjectile.Register(OnNewProjectile); @@ -51,6 +52,33 @@ namespace TShockAPI GetDataHandlers.TileEdit.Register(OnTileEdit); } + /// Handles ProjectileKill events for throttling & out of bounds projectiles. + /// The object that triggered the event. + /// The packet arguments that the event has. + internal void OnProjectileKill(object sender, GetDataHandlers.ProjectileKillEventArgs args) + { + if (args.ProjectileIndex > Main.maxProjectiles || args.ProjectileIndex < 0) + { + // TODO: Should this be /true/ to stop the server from processing it? + args.Handled = false; + return; + } + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.RemoveProjectile(args.ProjectileIdentity, args.ProjectileOwner); + args.Handled = true; + return; + } + + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + args.Player.RemoveProjectile(args.ProjectileIdentity, args.ProjectileOwner); + args.Handled = true; + return; + } + } + /// Handles disabling enforcement & minor anti-exploit stuff /// The object that triggered the event. /// The packet arguments that the event has. diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 888bce64..3eb03926 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -384,6 +384,45 @@ namespace TShockAPI return args.Handled; } + /// The arguments to the ProjectileKill packet. + public class ProjectileKillEventArgs : HandledEventArgs + { + /// The TSPlayer that fired the event. + public TSPlayer Player; + /// The projectile's identity...? + public int ProjectileIdentity; + /// The the player index of the projectile's owner (Main.players). + public byte ProjectileOwner; + /// The index of the projectile in Main.projectile. + public int ProjectileIndex; + } + + /// The event fired when a projectile kill packet is received. + public static HandlerList ProjectileKill; + + /// Fires the ProjectileKill event. + /// The TSPlayer that caused the event. + /// The projectile identity (from the packet). + /// The projectile's owner (from the packet). + /// The projectile's index (from Main.projectiles). + /// bool + private static bool OnProjectileKill(TSPlayer player, int identity, byte owner, int index) + { + if (ProjectileKill == null) + return false; + + var args = new ProjectileKillEventArgs + { + Player = player, + ProjectileIdentity = identity, + ProjectileOwner = owner, + ProjectileIndex = index, + }; + + ProjectileKill.Invoke(null, args); + return args.Handled; + } + /// /// For use in a KillMe event /// @@ -2213,19 +2252,14 @@ namespace TShockAPI owner = (byte)args.Player.Index; var index = TShock.Utils.SearchProjectile(ident, owner); - if (index > Main.maxProjectiles || index < 0) + if (OnProjectileKill(args.Player, ident, owner, index)) { - return false; + return true; } var type = Main.projectile[index].type; - if (TShock.CheckIgnores(args.Player)) - { - args.Player.RemoveProjectile(ident, owner); - return true; - } - + // TODO: This needs to be moved somewhere else. if (TShock.CheckProjectilePermission(args.Player, index, type) && type != 102 && type != 100 && !TShock.Config.IgnoreProjKill) { args.Player.Disable("Does not have projectile permission to kill projectile.", DisableFlags.WriteToLogAndConsole); @@ -2233,12 +2267,6 @@ namespace TShockAPI return true; } - if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) - { - args.Player.RemoveProjectile(ident, owner); - return true; - } - args.Player.LastKilledProjectile = type; return false;