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.
This commit is contained in:
Zidonuke 2011-12-27 12:02:07 -05:00
parent a766f1e5d9
commit 5c6d03f9af
5 changed files with 119 additions and 45 deletions

View file

@ -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)
{

View file

@ -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)

View file

@ -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")]

View file

@ -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<Vector2, Tile> TilesDestroyed { get; protected set; }
public Dictionary<Vector2, Tile> 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<Vector2, Tile>();
TilesCreated = new Dictionary<Vector2, Tile>();
Index = index;
Group = new Group("null");
}
@ -164,6 +167,7 @@ namespace TShockAPI
protected TSPlayer(String playerName)
{
TilesDestroyed = new Dictionary<Vector2, Tile>();
TilesCreated = new Dictionary<Vector2, Tile>();
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<Vector2, Tile> destroyedTiles)
public void RevertTiles(Dictionary<Vector2, Tile> tiles)
{
// Update Main.Tile first so that when tile sqaure is sent it is correct
foreach (KeyValuePair<Vector2, Tile> entry in destroyedTiles)
foreach (KeyValuePair<Vector2, Tile> 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);
}

View file

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