innaircbot/src/main/java/InnaIrcBot/ProvidersConsumers/DataProvider.java

135 lines
5.3 KiB
Java
Raw Normal View History

2018-12-16 17:27:44 +03:00
package InnaIrcBot.ProvidersConsumers;
2020-10-20 03:37:20 +03:00
import InnaIrcBot.config.ConfigurationFile;
import InnaIrcBot.IrcChannel;
2020-10-20 18:19:20 +03:00
import InnaIrcBot.logging.LogDriver;
2018-12-16 17:27:44 +03:00
import InnaIrcBot.ReconnectControl;
import java.io.*;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
2020-10-20 03:37:20 +03:00
import java.util.*;
import java.util.concurrent.BlockingQueue;
2018-12-16 17:27:44 +03:00
public class DataProvider implements Runnable {
2020-10-20 03:37:20 +03:00
private final ConfigurationFile configurationFile;
2020-10-20 18:19:20 +03:00
private final String server;
2020-10-20 03:37:20 +03:00
private final String nickName;
2020-10-20 18:19:20 +03:00
private BufferedReader mainReader;
2018-12-16 17:27:44 +03:00
/**
* Initiate connection and prepare input/output streams for run()
* */
2020-10-20 03:37:20 +03:00
public DataProvider(ConfigurationFile configurationFile){
this.configurationFile = configurationFile;
2020-10-20 18:19:20 +03:00
this.server = configurationFile.getServerName();
2020-10-20 03:37:20 +03:00
this.nickName = configurationFile.getUserNick();
}
2018-12-16 17:27:44 +03:00
2020-10-20 03:37:20 +03:00
public void run(){
2018-12-16 17:27:44 +03:00
try {
2020-10-20 03:37:20 +03:00
connect();
} catch (Exception e){
System.out.println("Internal issue: DataProvider->run() caused exception:\n\t"+e.getMessage());
e.printStackTrace();
2020-10-20 18:19:20 +03:00
close();
2018-12-16 17:27:44 +03:00
return;
}
2020-10-20 18:19:20 +03:00
ReconnectControl.register(server);
LogDriver.setLogDriver(server);
2020-10-20 18:19:20 +03:00
2018-12-16 17:27:44 +03:00
/* Used for sending data into consumers objects*/
2020-10-20 03:37:20 +03:00
Map<String, IrcChannel> ircChannels = Collections.synchronizedMap(new HashMap<>());
2018-12-16 17:27:44 +03:00
2020-10-20 03:37:20 +03:00
IrcChannel systemConsumerChannel = new IrcChannel("");
BlockingQueue<String> systemConsumerQueue = systemConsumerChannel.getChannelQueue();
2018-12-16 17:27:44 +03:00
2020-10-20 03:37:20 +03:00
Thread SystemConsumerThread = new Thread(
new SystemConsumer(systemConsumerQueue, nickName, ircChannels, this.configurationFile));
SystemConsumerThread.start();
2019-01-12 18:31:05 +03:00
2020-10-20 18:19:20 +03:00
StreamProvider.setSysConsumer(server, systemConsumerQueue); // Register system consumer at StreamProvider
2019-01-12 18:31:05 +03:00
2020-10-20 03:37:20 +03:00
ircChannels.put(systemConsumerChannel.toString(), systemConsumerChannel); // Not sure that PrintWriter is thread-safe..
2018-12-16 17:27:44 +03:00
////////////////////////////////////// Start loop //////////////////////////////////////////////////////////////
2020-10-20 18:19:20 +03:00
StreamProvider.writeToStream(server,"NICK "+this.nickName);
StreamProvider.writeToStream(server,"USER "+ configurationFile.getUserIdent()+" 8 * :"+ configurationFile.getUserRealName()); // TODO: Add usermode 4 rusnet
2018-12-16 17:27:44 +03:00
try {
String rawMessage;
String[] rawStrings; // prefix[0] command[1] command-parameters\r\n[2]
//if there is no prefix, you should assume the message came from your client.
2020-10-20 18:19:20 +03:00
while ((rawMessage = mainReader.readLine()) != null) {
2020-10-20 03:37:20 +03:00
System.out.println(rawMessage);
2018-12-16 17:27:44 +03:00
if (rawMessage.startsWith(":")) {
rawStrings = rawMessage
.substring(1)
.split(" :?", 3); // Removing ':'
2020-10-20 03:37:20 +03:00
String chan = rawStrings[2].replaceAll("(\\s.?$)|(\\s.+?$)", "");
2018-12-16 17:27:44 +03:00
if (rawStrings[1].equals("QUIT") || rawStrings[1].equals("NICK")) { // replace regex
2020-10-20 03:37:20 +03:00
for (IrcChannel ircChannel : ircChannels.values()) {
ircChannel.getChannelQueue().add(rawStrings[1] + " " + rawStrings[0] + " " + rawStrings[2]);
2018-12-16 17:27:44 +03:00
}
}
2020-10-20 03:37:20 +03:00
else if (ircChannels.containsKey(chan)) {
IrcChannel chnl = ircChannels.get(chan);
chnl.getChannelQueue().add(rawStrings[1] + " " + rawStrings[0] + " " + rawStrings[2]);
}
else {
systemConsumerQueue.add(rawStrings[1] + " " + rawStrings[0] + " " + rawStrings[2]);
}
}
else if (rawMessage.startsWith("PING :")) {
sendPingReply(rawMessage);
}
else {
2018-12-16 17:27:44 +03:00
System.out.println("Not a valid response=" + rawMessage);
}
}
} catch (IOException e){
2020-10-20 18:19:20 +03:00
System.out.println("Socket issue: I/O exception: "+e.getMessage()); //Connection closed. TODO: MAYBE try reconnect
2018-12-16 17:27:44 +03:00
}
finally {
2020-10-20 03:37:20 +03:00
SystemConsumerThread.interrupt();
close();
2018-12-16 17:27:44 +03:00
}
}
2020-10-20 03:37:20 +03:00
private void connect() throws Exception{
final int port = configurationFile.getServerPort();
2020-10-20 18:19:20 +03:00
InetAddress inetAddress = InetAddress.getByName(server);
2020-10-20 03:37:20 +03:00
Socket socket = new Socket(); // TODO: set timeout?
for (int i = 0; i < 5; i++) {
socket.connect(new InetSocketAddress(inetAddress, port), 5000); // 5sec
if (socket.isConnected())
break;
2018-12-16 17:27:44 +03:00
}
2020-10-20 03:37:20 +03:00
if (! socket.isConnected())
throw new Exception("Unable to connect server.");
2018-12-16 17:27:44 +03:00
2020-10-20 18:19:20 +03:00
StreamProvider.setStream(server, socket);
2018-12-16 17:27:44 +03:00
2020-10-20 03:37:20 +03:00
InputStream inStream = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(inStream, StandardCharsets.UTF_8); //TODO set charset in options;
2020-10-20 18:19:20 +03:00
mainReader = new BufferedReader(isr);
2020-10-20 03:37:20 +03:00
}
2019-01-02 17:11:14 +03:00
2020-10-20 03:37:20 +03:00
private void sendPingReply(String rawData){
2020-10-20 18:19:20 +03:00
StreamProvider.writeToStream(server,"PONG :" + rawData.replace("PING :", ""));
2020-10-20 03:37:20 +03:00
}
2019-01-02 17:11:14 +03:00
2020-10-20 03:37:20 +03:00
private void close(){
2020-10-20 18:19:20 +03:00
StreamProvider.delStream(server);
ReconnectControl.notify(server);
2018-12-16 17:27:44 +03:00
}
}