2018-12-16 17:27:44 +03:00
|
|
|
package InnaIrcBot.Commanders;
|
|
|
|
|
|
|
|
import InnaIrcBot.ProvidersConsumers.StreamProvider;
|
2020-10-23 13:43:53 +03:00
|
|
|
import InnaIrcBot.config.ConfigurationChannel;
|
|
|
|
import InnaIrcBot.config.ConfigurationManager;
|
2018-12-16 17:27:44 +03:00
|
|
|
|
|
|
|
import java.time.LocalTime;
|
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
2020-10-20 03:37:20 +03:00
|
|
|
import java.util.concurrent.BlockingQueue;
|
2018-12-16 17:27:44 +03:00
|
|
|
import java.util.regex.Pattern;
|
2020-10-23 13:43:53 +03:00
|
|
|
//TODO: FLOOD
|
2018-12-16 17:27:44 +03:00
|
|
|
public class ChanelCommander implements Runnable {
|
2020-10-20 03:37:20 +03:00
|
|
|
private final BlockingQueue<String> streamQueue;
|
|
|
|
private final String server;
|
|
|
|
private final String channel;
|
2018-12-16 17:27:44 +03:00
|
|
|
//TODO: add timers
|
2020-10-23 13:43:53 +03:00
|
|
|
private HashMap<String, String[]> joinMap; // Mask(Pattern) ->, Action | Where Action[0] could be: raw
|
|
|
|
private HashMap<String, String[]> msgMap; // Mask(Pattern) ->, Action | Where Action[0] could be: raw
|
|
|
|
private HashMap<String, String[]> nickMap; // Mask(Pattern) ->, Action | Where Action[0] could be: raw
|
2018-12-16 17:27:44 +03:00
|
|
|
|
2020-10-25 23:39:05 +03:00
|
|
|
private boolean joinFloodTrackNeed;
|
2018-12-16 17:27:44 +03:00
|
|
|
private JoinFloodHandler jfh;
|
|
|
|
|
2020-10-25 23:39:05 +03:00
|
|
|
private boolean joinCloneTrackNeed;
|
2019-04-18 04:46:45 +03:00
|
|
|
private JoinCloneHandler jch;
|
|
|
|
|
2020-10-23 13:43:53 +03:00
|
|
|
public ChanelCommander(BlockingQueue<String> stream, String serverName, String channel) throws Exception{
|
2020-10-20 03:37:20 +03:00
|
|
|
this.streamQueue = stream;
|
2018-12-16 17:27:44 +03:00
|
|
|
this.server = serverName;
|
2020-10-20 03:37:20 +03:00
|
|
|
this.channel = channel;
|
2020-10-23 13:43:53 +03:00
|
|
|
readConfing();
|
2018-12-16 17:27:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2020-10-20 03:37:20 +03:00
|
|
|
System.out.println("["+LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))+"] ChanelCommander thread "
|
|
|
|
+server+":"+this.channel +" started");// TODO:REMOVE DEBUG
|
2018-12-16 17:27:44 +03:00
|
|
|
try {
|
2020-10-20 03:37:20 +03:00
|
|
|
while (true) {
|
|
|
|
String data = streamQueue.take();
|
2020-10-25 23:39:05 +03:00
|
|
|
String[] dataStrings = data.split(" :?",3);
|
2020-10-20 03:37:20 +03:00
|
|
|
|
2020-10-25 23:39:05 +03:00
|
|
|
switch (dataStrings[1]) {
|
2018-12-16 17:27:44 +03:00
|
|
|
case "NICK":
|
2020-10-25 23:39:05 +03:00
|
|
|
nickCame(dataStrings[2]+dataStrings[0].replaceAll("^.+?!","!"));
|
2018-12-16 17:27:44 +03:00
|
|
|
break; // todo: need to track join flood
|
|
|
|
case "JOIN":
|
|
|
|
if (joinFloodTrackNeed)
|
2020-10-25 23:39:05 +03:00
|
|
|
jfh.track(simplifyNick(dataStrings[0]));
|
2019-04-18 04:46:45 +03:00
|
|
|
if (joinCloneTrackNeed)
|
2020-10-25 23:39:05 +03:00
|
|
|
jch.track(dataStrings[0]);
|
|
|
|
joinCame(dataStrings[0]);
|
2018-12-16 17:27:44 +03:00
|
|
|
break;
|
|
|
|
case "PRIVMSG":
|
2020-10-25 23:39:05 +03:00
|
|
|
privmsgCame(dataStrings[0], dataStrings[2]);
|
2018-12-16 17:27:44 +03:00
|
|
|
break;
|
|
|
|
/*
|
|
|
|
case "PART": // todo: need to track join flood? Fuck that. Track using JOIN
|
|
|
|
case "QUIT": // todo: need this?
|
|
|
|
case "TOPIC": // todo: need this?
|
|
|
|
case "MODE": // todo: need this?
|
2020-10-23 13:43:53 +03:00
|
|
|
case "KICK": // todo: need this? */
|
2018-12-16 17:27:44 +03:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-10-20 03:37:20 +03:00
|
|
|
}
|
|
|
|
catch (InterruptedException ie){
|
2020-10-25 23:39:05 +03:00
|
|
|
System.out.println("ChanelCommander interrupted.");
|
2018-12-16 17:27:44 +03:00
|
|
|
}
|
2020-10-25 23:39:05 +03:00
|
|
|
System.out.println("["+LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))+"] ChanelCommander thread "
|
|
|
|
+server+":"+this.channel +" ended");// TODO:REMOVE DEBUG
|
2018-12-16 17:27:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Do we need old nick?
|
|
|
|
private void nickCame(String newNick){
|
|
|
|
came(nickMap, newNick, newNick);
|
|
|
|
}
|
|
|
|
private void joinCame(String who){
|
|
|
|
came(joinMap, who, who);
|
|
|
|
}
|
|
|
|
private void privmsgCame(String who, String what){
|
2019-01-02 18:08:45 +03:00
|
|
|
if (what.indexOf(":")+1 < what.length()){
|
|
|
|
what = what.substring(what.indexOf(":")+1);
|
|
|
|
came(msgMap, what, who);
|
|
|
|
}
|
2018-12-16 17:27:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
private void came(HashMap<String, String[]> map, String arg1, String arg2){
|
|
|
|
for (String pattern : map.keySet())
|
|
|
|
if (Pattern.matches(pattern, arg1)){ // NOTE: validation based on new nick //TODO: parse here
|
|
|
|
String[] cmdOrMsg = map.get(pattern);
|
2019-01-29 01:28:11 +03:00
|
|
|
|
|
|
|
StringBuilder whatToSendStringBuilder;
|
|
|
|
ArrayList<String> whatToSendList;
|
2020-10-25 23:39:05 +03:00
|
|
|
for (int i = 0; i < cmdOrMsg.length;) {
|
2018-12-16 17:27:44 +03:00
|
|
|
switch (cmdOrMsg[i]) {
|
|
|
|
case "\\chanmsg":
|
2019-01-29 01:28:11 +03:00
|
|
|
whatToSendList = new ArrayList<>();
|
2018-12-16 17:27:44 +03:00
|
|
|
for (i++; (i < cmdOrMsg.length) && !(cmdOrMsg[i].startsWith("\\")); i++)
|
2019-01-29 01:28:11 +03:00
|
|
|
whatToSendList.add(cmdOrMsg[i]);
|
|
|
|
msgAction(whatToSendList.toArray(new String[0]), arg2, false);
|
2018-12-16 17:27:44 +03:00
|
|
|
break;
|
|
|
|
case "\\privmsg":
|
2019-01-29 01:28:11 +03:00
|
|
|
whatToSendList = new ArrayList<>();
|
2018-12-16 17:27:44 +03:00
|
|
|
for (i++; (i < cmdOrMsg.length) && !(cmdOrMsg[i].startsWith("\\")); i++)
|
2019-01-29 01:28:11 +03:00
|
|
|
whatToSendList.add(cmdOrMsg[i]);
|
|
|
|
msgAction(whatToSendList.toArray(new String[0]), arg2, true);
|
2018-12-16 17:27:44 +03:00
|
|
|
break;
|
|
|
|
case "\\ban":
|
|
|
|
banAction(arg2);
|
|
|
|
i++;
|
|
|
|
break;
|
2020-03-24 02:01:25 +03:00
|
|
|
case "\\voice":
|
|
|
|
voiceAction(arg2);
|
|
|
|
i++;
|
|
|
|
break;
|
2018-12-16 17:27:44 +03:00
|
|
|
case "\\kick":
|
2019-01-29 01:28:11 +03:00
|
|
|
whatToSendList = new ArrayList<>();
|
2018-12-16 17:27:44 +03:00
|
|
|
for (i++; (i < cmdOrMsg.length) && !(cmdOrMsg[i].startsWith("\\")); i++)
|
2019-01-29 01:28:11 +03:00
|
|
|
whatToSendList.add(cmdOrMsg[i]);
|
|
|
|
kickAction(whatToSendList.toArray(new String[0]), arg2);
|
2018-12-16 17:27:44 +03:00
|
|
|
break;
|
|
|
|
case "\\kickban":
|
2019-01-29 01:28:11 +03:00
|
|
|
whatToSendList = new ArrayList<>();
|
2018-12-16 17:27:44 +03:00
|
|
|
for (i++; (i < cmdOrMsg.length) && !(cmdOrMsg[i].startsWith("\\")); i++)
|
2019-01-29 01:28:11 +03:00
|
|
|
whatToSendList.add(cmdOrMsg[i]);
|
2018-12-16 17:27:44 +03:00
|
|
|
banAction(arg2);
|
2019-01-29 01:28:11 +03:00
|
|
|
kickAction(whatToSendList.toArray(new String[0]), arg2);
|
2018-12-16 17:27:44 +03:00
|
|
|
break;
|
|
|
|
case "\\raw":
|
2019-01-29 01:28:11 +03:00
|
|
|
whatToSendStringBuilder = new StringBuilder();
|
2018-12-16 17:27:44 +03:00
|
|
|
for (i++; (i < cmdOrMsg.length) && !(cmdOrMsg[i].startsWith("\\")); i++)
|
2019-01-29 01:28:11 +03:00
|
|
|
whatToSendStringBuilder.append(cmdOrMsg[i]);
|
|
|
|
StreamProvider.writeToStream(server, whatToSendStringBuilder.toString()); //TODO
|
2019-01-22 05:31:43 +03:00
|
|
|
break; //todo: add script
|
|
|
|
case "\\whois": // result will be noted in 'system' log
|
|
|
|
whoisAction(arg2);
|
|
|
|
i++;
|
2019-01-29 01:28:11 +03:00
|
|
|
break;
|
|
|
|
case "\\cclientinfo": // NOTE: All this handled by CTCPHelper instance
|
|
|
|
case "\\cfinger": // C - publish request result to chan
|
|
|
|
case "\\cping":
|
|
|
|
case "\\csource":
|
|
|
|
case "\\ctime":
|
|
|
|
case "\\cuserinfo":
|
|
|
|
case "\\cversion":
|
|
|
|
case "\\pclientinfo": // P - reply to privmsg
|
|
|
|
case "\\pfinger":
|
|
|
|
case "\\pping":
|
|
|
|
case "\\psource":
|
|
|
|
case "\\ptime":
|
|
|
|
case "\\puserinfo":
|
|
|
|
case "\\pversion":
|
|
|
|
String CTCPType = cmdOrMsg[i];
|
|
|
|
String objectRegexp = null;
|
|
|
|
whatToSendStringBuilder = new StringBuilder();
|
|
|
|
|
|
|
|
for (i++; (i < cmdOrMsg.length) && !(cmdOrMsg[i].startsWith("\\")); i++){
|
|
|
|
if (objectRegexp == null && !cmdOrMsg[i].trim().isEmpty())
|
|
|
|
objectRegexp = cmdOrMsg[i].trim();
|
|
|
|
else
|
|
|
|
whatToSendStringBuilder.append(cmdOrMsg[i]);
|
|
|
|
}
|
2020-10-25 23:39:05 +03:00
|
|
|
|
|
|
|
if (objectRegexp == null)
|
|
|
|
break;
|
|
|
|
|
|
|
|
String objectToCtcp = arg1.trim().replaceAll(objectRegexp, ""); // note: trim() ?
|
|
|
|
|
|
|
|
if (objectToCtcp.isEmpty())
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (CTCPType.startsWith("\\c"))
|
|
|
|
registerCTCPforChannel(CTCPType.substring(2).toUpperCase(), objectToCtcp, whatToSendStringBuilder.toString());
|
|
|
|
else
|
|
|
|
registerCTCPforUser(simplifyNick(arg2), CTCPType.substring(2).toUpperCase(), objectToCtcp, whatToSendStringBuilder.toString());
|
2019-01-29 01:28:11 +03:00
|
|
|
|
2019-01-22 05:31:43 +03:00
|
|
|
break;
|
2018-12-16 17:27:44 +03:00
|
|
|
default:
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-10-25 23:39:05 +03:00
|
|
|
|
2018-12-16 17:27:44 +03:00
|
|
|
///////// /////////
|
2020-10-25 23:39:05 +03:00
|
|
|
private void registerCTCPforChannel(String CTCPType, String object, String message){
|
|
|
|
CTCPHelper.getInstance().registerRequest(server, channel, CTCPType, object, message);
|
|
|
|
}
|
|
|
|
private void registerCTCPforUser(String user, String CTCPType, String object, String message){
|
|
|
|
CTCPHelper.getInstance().registerRequest(server, user, CTCPType, object, message);
|
|
|
|
}
|
2019-01-22 05:31:43 +03:00
|
|
|
private void whoisAction(String who){ // TODO: maybe we have to extend functionality to reuse received information.
|
|
|
|
StreamProvider.writeToStream(server, "WHOIS "+simplifyNick(who));
|
|
|
|
}
|
2019-01-29 01:28:11 +03:00
|
|
|
|
2020-10-25 23:39:05 +03:00
|
|
|
private void msgAction(String[] messages, String who, boolean isToUser){
|
2018-12-16 17:27:44 +03:00
|
|
|
StringBuilder executiveStr = new StringBuilder();
|
|
|
|
executiveStr.append("PRIVMSG ");
|
2020-10-25 23:39:05 +03:00
|
|
|
if(isToUser) {
|
2018-12-16 17:27:44 +03:00
|
|
|
executiveStr.append(simplifyNick(who));
|
|
|
|
executiveStr.append(" :");
|
|
|
|
}
|
|
|
|
else {
|
2020-10-20 03:37:20 +03:00
|
|
|
executiveStr.append(channel);
|
2018-12-16 17:27:44 +03:00
|
|
|
executiveStr.append(" :");
|
|
|
|
executiveStr.append(simplifyNick(who));
|
|
|
|
executiveStr.append(": ");
|
|
|
|
}
|
|
|
|
|
2020-10-20 03:37:20 +03:00
|
|
|
for (String message : messages) {
|
|
|
|
if (!message.startsWith("\\"))
|
|
|
|
executiveStr.append(message);
|
|
|
|
else if (message.equals("\\time")) // TODO: remove this shit
|
2018-12-16 17:27:44 +03:00
|
|
|
executiveStr.append(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
|
|
|
}
|
2019-01-02 15:25:04 +03:00
|
|
|
//System.out.println(executiveStr.toString()); //TODO: debug
|
2018-12-16 17:27:44 +03:00
|
|
|
StreamProvider.writeToStream(server, executiveStr.toString());
|
|
|
|
}
|
|
|
|
private void banAction(String whom){
|
2020-10-20 03:37:20 +03:00
|
|
|
StreamProvider.writeToStream(server, "MODE "+ channel +" +b "+simplifyNick(whom)+"*!*@*");
|
|
|
|
StreamProvider.writeToStream(server, "MODE "+ channel +" +b "+"*!*@"+whom.replaceAll("^.+@",""));
|
2018-12-16 17:27:44 +03:00
|
|
|
}
|
2020-03-24 02:01:25 +03:00
|
|
|
private void voiceAction(String whom){
|
2020-10-20 03:37:20 +03:00
|
|
|
StreamProvider.writeToStream(server, "MODE "+ channel +" +v "+simplifyNick(whom));
|
2020-03-24 02:01:25 +03:00
|
|
|
}
|
2018-12-16 17:27:44 +03:00
|
|
|
private void kickAction(String[] messages, String whom){
|
|
|
|
StringBuilder executiveStr = new StringBuilder();
|
|
|
|
executiveStr.append("KICK ");
|
2020-10-20 03:37:20 +03:00
|
|
|
executiveStr.append(channel);
|
2018-12-16 17:27:44 +03:00
|
|
|
executiveStr.append(" ");
|
|
|
|
executiveStr.append(simplifyNick(whom));
|
|
|
|
executiveStr.append(" :");
|
|
|
|
|
2020-10-20 03:37:20 +03:00
|
|
|
for (String message : messages) {
|
|
|
|
if (!message.startsWith("\\"))
|
|
|
|
executiveStr.append(message);
|
|
|
|
else if (message.equals("\\time"))
|
2018-12-16 17:27:44 +03:00
|
|
|
executiveStr.append(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
|
|
|
}
|
|
|
|
StreamProvider.writeToStream(server, executiveStr.toString());
|
|
|
|
}
|
|
|
|
|
2020-10-23 13:43:53 +03:00
|
|
|
private String simplifyNick(String nick){ return nick.replaceAll("!.*$",""); }
|
2020-10-20 03:37:20 +03:00
|
|
|
|
2020-10-23 13:43:53 +03:00
|
|
|
private void readConfing() throws Exception{
|
|
|
|
ConfigurationChannel configChannel = ConfigurationManager.getConfiguration(server).getChannelConfig(channel);
|
2020-10-25 23:39:05 +03:00
|
|
|
if (configChannel == null){
|
|
|
|
joinMap = new HashMap<>();
|
|
|
|
msgMap = new HashMap<>();
|
|
|
|
nickMap = new HashMap<>();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-10-23 13:43:53 +03:00
|
|
|
joinMap = configChannel.getJoinMap();
|
|
|
|
msgMap = configChannel.getMsgMap();
|
|
|
|
nickMap = configChannel.getNickMap();
|
2020-10-20 03:37:20 +03:00
|
|
|
|
2020-10-23 13:43:53 +03:00
|
|
|
if (configChannel.isJoinFloodControl()) {
|
|
|
|
jfh = new JoinFloodHandler(configChannel.getJoinFloodControlEvents(), configChannel.getJoinFloodControlTimeframe(), server, channel);
|
|
|
|
joinFloodTrackNeed = true;
|
2020-10-20 03:37:20 +03:00
|
|
|
}
|
2020-10-23 13:43:53 +03:00
|
|
|
if (configChannel.isJoinCloneControl()) {
|
|
|
|
jch = new JoinCloneHandler(configChannel.getJoinCloneControlPattern(), configChannel.getJoinCloneControlTimeframe(), server, channel); // TODO: REMOVE
|
|
|
|
joinCloneTrackNeed = true;
|
2018-12-16 17:27:44 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|