Skip to content

Commit

Permalink
Code Optimization: Improving Readability and Performance (#14)
Browse files Browse the repository at this point in the history
* Multithread and fixes

* Working Bungee, performance metrics, optimizations.
  • Loading branch information
wiktor-jozwiak authored Jan 2, 2024
1 parent 0522ea1 commit b0c202b
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 41 deletions.
101 changes: 62 additions & 39 deletions bukkit/src/main/java/app/shopmc/plugin/bukkit/BukkitShopMCPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
}

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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
112 changes: 110 additions & 2 deletions bungee/src/main/java/app/shopmc/plugin/bungee/BungeeShopMCPlugin.java
Original file line number Diff line number Diff line change
@@ -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();
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}

0 comments on commit b0c202b

Please sign in to comment.