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