Added untested rate limits
This commit is contained in:
@@ -160,7 +160,7 @@ public class NetClient implements ApplicationListener{
|
||||
throw new ValidateException(player, "Player has sent a message above the text limit.");
|
||||
}
|
||||
|
||||
String original = message;
|
||||
Events.fire(new PlayerChatEvent(player, message));
|
||||
|
||||
//check if it's a command
|
||||
CommandResponse response = netServer.clientCommands.handleMessage(message, player);
|
||||
@@ -197,8 +197,6 @@ public class NetClient implements ApplicationListener{
|
||||
player.sendMessage(text);
|
||||
}
|
||||
}
|
||||
|
||||
Events.fire(new PlayerChatEvent(player, message, original));
|
||||
}
|
||||
|
||||
public static String colorizeName(int id, String name){
|
||||
|
||||
@@ -35,7 +35,7 @@ import static mindustry.Vars.*;
|
||||
|
||||
public class NetServer implements ApplicationListener{
|
||||
private final static int maxSnapshotSize = 430, timerBlockSync = 0;
|
||||
private final static float serverSyncTime = 12, kickDuration = 30 * 1000, blockSyncTime = 60 * 8;
|
||||
private final static float serverSyncTime = 12, blockSyncTime = 60 * 8;
|
||||
private final static Vec2 vector = new Vec2();
|
||||
private final static Rect viewport = new Rect();
|
||||
/** If a player goes away of their server-side coordinates by this distance, they get teleported back. */
|
||||
@@ -115,7 +115,7 @@ public class NetServer implements ApplicationListener{
|
||||
return;
|
||||
}
|
||||
|
||||
if(Time.millis() - info.lastKicked < kickDuration){
|
||||
if(Time.millis() < info.lastKicked){
|
||||
con.kick(KickReason.recentKick);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -64,13 +64,10 @@ public class EventType{
|
||||
public static class PlayerChatEvent{
|
||||
public final Player player;
|
||||
public final String message;
|
||||
/** The original, unfiltered message. */
|
||||
public final String originalMessage;
|
||||
|
||||
public PlayerChatEvent(Player player, String message, String originalMessage){
|
||||
public PlayerChatEvent(Player player, String message){
|
||||
this.player = player;
|
||||
this.message = message;
|
||||
this.originalMessage = originalMessage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package mindustry.net;
|
||||
|
||||
import arc.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.ArcAnnotate.*;
|
||||
import mindustry.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
@@ -19,6 +20,38 @@ public class Administration{
|
||||
|
||||
public Administration(){
|
||||
load();
|
||||
|
||||
//anti-spam
|
||||
addChatFilter((player, message) -> {
|
||||
long resetTime = Config.messageRateLimit.num() * 1000;
|
||||
if(Config.antiSpam.bool() && !player.isLocal && !player.isAdmin){
|
||||
//prevent people from spamming messages quickly
|
||||
if(resetTime > 0 && Time.timeSinceMillis(player.getInfo().lastMessageTime) < resetTime){
|
||||
//supress message
|
||||
player.sendMessage("[scarlet]You may only send messages every " + Config.messageRateLimit.num() + " seconds.");
|
||||
player.getInfo().messageInfractions ++;
|
||||
//kick player for spamming and prevent connection if they've done this several times
|
||||
if(player.getInfo().messageInfractions >= Config.messageSpamKick.num() && Config.messageSpamKick.num() != 0){
|
||||
player.con.kick("You have been kicked for spamming.", 1000 * 60 * 2);
|
||||
}
|
||||
player.lastText = message;
|
||||
return null;
|
||||
}else{
|
||||
player.getInfo().messageInfractions = 0;
|
||||
}
|
||||
|
||||
//prevent players from sending the same message twice in the span of 50 seconds
|
||||
if(message.equals(player.lastText) && Time.timeSinceMillis(player.getInfo().lastMessageTime) < 1000 * 50){
|
||||
player.sendMessage("[scarlet]You may not send the same message twice.");
|
||||
return null;
|
||||
}
|
||||
|
||||
player.lastText = message;
|
||||
player.getInfo().lastMessageTime = Time.millis();
|
||||
}
|
||||
|
||||
return message;
|
||||
});
|
||||
}
|
||||
|
||||
/** Adds a chat filter. This will transform the chat messages of every player.
|
||||
@@ -326,6 +359,9 @@ public class Administration{
|
||||
crashReport("Whether to send crash reports.", false, "crashreport"),
|
||||
logging("Whether to log everything to files.", true),
|
||||
strict("Whether strict mode is on - corrects positions and prevents duplicate UUIDs.", true),
|
||||
antiSpam("Whether spammers are automatically kicked and rate-limited.", true),
|
||||
messageRateLimit("Message rate limit in seconds. 0 to disable.", 0),
|
||||
messageSpamKick("How many times a player must send a message before the cooldown to get kicked. 0 to disable.", 3),
|
||||
socketInput("Allows a local application to control this server through a local TCP socket.", false, "socket", () -> Events.fire(Trigger.socketConfigChanged)),
|
||||
socketInputPort("The port for socket input.", 6859, () -> Events.fire(Trigger.socketConfigChanged)),
|
||||
socketInputAddress("The bind address for socket input.", "localhost", () -> Events.fire(Trigger.socketConfigChanged)),
|
||||
@@ -402,7 +438,11 @@ public class Administration{
|
||||
public int timesKicked;
|
||||
public int timesJoined;
|
||||
public boolean banned, admin;
|
||||
public long lastKicked; //last kicked timestamp
|
||||
public long lastKicked; //last kicked time to expiration
|
||||
|
||||
public transient long lastMessageTime;
|
||||
public transient String lastSentMessage;
|
||||
public transient int messageInfractions;
|
||||
|
||||
PlayerInfo(String id){
|
||||
this.id = id;
|
||||
|
||||
@@ -37,7 +37,7 @@ public abstract class NetConnection{
|
||||
if(player != null && (reason == KickReason.kick || reason == KickReason.banned || reason == KickReason.vote) && player.uuid != null){
|
||||
PlayerInfo info = netServer.admins.getInfo(player.uuid);
|
||||
info.timesKicked++;
|
||||
info.lastKicked = Math.max(Time.millis(), info.lastKicked);
|
||||
info.lastKicked = Math.max(Time.millis() + 30 * 1000, info.lastKicked);
|
||||
}
|
||||
|
||||
Call.onKick(this, reason);
|
||||
@@ -49,12 +49,17 @@ public abstract class NetConnection{
|
||||
|
||||
/** Kick with an arbitrary reason. */
|
||||
public void kick(String reason){
|
||||
kick(reason, 30 * 1000);
|
||||
}
|
||||
|
||||
/** Kick with an arbitrary reason, and a kick duration in milliseconds. */
|
||||
public void kick(String reason, int kickDuration){
|
||||
Log.info("Kicking connection {0}; Reason: {1}", address, reason.replace("\n", " "));
|
||||
|
||||
if(player != null && player.uuid != null){
|
||||
PlayerInfo info = netServer.admins.getInfo(player.uuid);
|
||||
info.timesKicked++;
|
||||
info.lastKicked = Math.max(Time.millis(), info.lastKicked);
|
||||
info.lastKicked = Math.max(Time.millis() + kickDuration, info.lastKicked);
|
||||
}
|
||||
|
||||
Call.onKick(this, reason);
|
||||
|
||||
Reference in New Issue
Block a user