From 319e82391bfb8822fd75684f17ae28b26c1e3b0c Mon Sep 17 00:00:00 2001
From: Leonard Kugis <leonard@kug.is>
Date: Mon, 25 Apr 2022 18:49:40 +0200
Subject: Initial commit

---
 src/com/encrox/twitchbot/client/Client.java        | 135 +++++++++++++++++++++
 src/com/encrox/twitchbot/client/Core.java          |  59 +++++++++
 src/com/encrox/twitchbot/client/IRCMessage.java    |  26 ++++
 src/com/encrox/twitchbot/client/MessageTypes.java  |   8 ++
 src/com/encrox/twitchbot/client/Plugin.java        |  11 ++
 src/com/encrox/twitchbot/client/PluginHandler.java |  82 +++++++++++++
 src/com/encrox/twitchbot/client/Utils.java         |  48 ++++++++
 .../encrox/twitchbot/client/messages/Login.java    |  49 ++++++++
 .../encrox/twitchbot/client/messages/Message.java  |   9 ++
 9 files changed, 427 insertions(+)
 create mode 100755 src/com/encrox/twitchbot/client/Client.java
 create mode 100755 src/com/encrox/twitchbot/client/Core.java
 create mode 100755 src/com/encrox/twitchbot/client/IRCMessage.java
 create mode 100755 src/com/encrox/twitchbot/client/MessageTypes.java
 create mode 100755 src/com/encrox/twitchbot/client/Plugin.java
 create mode 100755 src/com/encrox/twitchbot/client/PluginHandler.java
 create mode 100755 src/com/encrox/twitchbot/client/Utils.java
 create mode 100755 src/com/encrox/twitchbot/client/messages/Login.java
 create mode 100755 src/com/encrox/twitchbot/client/messages/Message.java

(limited to 'src/com/encrox/twitchbot')

