From 319e82391bfb8822fd75684f17ae28b26c1e3b0c Mon Sep 17 00:00:00 2001 From: Leonard Kugis Date: Mon, 25 Apr 2022 18:49:40 +0200 Subject: Initial commit --- .classpath | 6 + .gitignore | 171 +++++++++++++++++++++ .project | 17 ++ .project (1) | 17 ++ bin (1)/.project | 17 ++ 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 ++ 14 files changed, 655 insertions(+) create mode 100755 .classpath create mode 100644 .gitignore create mode 100755 .project create mode 100755 .project (1) create mode 100755 bin (1)/.project 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 diff --git a/.classpath b/.classpath new file mode 100755 index 0000000..91ee9a5 --- /dev/null +++ b/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9d02df8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,171 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/eclipse,java,windows,linux,macos +# Edit at https://www.toptal.com/developers/gitignore?templates=eclipse,java,windows,linux,macos + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ +.apt_generated_test/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +# Uncomment this line if you wish to ignore the project description file. +# Typically, this file would be tracked if it contains build/dependency configurations: +#.project + +### Eclipse Patch ### +# Spring Boot Tooling +.sts4-cache/ + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/eclipse,java,windows,linux,macos diff --git a/.project b/.project new file mode 100755 index 0000000..e790f52 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + Twitchbot-client + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.project (1) b/.project (1) new file mode 100755 index 0000000..e790f52 --- /dev/null +++ b/.project (1) @@ -0,0 +1,17 @@ + + + Twitchbot-client + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/bin (1)/.project b/bin (1)/.project new file mode 100755 index 0000000..e790f52 --- /dev/null +++ b/bin (1)/.project @@ -0,0 +1,17 @@ + + + Twitchbot-client + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + 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 plugins = new ArrayList(); + + 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