diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index d11cac4d..3e16c10a 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -41,12 +41,119 @@ namespace TShockAPI { // Setup hooks + GetDataHandlers.NewProjectile.Register(OnNewProjectile); GetDataHandlers.PlaceObject.Register(OnPlaceObject); GetDataHandlers.SendTileSquare.Register(OnSendTileSquare); GetDataHandlers.HealOtherPlayer.Register(OnHealOtherPlayer); GetDataHandlers.TileEdit.Register(OnTileEdit); } + internal void OnNewProjectile(object sender, GetDataHandlers.NewProjectileEventArgs args) + { + short ident = args.Identity; + Vector2 pos = args.Position; + Vector2 vel = args.Velocity; + float knockback = args.Knockback; + short dmg = args.Damage; + byte owner = args.Owner; + short type = args.Type; + int index = args.Index; + + if (index > Main.maxProjectiles || index < 0) + { + args.Player.RemoveProjectile(ident, owner); + args.Handled = true; + return; + } + + if (TShock.ProjectileBans.ProjectileIsBanned(type, args.Player)) + { + args.Player.Disable("Player does not have permission to create that projectile.", DisableFlags.WriteToLogAndConsole); + args.Player.SendErrorMessage("You do not have permission to create that projectile."); + args.Player.RemoveProjectile(ident, owner); + args.Handled = true; + return; + } + + if (dmg > TShock.Config.MaxProjDamage && !args.Player.HasPermission(Permissions.ignoredamagecap)) + { + args.Player.Disable(String.Format("Projectile damage is higher than {0}.", TShock.Config.MaxProjDamage), DisableFlags.WriteToLogAndConsole); + args.Player.RemoveProjectile(ident, owner); + args.Handled = true; + return; + } + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.RemoveProjectile(ident, owner); + args.Handled = true; + return; + } + + bool hasPermission = !TShock.CheckProjectilePermission(args.Player, index, type); + if (!TShock.Config.IgnoreProjUpdate && !hasPermission && !args.Player.HasPermission(Permissions.ignoreprojectiledetection)) + { + if (type == ProjectileID.BlowupSmokeMoonlord + || type == ProjectileID.PhantasmalEye + || type == ProjectileID.CultistBossIceMist + || (type >= ProjectileID.MoonlordBullet && type <= ProjectileID.MoonlordTurretLaser) + || type == ProjectileID.DeathLaser || type == ProjectileID.Landmine + || type == ProjectileID.BulletDeadeye || type == ProjectileID.BoulderStaffOfEarth + || (type > ProjectileID.ConfettiMelee && type < ProjectileID.SpiritHeal) + || (type >= ProjectileID.FlamingWood && type <= ProjectileID.GreekFire3) + || (type >= ProjectileID.PineNeedleHostile && type <= ProjectileID.Spike) + || (type >= ProjectileID.MartianTurretBolt && type <= ProjectileID.RayGunnerLaser) + || type == ProjectileID.CultistBossLightningOrb) + { + TShock.Log.Debug("Certain projectiles have been ignored for cheat detection."); + } + else + { + args.Player.Disable(String.Format("Does not have projectile permission to update projectile. ({0})", type), DisableFlags.WriteToLogAndConsole); + args.Player.RemoveProjectile(ident, owner); + } + args.Handled = true; + return; + } + + if (args.Player.ProjectileThreshold >= TShock.Config.ProjectileThreshold) + { + args.Player.Disable("Reached projectile update threshold.", DisableFlags.WriteToLogAndConsole); + args.Player.RemoveProjectile(ident, owner); + args.Handled = true; + return; + } + + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + args.Player.RemoveProjectile(ident, owner); + args.Handled = true; + return; + } + + if (!args.Player.HasPermission(Permissions.ignoreprojectiledetection)) + { + if (type == ProjectileID.CrystalShard && TShock.Config.ProjIgnoreShrapnel) // Ignore crystal shards + { + TShock.Log.Debug("Ignoring shrapnel per config.."); + } + else if (!Main.projectile[index].active) + { + args.Player.ProjectileThreshold++; // Creating new projectile + } + } + + if (hasPermission && + (type == ProjectileID.Bomb + || type == ProjectileID.Dynamite + || type == ProjectileID.StickyBomb + || type == ProjectileID.StickyDynamite)) + { + // Denotes that the player has recently set a fuse - used for cheat detection. + args.Player.RecentFuse = 10; + } + } + internal void OnPlaceObject(object sender, GetDataHandlers.PlaceObjectEventArgs args) { short x = args.X; diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 99c3e8be..bde25e27 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -681,6 +681,8 @@ namespace TShockAPI /// public class NewProjectileEventArgs : HandledEventArgs { + /// The TSPlayer that triggered the new projectile. + public TSPlayer Player { get; set; } /// /// ??? /// @@ -719,7 +721,7 @@ namespace TShockAPI /// public static HandlerList NewProjectile; - private static bool OnNewProjectile(short ident, Vector2 pos, Vector2 vel, float knockback, short dmg, byte owner, short type, int index) + private static bool OnNewProjectile(short ident, Vector2 pos, Vector2 vel, float knockback, short dmg, byte owner, short type, int index, TSPlayer player) { if (NewProjectile == null) return false; @@ -734,6 +736,7 @@ namespace TShockAPI Owner = owner, Type = type, Index = index, + Player = player, }; NewProjectile.Invoke(null, args); return args.Handled; @@ -2261,97 +2264,9 @@ namespace TShockAPI var index = TShock.Utils.SearchProjectile(ident, owner); - if (OnNewProjectile(ident, pos, vel, knockback, dmg, owner, type, index)) + if (OnNewProjectile(ident, pos, vel, knockback, dmg, owner, type, index, args.Player)) return true; - if (index > Main.maxProjectiles || index < 0) - { - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if (TShock.ProjectileBans.ProjectileIsBanned(type, args.Player)) - { - args.Player.Disable("Player does not have permission to create that projectile.", DisableFlags.WriteToLogAndConsole); - args.Player.SendErrorMessage("You do not have permission to create that projectile."); - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if (dmg > TShock.Config.MaxProjDamage && !args.Player.HasPermission(Permissions.ignoredamagecap)) - { - args.Player.Disable(String.Format("Projectile damage is higher than {0}.", TShock.Config.MaxProjDamage), DisableFlags.WriteToLogAndConsole); - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if (TShock.CheckIgnores(args.Player)) - { - args.Player.RemoveProjectile(ident, owner); - return true; - } - - bool hasPermission = !TShock.CheckProjectilePermission(args.Player, index, type); - if (!TShock.Config.IgnoreProjUpdate && !hasPermission && !args.Player.HasPermission(Permissions.ignoreprojectiledetection)) - { - if (type == ProjectileID.BlowupSmokeMoonlord - || type == ProjectileID.PhantasmalEye - || type == ProjectileID.CultistBossIceMist - || (type >= ProjectileID.MoonlordBullet && type <= ProjectileID.MoonlordTurretLaser) - || type == ProjectileID.DeathLaser || type == ProjectileID.Landmine - || type == ProjectileID.BulletDeadeye || type == ProjectileID.BoulderStaffOfEarth - || (type > ProjectileID.ConfettiMelee && type < ProjectileID.SpiritHeal) - || (type >= ProjectileID.FlamingWood && type <= ProjectileID.GreekFire3) - || (type >= ProjectileID.PineNeedleHostile && type <= ProjectileID.Spike) - || (type >= ProjectileID.MartianTurretBolt && type <= ProjectileID.RayGunnerLaser) - || type == ProjectileID.CultistBossLightningOrb) - { - TShock.Log.Debug("Certain projectiles have been ignored for cheat detection."); - } - else - { - args.Player.Disable(String.Format("Does not have projectile permission to update projectile. ({0})", type), DisableFlags.WriteToLogAndConsole); - args.Player.RemoveProjectile(ident, owner); - } - return true; - } - - if (args.Player.ProjectileThreshold >= TShock.Config.ProjectileThreshold) - { - args.Player.Disable("Reached projectile update threshold.", DisableFlags.WriteToLogAndConsole); - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) - { - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if (!args.Player.HasPermission(Permissions.ignoreprojectiledetection)) - { - if (type == ProjectileID.CrystalShard && TShock.Config.ProjIgnoreShrapnel) // Ignore crystal shards - { - TShock.Log.Debug("Ignoring shrapnel per config.."); - } - else if (!Main.projectile[index].active) - { - args.Player.ProjectileThreshold++; // Creating new projectile - } - } - - if (hasPermission && - (type == ProjectileID.Bomb - || type == ProjectileID.Dynamite - || type == ProjectileID.StickyBomb - || type == ProjectileID.StickyDynamite)) - { - // Denotes that the player has recently set a fuse - used for cheat detection. - args.Player.RecentFuse = 10; - //return true; - } - return false; }