From 5c6d03f9afa7f7c3f3f54cd1b7e0ddd305140525 Mon Sep 17 00:00:00 2001 From: Zidonuke Date: Tue, 27 Dec 2011 12:02:07 -0500 Subject: [PATCH] Improved spam detection for create and kill tiles. Improved item use blocking with banned items. Reserved slots should work now to 5 slots above max. --- TShockAPI/ConfigFile.cs | 12 ++++-- TShockAPI/GetDataHandlers.cs | 78 +++++++++++++++++++++++++++++------- TShockAPI/Permissions.cs | 6 ++- TShockAPI/TSPlayer.cs | 14 ++++--- TShockAPI/TShock.cs | 54 ++++++++++++++++--------- 5 files changed, 119 insertions(+), 45 deletions(-) diff --git a/TShockAPI/ConfigFile.cs b/TShockAPI/ConfigFile.cs index b31c641a..50135090 100644 --- a/TShockAPI/ConfigFile.cs +++ b/TShockAPI/ConfigFile.cs @@ -51,8 +51,6 @@ namespace TShockAPI public bool RangeChecks = true; [Description("Disables any building; placing of blocks")] public bool DisableBuild; - [Description("Kick a player if they exceed this number of tile kills within 1 second.")] - public int TileThreshold = 120; [Description("#.#.#. = Red/Blue/Green - RGB Colors for the Admin Chat Color. Max value: 255")] public float[] SuperAdminChatRGB = { 255, 0, 0 }; [Description("Super admin group chat prefix")] @@ -177,10 +175,10 @@ namespace TShockAPI [Description("Disables reporting of playercount to the stat system.")] public bool DisablePlayerCountReporting = false; - [Description("Disables clown bomb projectiles from spawning")] //Change this to stop the tile from spawning + [Description("Disables clown bomb projectiles from spawning")] public bool DisableClownBombs = false; - [Description("Disables snow ball projectiles from spawning")] //Change this to stop the tile from spawning + [Description("Disables snow ball projectiles from spawning")] public bool DisableSnowBalls = false; [Description("Change ingame chat format, {0} = Group Name, {1} = Group Prefix, {2} = Player Name, {3} = Group Suffix, {4} = Chat Message")] @@ -188,6 +186,12 @@ namespace TShockAPI [Description("Force the world time to be normal, day, or night")] public string ForceTime = "normal"; + + [Description("Disable/Revert a player if they exceed this number of tile kills within 1 second.")] + public int TileKillThreshold = 80; + + [Description("Disable/Revert a player if they exceed this number of tile places within 1 second.")] + public int TilePlaceThreshold = 20; public static ConfigFile Read(string path) { diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index dba8d515..38c4dcd0 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -520,9 +520,17 @@ namespace TShockAPI return true; } - if (type == 0 && Main.tileSolid[Main.tile[tileX, tileY].type] && args.Player.Active) + if(type == 1) { - args.Player.TileThreshold++; + args.Player.TilePlaceThreshold++; + var coords = new Vector2(tileX, tileY); + if (!args.Player.TilesCreated.ContainsKey(coords)) + args.Player.TilesCreated.Add(coords, Main.tile[tileX, tileY]); + } + + if ((type == 0 || type == 4) && Main.tileSolid[Main.tile[tileX, tileY].type]) + { + args.Player.TileKillThreshold++; var coords = new Vector2(tileX, tileY); if (!args.Player.TilesDestroyed.ContainsKey(coords)) args.Player.TilesDestroyed.Add(coords, Main.tile[tileX, tileY]); @@ -588,16 +596,6 @@ namespace TShockAPI return true; } - if ((control & 32) == 32) - { - if (!args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned(args.TPlayer.inventory[item].name)) - { - args.Player.LastThreat = DateTime.UtcNow; - args.Player.SendMessage(string.Format("You cannot use {0} on this server. Your actions are being ignored.", args.TPlayer.inventory[item].name), Color.Red); - return true; - } - } - if (!pos.Equals(args.Player.LastNetPosition)) { float distance = Vector2.Distance(new Vector2((pos.X / 16f), (pos.Y / 16f)), new Vector2(Main.spawnTileX, Main.spawnTileY)); @@ -623,9 +621,61 @@ namespace TShockAPI return true; } } - args.Player.LastNetPosition = pos; - return false; + + if ((control & 32) == 32) + { + if (!args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned(args.TPlayer.inventory[item].name)) + { + control -= 32; + args.Player.LastThreat = DateTime.UtcNow; + args.Player.SendMessage(string.Format("You cannot use {0} on this server. Your actions are being ignored.", args.TPlayer.inventory[item].name), Color.Red); + } + } + + args.TPlayer.selectedItem = item; + args.TPlayer.position = pos; + args.TPlayer.velocity = vel; + args.TPlayer.oldVelocity = args.TPlayer.velocity; + args.TPlayer.fallStart = (int)(pos.Y / 16f); + args.TPlayer.controlUp = false; + args.TPlayer.controlDown = false; + args.TPlayer.controlLeft = false; + args.TPlayer.controlRight = false; + args.TPlayer.controlJump = false; + args.TPlayer.controlUseItem = false; + args.TPlayer.direction = -1; + if ((control & 1) == 1) + { + args.TPlayer.controlUp = true; + } + if ((control & 2) == 2) + { + args.TPlayer.controlDown = true; + } + if ((control & 4) == 4) + { + args.TPlayer.controlLeft = true; + } + if ((control & 8) == 8) + { + args.TPlayer.controlRight = true; + } + if ((control & 16) == 16) + { + args.TPlayer.controlJump = true; + } + if ((control & 32) == 32) + { + args.TPlayer.controlUseItem = true; + } + if ((control & 64) == 64) + { + args.TPlayer.direction = 1; + } + NetMessage.SendData((int)PacketTypes.PlayerUpdate, -1, args.Player.Index, "", args.Player.Index); + + return true; } private static bool HandleProjectileNew(GetDataHandlerArgs args) diff --git a/TShockAPI/Permissions.cs b/TShockAPI/Permissions.cs index 05beed20..e4d72245 100644 --- a/TShockAPI/Permissions.cs +++ b/TShockAPI/Permissions.cs @@ -35,11 +35,13 @@ namespace TShockAPI [Description("Prevents you from being reverted by kill tile abuse detection")] public static readonly string ignorekilltiledetection; + [Description("Prevents you from being reverted by place tile abuse detection")] + public static readonly string ignoreplacetiledetection; + [Description("Specific log messages are sent to users with this permission")] public static readonly string logs; - [Todo] - [Description("Not currently working")] + [Description("Allows you to bypass the max slots for up to 5 slots above your max")] public static readonly string reservedslot; [Description("User is notified when an update is available")] diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index def97382..45792a67 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -30,8 +30,10 @@ namespace TShockAPI { public static readonly TSServerPlayer Server = new TSServerPlayer(); public static readonly TSPlayer All = new TSPlayer("All"); - public int TileThreshold { get; set; } + public int TileKillThreshold { get; set; } + public int TilePlaceThreshold { get; set; } public Dictionary TilesDestroyed { get; protected set; } + public Dictionary TilesCreated { get; protected set; } public bool SyncHP { get; set; } public bool SyncMP { get; set; } public Group Group { get; set; } @@ -157,6 +159,7 @@ namespace TShockAPI public TSPlayer(int index) { TilesDestroyed = new Dictionary(); + TilesCreated = new Dictionary(); Index = index; Group = new Group("null"); } @@ -164,6 +167,7 @@ namespace TShockAPI protected TSPlayer(String playerName) { TilesDestroyed = new Dictionary(); + TilesCreated = new Dictionary(); Index = -1; FakePlayer = new Player { name = playerName, whoAmi = -1 }; Group = new Group("null"); @@ -419,17 +423,17 @@ namespace TShockAPI NetMessage.SendData((int)PacketTypes.NpcStrike, -1, -1, "", npcid, damage, knockBack, hitDirection); } - public void RevertKillTile(Dictionary destroyedTiles) + public void RevertTiles(Dictionary tiles) { // Update Main.Tile first so that when tile sqaure is sent it is correct - foreach (KeyValuePair entry in destroyedTiles) + foreach (KeyValuePair entry in tiles) { Main.tile[(int)entry.Key.X, (int)entry.Key.Y] = entry.Value; - Log.Debug(string.Format("Reverted DestroyedTile(TileXY:{0}_{1}, Type:{2})", + Log.Debug(string.Format("Reverted Tiles(TileXY:{0}_{1}, Type:{2})", entry.Key.X, entry.Key.Y, Main.tile[(int)entry.Key.X, (int)entry.Key.Y].type)); } // Send all players updated tile sqaures - foreach (Vector2 coords in destroyedTiles.Keys) + foreach (Vector2 coords in tiles.Keys) { All.SendTileSquare((int)coords.X, (int)coords.Y, 3); } diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 07427ffd..bf68d226 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -472,16 +472,28 @@ namespace TShockAPI count++; if (player.TilesDestroyed != null) { - if (player.TileThreshold >= Config.TileThreshold) + if (player.TileKillThreshold >= Config.TileKillThreshold) { - TSPlayer.Server.RevertKillTile(player.TilesDestroyed); + TSPlayer.Server.RevertTiles(player.TilesDestroyed); } - if (player.TileThreshold > 0) + if (player.TileKillThreshold > 0) { - player.TileThreshold = 0; + player.TileKillThreshold = 0; player.TilesDestroyed.Clear(); } } + if (player.TilesCreated != null) + { + if (player.TilePlaceThreshold >= Config.TilePlaceThreshold) + { + TSPlayer.Server.RevertTiles(player.TilesCreated); + } + if (player.TilePlaceThreshold > 0) + { + player.TilePlaceThreshold = 0; + player.TilesCreated.Clear(); + } + } if (player.ForceSpawn && (DateTime.Now - player.LastDeath).Seconds >= 3) { player.Spawn(); @@ -679,24 +691,16 @@ namespace TShockAPI return; } - // Stop accepting updates from player as this player is going to be kicked/banned during OnUpdate (different thread so can produce race conditions) - if (player.TileThreshold >= Config.TileThreshold && !player.Group.HasPermission(Permissions.ignorekilltiledetection)) + using (var data = new MemoryStream(e.Msg.readBuffer, e.Index, e.Length)) { - e.Handled = true; - } - else - { - using (var data = new MemoryStream(e.Msg.readBuffer, e.Index, e.Length)) + try { - try - { - if (GetDataHandlers.HandlerGetData(type, player, data)) - e.Handled = true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } + if (GetDataHandlers.HandlerGetData(type, player, data)) + e.Handled = true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); } } } @@ -972,6 +976,16 @@ namespace TShockAPI public static bool CheckTilePermission(TSPlayer player, int tileX, int tileY) { + if (player.TileKillThreshold >= Config.TileKillThreshold && !player.Group.HasPermission(Permissions.ignorekilltiledetection)) + { + player.LastThreat = DateTime.UtcNow; + return true; + } + if (player.TilePlaceThreshold >= Config.TilePlaceThreshold && !player.Group.HasPermission(Permissions.ignoreplacetiledetection)) + { + player.LastThreat = DateTime.UtcNow; + return true; + } if (!player.Group.HasPermission(Permissions.canbuild)) { player.SendMessage("You do not have permission to build!", Color.Red);