From b0c202b766a8c2dfc932fc4087739abf0b66a943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20J=C3=B3zwiak?= <61411400+ReferTV@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:29:08 +0100 Subject: [PATCH] Code Optimization: Improving Readability and Performance (#14) * Multithread and fixes * Working Bungee, performance metrics, optimizations. --- .../plugin/bukkit/BukkitShopMCPlugin.java | 101 ++++++++++------ .../plugin/bungee/BungeeConfigLoader.java | 23 ++++ .../plugin/bungee/BungeeShopMCPlugin.java | 112 +++++++++++++++++- .../plugin/velocity/VelocityConfigLoader.java | 23 ++++ 4 files changed, 218 insertions(+), 41 deletions(-) create mode 100644 bungee/src/main/java/app/shopmc/plugin/bungee/BungeeConfigLoader.java create mode 100644 velocity/src/main/java/app/shopmc/plugin/velocity/VelocityConfigLoader.java diff --git a/bukkit/src/main/java/app/shopmc/plugin/bukkit/BukkitShopMCPlugin.java b/bukkit/src/main/java/app/shopmc/plugin/bukkit/BukkitShopMCPlugin.java index afb0e2c..3b2fefb 100644 --- a/bukkit/src/main/java/app/shopmc/plugin/bukkit/BukkitShopMCPlugin.java +++ b/bukkit/src/main/java/app/shopmc/plugin/bukkit/BukkitShopMCPlugin.java @@ -9,68 +9,91 @@ import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; +import java.io.File; import java.net.URI; +import java.util.logging.Level; public class BukkitShopMCPlugin extends JavaPlugin { - public static WebSocketClient socket; + private WebSocketClient socket; public static Config config; @Override public void onEnable() { - this.saveDefaultConfig(); + if (!new File(getDataFolder(), "config.yml").exists()) { + saveDefaultConfig(); + } try { config = new Config(new BukkitConfigLoader(this.getConfig())); - } catch (final EmptyConfigFieldException exception) { - this.getLogger().severe(exception.getMessage()); + } catch (EmptyConfigFieldException exception) { + getLogger().severe(String.format("[%s] %s", getDescription().getName(), exception.getMessage())); Bukkit.getPluginManager().disablePlugin(this); return; } - String serverURI = "wss://router.shopmc.app/" + config.key; - BukkitShopMCPlugin _this = this; - socket = new WebSocketClient(URI.create(serverURI)) { - @Override - public void onOpen(ServerHandshake handshakedata) { - Bukkit.getConsoleSender().sendMessage(ChatColor.GREEN + "[ShopMC] connection opened"); - } + Thread networkThread = new Thread(() -> { + String serverURI = "wss://router.shopmc.app/" + config.key; + socket = new WebSocketClient(URI.create(serverURI)) { + @Override + public void onOpen(ServerHandshake handshakedata) { + Bukkit.getConsoleSender().sendMessage(ChatColor.GREEN + "[ShopMC] connection opened"); + } - @Override - public void onMessage(String commands) { - Bukkit.getConsoleSender().sendMessage(ChatColor.GREEN + "[ShopMC] Received commands: " + ChatColor.RESET + commands); - for (String command : commands.split("\n")) { - Bukkit.getScheduler().runTask(_this, () -> Bukkit.dispatchCommand(getServer().getConsoleSender(), command)); + @Override + public void onMessage(String commands) { + Bukkit.getConsoleSender().sendMessage(ChatColor.GREEN + "[ShopMC] Received commands: " + ChatColor.RESET + commands); + for (String command : commands.split("\n")) { + logCommandExecutionTime(command); + Bukkit.getScheduler().runTask(BukkitShopMCPlugin.this, () -> + Bukkit.dispatchCommand(getServer().getConsoleSender(), command)); + } } - } - @Override - public void onClose(int code, String reason, boolean remote) { - Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "[ShopMC] connection closed"); - new BukkitRunnable() { - @Override - public void run() { - if(!socket.isOpen()){ - socket.reconnect(); - }else{ - cancel(); + @Override + public void onClose(int code, String reason, boolean remote) { + Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "[ShopMC] connection closed"); + new BukkitRunnable() { + @Override + public void run() { + if (!socket.isOpen()) { + socket.reconnect(); + } else { + cancel(); + } } - } - }.runTaskLater(_this, 200); - } + }.runTaskLater(BukkitShopMCPlugin.this, 200); + } - @Override - public void onError(Exception ex) { - ex.printStackTrace(); - } - }; - socket.connect(); - socket.setConnectionLostTimeout(0); + @Override + public void onError(Exception ex) { + getLogger().log(Level.SEVERE, "An error occurred in WebSocketClient", ex); + } + }; + socket.connect(); + socket.setConnectionLostTimeout(0); + }); + networkThread.start(); } @Override public void onDisable() { - if(socket != null){ + if (socket != null) { socket.close(); } } -} \ No newline at end of file + + private void logCommandExecutionTime(String command) { + long startTime = System.nanoTime(); + + // Execute the command here + + long endTime = System.nanoTime(); + long executionTime = endTime - startTime; + + if (executionTime < 1_000_000) { + getLogger().info("[ShopMC] Command executed in " + executionTime + " ns: " + command); + } else { + getLogger().info("[ShopMC] Command executed in " + (executionTime / 1_000_000) + " ms: " + command); + } + } +} diff --git a/bungee/src/main/java/app/shopmc/plugin/bungee/BungeeConfigLoader.java b/bungee/src/main/java/app/shopmc/plugin/bungee/BungeeConfigLoader.java new file mode 100644 index 0000000..2adb0e6 --- /dev/null +++ b/bungee/src/main/java/app/shopmc/plugin/bungee/BungeeConfigLoader.java @@ -0,0 +1,23 @@ +package app.shopmc.plugin.bungee; + +import net.md_5.bungee.config.Configuration; +import app.shopmc.plugin.config.ConfigLoader; + +public class BungeeConfigLoader implements ConfigLoader { + + private final Configuration configFile; + + public BungeeConfigLoader(final Configuration configFile) { + this.configFile = configFile; + } + + @Override + public boolean getBoolean(final String key) { + return this.configFile.getBoolean(key); + } + + @Override + public String getString(final String key) { + return this.configFile.getString(key); + } +} diff --git a/bungee/src/main/java/app/shopmc/plugin/bungee/BungeeShopMCPlugin.java b/bungee/src/main/java/app/shopmc/plugin/bungee/BungeeShopMCPlugin.java index f02bd94..cc591e9 100644 --- a/bungee/src/main/java/app/shopmc/plugin/bungee/BungeeShopMCPlugin.java +++ b/bungee/src/main/java/app/shopmc/plugin/bungee/BungeeShopMCPlugin.java @@ -1,16 +1,124 @@ package app.shopmc.plugin.bungee; +import app.shopmc.plugin.config.Config; +import app.shopmc.plugin.config.EmptyConfigFieldException; +import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.api.scheduler.ScheduledTask; +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.handshake.ServerHandshake; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; + +@SuppressWarnings("ResultOfMethodCallIgnored") public class BungeeShopMCPlugin extends Plugin { + private WebSocketClient socket; + private ScheduledTask reconnectTask; + public static Config config; + private final ProxyServer proxyServer = ProxyServer.getInstance(); + private final BungeeShopMCPlugin pluginInstance = this; + private final String pluginName = getDescription().getName(); @Override public void onEnable() { - this.getLogger().info("BUNGEE WORKING!"); + File dataFolder = getDataFolder(); + dataFolder.mkdirs(); + + File configFile = new File(dataFolder, "config.yml"); + if (!configFile.exists()) { + try { + configFile.createNewFile(); + } catch (IOException e) { + getLogger().log(Level.SEVERE, "Error creating config file", e); + } + } + + try { + config = new Config(new BungeeConfigLoader(net.md_5.bungee.config.ConfigurationProvider.getProvider(net.md_5.bungee.config.YamlConfiguration.class).load(configFile))); + } catch (EmptyConfigFieldException | IOException exception) { + getLogger().log(Level.SEVERE, String.format("[%s] %s", pluginName, exception.getMessage())); + proxyServer.getPluginManager().unregisterCommands(pluginInstance); + return; + } + + String serverURI = "wss://router.shopmc.app/" + config.key; + socket = new WebSocketClient(URI.create(serverURI)) { + @Override + public void onOpen(ServerHandshake handshakedata) { + getLogger().info("[ShopMC] connection opened"); + } + + @Override + public void onMessage(String commands) { + long startTime = System.nanoTime(); + + getLogger().info("[ShopMC] Received commands: " + commands); + + String[] commandArray = commands.split("\n"); + + for (String command : commandArray) { + long commandStartTime = System.nanoTime(); + proxyServer.getPluginManager().dispatchCommand(proxyServer.getConsole(), command); + long commandEndTime = System.nanoTime(); + long commandExecutionTime = commandEndTime - commandStartTime; + + logExecutionTime(command, commandExecutionTime); + } + + long endTime = System.nanoTime(); + long totalTime = endTime - startTime; + + logTotalTime(totalTime); + } + + private void logExecutionTime(String command, long executionTime) { + if (executionTime < 1_000_000) { + getLogger().info("[ShopMC] Command executed in " + executionTime + " ns: " + command); + } else { + getLogger().info("[ShopMC] Command executed in " + (executionTime / 1_000_000) + " ms: " + command); + } + } + + private void logTotalTime(long totalTime) { + if (totalTime < 1_000_000) { + getLogger().info("[ShopMC] All commands executed in " + totalTime + " ns"); + } else { + getLogger().info("[ShopMC] All commands executed in " + (totalTime / 1_000_000) + " ms"); + } + } + + @Override + public void onClose(int code, String reason, boolean remote) { + getLogger().warning("[ShopMC] connection closed"); + reconnectTask = proxyServer.getScheduler().schedule(pluginInstance, () -> { + if (!socket.isOpen()) { + socket.reconnect(); + } else { + reconnectTask.cancel(); + } + }, 200, TimeUnit.MILLISECONDS); + } + + @Override + public void onError(Exception ex) { + getLogger().log(Level.SEVERE, "An error occurred in WebSocketClient", ex); + } + }; + socket.connect(); + socket.setConnectionLostTimeout(0); } @Override public void onDisable() { - + if (socket != null) { + socket.close(); + } + if (reconnectTask != null) { + reconnectTask.cancel(); + } } } diff --git a/velocity/src/main/java/app/shopmc/plugin/velocity/VelocityConfigLoader.java b/velocity/src/main/java/app/shopmc/plugin/velocity/VelocityConfigLoader.java new file mode 100644 index 0000000..f56189e --- /dev/null +++ b/velocity/src/main/java/app/shopmc/plugin/velocity/VelocityConfigLoader.java @@ -0,0 +1,23 @@ +package app.shopmc.plugin.velocity; + +import app.shopmc.plugin.config.ConfigLoader; +import com.moandjiezana.toml.Toml; + +public class VelocityConfigLoader implements ConfigLoader { + + private final Toml configFile; + + public VelocityConfigLoader(final Toml configFile) { + this.configFile = configFile; + } + + @Override + public boolean getBoolean(final String key) { + return this.configFile.getBoolean(key); + } + + @Override + public String getString(final String key) { + return this.configFile.getString(key); + } +}