diff --git a/src/com/encrox/twitchbot/client/Client.java b/src/com/encrox/twitchbot/client/Client.java
new file mode 100755
index 0000000..557517e
--- /dev/null
+++ b/src/com/encrox/twitchbot/client/Client.java
@@ -0,0 +1,135 @@
+package com.encrox.twitchbot.client;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import com.encrox.twitchbot.client.messages.Message;
+
+public class Client implements Runnable {
+	
+	private volatile Socket socket, iSocket;
+	private volatile BufferedInputStream bis = null;
+	private volatile DataOutputStream dos = null;
+	private volatile DataOutputStream iDos = null;
+	
+	public int connect() {
+		try {
+			socket = new Socket("encrox.com", 5424);
+			bis = new BufferedInputStream(socket.getInputStream());
+			dos = new DataOutputStream(socket.getOutputStream());
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+			return MessageTypes.ERROR;
+		} catch (IOException e) {
+			e.printStackTrace();
+			return MessageTypes.ERROR;
+		}
+		Runtime.getRuntime().addShutdownHook(new Thread(this));
+		return MessageTypes.OK;
+	}
+	
+	public void login() {
+		try {
+			iSocket = new Socket("encrox.com", 5425);
+			iDos = new DataOutputStream(iSocket.getOutputStream());
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public void post(String message) {
+		try {
+			iDos.writeInt(message.length());
+			iDos.write(message.getBytes("UTF-8"));
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public void write(byte[] data) {
+		try {
+			dos.write(data);
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public int send(Message message) {
+		try {
+			dos.write(message.getID());
+			dos.write(message.getData());
+			byte[] res = new byte[4];
+			bis.read(res);
+			System.out.println(Utils.ba_to_int(res));
+			return Utils.ba_to_int(res);
+		} catch (IOException e) {
+			e.printStackTrace();
+			return MessageTypes.ERROR;
+		}
+	}
+	
+	public IRCMessage getMessage() {
+		byte[] user = new byte[32];
+		byte level;
+		byte[] message;
+		byte[] buffer;
+		try {
+			bis.read(user);
+			buffer = new byte[1];
+			bis.read(buffer);
+			level = buffer[0];
+			buffer = new byte[4];
+			bis.read(buffer);
+			message = new byte [Utils.ba_to_int(buffer)];
+			bis.read(message);
+			return new IRCMessage(new String(Utils.crop(user), "UTF-8"), level, new String(message, "UTF-8"));
+		} catch (IOException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	@Override
+	public void run() {
+		try {
+			bis.close();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		try {
+			dos.close();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		try {
+			iDos.close();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		try {
+			socket.close();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		try {
+			iSocket.close();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+}
diff --git a/src/com/encrox/twitchbot/client/Core.java b/src/com/encrox/twitchbot/client/Core.java
new file mode 100755
index 0000000..a872432
--- /dev/null
+++ b/src/com/encrox/twitchbot/client/Core.java
@@ -0,0 +1,59 @@
+package com.encrox.twitchbot.client;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+
+import com.encrox.twitchbot.client.Plugin;
+import com.encrox.twitchbot.client.messages.Login;
+
+public class Core {
+	
+	public static String username, password;
+	private static BufferedReader br;
+	public static Client client;
+	
+	public static void main(String[] args) {
+		br = new BufferedReader(new InputStreamReader(System.in));
+		System.out.println("Twitchbot-client build 201510042114");
+		System.out.println("Setting up...");
+		setup();
+		System.out.println("Connecting to the server...");
+		client = new Client();
+		if(client.connect() != MessageTypes.OK) {
+			System.out.println("Failed to connect to the server!");
+			return;
+		}
+		Login login = new Login();
+		do {
+			System.out.println("Encrox username: ");
+			try {
+				login.setUsername(br.readLine());
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			System.out.println("Encrox password: ");
+			try {
+				login.setPassword(br.readLine());
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		} while(client.send(login) != MessageTypes.OK);
+		client.login();
+		new PluginHandler(client);
+	}
+	
+	public static void setup() {
+		File plugindir = new File("plugins/");
+		if(!plugindir.exists()) {
+			plugindir.mkdir();
+		}
+	}
+
+}
diff --git a/src/com/encrox/twitchbot/client/IRCMessage.java b/src/com/encrox/twitchbot/client/IRCMessage.java
new file mode 100755
index 0000000..69f8cd5
--- /dev/null
+++ b/src/com/encrox/twitchbot/client/IRCMessage.java
@@ -0,0 +1,26 @@
+package com.encrox.twitchbot.client;
+
+public class IRCMessage {
+	
+	private String username, message;
+	private byte level;
+	
+	public IRCMessage(String username, byte level, String message) {
+		this.username = username;
+		this.level = level;
+		this.message = message;
+	}
+	
+	public String getUsername() {
+		return username;
+	}
+	
+	public byte getLevel() {
+		return level;
+	}
+	
+	public String getMessage() {
+		return message;
+	}
+
+}
diff --git a/src/com/encrox/twitchbot/client/MessageTypes.java b/src/com/encrox/twitchbot/client/MessageTypes.java
new file mode 100755
index 0000000..c70fa08
--- /dev/null
+++ b/src/com/encrox/twitchbot/client/MessageTypes.java
@@ -0,0 +1,8 @@
+package com.encrox.twitchbot.client;
+
+public class MessageTypes {
+	
+	public static final int ERROR = 0;
+	public static final int OK = 1;
+
+}
diff --git a/src/com/encrox/twitchbot/client/Plugin.java b/src/com/encrox/twitchbot/client/Plugin.java
new file mode 100755
index 0000000..c70cd57
--- /dev/null
+++ b/src/com/encrox/twitchbot/client/Plugin.java
@@ -0,0 +1,11 @@
+package com.encrox.twitchbot.client;
+
+public abstract class Plugin {
+	
+	public abstract void load(String locale);
+	
+	public abstract String message(String user, byte level, String message);
+	
+	public abstract String post();
+
+}
diff --git a/src/com/encrox/twitchbot/client/PluginHandler.java b/src/com/encrox/twitchbot/client/PluginHandler.java
new file mode 100755
index 0000000..7a759fb
--- /dev/null
+++ b/src/com/encrox/twitchbot/client/PluginHandler.java
@@ -0,0 +1,82 @@
+package com.encrox.twitchbot.client;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+
+public class PluginHandler implements Runnable {
+	
+	private Client client;
+	private ArrayList<Plugin> plugins = new ArrayList<Plugin>();
+	
+	public PluginHandler(Client client) {
+		this.client = client;
+		File path = new File("plugins/");
+		URL[] urls;
+		ClassLoader cl;
+		try {
+			urls = new URL[] { path.toURI().toURL() };
+			cl = new URLClassLoader(urls);
+			File[] files = path.listFiles();
+			for (int i = 0; i < files.length; i++) {
+				String name = files[i].getName();
+				plugins.add((Plugin) cl.loadClass(name.substring(0, name.indexOf('.'))).newInstance());
+				plugins.get(i).load("en-GB");
+			}
+		} catch (MalformedURLException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (ClassNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (InstantiationException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IllegalAccessException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		new Thread(this).start();
+		String answer = null;
+		while(true) {
+			IRCMessage msg = client.getMessage();
+			if(msg != null) {
+				System.out.println("[" + msg.getUsername() + "][" + msg.getLevel() + "] " + msg.getMessage());
+				for(int i = 0, size = plugins.size(); i < size; i++) {
+					answer = plugins.get(i).message(msg.getUsername(), msg.getLevel(), msg.getMessage());
+					if(answer == null) {
+						client.write(Utils.int_to_ba(1));
+						client.write(new byte[] { (byte)0x00 });
+					} else {
+						client.write(Utils.int_to_ba(answer.length()));
+						try {
+							client.write(answer.getBytes("UTF-8"));
+						} catch (UnsupportedEncodingException e) {
+							e.printStackTrace();
+						}
+						System.out.println("Answer: " + answer);
+					}
+				}
+			} else {
+				return;
+			}
+		}
+	}
+	
+	public void run() {
+		String post;
+		while(true) {
+			for(int i = 0, size = plugins.size(); i < size; i++) {
+				post = plugins.get(i).post();
+				if(post != null) {
+					client.post(post);
+					post = null;
+				}
+			}
+		}
+	}
+
+}
diff --git a/src/com/encrox/twitchbot/client/Utils.java b/src/com/encrox/twitchbot/client/Utils.java
new file mode 100755
index 0000000..dccb4ce
--- /dev/null
+++ b/src/com/encrox/twitchbot/client/Utils.java
@@ -0,0 +1,48 @@
+package com.encrox.twitchbot.client;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+public class Utils {
+	
+	public static int ba_to_int(byte[] arr) {
+		return ByteBuffer.wrap(arr).getInt();
+	}
+	
+	public static byte[] int_to_ba(int integer) {
+		return ByteBuffer.allocate(4).putInt(integer).array();
+	}
+	
+	public static short ba_to_short(byte[] arr) {
+		return ByteBuffer.wrap(arr).getShort();
+	}
+	
+	public static byte[] short_to_ba(short s) {
+		return ByteBuffer.allocate(2).putShort(s).array();
+	}
+	
+	public static byte[] fill(byte[] arr, int length) {
+		if(length <= arr.length)
+			return arr;
+		byte[] output = new byte[length];
+		for(int i = 0; i<arr.length; i++)
+			output[i] = arr[i];
+		for(int i = arr.length; i<length; i++)
+			output[i] = (byte) 0x00;
+		return output;
+	}
+	
+	public static byte[] crop(byte[] arr) {
+		byte[] swap = new byte[arr.length];
+		for(int i = 0; i<swap.length; i++) {
+			if(arr[i] != (byte) 0x00)
+				swap[i] = arr[i];
+			else {
+				arr = Arrays.copyOfRange(swap, 0, i);
+				break;
+			}
+		}
+		return arr;
+	}
+
+}
diff --git a/src/com/encrox/twitchbot/client/messages/Login.java b/src/com/encrox/twitchbot/client/messages/Login.java
new file mode 100755
index 0000000..b439c99
--- /dev/null
+++ b/src/com/encrox/twitchbot/client/messages/Login.java
@@ -0,0 +1,49 @@
+package com.encrox.twitchbot.client.messages;
+
+import java.io.UnsupportedEncodingException;
+
+import com.encrox.twitchbot.client.Utils;
+
+public class Login extends Message {
+	
+	private byte id = 1;
+	private String username, password;
+	
+	public Login(String username, String password) {
+		this.username = username;
+		this.password = password;
+	}
+	
+	public Login() {
+		username = null;
+		password = null;
+	}
+	
+	public void setUsername(String username) {
+		this.username = username;
+	}
+	
+	public void setPassword(String password) {
+		this.password = password;
+	}
+	
+	public byte getID() {
+		return id;
+	}
+	
+	public byte[] getData() {
+		byte[] output = new byte[160];
+		try {
+			byte[] user = Utils.fill(username.getBytes("UTF-8"), 32), pass = Utils.fill(password.getBytes("UTF-8"), 128);
+			for(int i = 0; i < 32; i++)
+				output[i] = user[i];
+			for(int i = 0; i < 128; i++)
+				output[32+i] = pass[i];
+			return output;
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+}
diff --git a/src/com/encrox/twitchbot/client/messages/Message.java b/src/com/encrox/twitchbot/client/messages/Message.java
new file mode 100755
index 0000000..aac9f38
--- /dev/null
+++ b/src/com/encrox/twitchbot/client/messages/Message.java
@@ -0,0 +1,9 @@
+package com.encrox.twitchbot.client.messages;
+
+public abstract class Message {
+	
+	public abstract byte getID();
+	
+	public abstract byte[] getData();
+
+}
-- 
cgit v1.2.1