diff --git a/ConfigurationExamples/ChannelScripts/srv#lpr.csv b/ConfigurationExamples/ChannelScripts/srv#lpr.csv index 4373eff..218c333 100644 --- a/ConfigurationExamples/ChannelScripts/srv#lpr.csv +++ b/ConfigurationExamples/ChannelScripts/srv#lpr.csv @@ -1,6 +1,8 @@ # NOTE: Filename should be servername#channel OR servernamechannel (is started not from '#'). It MUST have .csv extension and hold tab-separated-values. This example works for server='srv' and channel='#lpr' #Join Flood Control Number of events Time Frame in seconds -JoinFloodControl 5 10 +JoinFloodControl 5 10 +#Join Clone Control Number of events Pattern +JoinCloneControl 1 ^.+[0-9]+?!.*$ #event regexp command message_or_command message_or_command message_or_ N+1 msg ^!help(.+)? \chanmsg Ничего не знаю! join ^Мерзавец(.+)?!.* \kickban requested diff --git a/pom.xml b/pom.xml index 1f929b2..61e1039 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 loper InnaIrcBot - 0.5.2-SNAPSHOT + 0.6-SNAPSHOT jar InnaIrcBot diff --git a/src/main/java/InnaIrcBot/Commanders/ChanelCommander.java b/src/main/java/InnaIrcBot/Commanders/ChanelCommander.java index bb61cb0..d44c56c 100644 --- a/src/main/java/InnaIrcBot/Commanders/ChanelCommander.java +++ b/src/main/java/InnaIrcBot/Commanders/ChanelCommander.java @@ -23,6 +23,9 @@ public class ChanelCommander implements Runnable { private boolean joinFloodTrackNeed = false; private JoinFloodHandler jfh; + private boolean joinCloneTrackNeed = false; // todo:fix + private JoinCloneHandler jch; + public ChanelCommander(BufferedReader streamReader, String serverName, String chan, String configFilePath){ this.reader = streamReader; this.server = serverName; @@ -50,6 +53,8 @@ public class ChanelCommander implements Runnable { case "JOIN": if (joinFloodTrackNeed) jfh.track(simplifyNick(dataStrings[1])); + if (joinCloneTrackNeed) + jch.track(dataStrings[1]); joinCame(dataStrings[1]); break; case "PRIVMSG": @@ -250,12 +255,25 @@ public class ChanelCommander implements Runnable { jfh = new JoinFloodHandler(events, timeFrame, server, chanel); joinFloodTrackNeed = true; } else { - System.out.println("Internal issue: thread ChanelCommander->parse(): 'Number of events' and/or 'Time Frame in seconds' should be greater then 0"); + System.out.println("Internal issue: thread ChanelCommander->parse(): 'Number of events' and/or 'Time Frame in seconds' should be greater than 0"); } } else - System.out.println("Internal issue: thread ChanelCommander->parse(): 'Number of events' and/or 'Time Frame in seconds' should be numbers greater then 0"); + System.out.println("Internal issue: thread ChanelCommander->parse(): 'Number of events' and/or 'Time Frame in seconds' should be numbers greater than 0"); break; + case "joinclonecontrol": + if (!directive[1].isEmpty() && !directive[2].isEmpty() && Pattern.matches("^[0-9]+?$", directive[1].trim())) { + int events = Integer.valueOf(directive[1].trim()); + if (events > 0){ + jch = new JoinCloneHandler(directive[2], events, server, chanel); // TODO: REMOVE + joinCloneTrackNeed = true; + } + else { + System.out.println("Internal issue: thread ChanelCommander->parse(): 'Number of events' should be greater than 0"); + } + } else { + System.out.println("Internal issue: thread ChanelCommander->parse(): 'Number of events' should be greater than 0 and pattern shouldn't be empty."); + } } } } diff --git a/src/main/java/InnaIrcBot/Commanders/JoinCloneHandler.java b/src/main/java/InnaIrcBot/Commanders/JoinCloneHandler.java new file mode 100644 index 0000000..9162baa --- /dev/null +++ b/src/main/java/InnaIrcBot/Commanders/JoinCloneHandler.java @@ -0,0 +1,46 @@ +package InnaIrcBot.Commanders; + +import InnaIrcBot.ProvidersConsumers.StreamProvider; + +import java.time.LocalDateTime; + +public class JoinCloneHandler { + + private String pattern; + private String server; + private String chanel; + private int timeFrameInSeconds; + + private LocalDateTime lastCame; + private String prevUserNick; + + public JoinCloneHandler(String pattern, int timeFrameInSeconds, String serverName, String chanelName){ + this.pattern = pattern; + this.timeFrameInSeconds = timeFrameInSeconds; + this.server = serverName; + this.chanel = chanelName; + prevUserNick = ""; + lastCame = LocalDateTime.now().minusDays(1L); + } + + public void track(String userNick){ + if (userNick.matches(pattern)){ + if (lastCame.isAfter(LocalDateTime.now().minusSeconds(timeFrameInSeconds)) && !prevUserNick.equals(userNick)){ + StreamProvider.writeToStream(server, + "MODE "+chanel+" +b *!*"+getIdentHost(userNick)+"\n"+ + "MODE "+chanel+" +b *!*"+getIdentHost(prevUserNick)+"\n"+ + "KICK "+chanel+" "+getNickOnly(userNick)+" :clone\n"+ + "KICK "+chanel+" "+getNickOnly(prevUserNick)+" :clone" + ); + } + prevUserNick = userNick; + lastCame = LocalDateTime.now(); + } + } + private String getIdentHost(String fullNick){ + return fullNick.replaceAll("^.*@","@"); + } + private String getNickOnly(String fullNick){ + return fullNick.replaceAll("!.*$",""); + } +} diff --git a/src/main/java/InnaIrcBot/GlobalData.java b/src/main/java/InnaIrcBot/GlobalData.java index 3be3b00..47992ad 100644 --- a/src/main/java/InnaIrcBot/GlobalData.java +++ b/src/main/java/InnaIrcBot/GlobalData.java @@ -1,7 +1,7 @@ package InnaIrcBot; public class GlobalData { - private static final String version = "InnaIrcBot v0.5.2 \"Шикотан\""; + private static final String version = "InnaIrcBot v0.6 \"Большевик\""; public static synchronized String getAppVersion(){ return version; } diff --git a/src/main/java/InnaIrcBot/ProvidersConsumers/SystemConsumer.java b/src/main/java/InnaIrcBot/ProvidersConsumers/SystemConsumer.java index d517cf6..6ae7bb6 100644 --- a/src/main/java/InnaIrcBot/ProvidersConsumers/SystemConsumer.java +++ b/src/main/java/InnaIrcBot/ProvidersConsumers/SystemConsumer.java @@ -9,6 +9,7 @@ import InnaIrcBot.LogDriver.BotSystemWorker; import java.io.*; import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -29,6 +30,8 @@ public class SystemConsumer implements Runnable{ private PrivateMsgCommander commander; + private LocalDateTime lastCTCPReplyTime; + SystemConsumer(BufferedReader streamReader, String userNick, Map map, StorageFile storage) { this.writerWorker = BotDriver.getSystemWorker(storage.getServerName()); this.nick = userNick; @@ -49,6 +52,8 @@ public class SystemConsumer implements Runnable{ message.append("\n"); } StreamProvider.writeToStream(serverName,message.toString()); + + lastCTCPReplyTime = LocalDateTime.now(); } @Override @@ -130,33 +135,31 @@ public class SystemConsumer implements Runnable{ } private void replyCTCP(String sender, String message){ // got simplified nick - if (message.equals("\u0001VERSION\u0001")){ - StreamProvider.writeToStream(serverName,"NOTICE "+sender+" :\u0001VERSION "+ GlobalData.getAppVersion()+"\u0001"); - writerWorker.logAdd("[system]", "catch/handled CTCP VERSION from", sender); - //System.out.println("NOTICE "+sender+" \u0001VERSION "+ GlobalData.getAppVersion()+"\u0001"); + if (lastCTCPReplyTime.isBefore(LocalDateTime.now().minusSeconds(3))) { // TODO: Consider moving to config file. Now set to 3 sec + lastCTCPReplyTime = LocalDateTime.now(); + if (message.equals("\u0001VERSION\u0001")) { + StreamProvider.writeToStream(serverName, "NOTICE " + sender + " :\u0001VERSION " + GlobalData.getAppVersion() + "\u0001"); + writerWorker.logAdd("[system]", "catch/handled CTCP VERSION from", sender); + //System.out.println("NOTICE "+sender+" \u0001VERSION "+ GlobalData.getAppVersion()+"\u0001"); + } else if (message.startsWith("\u0001PING ") && message.endsWith("\u0001")) { + StreamProvider.writeToStream(serverName, "NOTICE " + sender + " :" + message); + writerWorker.logAdd("[system]", "catch/handled CTCP PING from", sender); + //System.out.println(":"+sender+" NOTICE "+sender.substring(0,sender.indexOf("!"))+" "+message); + } else if (message.equals("\u0001CLIENTINFO\u0001")) { + StreamProvider.writeToStream(serverName, "NOTICE " + sender + " :\u0001CLIENTINFO ACTION PING VERSION TIME CLIENTINFO SOURCE\u0001"); + writerWorker.logAdd("[system]", "catch/handled CTCP CLIENTINFO from", sender); + //System.out.println(":"+sender+" NOTICE "+sender.substring(0,sender.indexOf("!"))+" \u0001CLIENTINFO ACTION PING VERSION TIME CLIENTINFO\u0001"); + } else if (message.equals("\u0001TIME\u0001")) { + StreamProvider.writeToStream(serverName, "NOTICE " + sender + " :\u0001TIME " + ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME) + "\u0001"); + writerWorker.logAdd("[system]", "catch/handled CTCP TIME from", sender); + //System.out.println(":"+sender+" NOTICE "+sender.substring(0,sender.indexOf("!"))+" \u0001TIME "+ ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME)+"\u0001"); + } else if (message.equals("\u0001SOURCE\u0001")) { + StreamProvider.writeToStream(serverName, "NOTICE " + sender + " :\u0001SOURCE https://github.com/developersu/InnaIrcBot\u0001"); + writerWorker.logAdd("[system]", "catch/handled CTCP TIME from", sender); + //System.out.println(":"+sender+" NOTICE "+sender.substring(0,sender.indexOf("!"))+" \u0001SOURCE "+ ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME)+"\u0001"); + } else + writerWorker.logAdd("[system]", "catch unknown CTCP request \"" + message + "\" from ", sender); } - else if (message.startsWith("\u0001PING ") && message.endsWith("\u0001")){ - StreamProvider.writeToStream(serverName,"NOTICE "+sender+" :"+message); - writerWorker.logAdd("[system]", "catch/handled CTCP PING from", sender); - //System.out.println(":"+sender+" NOTICE "+sender.substring(0,sender.indexOf("!"))+" "+message); - } - else if (message.equals("\u0001CLIENTINFO\u0001")){ - StreamProvider.writeToStream(serverName,"NOTICE "+sender+" :\u0001CLIENTINFO ACTION PING VERSION TIME CLIENTINFO SOURCE\u0001"); - writerWorker.logAdd("[system]", "catch/handled CTCP CLIENTINFO from", sender); - //System.out.println(":"+sender+" NOTICE "+sender.substring(0,sender.indexOf("!"))+" \u0001CLIENTINFO ACTION PING VERSION TIME CLIENTINFO\u0001"); - } - else if (message.equals("\u0001TIME\u0001")){ - StreamProvider.writeToStream(serverName,"NOTICE "+sender+" :\u0001TIME "+ ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME)+"\u0001"); - writerWorker.logAdd("[system]", "catch/handled CTCP TIME from", sender); - //System.out.println(":"+sender+" NOTICE "+sender.substring(0,sender.indexOf("!"))+" \u0001TIME "+ ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME)+"\u0001"); - } - else if (message.equals("\u0001SOURCE\u0001")){ - StreamProvider.writeToStream(serverName,"NOTICE "+sender+" :\u0001SOURCE https://github.com/developersu/InnaIrcBot\u0001"); - writerWorker.logAdd("[system]", "catch/handled CTCP TIME from", sender); - //System.out.println(":"+sender+" NOTICE "+sender.substring(0,sender.indexOf("!"))+" \u0001SOURCE "+ ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME)+"\u0001"); - } - else - writerWorker.logAdd("[system]", "catch unknown CTCP request \""+message+"\" from ", sender); } private String simplifyNick(String nick){ return nick.replaceAll("!.*$",""); }