From bcbea04002d1a1fe3a7db774f1ee04b371189992 Mon Sep 17 00:00:00 2001
From: AxeelAnder <1491773534@qq.com>
Date: Sat, 20 Oct 2018 17:48:50 +0800
Subject: [PATCH 1/8] update changelog
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 79f36e88..e97338de 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -90,6 +90,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
* Added filtering and validation on packet 96 (Teleport player through portal) (@QuiCM)
* Update tracker now uses TLS (@pandabear41)
* When deleting an user account, any player logged in to that account is now logged out properly (@Enerdy)
+* Add NPCAddBuff data handler and bouncer (@AxeelAnder)
## TShock 4.3.25
* Fixed a critical exploit in the Terraria protocol that could cause massive unpreventable world corruption as well as a number of other problems. Thanks to @bartico6 for reporting. Fixed by the efforts of @QuiCM, @hakusaro, and tips in the right directioon from @bartico6.
From 6b8f346868fb98d664710f5e83dc7512b90c1239 Mon Sep 17 00:00:00 2001
From: AxeelAnder <1491773534@qq.com>
Date: Sat, 20 Oct 2018 12:48:05 +0800
Subject: [PATCH 2/8] add NPCAddBuff GetDataHandler
---
TShockAPI/GetDataHandlers.cs | 54 ++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs
index c59ce1a7..b3769e4e 100644
--- a/TShockAPI/GetDataHandlers.cs
+++ b/TShockAPI/GetDataHandlers.cs
@@ -1003,6 +1003,46 @@ namespace TShockAPI
NPCHome.Invoke(null, args);
return args.Handled;
}
+
+ ///
+ /// For use in a NPCAddBuff event
+ ///
+ public class NPCAddBuffEventArgs : GetDataHandledEventArgs
+ {
+ ///
+ /// The ID of the npc
+ ///
+ public short ID { get; set; }
+ ///
+ /// Buff Type
+ ///
+ public byte Type { get; set; }
+ ///
+ /// Time the buff lasts
+ ///
+ public short Time { get; set; }
+ }
+ ///
+ /// NPCAddBuff - Called when a npc is buffed
+ ///
+ public static HandlerList NPCAddBuff = new HandlerList();
+
+ private static bool OnNPCAddBuff(TSPlayer player, MemoryStream data, short id, byte type, short time)
+ {
+ if (NPCAddBuff == null)
+ return false;
+
+ var args = new NPCAddBuffEventArgs
+ {
+ Player = player,
+ Data = data,
+ ID = id,
+ Type = type,
+ Time = time
+ };
+ NPCAddBuff.Invoke(null, args);
+ return args.Handled;
+ }
///
/// For use in a PlayerBuff event
@@ -1455,6 +1495,7 @@ namespace TShockAPI
{ PacketTypes.PlayerSlot, HandlePlayerSlot },
{ PacketTypes.TileGetSection, HandleGetSection },
{ PacketTypes.UpdateNPCHome, UpdateNPCHome },
+ { PacketTypes.NpcAddBuff, HandleNPCAddBuff },
{ PacketTypes.PlayerAddBuff, HandlePlayerAddBuff },
{ PacketTypes.ItemDrop, HandleItemDrop },
{ PacketTypes.UpdateItemDrop, HandleItemDrop },
@@ -2627,6 +2668,19 @@ namespace TShockAPI
}
return false;
}
+
+ private static bool HandleNPCAddBuff(GetDataHandlerArgs args)
+ {
+ var id = args.Data.ReadInt16();
+ var type = args.Data.ReadInt8();
+ var time = args.Data.ReadInt16();
+
+ if (OnNPCAddBuff(args.Player, args.Data, id, type, time))
+ return true;
+
+ args.Player.SendData(PacketTypes.NpcAddBuff, "", id);
+ return true;
+ }
private static bool HandlePlayerAddBuff(GetDataHandlerArgs args)
{
From 87915b70b0e6be7484263bdebc19b5f208750ff8 Mon Sep 17 00:00:00 2001
From: AxeelAnder <1491773534@qq.com>
Date: Sat, 20 Oct 2018 14:41:58 +0800
Subject: [PATCH 3/8] add ignoreNpcAddBuffPermission
---
TShockAPI/Permissions.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/TShockAPI/Permissions.cs b/TShockAPI/Permissions.cs
index 7733f110..dec457d3 100644
--- a/TShockAPI/Permissions.cs
+++ b/TShockAPI/Permissions.cs
@@ -169,6 +169,9 @@ namespace TShockAPI
[Description("Prevents you from being disabled by abnormal MP.")]
public static readonly string ignoremp = "tshock.ignore.mp";
+
+ [Description("Prevents you from being disabled by add buffs to npcs abnormally.")]
+ public static readonly string ignorenpcaddbuffdetection = "tshock.ignore.npcaddbuff";
// tshock.item nodes
From fc38521dbd4538cd0e644265799a141d9b6ba815 Mon Sep 17 00:00:00 2001
From: AxeelAnder <1491773534@qq.com>
Date: Sat, 20 Oct 2018 13:21:38 +0800
Subject: [PATCH 4/8] add NPCAddBuff bouncer
---
TShockAPI/Bouncer.cs | 32 ++++++++++++++++++++++++++++++++
TShockAPI/GetDataHandlers.cs | 3 +--
2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs
index 223de05b..b71c7de8 100644
--- a/TShockAPI/Bouncer.cs
+++ b/TShockAPI/Bouncer.cs
@@ -49,6 +49,7 @@ namespace TShockAPI
GetDataHandlers.PlayerAnimation += OnPlayerAnimation;
GetDataHandlers.NPCStrike += OnNPCStrike;
GetDataHandlers.ItemDrop += OnItemDrop;
+ GetDataHandlers.NPCAddBuff += OnNPCAddBuff;
GetDataHandlers.PlayerBuff += OnPlayerBuff;
GetDataHandlers.ChestItemChange += OnChestItemChange;
GetDataHandlers.NPCHome += OnUpdateNPCHome;
@@ -453,6 +454,37 @@ namespace TShockAPI
return;
}
}
+
+ /// Handles NPCAddBuff events.
+ /// The object that triggered the event.
+ /// The packet arguments that the event has.
+ internal void OnNPCAddBuff(object sender, GetDataHandlers.NPCAddBuffEventArgs args)
+ {
+ short id = args.ID;
+ byte type = args.Type;
+ short time = args.Time;
+
+ if (id >= Main.npc.Length)
+ {
+ args.Handled = true;
+ return;
+ }
+
+ NPC npc = Main.npc[id];
+
+ if (npc == null)
+ {
+ args.Handled = true;
+ return;
+ }
+
+ if (args.Player.IsBeingDisabled())
+ {
+ args.Player.SendData(PacketTypes.NpcAddBuff, "", id);
+ args.Handled = true;
+ return;
+ }
+ }
/// Handles Buff events.
/// The object that triggered the event.
diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs
index b3769e4e..6673dd64 100644
--- a/TShockAPI/GetDataHandlers.cs
+++ b/TShockAPI/GetDataHandlers.cs
@@ -2677,8 +2677,7 @@ namespace TShockAPI
if (OnNPCAddBuff(args.Player, args.Data, id, type, time))
return true;
-
- args.Player.SendData(PacketTypes.NpcAddBuff, "", id);
+
return true;
}
From b9dedd77dcb03a0e47ae0beeb12a7f19568beaad Mon Sep 17 00:00:00 2001
From: AxeelAnder <1491773534@qq.com>
Date: Sat, 20 Oct 2018 17:44:34 +0800
Subject: [PATCH 5/8] add some anti-cheat code
---
TShockAPI/Bouncer.cs | 60 +++++++++++++++++++++++++++++++++++-
TShockAPI/GetDataHandlers.cs | 2 +-
TShockAPI/TShock.cs | 32 +++++++++++++++++++
3 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs
index b71c7de8..79dce7d1 100644
--- a/TShockAPI/Bouncer.cs
+++ b/TShockAPI/Bouncer.cs
@@ -480,10 +480,68 @@ namespace TShockAPI
if (args.Player.IsBeingDisabled())
{
- args.Player.SendData(PacketTypes.NpcAddBuff, "", id);
args.Handled = true;
return;
}
+
+ if (!args.Player.HasPermission(Permissions.ignorenpcaddbuffdetection))
+ {
+ bool cheat = false;
+
+ if(TShock.NPCAddBuffTimeMax.ContainsKey(type))
+ {
+ if(time > TShock.NPCAddBuffTimeMax[type])
+ {
+ cheat = true;
+ }
+
+ if(npc.townNPC && npc.netID != NPCID.Guide && npc.netID != NPCID.Clothier)
+ {
+ if(type != BuffID.Lovestruck && type != BuffID.Stinky && type != BuffID.DryadsWard &&
+ type != BuffID.Wet && type != BuffID.Slimed)
+ {
+ cheat = true;
+ }
+ }
+ // Want to check voodoo doll but it may be wrong.
+ //else if(npc.netID == NPCID.Guide)
+ //{
+ // bool hasDoll = false;
+ // foreach (var item in args.Player.Accessories)
+ // {
+ // if (item.netID == ItemID.GuideVoodooDoll)
+ // {
+ // hasDoll = true;
+ // break;
+ // }
+ // }
+ // cheat = !hasDoll;
+ //}
+ //else if (npc.netID == NPCID.Clothier)
+ //{
+ // bool hasDoll = false;
+ // foreach (var item in args.Player.Accessories)
+ // {
+ // if (item.netID == ItemID.ClothierVoodooDoll)
+ // {
+ // hasDoll = true;
+ // break;
+ // }
+ // }
+ // cheat = !hasDoll;
+ //}
+ }
+ else
+ {
+ cheat = true;
+ }
+
+ if (cheat)
+ {
+ args.Player.Disable("Add buff to NPC abnormally.", DisableFlags.WriteToLogAndConsole);
+ args.Handled = true;
+ }
+ }
}
/// Handles Buff events.
diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs
index 6673dd64..a7792569 100644
--- a/TShockAPI/GetDataHandlers.cs
+++ b/TShockAPI/GetDataHandlers.cs
@@ -2678,7 +2678,7 @@ namespace TShockAPI
if (OnNPCAddBuff(args.Player, args.Data, id, type, time))
return true;
- return true;
+ return false;
}
private static bool HandlePlayerAddBuff(GetDataHandlerArgs args)
diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs
index f839019d..18cff28e 100644
--- a/TShockAPI/TShock.cs
+++ b/TShockAPI/TShock.cs
@@ -131,6 +131,9 @@ namespace TShockAPI
///
public static Dictionary RESTStartupTokens = new Dictionary();
+ /// The longest time of buffs players can add to NPCs.
+ public static Dictionary NPCAddBuffTimeMax;
+
/// The TShock anti-cheat/anti-exploit system.
internal Bouncer Bouncer;
@@ -323,6 +326,7 @@ namespace TShockAPI
RestApi = new SecureRest(Netplay.ServerIP, Config.RestApiPort);
RestManager = new RestManager(RestApi);
RestManager.RegisterRestfulCommands();
+ NPCAddBuffTimeMax = InitNPCAddBuffTimeMax();
Bouncer = new Bouncer();
RegionSystem = new RegionHandler(Regions);
@@ -385,6 +389,34 @@ namespace TShockAPI
}
}
+ private Dictionary InitNPCAddBuffTimeMax()
+ {
+ var dict = new Dictionary();
+
+ dict.Add(BuffID.Poisoned, 3600);
+ dict.Add(BuffID.OnFire, 1200);
+ dict.Add(BuffID.CursedInferno, 420);
+ dict.Add(BuffID.Frostburn, 900);
+ dict.Add(BuffID.Ichor, 1200);
+ dict.Add(BuffID.Venom, 1260);
+ dict.Add(BuffID.Midas, 120);
+ dict.Add(BuffID.Wet, 1500);
+ dict.Add(BuffID.Slimed, 1500);
+ dict.Add(BuffID.Lovestruck, 1800);
+ dict.Add(BuffID.Stinky, 1800);
+ dict.Add(BuffID.SoulDrain, 30);
+ dict.Add(BuffID.ShadowFlame, 660);
+ dict.Add(BuffID.DryadsWard, 120);
+ dict.Add(BuffID.BoneJavelin, 900);
+ dict.Add(BuffID.StardustMinionBleed, 900);
+ dict.Add(BuffID.DryadsWardDebuff, 120);
+ dict.Add(BuffID.Daybreak, 300);
+ dict.Add(BuffID.BetsysCurse, 600);
+ dict.Add(BuffID.Oiled, 540);
+
+ return dict;
+ }
+
protected void CrashReporter_HeapshotRequesting(object sender, EventArgs e)
{
foreach (TSPlayer player in TShock.Players)
From 6efa0d2bb6d0c53cc2094ca681236261429788b7 Mon Sep 17 00:00:00 2001
From: AxeelAnder <1491773534@qq.com>
Date: Sat, 20 Oct 2018 20:07:04 +0800
Subject: [PATCH 6/8] better code
---
TShockAPI/Bouncer.cs | 97 +++++++++++++++++++---------------------
TShockAPI/Permissions.cs | 3 --
TShockAPI/TShock.cs | 32 -------------
3 files changed, 46 insertions(+), 86 deletions(-)
diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs
index 79dce7d1..ba7c2c85 100644
--- a/TShockAPI/Bouncer.cs
+++ b/TShockAPI/Bouncer.cs
@@ -36,6 +36,31 @@ namespace TShockAPI
/// Bouncer is the TShock anti-hack and anti-cheat system.
internal sealed class Bouncer
{
+ static Dictionary NPCAddBuffTimeMax = new Dictionary()
+ {
+ { BuffID.Poisoned, 3600 },
+ { BuffID.OnFire, 1200 },
+ { BuffID.CursedInferno, 420 },
+ { BuffID.Frostburn, 900 },
+ { BuffID.Ichor, 1200 },
+ { BuffID.Venom, 1260 },
+ { BuffID.Midas, 120 },
+ { BuffID.Wet, 1500 },
+ { BuffID.Slimed, 1500 },
+ { BuffID.Lovestruck, 1800 },
+ { BuffID.Stinky, 1800 },
+ { BuffID.SoulDrain, 30 },
+ { BuffID.ShadowFlame, 660 },
+ { BuffID.DryadsWard, 120 },
+ { BuffID.BoneJavelin, 900 },
+ { BuffID.StardustMinionBleed, 900 },
+ { BuffID.DryadsWardDebuff, 120 },
+ { BuffID.Daybreak, 300 },
+ { BuffID.BetsysCurse, 600 },
+ { BuffID.Oiled, 540 }
+ };
+
+
/// Constructor call initializes Bouncer and related functionality.
/// A new Bouncer.
internal Bouncer()
@@ -454,7 +479,7 @@ namespace TShockAPI
return;
}
}
-
+
/// Handles NPCAddBuff events.
/// The object that triggered the event.
/// The packet arguments that the event has.
@@ -484,64 +509,34 @@ namespace TShockAPI
return;
}
- if (!args.Player.HasPermission(Permissions.ignorenpcaddbuffdetection))
+ bool cheat = false;
+
+ if (NPCAddBuffTimeMax.ContainsKey(type))
{
- bool cheat = false;
-
- if(TShock.NPCAddBuffTimeMax.ContainsKey(type))
- {
- if(time > TShock.NPCAddBuffTimeMax[type])
- {
- cheat = true;
- }
-
- if(npc.townNPC && npc.netID != NPCID.Guide && npc.netID != NPCID.Clothier)
- {
- if(type != BuffID.Lovestruck && type != BuffID.Stinky && type != BuffID.DryadsWard &&
- type != BuffID.Wet && type != BuffID.Slimed)
- {
- cheat = true;
- }
- }
- // Want to check voodoo doll but it may be wrong.
- //else if(npc.netID == NPCID.Guide)
- //{
- // bool hasDoll = false;
- // foreach (var item in args.Player.Accessories)
- // {
- // if (item.netID == ItemID.GuideVoodooDoll)
- // {
- // hasDoll = true;
- // break;
- // }
- // }
- // cheat = !hasDoll;
- //}
- //else if (npc.netID == NPCID.Clothier)
- //{
- // bool hasDoll = false;
- // foreach (var item in args.Player.Accessories)
- // {
- // if (item.netID == ItemID.ClothierVoodooDoll)
- // {
- // hasDoll = true;
- // break;
- // }
- // }
- // cheat = !hasDoll;
- //}
- }
- else
+ if (time > NPCAddBuffTimeMax[type])
{
cheat = true;
}
- if (cheat)
+ if (npc.townNPC && npc.netID != NPCID.Guide && npc.netID != NPCID.Clothier)
{
- args.Player.Disable("Add buff to NPC abnormally.", DisableFlags.WriteToLogAndConsole);
- args.Handled = true;
+ if (type != BuffID.Lovestruck && type != BuffID.Stinky && type != BuffID.DryadsWard &&
+ type != BuffID.Wet && type != BuffID.Slimed)
+ {
+ cheat = true;
+ }
}
}
+ else
+ {
+ cheat = true;
+ }
+
+ if (cheat)
+ {
+ args.Player.Disable("Add buff to NPC abnormally.", DisableFlags.WriteToLogAndConsole);
+ args.Handled = true;
+ }
}
/// Handles Buff events.
diff --git a/TShockAPI/Permissions.cs b/TShockAPI/Permissions.cs
index dec457d3..7733f110 100644
--- a/TShockAPI/Permissions.cs
+++ b/TShockAPI/Permissions.cs
@@ -169,9 +169,6 @@ namespace TShockAPI
[Description("Prevents you from being disabled by abnormal MP.")]
public static readonly string ignoremp = "tshock.ignore.mp";
-
- [Description("Prevents you from being disabled by add buffs to npcs abnormally.")]
- public static readonly string ignorenpcaddbuffdetection = "tshock.ignore.npcaddbuff";
// tshock.item nodes
diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs
index 18cff28e..f839019d 100644
--- a/TShockAPI/TShock.cs
+++ b/TShockAPI/TShock.cs
@@ -131,9 +131,6 @@ namespace TShockAPI
///
public static Dictionary RESTStartupTokens = new Dictionary();
- /// The longest time of buffs players can add to NPCs.
- public static Dictionary NPCAddBuffTimeMax;
-
/// The TShock anti-cheat/anti-exploit system.
internal Bouncer Bouncer;
@@ -326,7 +323,6 @@ namespace TShockAPI
RestApi = new SecureRest(Netplay.ServerIP, Config.RestApiPort);
RestManager = new RestManager(RestApi);
RestManager.RegisterRestfulCommands();
- NPCAddBuffTimeMax = InitNPCAddBuffTimeMax();
Bouncer = new Bouncer();
RegionSystem = new RegionHandler(Regions);
@@ -389,34 +385,6 @@ namespace TShockAPI
}
}
- private Dictionary InitNPCAddBuffTimeMax()
- {
- var dict = new Dictionary();
-
- dict.Add(BuffID.Poisoned, 3600);
- dict.Add(BuffID.OnFire, 1200);
- dict.Add(BuffID.CursedInferno, 420);
- dict.Add(BuffID.Frostburn, 900);
- dict.Add(BuffID.Ichor, 1200);
- dict.Add(BuffID.Venom, 1260);
- dict.Add(BuffID.Midas, 120);
- dict.Add(BuffID.Wet, 1500);
- dict.Add(BuffID.Slimed, 1500);
- dict.Add(BuffID.Lovestruck, 1800);
- dict.Add(BuffID.Stinky, 1800);
- dict.Add(BuffID.SoulDrain, 30);
- dict.Add(BuffID.ShadowFlame, 660);
- dict.Add(BuffID.DryadsWard, 120);
- dict.Add(BuffID.BoneJavelin, 900);
- dict.Add(BuffID.StardustMinionBleed, 900);
- dict.Add(BuffID.DryadsWardDebuff, 120);
- dict.Add(BuffID.Daybreak, 300);
- dict.Add(BuffID.BetsysCurse, 600);
- dict.Add(BuffID.Oiled, 540);
-
- return dict;
- }
-
protected void CrashReporter_HeapshotRequesting(object sender, EventArgs e)
{
foreach (TSPlayer player in TShock.Players)
From e9372be276a79eefba10187ce6aa8a94bce35dfc Mon Sep 17 00:00:00 2001
From: Lucas Nicodemus
Date: Sat, 20 Oct 2018 09:14:38 -0700
Subject: [PATCH 7/8] Rename cheat var to detectedNPCBuffTimeCheat.
---
TShockAPI/Bouncer.cs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs
index ba7c2c85..395ecc36 100644
--- a/TShockAPI/Bouncer.cs
+++ b/TShockAPI/Bouncer.cs
@@ -509,13 +509,13 @@ namespace TShockAPI
return;
}
- bool cheat = false;
+ bool detectedNPCBuffTimeCheat = false;
if (NPCAddBuffTimeMax.ContainsKey(type))
{
if (time > NPCAddBuffTimeMax[type])
{
- cheat = true;
+ detectedNPCBuffTimeCheat = true;
}
if (npc.townNPC && npc.netID != NPCID.Guide && npc.netID != NPCID.Clothier)
@@ -523,18 +523,18 @@ namespace TShockAPI
if (type != BuffID.Lovestruck && type != BuffID.Stinky && type != BuffID.DryadsWard &&
type != BuffID.Wet && type != BuffID.Slimed)
{
- cheat = true;
+ detectedNPCBuffTimeCheat = true;
}
}
}
else
{
- cheat = true;
+ detectedNPCBuffTimeCheat = true;
}
- if (cheat)
+ if (detectedNPCBuffTimeCheat)
{
- args.Player.Disable("Add buff to NPC abnormally.", DisableFlags.WriteToLogAndConsole);
+ args.Player.Disable("Added buff to NPC abnormally.", DisableFlags.WriteToLogAndConsole);
args.Handled = true;
}
}
From f715d91dc6682991c11a941c6367af39d1bb1f53 Mon Sep 17 00:00:00 2001
From: AxeelAnder <1491773534@qq.com>
Date: Sun, 21 Oct 2018 11:01:08 +0800
Subject: [PATCH 8/8] disable -> kick
---
TShockAPI/Bouncer.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs
index 395ecc36..7287924f 100644
--- a/TShockAPI/Bouncer.cs
+++ b/TShockAPI/Bouncer.cs
@@ -534,7 +534,7 @@ namespace TShockAPI
if (detectedNPCBuffTimeCheat)
{
- args.Player.Disable("Added buff to NPC abnormally.", DisableFlags.WriteToLogAndConsole);
+ args.Player.Kick("Added buff to NPC abnormally.", true);
args.Handled = true;
}
}