diff --git a/pom.xml b/pom.xml index 59b5444..d056808 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 loper InnaIrcBot - 0.2.2-SNAPSHOT + 0.3-SNAPSHOT jar InnaIrcBot diff --git a/src/main/java/InnaIrcBot/BotStart.java b/src/main/java/InnaIrcBot/BotStart.java index be3baf6..26ebf64 100644 --- a/src/main/java/InnaIrcBot/BotStart.java +++ b/src/main/java/InnaIrcBot/BotStart.java @@ -1,14 +1,14 @@ /** * InnaIrcBot * @author Dmitry Isaenko - * Russia, 2018. + * Russia, 2018-2019. * */ package InnaIrcBot; import InnaIrcBot.Config.StorageReader; public class BotStart { -//TODO: Steam link, flood control, kikbana +//TODO: flood control //TODO: setDaemon(true) //TODO: multiple connections to one server not allowed diff --git a/src/main/java/InnaIrcBot/Commanders/PrivateMsgCommander.java b/src/main/java/InnaIrcBot/Commanders/PrivateMsgCommander.java index b064a1b..fa650e6 100644 --- a/src/main/java/InnaIrcBot/Commanders/PrivateMsgCommander.java +++ b/src/main/java/InnaIrcBot/Commanders/PrivateMsgCommander.java @@ -22,6 +22,9 @@ public class PrivateMsgCommander { // T if (administrators.contains(sender) && !message.isEmpty()) { String[] cmd = message.split("(\\s)|(\t)+?", 2); cmd[0] = cmd[0].toLowerCase(); + if (cmd.length > 1) + cmd[1] = cmd[1].trim(); + switch (cmd[0]){ case "tell": diff --git a/src/main/java/InnaIrcBot/GlobalData.java b/src/main/java/InnaIrcBot/GlobalData.java index df62497..4de2d8a 100644 --- a/src/main/java/InnaIrcBot/GlobalData.java +++ b/src/main/java/InnaIrcBot/GlobalData.java @@ -1,7 +1,7 @@ package InnaIrcBot; public class GlobalData { - public static final String version = "InnaIrcBot v0.2.2 \"Маньчжурия\""; + private static final String version = "InnaIrcBot v0.3 \"Карелия\""; public static synchronized String getAppVersion(){ return version; } diff --git a/src/main/java/InnaIrcBot/LogDriver/BotDriver.java b/src/main/java/InnaIrcBot/LogDriver/BotDriver.java index 2824197..faedb96 100644 --- a/src/main/java/InnaIrcBot/LogDriver/BotDriver.java +++ b/src/main/java/InnaIrcBot/LogDriver/BotDriver.java @@ -6,8 +6,9 @@ public class BotDriver { private static HashMap serverDriver = new HashMap<>(); /** * Define driver for desired server - * */ // TODO: add proxy worker for using with multiple drivers - public static synchronized boolean setFileDriver(String serverName, String driver, String[] driverParams){ + * */ + // TODO: add proxy worker for using with multiple drivers + public static synchronized boolean setLogDriver(String serverName, String driver, String[] driverParams){ if (!driver.isEmpty() && driverParams != null && driverParams.length > 0 && driverParams[0] != null && !driverParams[0].isEmpty()) { String[][] drvAndParams = { {driver}, @@ -29,7 +30,9 @@ public class BotDriver { case "Zero": return new BotZeroWorker(); default: - System.out.println("Configuration issue: BotDriver->getWorker() can't find required driver \""+serverDriver.get(serverName)[0][0]+"\".Using \"ZeroWorker\"."); + System.out.println("Configuration issue: BotDriver->getWorker() can't find required driver \"" + +serverDriver.get(serverName)[0][0] + +"\".Using \"ZeroWorker\"."); return new BotZeroWorker(); } } diff --git a/src/main/java/InnaIrcBot/ProvidersConsumers/DataProvider.java b/src/main/java/InnaIrcBot/ProvidersConsumers/DataProvider.java index b62c171..a67a591 100644 --- a/src/main/java/InnaIrcBot/ProvidersConsumers/DataProvider.java +++ b/src/main/java/InnaIrcBot/ProvidersConsumers/DataProvider.java @@ -51,7 +51,6 @@ public class DataProvider implements Runnable { this.ableToRun = false; return; } - InputStream inStream = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(inStream, StandardCharsets.UTF_8); //TODO set charset in options; this.rawStreamReader = new BufferedReader(isr); @@ -69,22 +68,12 @@ public class DataProvider implements Runnable { } public void run(){ - if (!ableToRun) { + if (!ableToRun || !this.initConnection(rawStreamReader) + || !BotDriver.setLogDriver(serverName, configFile.getLogDriver(), configFile.getLogDriverParameters())) { //Prepare logDriver for using in threads. this.close(); return; } - if(!this.initConnection(rawStreamReader)) { - this.close(); - return; - } - - //Prepare logDriver for using in threads. - if(!BotDriver.setFileDriver(serverName, configFile.getLogDriver(), configFile.getLogDriverParameters())) { - this.close(); - return; - } - /* Used for sending data into consumers objects*/ Map channelsMap = Collections.synchronizedMap(new HashMap()); try { @@ -95,9 +84,13 @@ public class DataProvider implements Runnable { new PipedInputStream(streamOut), StandardCharsets.UTF_8) ); - Runnable consumer = new SystemConsumer(streamBufferedReader, userNick, channelsMap, this.configFile); - new Thread(consumer).start(); - channelsMap.put("", new PrintWriter(streamOut)); // Not sure that PrintWriter is thread-safe.. + Runnable systemConsumer = new SystemConsumer(streamBufferedReader, userNick, channelsMap, this.configFile); + new Thread(systemConsumer).start(); + PrintWriter systemConsumerWriter = new PrintWriter(streamOut); + + StreamProvider.setSysConsumer(serverName, systemConsumerWriter); // Register system consumer at StreamProvider + + channelsMap.put("", systemConsumerWriter); // Not sure that PrintWriter is thread-safe.. } catch (IOException e){ System.out.println("Internal issue: DataProvider->run() I/O exception while initialized child objects.\n\t"+e); // caused by Socket this.close(); diff --git a/src/main/java/InnaIrcBot/ProvidersConsumers/StreamProvider.java b/src/main/java/InnaIrcBot/ProvidersConsumers/StreamProvider.java index 15cc83a..00a2b2f 100644 --- a/src/main/java/InnaIrcBot/ProvidersConsumers/StreamProvider.java +++ b/src/main/java/InnaIrcBot/ProvidersConsumers/StreamProvider.java @@ -2,18 +2,26 @@ package InnaIrcBot.ProvidersConsumers; import java.io.OutputStream; import java.io.OutputStreamWriter; +import java.io.PrintWriter; import java.net.Socket; import java.util.HashMap; public class StreamProvider { private static HashMap srvStreamMap = new HashMap<>(); - //private static OutputStreamWriter streamWriter; + private static HashMap srvSysConsumersMap = new HashMap<>(); public static synchronized void writeToStream(String server, String message){ try { srvStreamMap.get(server).write(message+"\n"); srvStreamMap.get(server).flush(); + + //System.out.println(message); + // If this application says something, then pass it into system consumer thread to handle + if (message.startsWith("PRIVMSG")) { + srvSysConsumersMap.get(server).println("INNA "+message); + srvSysConsumersMap.get(server).flush(); + } } catch (java.io.IOException e){ System.out.println("Internal issue: StreamProvider->writeToStream() caused I/O exception."); } @@ -30,5 +38,10 @@ public class StreamProvider { } public static synchronized void delStream(String server){ srvStreamMap.remove(server); + srvSysConsumersMap.remove(server); + } + + public static synchronized void setSysConsumer(String server, PrintWriter pw){ + srvSysConsumersMap.put(server, pw); } } diff --git a/src/main/java/InnaIrcBot/ProvidersConsumers/SystemConsumer.java b/src/main/java/InnaIrcBot/ProvidersConsumers/SystemConsumer.java index 9249b56..e452f9b 100644 --- a/src/main/java/InnaIrcBot/ProvidersConsumers/SystemConsumer.java +++ b/src/main/java/InnaIrcBot/ProvidersConsumers/SystemConsumer.java @@ -14,7 +14,6 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Pattern; public class SystemConsumer implements Runnable{ @@ -73,7 +72,7 @@ public class SystemConsumer implements Runnable{ if (proxyRequired) if (getProxy(dataStrings[0], dataStrings[1], dataStrings[2])) - continue; + continue; // TODO: check this. Continue is fair? if (dataStrings[0].equals("PRIVMSG") && dataStrings[2].indexOf("\u0001") < dataStrings[2].lastIndexOf("\u0001")) replyCTCP(dataStrings[1], dataStrings[2].substring(dataStrings[2].indexOf(":")+1)); @@ -84,12 +83,22 @@ public class SystemConsumer implements Runnable{ commander.receiver(dataStrings[1], dataStrings[2].replaceAll("^.+?:", "").trim()); writerWorker.logAdd("[system]", "PRIVMSG sent to", "commander"); } + else if (dataStrings[0].equals("INNA")) { + String[] splitter; + if (dataStrings.length > 2){ // Don't touch 'cuz it's important + splitter = dataStrings[2].split(" ", 2); + if (splitter.length == 2){ + handleSpecial(dataStrings[1], splitter[0], splitter[1]); + } + } + } else writerWorker.logAdd(dataStrings[0], dataStrings[1], dataStrings[2]); // TODO: Track users //System.out.println("System: "+"|"+dataStrings[0]+"|"+dataStrings[1]+"|"+dataStrings[2]+"|"); } } catch (java.io.IOException e){ - System.out.println("Internal issue: thread SystemConsumer->run() caused I/O exception."); // TODO: reconnect + System.out.println("Internal issue: thread SystemConsumer->run() caused I/O exception."); // TODO: reconnect OR AT LEAST DIE + StreamProvider.writeToStream(serverName, "QUIT :Internal issue: thread ChanConsumer->run() caused I/O exception"); } } private boolean getProxy(String eventNum, String sender, String message){ //TODO: if can't join: like channel with password @@ -138,8 +147,16 @@ public class SystemConsumer implements Runnable{ } private String simplifyNick(String nick){ return nick.replaceAll("!.*$",""); } - //todo: nandle nickserv messages + private void handleSpecial(String event, String chanel, String message){ + //System.out.println("|"+event+"|"+chanel+"|"+message+"|"); + if (channelsMap.containsKey(chanel)){ + channelsMap.get(chanel).println(event+" "+nick+" "+chanel+" "+message); // WTF >< + channelsMap.get(chanel).flush(); + //System.out.println("Formatted: |"+event+"|"+nick+"|"+chanel+" "+message+"|"); + } + } + //todo: nandle nickserv messages private void handleNumeric(String eventNum, String sender, String message){ switch (eventNum){ case "433": // TODO: try to use alternative nickname @@ -165,7 +182,6 @@ public class SystemConsumer implements Runnable{ ChanConsumer consumer = new ChanConsumer(streamBufferedReader, storageFile.getServerName(), chan, nick, usersOnChanArr, storageFile.getRejoinOnKick(), channelsMap, storageFile.getChanelConfigurationsPath()); new Thread(consumer).start(); - for (String msgStored : proxyAList.get(chan)) { channelsMap.get(chan).println(msgStored); channelsMap.get(chan).flush(); @@ -185,9 +201,7 @@ public class SystemConsumer implements Runnable{ break; case "NICK": if (sender.startsWith(nick+"!")) { - String oldNick = nick; nick = message.trim(); - writerWorker.logAdd("[system]", "catch/handled own NICK change from:", sender+" to: "+message); } break; diff --git a/src/main/java/Temporary/DriverTest.java b/src/main/java/Temporary/DriverTest.java index 29b9c82..14b484d 100644 --- a/src/main/java/Temporary/DriverTest.java +++ b/src/main/java/Temporary/DriverTest.java @@ -6,7 +6,7 @@ import InnaIrcBot.LogDriver.Worker; public class DriverTest { public static void main(String[] args){ - if (BotDriver.setFileDriver("irc.tomsk.net", "SQLiteDriver", new String[]{"/tmp/"})) + if (BotDriver.setLogDriver("irc.tomsk.net", "SQLiteDriver", new String[]{"/tmp/"})) System.out.println("Successful driver initiation"); else { System.out.println("Failed driver initiation");