diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs
index dd55f6ef..f3a85f40 100644
--- a/TShockAPI/Bouncer.cs
+++ b/TShockAPI/Bouncer.cs
@@ -962,6 +962,18 @@ namespace TShockAPI
// Denotes that the player has recently set a fuse - used for cheat detection.
args.Player.RecentFuse = 10;
}
+
+ if (projectileCreatesLiquid.ContainsKey(type))
+ {
+ lock (args.Player.RecentlyCreatedProjectiles)
+ {
+ args.Player.RecentlyCreatedProjectiles.Add(new ProjectileStruct()
+ {
+ Index = ident,
+ CreatedAt = DateTime.Now
+ });
+ }
+ }
}
/// Handles the NPC Strike event for Bouncer.
@@ -1290,6 +1302,18 @@ namespace TShockAPI
args.Player.TileLiquidThreshold++;
}
+ bool wasThereABombNearby = false;
+
+ lock (args.Player.RecentlyCreatedProjectiles)
+ {
+ var keys = projectileCreatesLiquid.Where(k => k.Value == type).Select(k => k.Key);
+ var recentBombs = args.Player.RecentlyCreatedProjectiles.Where(keys.Contains(Main.projectile[p.Index].type));
+ wasThereABombNearby = recentBombs.Any(r => (args.TileX > (Main.projectile[r.Index].position.X / 16.0f) - 32
+ && args.TileX < (Main.projectile[r.Index].position.X / 16.0f) + 32)
+ && (args.TileY > (Main.projectile[r.Index].position.Y / 16.0f) - 32
+ && args.TileY < (Main.projectile[r.Index].position.Y / 16.0f) + 32));
+ }
+
// Liquid anti-cheat
// Arguably the banned buckets bit should be in the item bans system
if (amount != 0)
@@ -1326,7 +1350,7 @@ namespace TShockAPI
bucket = 6;
}
- if (type == LiquidType.Lava && !(bucket == 2 || bucket == 0 || bucket == 5 || bucket == 6))
+ if (!wasThereABombNearby && type == LiquidType.Lava && !(bucket == 2 || bucket == 0 || bucket == 5 || bucket == 6))
{
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 1 from {0}", args.Player.Name);
args.Player.SendErrorMessage("You do not have permission to perform this action.");
@@ -1336,7 +1360,7 @@ namespace TShockAPI
return;
}
- if (type == LiquidType.Lava && TShock.Itembans.ItemIsBanned("Lava Bucket", args.Player))
+ if (!wasThereABombNearby && type == LiquidType.Lava && TShock.Itembans.ItemIsBanned("Lava Bucket", args.Player))
{
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected lava bucket from {0}", args.Player.Name);
args.Player.SendErrorMessage("You do not have permission to perform this action.");
@@ -1346,7 +1370,7 @@ namespace TShockAPI
return;
}
- if (type == LiquidType.Water && !(bucket == 1 || bucket == 0 || bucket == 4))
+ if (!wasThereABombNearby && type == LiquidType.Water && !(bucket == 1 || bucket == 0 || bucket == 4))
{
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 2 from {0}", args.Player.Name);
args.Player.SendErrorMessage("You do not have permission to perform this action.");
@@ -1356,7 +1380,7 @@ namespace TShockAPI
return;
}
- if (type == LiquidType.Water && TShock.Itembans.ItemIsBanned("Water Bucket", args.Player))
+ if (!wasThereABombNearby && type == LiquidType.Water && TShock.Itembans.ItemIsBanned("Water Bucket", args.Player))
{
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 3 from {0}", args.Player.Name);
args.Player.SendErrorMessage("You do not have permission to perform this action.");
@@ -1366,7 +1390,7 @@ namespace TShockAPI
return;
}
- if (type == LiquidType.Honey && !(bucket == 3 || bucket == 0))
+ if (!wasThereABombNearby && type == LiquidType.Honey && !(bucket == 3 || bucket == 0))
{
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 4 from {0}", args.Player.Name);
args.Player.SendErrorMessage("You do not have permission to perform this action.");
@@ -1376,7 +1400,7 @@ namespace TShockAPI
return;
}
- if (type == LiquidType.Honey && TShock.Itembans.ItemIsBanned("Honey Bucket", args.Player))
+ if (!wasThereABombNearby && type == LiquidType.Honey && TShock.Itembans.ItemIsBanned("Honey Bucket", args.Player))
{
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 5 from {0}", args.Player.Name);
args.Player.SendErrorMessage("You do not have permission to perform this action.");
@@ -1395,7 +1419,7 @@ namespace TShockAPI
return;
}
- if (!args.Player.IsInRange(tileX, tileY, 16))
+ if (!wasThereABombNearby && !args.Player.IsInRange(tileX, tileY, 16))
{
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected range checks from {0}", args.Player.Name);
args.Player.SendTileSquare(tileX, tileY, 1);
diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs
index 19c6f4b0..57c8985f 100644
--- a/TShockAPI/GetDataHandlers.cs
+++ b/TShockAPI/GetDataHandlers.cs
@@ -2386,6 +2386,10 @@ namespace TShockAPI
}
args.Player.LastKilledProjectile = type;
+ lock (args.Player.RecentlyCreatedProjectiles)
+ {
+ args.Player.RecentlyCreatedProjectiles.ForEach(s => { if (s.Index == index) { s.Killed = true; } });
+ }
return false;
}
@@ -3446,6 +3450,13 @@ namespace TShockAPI
{ ProjectileID.MysticSnakeCoil, TileID.MysticSnakeRope }
};
+ internal static Dictionary projectileCreatesLiquid = new Dictionary
+ {
+ {ProjectileID.LavaBomb, LiquidType.Lava},
+ {ProjectileID.WetBomb, LiquidType.Water},
+ {ProjectileID.HoneyBomb, LiquidType.Honey}
+ };
+
internal static Dictionary ropeCoilPlacements = new Dictionary
{
{ItemID.RopeCoil, TileID.Rope},
@@ -3461,5 +3472,12 @@ namespace TShockAPI
{
{TileID.MinecartTrack, 3}
};
+
+ internal struct ProjectileStruct
+ {
+ public int Index { get; set; }
+ public DateTime CreatedAt { get; set; }
+ public bool Killed { get; internal set; }
+ }
}
}
diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs
index 86642e69..277e9b00 100644
--- a/TShockAPI/TSPlayer.cs
+++ b/TShockAPI/TSPlayer.cs
@@ -764,6 +764,12 @@ namespace TShockAPI
///
public int LastKilledProjectile = 0;
+ ///
+ /// Keeps track of recently created projectiles by this player. TShock.cs OnSecondUpdate() removes from this in an async task.
+ /// Projectiles older than 5 seconds are purged from this collection as they are no longer "recent".
+ ///
+ internal List RecentlyCreatedProjectiles = new List();
+
///
/// The current region this player is in, or null if none.
///
diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs
index d0b174b4..656a1314 100644
--- a/TShockAPI/TShock.cs
+++ b/TShockAPI/TShock.cs
@@ -44,6 +44,7 @@ using Microsoft.Xna.Framework;
using TShockAPI.Sockets;
using TShockAPI.CLI;
using TShockAPI.Localization;
+using System.Threading.Tasks;
namespace TShockAPI
{
@@ -1064,6 +1065,18 @@ namespace TShockAPI
}
}
}
+
+ Task.Run(() =>
+ {
+ if (player != null && player.TPlayer.whoAmI >= 0)
+ {
+ var threshold = DateTime.Now.AddSeconds(-5);
+ lock (player.RecentlyCreatedProjectiles)
+ {
+ player.RecentlyCreatedProjectiles = player.RecentlyCreatedProjectiles.Where(s => s.CreatedAt > threshold).ToList();
+ }
+ }
+ });
}
Utils.SetConsoleTitle(false);
}