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;
}