From 15a130505e77c7bcf2738643efdf8f548b4b3106 Mon Sep 17 00:00:00 2001 From: games647 Date: Mon, 1 Aug 2016 12:52:49 +0200 Subject: [PATCH] Make use of plugin channels instead of sockets connections --- .../com/fuzzoland/CommandSyncClient/CSC.java | 182 +++++----- .../CommandSyncClient/ClientThread.java | 119 ------- .../CommandSyncClient/CommandSynchronize.java | 158 +++++---- .../CommandSyncClient/MessageListener.java | 33 ++ .../CommandSyncClient/QueueMessageTask.java | 26 ++ .../com/fuzzoland/CommandSyncServer/CSS.java | 319 +++++++++--------- .../CommandSyncServer/ClientHandler.java | 171 +++------- .../CommandSyncServer/ClientListener.java | 26 -- .../CommandSyncServer/CommandThread.java | 63 ++-- .../CommandSyncServer/EventListener.java | 97 +++++- 10 files changed, 566 insertions(+), 628 deletions(-) delete mode 100644 CommandSyncClient/src/com/fuzzoland/CommandSyncClient/ClientThread.java create mode 100644 CommandSyncClient/src/com/fuzzoland/CommandSyncClient/MessageListener.java create mode 100644 CommandSyncClient/src/com/fuzzoland/CommandSyncClient/QueueMessageTask.java delete mode 100644 CommandSyncServer/src/com/fuzzoland/CommandSyncServer/ClientListener.java diff --git a/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/CSC.java b/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/CSC.java index a6d2604..dacb2d6 100644 --- a/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/CSC.java +++ b/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/CSC.java @@ -1,5 +1,6 @@ package com.fuzzoland.CommandSyncClient; +import com.google.common.collect.Lists; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; @@ -7,121 +8,138 @@ import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Collections; +import java.util.Arrays; +import java.util.LinkedList; import java.util.List; +import java.util.Queue; import org.bukkit.plugin.java.JavaPlugin; public class CSC extends JavaPlugin { - public ClientThread client; - public List oq = Collections.synchronizedList(new ArrayList()); - public Integer qc = 0; - public String spacer = "@#@"; - public Debugger debugger; - - public void onEnable() { - String[] data = loadConfig(); - if(data[3].equals("UNSET") || data[4].equals("UNSET")) { - debugger.debug("THE CONFIG FILE CONTAINS UNSET VALUES - YOU MUST FIX THEM BEFORE THE PLUGIN WILL WORK !!! "); - return; - } - try { - client = new ClientThread(this, InetAddress.getByName(data[0]), Integer.parseInt(data[1]), Integer.parseInt(data[2]), data[3], data[4]); - client.start(); - } catch(Exception e) { - e.printStackTrace(); - } - loadData(); - getCommand("Sync").setExecutor(new CommandSynchronize(this)); - } - - public void onDisable() { - saveData(); + private final Queue messageQueue = new LinkedList<>(); + + private String name; + private String password; + + public Debugger debugger; + + public void onEnable() { + String[] data = loadConfig(); + if (data[3].equals("UNSET") || data[4].equals("UNSET")) { + debugger.debug("THE CONFIG FILE CONTAINS UNSET VALUES - YOU MUST FIX THEM BEFORE THE PLUGIN WILL WORK !!! "); + return; + } + + loadData(); + + name = data[3]; + password = data[4]; + + getCommand("Sync").setExecutor(new CommandSynchronize(this)); + + //check for incoming messages from the bungeecord version of this plugin + getServer().getMessenger().registerIncomingPluginChannel(this, getName(), new MessageListener(this)); + getServer().getMessenger().registerOutgoingPluginChannel(this, getName()); + + getServer().getScheduler().runTaskTimer(this, new QueueMessageTask(this), 20L, 20L); + } + + public void onDisable() { + saveData(); debugger.close(); - } + } - private String[] loadConfig() { - String[] defaults = new String[] { - "ip=localhost", "port=9190", "heartbeat=1000", "name=UNSET", "pass=UNSET", "debug=false" - }; - String[] data = new String[defaults.length]; + private String[] loadConfig() { + String[] defaults = new String[]{ + "ip=localhost", "port=9190", "heartbeat=1000", "name=UNSET", "pass=UNSET", "debug=false" + }; + + String[] data = new String[defaults.length]; try { File folder = getDataFolder(); - if(!folder.exists()) { + if (!folder.exists()) { folder.mkdir(); } + File file = new File(folder, "config.txt"); - if(!file.exists()) { + if (!file.exists()) { file.createNewFile(); } + BufferedReader br = new BufferedReader(new FileReader(file)); - for(int i = 0; i < defaults.length; i++) { + for (int i = 0; i < defaults.length; i++) { String l = br.readLine(); - if(l == null || l.isEmpty()) { + if (l == null || l.isEmpty()) { data[i] = defaults[i].split("=")[1]; } else { data[i] = l.split("=")[1]; defaults[i] = l; } } + br.close(); file.delete(); file.createNewFile(); PrintStream ps = new PrintStream(new FileOutputStream(file)); - for(int i = 0; i < defaults.length; i++) { + for (int i = 0; i < defaults.length; i++) { ps.println(defaults[i]); } + ps.close(); debugger = new Debugger(this, Boolean.valueOf(data[5])); debugger.debug("Configuration file loaded."); - } catch(IOException e) { + } catch (IOException e) { e.printStackTrace(); } return data; - } - - private void saveData() { - try{ - OutputStream os = new FileOutputStream(new File(getDataFolder(), "data.txt")); - PrintStream ps = new PrintStream(os); - for(String s : oq) { - ps.println("oq:" + s); - } - ps.println("qc:" + String.valueOf(qc)); - ps.close(); - debugger.debug("All data saved."); - }catch(IOException e){ - e.printStackTrace(); - } - } - - private void loadData() { - try{ - File file = new File(getDataFolder(), "data.txt"); - if(file.exists()) { - BufferedReader br = new BufferedReader(new FileReader(file)); - try { - String l = br.readLine(); - while(l != null) { - if(l.startsWith("oq:")) { - oq.add(new String(l.substring(3))); - } else if(l.startsWith("qc:")) { - qc = Integer.parseInt(new String(l.substring(3))); - } - l = br.readLine(); - } - debugger.debug("All data loaded."); - } finally { - br.close(); - } - } else { - debugger.debug("A data file was not found. If this is your first start-up with the plugin, this is normal."); - } - } catch(IOException e) { - e.printStackTrace(); - } - } + } + + private void saveData() { + try { + OutputStream os = new FileOutputStream(new File(getDataFolder(), "data.txt")); + PrintStream ps = new PrintStream(os); + for (byte[] s : messageQueue) { + ps.println(Arrays.toString(s)); + } + + ps.close(); + debugger.debug("All data saved."); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void loadData() { + try { + File file = new File(getDataFolder(), "data.txt"); + if (file.exists()) { + BufferedReader br = new BufferedReader(new FileReader(file)); + try { + String line = br.readLine(); + while (line != null) { + String trimmed = line.replace("[", "").replace("]", "").replace(",", ""); + List data = Lists.newArrayListWithExpectedSize(100); + String[] components = trimmed.split(" "); + for (String component : components) { + data.add(Byte.parseByte(component)); + } + + line = br.readLine(); + } + debugger.debug("All data loaded."); + } finally { + br.close(); + } + } else { + debugger.debug("A data file was not found. If this is your first start-up with the plugin, this is normal."); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public Queue getMessageQueue() { + return messageQueue; + } } diff --git a/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/ClientThread.java b/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/ClientThread.java deleted file mode 100644 index aeedffd..0000000 --- a/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/ClientThread.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.fuzzoland.CommandSyncClient; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.InetAddress; -import java.net.Socket; - -import org.bukkit.Bukkit; - -public class ClientThread extends Thread { - - private CSC plugin; - private InetAddress ip; - private Integer port; - private Boolean connected = false; - private Socket socket; - private PrintWriter out; - private BufferedReader in; - private Integer heartbeat = 0; - private String name; - private String pass; - private String version = "2.3"; - - public ClientThread(CSC plugin, InetAddress ip, Integer port, Integer heartbeat, String name, String pass) { - this.plugin = plugin; - this.ip = ip; - this.port = port; - this.heartbeat = heartbeat; - this.name = name; - this.pass = pass; - connect(false); - } - - public void run() { - while(true) { - if(connected) { - out.println("heartbeat"); - if(out.checkError()) { - connected = false; - plugin.debugger.debug("Lost connection to the server."); - } else { - try { - Integer size = plugin.oq.size(); - Integer count = plugin.qc; - if(size > count) { - for(int i = count; i < size; i++) { - count++; - String output = plugin.oq.get(i); - out.println(output); - plugin.debugger.debug("[" + socket.getInetAddress().getHostName() + ":" + socket.getPort() + "] " + "Sent output - " + output); - } - plugin.qc = count; - } - while(in.ready()) { - String input = in.readLine(); - if(!input.equals("heartbeat")) { - plugin.debugger.debug("[" + socket.getInetAddress().getHostName() + ":" + socket.getPort() + "] " + "Received input - " + input); - String[] data = input.split(plugin.spacer); - if(data[0].equals("console")) { - String command = data[2].replaceAll("\\+", " "); - Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), command); - plugin.debugger.debug("Ran command /" + command + "."); - } - } - } - } catch(IOException e) { - e.printStackTrace(); - } - } - } else { - connect(true); - } - try { - sleep(heartbeat); - } catch(InterruptedException e) { - e.printStackTrace(); - } - } - } - - private void connect(Boolean sleep) { - if(sleep) { - try { - sleep(10000); - } catch(InterruptedException e) { - e.printStackTrace(); - } - } - try { - socket = new Socket(ip, port); - out = new PrintWriter(socket.getOutputStream(), true); - in = new BufferedReader(new InputStreamReader(socket.getInputStream())); - out.println(name); - if(in.readLine().equals("n")) { - plugin.debugger.debug("The name " + name + " is already connected."); - socket.close(); - return; - } - out.println(pass); - if(in.readLine().equals("n")) { - plugin.debugger.debug("The password you provided is invalid."); - socket.close(); - return; - } - out.println(version); - if(in.readLine().equals("n")) { - plugin.debugger.debug("The client's version of " + version + " does not match the server's version of " + in.readLine() + "."); - socket.close(); - return; - } - connected = true; - plugin.debugger.debug("Connected to " + ip.getHostName() + ":" + String.valueOf(port) + " under name " + name + "."); - } catch(IOException e) { - plugin.debugger.debug("Could not connect to the server."); - } - } -} diff --git a/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/CommandSynchronize.java b/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/CommandSynchronize.java index 54de6bf..341dc1e 100644 --- a/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/CommandSynchronize.java +++ b/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/CommandSynchronize.java @@ -1,81 +1,99 @@ package com.fuzzoland.CommandSyncClient; +import com.google.common.collect.Iterables; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; + import org.apache.commons.lang.WordUtils; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; public class CommandSynchronize implements CommandExecutor { - private CSC plugin; - - public CommandSynchronize(CSC plugin) { - this.plugin = plugin; - } - - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { - if(sender.hasPermission("sync.use")) { - if(args.length >= 0) { - if(args.length <= 2) { - sender.sendMessage(ChatColor.BLUE + "CommandSync by YoFuzzy3"); - if(args.length >= 1) { - if(args[0].equalsIgnoreCase("console")){ - sender.sendMessage(ChatColor.GREEN + "/sync console "); - sender.sendMessage(ChatColor.GREEN + "/sync console all "); - sender.sendMessage(ChatColor.GREEN + "/sync console bungee "); - } else if(args[0].equalsIgnoreCase("player")) { - sender.sendMessage(ChatColor.GREEN + "/sync player "); - sender.sendMessage(ChatColor.GREEN + "/sync player all "); - } else { - sender.sendMessage(ChatColor.RED + "Type /sync for help."); - } - } else { - sender.sendMessage(ChatColor.GREEN + "/sync console"); - sender.sendMessage(ChatColor.GREEN + "/sync player"); - sender.sendMessage(ChatColor.BLUE + "Type the command for more info."); - } - sender.sendMessage(ChatColor.BLUE + "Visit www.spigotmc.org/resources/commandsync.115 for help."); - } else if(args.length >= 3) { - if(args[0].equalsIgnoreCase("console") || args[0].equalsIgnoreCase("player")) { - String[] newArgs = new String[3]; - newArgs[0] = args[0]; - newArgs[1] = args[1]; - StringBuilder sb = new StringBuilder(); - for(int i = 2; i < args.length; i++) { - sb.append(args[i]); - if(i < args.length - 1) { - sb.append("+"); - } - } - newArgs[2] = sb.toString(); - if(args[1].equalsIgnoreCase("all") || args[1].equalsIgnoreCase("bungee")) { - makeData(newArgs, false, sender); - } else { - makeData(newArgs, true, sender); - } - } else { - sender.sendMessage(ChatColor.RED + "Type /sync for help!"); - } - } - } - } else { - sender.sendMessage(ChatColor.RED + "You do not have permission to use that command."); - } - return true; - } - - private void makeData(String[] args, Boolean single, CommandSender sender) { - String data; - String message = ChatColor.GREEN + "Syncing command /" + args[2].replaceAll("\\+", " ") + " to " + args[0]; - if(single) { - data = args[0].toLowerCase() + plugin.spacer + "single" + plugin.spacer + args[2] + plugin.spacer + args[1]; - message = message + " [" + args[1] + "]..."; - } else { - data = args[0].toLowerCase() + plugin.spacer + args[1].toLowerCase() + plugin.spacer + args[2]; - message = message + " [" + WordUtils.capitalizeFully(args[1]) + "]..."; - } - plugin.oq.add(data); - sender.sendMessage(message); - } + private CSC plugin; + + public CommandSynchronize(CSC plugin) { + this.plugin = plugin; + } + + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (sender.hasPermission("sync.use")) { + if (args.length >= 0) { + if (args.length <= 2) { + sender.sendMessage(ChatColor.BLUE + "CommandSync by YoFuzzy3"); + if (args.length >= 1) { + if (args[0].equalsIgnoreCase("console")) { + sender.sendMessage(ChatColor.GREEN + "/sync console "); + sender.sendMessage(ChatColor.GREEN + "/sync console all "); + sender.sendMessage(ChatColor.GREEN + "/sync console bungee "); + } else if (args[0].equalsIgnoreCase("player")) { + sender.sendMessage(ChatColor.GREEN + "/sync player "); + sender.sendMessage(ChatColor.GREEN + "/sync player all "); + } else { + sender.sendMessage(ChatColor.RED + "Type /sync for help."); + } + } else { + sender.sendMessage(ChatColor.GREEN + "/sync console"); + sender.sendMessage(ChatColor.GREEN + "/sync player"); + sender.sendMessage(ChatColor.BLUE + "Type the command for more info."); + } + sender.sendMessage(ChatColor.BLUE + "Visit www.spigotmc.org/resources/commandsync.115 for help."); + } else if (args.length >= 3) { + if (args[0].equalsIgnoreCase("console") || args[0].equalsIgnoreCase("player")) { + String[] newArgs = new String[3]; + newArgs[0] = args[0]; + newArgs[1] = args[1]; + StringBuilder sb = new StringBuilder(); + for (int i = 2; i < args.length; i++) { + sb.append(args[i]); + if (i < args.length - 1) { + sb.append("+"); + } + } + newArgs[2] = sb.toString(); + if (args[1].equalsIgnoreCase("all") || args[1].equalsIgnoreCase("bungee")) { + makeData(newArgs, sender); +// makeData(newArgs, false, sender); + } else { +// makeData(newArgs, true, sender); + makeData(newArgs, sender); + } + } else { + sender.sendMessage(ChatColor.RED + "Type /sync for help!"); + } + } + } + } else { + sender.sendMessage(ChatColor.RED + "You do not have permission to use that command."); + } + return true; + } + + private void makeData(String[] args, CommandSender sender) { + String message = ChatColor.GREEN + "Syncing command /" + args[2].replaceAll("\\+", " ") + " to " + args[0]; + message = message + " [" + WordUtils.capitalizeFully(args[1]) + "]..."; + + sender.sendMessage(message); + + ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput(); + //target invoker + dataOutput.writeUTF(args[0].toLowerCase()); + dataOutput.writeUTF(args[1]); + dataOutput.writeUTF(args[2]); + + if (sender instanceof Player) { + ((Player) sender).sendPluginMessage(plugin, plugin.getName(), dataOutput.toByteArray()); + } else { + Player messageSender = Iterables.getFirst(Bukkit.getOnlinePlayers(), null); + if (messageSender == null) { + plugin.getMessageQueue().add(dataOutput.toByteArray()); + } else { + messageSender.sendPluginMessage(plugin, plugin.getName(), dataOutput.toByteArray()); + } + } + } } diff --git a/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/MessageListener.java b/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/MessageListener.java new file mode 100644 index 0000000..161c1f7 --- /dev/null +++ b/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/MessageListener.java @@ -0,0 +1,33 @@ +package com.fuzzoland.CommandSyncClient; + +import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteStreams; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.messaging.PluginMessageListener; + +public class MessageListener implements PluginMessageListener { + + private final CSC plugin; + + public MessageListener(CSC plugin) { + this.plugin = plugin; + } + + @Override + public void onPluginMessageReceived(String channel, Player player, byte[] bytes) { + if (!channel.equals(plugin.getName())) { + return; + } + + ByteArrayDataInput dataInput = ByteStreams.newDataInput(bytes); + String invoker = dataInput.readUTF(); + if (invoker.equals("console")) { +// String command = data[2]; + String command = dataInput.readUTF().replaceAll("\\+", " "); + + Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), command); + plugin.debugger.debug("Ran command /" + command + "."); + } + } +} diff --git a/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/QueueMessageTask.java b/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/QueueMessageTask.java new file mode 100644 index 0000000..f41e448 --- /dev/null +++ b/CommandSyncClient/src/com/fuzzoland/CommandSyncClient/QueueMessageTask.java @@ -0,0 +1,26 @@ +package com.fuzzoland.CommandSyncClient; + +import com.google.common.collect.Iterables; +import java.util.Queue; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class QueueMessageTask implements Runnable { + + private final CSC plugin; + + public QueueMessageTask(CSC plugin) { + this.plugin = plugin; + } + + @Override + public void run() { + Player messageSender = Iterables.getFirst(Bukkit.getOnlinePlayers(), null); + if (messageSender != null) { + Queue messageQueue = plugin.getMessageQueue(); + for (byte[] bytes : messageQueue) { + messageSender.sendPluginMessage(plugin, plugin.getName(), bytes); + } + } + } +} diff --git a/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/CSS.java b/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/CSS.java index 9f1ae36..519e6da 100644 --- a/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/CSS.java +++ b/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/CSS.java @@ -7,7 +7,6 @@ import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; -import java.net.InetAddress; import java.net.ServerSocket; import java.util.ArrayList; import java.util.Arrays; @@ -25,158 +24,168 @@ public class CSS extends Plugin { - public ServerSocket server; - public Set c = Collections.synchronizedSet(new HashSet()); - public List oq = Collections.synchronizedList(new ArrayList()); - public Map> pq = Collections.synchronizedMap(new HashMap>()); - public Map qc = Collections.synchronizedMap(new HashMap()); - public String spacer = "@#@"; - public Debugger debugger; - - public void onEnable() { - String[] data = loadConfig(); - if(data[3].equals("UNSET")) { - debugger.debug("!!! THE CONFIG FILE CONTAINS UNSET VALUES - YOU MUST FIX THEM BEFORE THE PLUGIN WILL WORK !!! "); - return; - } - try { - server = new ServerSocket(Integer.parseInt(data[1]), 50, InetAddress.getByName(data[0])); - debugger.debug("Opened server on " + data[0] + ":" + data[1] + "."); - new ClientListener(this, Integer.parseInt(data[2]), data[3]).start(); - } catch(Exception e) { - e.printStackTrace(); - } - loadData(); - try { - Metrics metrics = new Metrics(this); - Graph graph1 = metrics.createGraph("Total queries sent"); - graph1.addPlotter(new Metrics.Plotter() { - public int getValue() { - return oq.size(); - } - public String getColumnName() { - return "Total queries sent"; - } - }); - Graph graph2 = metrics.createGraph("Total servers linked"); - graph2.addPlotter(new Metrics.Plotter() { - public int getValue() { - return qc.keySet().size(); - } - public String getColumnName() { - return "Total servers linked"; - } - }); - metrics.start(); - getProxy().getPluginManager().registerListener(this, new EventListener(this)); - } catch(IOException e) { - e.printStackTrace(); - } - } - - public void onDisable() { - saveData(); - debugger.close(); - } - - private String[] loadConfig() { - String[] defaults = new String[] { - "ip=localhost", "port=9190", "heartbeat=1000", "pass=UNSET", "debug=false" - }; - String[] data = new String[defaults.length]; - try { - File folder = getDataFolder(); - if(!folder.exists()) { - folder.mkdir(); - } - File file = new File(folder, "config.txt"); - if(!file.exists()) { - file.createNewFile(); - } - BufferedReader br = new BufferedReader(new FileReader(file)); - for(int i = 0; i < defaults.length; i++) { - String l = br.readLine(); - if(l == null || l.isEmpty()) { - data[i] = defaults[i].split("=")[1]; - } else { - data[i] = l.split("=")[1]; - defaults[i] = l; - } - } - br.close(); - file.delete(); - file.createNewFile(); - PrintStream ps = new PrintStream(new FileOutputStream(file)); - for(int i = 0; i < defaults.length; i++) { - ps.println(defaults[i]); - } - ps.close(); - debugger = new Debugger(this, Boolean.valueOf(data[4])); - debugger.debug("Configuration file loaded."); - } catch(IOException e) { - e.printStackTrace(); - } - return data; - } - - private void saveData() { - try { - OutputStream os = new FileOutputStream(new File(getDataFolder(), "data.txt")); - PrintStream ps = new PrintStream(os); - for(String s : oq) { - ps.println("oq:" + s); - } - for(Entry> e : pq.entrySet()) { - String name = e.getKey(); - for(String command : e.getValue()) { - ps.println("pq:" + name + spacer + command); - } - } - for(Entry e : qc.entrySet()) { - ps.println("qc:" + e.getKey() + spacer + String.valueOf(e.getValue())); - } - ps.close(); - debugger.debug("All data saved."); - }catch(IOException e){ - e.printStackTrace(); - } - } - - private void loadData() { - try { - File file = new File(getDataFolder(), "data.txt"); - if(file.exists()) { - BufferedReader br = new BufferedReader(new FileReader(file)); - try { - String l = br.readLine(); - while(l != null) { - if(l.startsWith("oq:")) { - oq.add(new String(l.substring(3))); - } else if(l.startsWith("pq:")) { - String[] parts = new String(l.substring(3)).split(spacer); - if(pq.containsKey(parts[0])) { - List commands = pq.get(parts[0]); - commands.add(parts[1]); - pq.put(parts[0], commands); - } else { - List commands = new ArrayList(Arrays.asList(parts[1])); - pq.put(parts[0], commands); - } - } else if(l.startsWith("qc:")) { - String[] parts = new String(l.substring(3)).split(spacer); - qc.put(parts[0], Integer.parseInt(parts[1])); - } - l = br.readLine(); - } - debugger.debug("All data loaded."); - } finally { - br.close(); - } - } else { - debugger.debug("A data file was not found. If this is your first start-up with the plugin, this is normal."); - } - } catch(IOException e) { - e.printStackTrace(); - } - } + public ServerSocket server; + public Set c = Collections.synchronizedSet(new HashSet()); + public List serverQueue = Collections.synchronizedList(new ArrayList()); + public Map> playerQueue = Collections.synchronizedMap(new HashMap>()); + public Map servers = Collections.synchronizedMap(new HashMap()); + public Debugger debugger; + + public void onEnable() { + //this is required to listen to messages from the server + getProxy().registerChannel(getDescription().getName()); + + String[] data = loadConfig(); + if (data[3].equals("UNSET")) { + debugger.debug("!!! THE CONFIG FILE CONTAINS UNSET VALUES - YOU MUST FIX THEM BEFORE THE PLUGIN WILL WORK !!! "); + return; + } + + loadData(); + getProxy().getPluginManager().registerListener(this, new EventListener(this)); + + try { + Metrics metrics = new Metrics(this); + Graph graph1 = metrics.createGraph("Total queries sent"); + graph1.addPlotter(new Metrics.Plotter() { + public int getValue() { + return serverQueue.size(); + } + + public String getColumnName() { + return "Total queries sent"; + } + }); + Graph graph2 = metrics.createGraph("Total servers linked"); + graph2.addPlotter(new Metrics.Plotter() { + public int getValue() { + return servers.keySet().size(); + } + + public String getColumnName() { + return "Total servers linked"; + } + }); + + metrics.start(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void onDisable() { + saveData(); + debugger.close(); + } + + private String[] loadConfig() { + String[] defaults = new String[]{ + "ip=localhost", "port=9190", "heartbeat=1000", "pass=UNSET", "debug=false" + }; + + String[] data = new String[defaults.length]; + try { + File folder = getDataFolder(); + if (!folder.exists()) { + folder.mkdir(); + } + + File file = new File(folder, "config.txt"); + if (!file.exists()) { + file.createNewFile(); + } + + BufferedReader br = new BufferedReader(new FileReader(file)); + for (int i = 0; i < defaults.length; i++) { + String l = br.readLine(); + if (l == null || l.isEmpty()) { + data[i] = defaults[i].split("=")[1]; + } else { + data[i] = l.split("=")[1]; + defaults[i] = l; + } + } + + br.close(); + file.delete(); + file.createNewFile(); + PrintStream ps = new PrintStream(new FileOutputStream(file)); + for (int i = 0; i < defaults.length; i++) { + ps.println(defaults[i]); + } + + ps.close(); + debugger = new Debugger(this, Boolean.valueOf(data[4])); + debugger.debug("Configuration file loaded."); + } catch (IOException e) { + e.printStackTrace(); + } + return data; + } + + private void saveData() { + try { + OutputStream os = new FileOutputStream(new File(getDataFolder(), "data.txt")); + PrintStream ps = new PrintStream(os); + for (String s : serverQueue) { + ps.println("oq:" + s); + } + + for (Entry> e : playerQueue.entrySet()) { + String name = e.getKey(); + for (String command : e.getValue()) { + ps.println("pq:" + name + spacer + command); + } + } + + for (Entry e : servers.entrySet()) { + ps.println("qc:" + e.getKey() + spacer + String.valueOf(e.getValue())); + } + + ps.close(); + debugger.debug("All data saved."); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void loadData() { + try { + File file = new File(getDataFolder(), "data.txt"); + if (file.exists()) { + BufferedReader br = new BufferedReader(new FileReader(file)); + try { + String l = br.readLine(); + while (l != null) { + if (l.startsWith("oq:")) { + serverQueue.add(new String(l.substring(3))); + } else if (l.startsWith("pq:")) { + String[] parts = new String(l.substring(3)).split(spacer); + if (playerQueue.containsKey(parts[0])) { + List commands = playerQueue.get(parts[0]); + commands.add(parts[1]); + playerQueue.put(parts[0], commands); + } else { + List commands = new ArrayList(Arrays.asList(parts[1])); + playerQueue.put(parts[0], commands); + } + } else if (l.startsWith("qc:")) { + String[] parts = new String(l.substring(3)).split(spacer); + servers.put(parts[0], Integer.parseInt(parts[1])); + } + + l = br.readLine(); + } + + debugger.debug("All data loaded."); + } finally { + br.close(); + } + } else { + debugger.debug("A data file was not found. If this is your first start-up with the plugin, this is normal."); + } + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/ClientHandler.java b/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/ClientHandler.java index 82c759a..04672e2 100644 --- a/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/ClientHandler.java +++ b/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/ClientHandler.java @@ -1,144 +1,51 @@ package com.fuzzoland.CommandSyncServer; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import net.md_5.bungee.api.connection.ProxiedPlayer; public class ClientHandler extends Thread { - private CSS plugin; - private Socket socket; + private CSS plugin; + private Socket socket; private PrintWriter out; - private BufferedReader in; private Integer heartbeat = 0; - private String name; - private String pass; - private String version = "2.3"; - - public ClientHandler(CSS plugin, Socket socket, Integer heartbeat, String pass) throws IOException { - this.plugin = plugin; - this.socket = socket; - this.heartbeat = heartbeat; - this.pass = pass; - out = new PrintWriter(socket.getOutputStream(), true); - in = new BufferedReader(new InputStreamReader(socket.getInputStream())); - plugin.debugger.debug("Received new connection from " + socket.getInetAddress().getHostName() + ":" + socket.getPort() + "."); - name = in.readLine(); - if(plugin.c.contains(name)) { - plugin.debugger.debug("[" + socket.getInetAddress().getHostName() + ":" + socket.getPort() + "] [" + name + "] Provided a name that is already connected."); - out.println("n"); - socket.close(); - return; - } - out.println("y"); - if(!in.readLine().equals(this.pass)) { - plugin.debugger.debug("[" + socket.getInetAddress().getHostName() + ":" + socket.getPort() + "] [" + name + "] Provided an invalid password."); - out.println("n"); - socket.close(); - return; - } - out.println("y"); - String version = in.readLine(); - if(!version.equals(this.version)) { - plugin.debugger.debug("[" + socket.getInetAddress().getHostName() + ":" + socket.getPort() + "] [" + name + "] Client's version of " + version + " does not match the server's version of " + this.version + "."); - out.println("n"); - out.println(this.version); - socket.close(); - return; - } - out.println("y"); - if(!plugin.qc.containsKey(name)) { - plugin.qc.put(name, 0); - } - plugin.c.add(name); - plugin.debugger.debug("Connection from " + socket.getInetAddress().getHostName() + ":" + socket.getPort() + " under name " + name + " has been authorised."); - } - public void run() { - while(true) { - try { - out.println("heartbeat"); - if(out.checkError()) { - plugin.debugger.debug("Connection from " + socket.getInetAddress().getHostName() + ":" + socket.getPort() + " under name " + name + " has disconnected."); - plugin.c.remove(name); - return; - } - while(in.ready()) { - String input = in.readLine(); - if(!input.equals("heartbeat")) { - plugin.debugger.debug("[" + socket.getInetAddress().getHostName() + ":" + socket.getPort() + "] [" + name + "] Received input - " + input); - String[] data = input.split(plugin.spacer); - if(data[0].equals("player")) { - String command = "/" + data[2].replaceAll("\\+", " "); - if(data[1].equals("single")) { - String name = data[3]; - Boolean found = false; - for(ProxiedPlayer player : plugin.getProxy().getPlayers()) { - if(name.equals(player.getName())){ - player.chat(command); - plugin.debugger.debug("Ran command " + command + " for player " + name + "."); - found = true; - break; - } - } - if(!found) { - if(plugin.pq.containsKey(name)) { - List commands = plugin.pq.get(name); - commands.add(command); - plugin.pq.put(name, commands); - } else { - plugin.pq.put(name, new ArrayList(Arrays.asList(command))); - } - plugin.debugger.debug(" Since " + name + " is offline the command " + command + " will run when they come online."); - } - } else if(data[1].equals("all")) { - for(ProxiedPlayer player : plugin.getProxy().getPlayers()) { - player.chat(command); - } - plugin.debugger.debug("Ran command " + command + " for all online players."); - } - } else { - if(data[1].equals("bungee")) { - String command = data[2].replaceAll("\\+", " "); - plugin.getProxy().getPluginManager().dispatchCommand(plugin.getProxy().getConsole(), command); - plugin.debugger.debug("Ran command /" + command + "."); - } else { - plugin.oq.add(input); - } - } - } - } - Integer size = plugin.oq.size(); - Integer count = plugin.qc.get(name); - if(size > count) { - for(int i = count; i < size; i++) { - count++; - String output = plugin.oq.get(i); - String[] data = output.split(plugin.spacer); - if(data[1].equals("single")) { - if(data[3].equals(name)) { - out.println(output); - plugin.debugger.debug("[" + socket.getInetAddress().getHostName() + ":" + socket.getPort() + "] [" + name + "] Sent output - " + output); - } - } else { - out.println(output); - plugin.debugger.debug("[" + socket.getInetAddress().getHostName() + ":" + socket.getPort() + "] [" + name + "] Sent output - " + output); - } - } - plugin.qc.put(name, count); - } - sleep(heartbeat); - } catch(Exception e) { - plugin.c.remove(name); - e.printStackTrace(); - } - } - } + public ClientHandler(CSS plugin, Socket socket, Integer heartbeat, String pass) throws IOException { + this.plugin = plugin; + this.socket = socket; + this.heartbeat = heartbeat; + } + + public void run() { + while (true) { + try { + Integer size = plugin.serverQueue.size(); + Integer count = plugin.servers.get(name); + if (size > count) { + for (int i = count; i < size; i++) { + count++; + String output = plugin.serverQueue.get(i); + String[] data = output.split(plugin.spacer); + if (data[1].equals("single")) { + if (data[3].equals(name)) { + out.println(output); + plugin.debugger.debug("[" + socket.getInetAddress().getHostName() + ":" + socket.getPort() + "] [" + name + "] Sent output - " + output); + } + } else { + out.println(output); + plugin.debugger.debug("[" + socket.getInetAddress().getHostName() + ":" + socket.getPort() + "] [" + name + "] Sent output - " + output); + } + } + + plugin.servers.put(name, count); + } + + sleep(heartbeat); + } catch (Exception e) { + plugin.c.remove(name); + e.printStackTrace(); + } + } + } } diff --git a/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/ClientListener.java b/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/ClientListener.java deleted file mode 100644 index 038ec36..0000000 --- a/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/ClientListener.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.fuzzoland.CommandSyncServer; - -import java.io.IOException; - -public class ClientListener extends Thread { - - private CSS plugin; - private Integer heartbeat; - private String pass; - - public ClientListener(CSS plugin, Integer heartbeat, String pass) { - this.plugin = plugin; - this.heartbeat = heartbeat; - this.pass = pass; - } - - public void run() { - while(true) { - try { - new ClientHandler(plugin, plugin.server.accept(), heartbeat, pass).start(); - } catch(IOException e) { - e.printStackTrace(); - } - } - } -} diff --git a/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/CommandThread.java b/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/CommandThread.java index 85d872e..62f3869 100644 --- a/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/CommandThread.java +++ b/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/CommandThread.java @@ -4,36 +4,37 @@ import net.md_5.bungee.api.connection.ProxiedPlayer; -public class CommandThread extends Thread { +public class CommandThread implements Runnable { - private CSS plugin; - private ProxiedPlayer player; - private String name; - private List commands; - - public CommandThread(CSS plugin, ProxiedPlayer player) { - this.plugin = plugin; - this.player = player; - this.name = player.getName(); - this.commands = plugin.pq.get(name); - } - - public void run() { - while(true) { - try { - for(String command : commands) { - player.chat(command); - plugin.debugger.debug("Ran command " + command + " for player " + name + "."); - } - plugin.pq.remove(name); - return; - } catch(IllegalStateException e1) { - try { - sleep(1000); - } catch(InterruptedException e2) { - e2.printStackTrace(); - } - } - } - } + private CSS plugin; + private ProxiedPlayer player; + private String name; + private List commands; + + public CommandThread(CSS plugin, ProxiedPlayer player) { + this.plugin = plugin; + this.player = player; + this.name = player.getName(); + this.commands = plugin.playerQueue.get(name); + } + + public void run() { + while (true) { + try { + for (String command : commands) { + player.chat(command); + plugin.debugger.debug("Ran command " + command + " for player " + name + "."); + } + + plugin.playerQueue.remove(name); + return; + } catch (IllegalStateException e1) { + try { + Thread.sleep(1000); + } catch (InterruptedException e2) { + e2.printStackTrace(); + } + } + } + } } diff --git a/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/EventListener.java b/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/EventListener.java index 490af84..60dbb55 100644 --- a/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/EventListener.java +++ b/CommandSyncServer/src/com/fuzzoland/CommandSyncServer/EventListener.java @@ -1,23 +1,94 @@ package com.fuzzoland.CommandSyncServer; +import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.connection.Server; +import net.md_5.bungee.api.event.PluginMessageEvent; import net.md_5.bungee.api.event.ServerConnectedEvent; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.event.EventHandler; public class EventListener implements Listener { - private CSS plugin; - - public EventListener(CSS plugin) { - this.plugin = plugin; - } - - @EventHandler - public void onServerConnected(ServerConnectedEvent event) { - ProxiedPlayer player = event.getPlayer(); - if(plugin.pq.containsKey(player.getName())) { - new CommandThread(plugin, player).start(); - } - } + private CSS plugin; + + public EventListener(CSS plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onServerConnected(ServerConnectedEvent connectedEvent) { + ProxiedPlayer player = connectedEvent.getPlayer(); + if (plugin.playerQueue.containsKey(player.getName())) { + plugin.getProxy().getScheduler().runAsync(plugin, new CommandThread(plugin, player)); + ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput(); + dataOutput.writeUTF("AUTHENTICATE"); + dataOutput.writeUTF(plugin.getUsername); + dataOutput.writeUTF("AUTHENTICATE"); + player.getServer().sendData(plugin.getDescription().getName(), bytes); + } + } + + @EventHandler + public void onServerConnected(PluginMessageEvent messageEvent) { + String channel = messageEvent.getTag(); + if (messageEvent.isCancelled() || !plugin.getDescription().getName().equals(channel)) { + return; + } + + //check if the message is sent from the server + if (Server.class.isAssignableFrom(messageEvent.getSender().getClass())) { + ByteArrayDataInput dataInput = ByteStreams.newDataInput(messageEvent.getData()); + String invoker = dataInput.readUTF(); + String receiver = dataInput.readUTF(); + + String arguments = dataInput.readUTF(); + if (invoker.equals("player")) { + String command = "/" + arguments.replaceAll("\\+", " "); + if (receiver.equals("single")) { + String name = receiver; + Boolean found = false; + for (ProxiedPlayer player : plugin.getProxy().getPlayers()) { + if (name.equals(player.getName())) { + player.chat(command); + plugin.debugger.debug("Ran command " + command + " for player " + name + "."); + found = true; + break; + } + } + + if (!found) { + if (plugin.playerQueue.containsKey(name)) { + List commands = plugin.playerQueue.get(name); + commands.add(command); + plugin.playerQueue.put(name, commands); + } else { + plugin.playerQueue.put(name, new ArrayList(Arrays.asList(command))); + } + + plugin.debugger.debug(" Since " + name + " is offline the command " + command + " will run when they come online."); + } + } else if (receiver.equals("all")) { + for (ProxiedPlayer player : plugin.getProxy().getPlayers()) { + player.chat(command); + } + + plugin.debugger.debug("Ran command " + command + " for all online players."); + } + } else if (receiver.equals("bungee")) { + String command = arguments.replaceAll("\\+", " "); + plugin.getProxy().getPluginManager().dispatchCommand(plugin.getProxy().getConsole(), command); + plugin.debugger.debug("Ran command /" + command + "."); + } else { + plugin.serverQueue.add(messageEvent.getData()); + } + } + } }