diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs
index b4dbdd28e..b2af3fc3b 100644
--- a/TShockAPI/TSPlayer.cs
+++ b/TShockAPI/TSPlayer.cs
@@ -273,6 +273,11 @@ public Group Group
///
public DateTime LastPvPTeamChange;
+ ///
+ /// The last time stack-hack detection was run for this player.
+ ///
+ public DateTime LastStackDetectionCheck;
+
///
/// Temp points for use in regions and other plugins.
///
@@ -1528,6 +1533,7 @@ public TSPlayer(int index)
Group = Group.DefaultGroup;
IceTiles = new List();
AwaitingResponse = new Dictionary>();
+ LastStackDetectionCheck = DateTime.UtcNow.AddSeconds(-(index % 5));
}
///
@@ -1542,6 +1548,7 @@ protected TSPlayer(String playerName)
FakePlayer = new Player { name = playerName, whoAmI = -1 };
Group = Group.DefaultGroup;
AwaitingResponse = new Dictionary>();
+ LastStackDetectionCheck = DateTime.UtcNow;
if (playerName == "All" || playerName == "Server")
FinishedHandshake = true; //Hot fix for the all player object not getting packets like TimeSet, etc because they have no state and finished handshake will always be false.
diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs
index 28cf03c1f..3d25229b8 100644
--- a/TShockAPI/TShock.cs
+++ b/TShockAPI/TShock.cs
@@ -1221,15 +1221,20 @@ private void OnSecondUpdate()
if (!Main.ServerSideCharacter || (Main.ServerSideCharacter && player.IsLoggedIn))
{
- if (!player.HasPermission(Permissions.ignorestackhackdetection))
+ var stackCheckDue = (DateTime.UtcNow - player.LastStackDetectionCheck).TotalSeconds >= 5;
+ if (stackCheckDue)
{
- player.IsDisabledForStackDetection = player.HasHackedItemStacks(shouldWarnPlayer: true);
+ player.LastStackDetectionCheck = DateTime.UtcNow;
+ if (!player.HasPermission(Permissions.ignorestackhackdetection))
+ {
+ player.IsDisabledForStackDetection = player.HasHackedItemStacks(shouldWarnPlayer: true);
+ }
}
+ }
- if (player.IsBeingDisabled())
- {
- player.Disable(flags: flags);
- }
+ if (player.IsBeingDisabled())
+ {
+ player.Disable(flags: flags);
}
}
}