innaircbot/src/main/java/InnaIrcBot/Commanders/flood/JoinFloodHandler.java

74 lines
2.5 KiB
Java
Raw Normal View History

package InnaIrcBot.Commanders.flood;
2018-12-16 17:27:44 +03:00
import InnaIrcBot.ProvidersConsumers.StreamProvider;
import java.time.LocalDateTime;
2020-10-20 03:37:20 +03:00
import java.util.*;
public class JoinFloodHandler implements EventHandler {
2020-10-20 03:37:20 +03:00
private final int joinMaxNumber; // How many events should happens before we start validation
private final int timeFrameInSeconds; // For which period critical amount of events should happens
private final String server;
private final String channel;
protected final HashMap<String, LinkedList<LocalDateTime>> users;
public JoinFloodHandler(String server, String channel, int joinMaxNumber, int timeFrameInSeconds){
this.server = server;
this.channel = channel;
2020-10-20 03:37:20 +03:00
this.joinMaxNumber = joinMaxNumber;
2018-12-16 17:27:44 +03:00
this.timeFrameInSeconds = timeFrameInSeconds;
2020-10-20 03:37:20 +03:00
this.users = new HashMap<>();
2018-12-16 17:27:44 +03:00
}
@Override
public void track(String nick){
nick = simplifyNick(nick);
2018-12-16 17:27:44 +03:00
if (isNewcomer(nick)) {
registerNewUser(nick);
2020-10-20 03:37:20 +03:00
return;
2018-12-16 17:27:44 +03:00
}
2020-10-20 03:37:20 +03:00
if(isJoinFlooder(nick)){
kickBanUser(nick);
users.remove(nick);
2018-12-16 17:27:44 +03:00
}
}
2020-10-20 03:37:20 +03:00
private boolean isNewcomer(String user){
return ! users.containsKey(user);
}
private void registerNewUser(String user){
users.put(user, new LinkedList<>());
users.get(user).addFirst(LocalDateTime.now());
}
2018-12-16 17:27:44 +03:00
2020-10-20 03:37:20 +03:00
private boolean isJoinFlooder(String user){
final LocalDateTime firstJoinTime = getFirstJoinTimeAndUpdate(user);
return firstJoinTime.isAfter(LocalDateTime.now().minusSeconds(timeFrameInSeconds));
2018-12-16 17:27:44 +03:00
}
2020-10-20 03:37:20 +03:00
private LocalDateTime getFirstJoinTimeAndUpdate(String user){
LinkedList<LocalDateTime> userJoinHistory = users.get(user);
LocalDateTime fistJoinTime;
userJoinHistory.addLast(LocalDateTime.now());
if (userJoinHistory.size() > joinMaxNumber){
fistJoinTime = userJoinHistory.getFirst();
userJoinHistory.removeFirst();
}
else {
fistJoinTime = LocalDateTime.MIN;
}
return fistJoinTime;
}
private void kickBanUser(String user){
StreamProvider.writeToStream(server,
"PRIVMSG "+ channel +" :"+user+": join flood ("+ joinMaxNumber +" connections in "+timeFrameInSeconds+" seconds).\n"+
"MODE "+ channel +" +b "+user+"!*@*"); // TODO: consider other ban methods
2018-12-16 17:27:44 +03:00
}
private String simplifyNick(String nick){ return nick.replaceAll("!.*$",""); }
2018-12-16 17:27:44 +03:00
}