From 1460a7ad91a708cef38e7deb8af887229def7531 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 17 Oct 2016 15:51:49 +0300 Subject: [PATCH 1/3] Fix for HealOtherPlayer exploit, also fix #1309 --- TShockAPI/ConfigFile.cs | 4 ++++ TShockAPI/GetDataHandlers.cs | 40 +++++++++++++++++++++++++++++++++++- TShockAPI/TSPlayer.cs | 7 ++++++- TShockAPI/TShock.cs | 11 +++++++++- 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/TShockAPI/ConfigFile.cs b/TShockAPI/ConfigFile.cs index c4f9cf35..2b9466ca 100755 --- a/TShockAPI/ConfigFile.cs +++ b/TShockAPI/ConfigFile.cs @@ -295,6 +295,10 @@ namespace TShockAPI [Description("Disable a player if this number of projectiles is created within 1 second.")] public int ProjectileThreshold = 50; + /// ProjectileThreshold - Disables a player if this number of projectiles is created within 1 second. + [Description("Disable a player if this number of projectiles is created within 1 second.")] + public int HealOtherThreshold = 50; + /// ProjIgnoreShrapnel - Whether or not to ignore shrapnel from crystal bullets for the projectile threshold count. [Description("Ignore shrapnel from crystal bullets for projectile threshold.")] public bool ProjIgnoreShrapnel = true; diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 92a8b7f6..0f7781f3 100755 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -1261,7 +1261,8 @@ namespace TShockAPI { PacketTypes.PlaceItemFrame, HandlePlaceItemFrame }, { PacketTypes.SyncExtraValue, HandleSyncExtraValue }, { PacketTypes.LoadNetModule, HandleLoadNetModule }, - { PacketTypes.ToggleParty, HandleToggleParty } + { PacketTypes.ToggleParty, HandleToggleParty }, + { PacketTypes.PlayerHealOther, HandleHealOther } }; } @@ -1283,6 +1284,43 @@ namespace TShockAPI return false; } + private static bool HandleHealOther(GetDataHandlerArgs args) + { + byte plr = args.Data.ReadInt8(); + short amount = args.Data.ReadInt16(); + + if (amount <= 0 || Main.player[plr] == null || !Main.player[plr].active) + { + return true; + } + + if (amount > TShock.Config.MaxDamage * 0.2) + { + args.Player.Disable("HealOtherPlayer max amount cheat attempt!", DisableFlags.WriteToLogAndConsole); + return true; + } + + if (args.TPlayer.whoAmI != plr && (args.TPlayer.team == 0 || args.TPlayer.team != Main.player[plr].team)) + { + args.Player.Disable("HealOtherPlayer cheat attempt!", DisableFlags.WriteToLogAndConsole); + return true; + } + + if (args.Player.HealOtherThreshold > TShock.Config.HealOtherThreshold) + { + args.Player.Disable("Reached HealOtherPlayer threshold.", DisableFlags.WriteToLogAndConsole); + return true; + } + + if (TShock.CheckIgnores(args.Player) || (DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + return true; + } + + args.Player.HealOtherThreshold++; + return false; + } + private static bool HandlePlayerSlot(GetDataHandlerArgs args) { byte plr = args.Data.ReadInt8(); diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 95feb980..d8a5537a 100755 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -93,7 +93,12 @@ namespace TShockAPI /// The number of projectiles created by the player in the last second. /// public int ProjectileThreshold { get; set; } - + + /// + /// The number of HealOtherPlayer packets sent by the player in the last second. + /// + public int HealOtherThreshold { get; set; } + /// /// A timer to keep track of whether or not the player has recently thrown an explosive /// diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 1bbb7052..046f274c 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -1030,6 +1030,15 @@ namespace TShockAPI player.PaintThreshold = 0; } + if (player.HealOtherThreshold > TShock.Config.HealOtherThreshold) + { + player.Disable("Reached HealOtherPlayer threshold", flags); + } + if (player.HealOtherThreshold > 0) + { + player.HealOtherThreshold = 0; + } + if (player.RespawnTimer > 0 && --player.RespawnTimer == 0 && player.Difficulty != 2) { player.Spawn(); @@ -1458,7 +1467,7 @@ namespace TShockAPI /// The CommandEventArgs object private void ServerHooks_OnCommand(CommandEventArgs args) { - if (args.Handled) + if (args.Handled || string.IsNullOrWhiteSpace(args.Command)) return; // Damn you ThreadStatic and Redigit From 464a52a70a5225323a2f957ec5dfc42f4c535e24 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 17 Oct 2016 16:05:18 +0300 Subject: [PATCH 2/3] Misleading wiki caused this commit --- TShockAPI/GetDataHandlers.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 0f7781f3..c87fcc53 100755 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -1295,12 +1295,6 @@ namespace TShockAPI } if (amount > TShock.Config.MaxDamage * 0.2) - { - args.Player.Disable("HealOtherPlayer max amount cheat attempt!", DisableFlags.WriteToLogAndConsole); - return true; - } - - if (args.TPlayer.whoAmI != plr && (args.TPlayer.team == 0 || args.TPlayer.team != Main.player[plr].team)) { args.Player.Disable("HealOtherPlayer cheat attempt!", DisableFlags.WriteToLogAndConsole); return true; From 68799d9d20b7291ab7b540ba18fb113bfba4ce5b Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 17 Oct 2016 16:17:44 +0300 Subject: [PATCH 3/3] Fix description --- TShockAPI/ConfigFile.cs | 4 ++-- TShockAPI/TShock.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/TShockAPI/ConfigFile.cs b/TShockAPI/ConfigFile.cs index 2b9466ca..ad4b43b0 100755 --- a/TShockAPI/ConfigFile.cs +++ b/TShockAPI/ConfigFile.cs @@ -295,8 +295,8 @@ namespace TShockAPI [Description("Disable a player if this number of projectiles is created within 1 second.")] public int ProjectileThreshold = 50; - /// ProjectileThreshold - Disables a player if this number of projectiles is created within 1 second. - [Description("Disable a player if this number of projectiles is created within 1 second.")] + /// HealOtherThreshold - Disables a player if this number of HealOtherPlayer packets is sent within 1 second. + [Description("Disables a player if this number of HealOtherPlayer packets is sent within 1 second.")] public int HealOtherThreshold = 50; /// ProjIgnoreShrapnel - Whether or not to ignore shrapnel from crystal bullets for the projectile threshold count. diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 046f274c..9679a032 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -1030,7 +1030,7 @@ namespace TShockAPI player.PaintThreshold = 0; } - if (player.HealOtherThreshold > TShock.Config.HealOtherThreshold) + if (player.HealOtherThreshold >= TShock.Config.HealOtherThreshold) { player.Disable("Reached HealOtherPlayer threshold", flags); }