diff --git a/src/main/java/net/cytonic/cytosis/CytonicNetwork.java b/src/main/java/net/cytonic/cytosis/CytonicNetwork.java index 960d7992..19f94b10 100644 --- a/src/main/java/net/cytonic/cytosis/CytonicNetwork.java +++ b/src/main/java/net/cytonic/cytosis/CytonicNetwork.java @@ -2,8 +2,7 @@ import lombok.Getter; import net.cytonic.cytosis.data.RedisDatabase; -import net.cytonic.cytosis.data.obj.CytonicServer; - +import net.cytonic.cytosis.data.objects.CytonicServer; import java.util.HashSet; import java.util.Set; import java.util.UUID; diff --git a/src/main/java/net/cytonic/cytosis/Cytosis.java b/src/main/java/net/cytonic/cytosis/Cytosis.java index f78dd4fb..f6abcf07 100644 --- a/src/main/java/net/cytonic/cytosis/Cytosis.java +++ b/src/main/java/net/cytonic/cytosis/Cytosis.java @@ -4,6 +4,7 @@ import net.cytonic.cytosis.commands.CommandHandler; import net.cytonic.cytosis.config.CytosisSettings; import net.cytonic.cytosis.data.DatabaseManager; +import net.cytonic.cytosis.data.objects.CytonicServer; import net.cytonic.cytosis.events.EventHandler; import net.cytonic.cytosis.events.ServerEventListeners; import net.cytonic.cytosis.files.FileManager; @@ -295,11 +296,6 @@ public static void completeNonEssentialTasks(long start) { ) ); - Logger.info("Initializing server commands"); - commandHandler = new CommandHandler(); - commandHandler.setupConsole(); - commandHandler.registerCytosisCommands(); - messagingManager = new MessagingManager(); messagingManager.initialize().whenComplete((_, th) -> { if (th != null) { @@ -329,8 +325,14 @@ public static void completeNonEssentialTasks(long start) { Logger.info("Loading network setup!"); cytonicNetwork = new CytonicNetwork(); cytonicNetwork.importDataFromRedis(databaseManager.getRedisDatabase()); + cytonicNetwork.getServers().add(new CytonicServer(Utils.getServerIP(),SERVER_ID,CytosisSettings.SERVER_PORT)); } + Logger.info("Initializing server commands"); + commandHandler = new CommandHandler(); + commandHandler.setupConsole(); + commandHandler.registerCytosisCommands(); + Thread.ofVirtual().name("WorldLoader").start(Cytosis::loadWorld); @@ -340,6 +342,7 @@ public static void completeNonEssentialTasks(long start) { long end = System.currentTimeMillis(); Logger.info(STR."Server started in \{end - start}ms!"); + Logger.info(STR."Server id = \{SERVER_ID}"); if (FLAGS.contains("--ci-test")) { Logger.info("Stopping server due to '--ci-test' flag."); diff --git a/src/main/java/net/cytonic/cytosis/commands/CommandHandler.java b/src/main/java/net/cytonic/cytosis/commands/CommandHandler.java index 36fba68a..b5b6101c 100644 --- a/src/main/java/net/cytonic/cytosis/commands/CommandHandler.java +++ b/src/main/java/net/cytonic/cytosis/commands/CommandHandler.java @@ -36,6 +36,7 @@ public void registerCytosisCommands() { cm.register(new BanCommand()); cm.register(new ChatChannelCommand()); cm.register(new StopCommand()); + cm.register(new ServerCommand()); } /** diff --git a/src/main/java/net/cytonic/cytosis/commands/ServerCommand.java b/src/main/java/net/cytonic/cytosis/commands/ServerCommand.java new file mode 100644 index 00000000..bdf25251 --- /dev/null +++ b/src/main/java/net/cytonic/cytosis/commands/ServerCommand.java @@ -0,0 +1,52 @@ +package net.cytonic.cytosis.commands; + +import net.cytonic.cytosis.Cytosis; +import net.cytonic.cytosis.data.objects.CytonicServer; +import net.cytonic.cytosis.logging.Logger; +import net.cytonic.cytosis.utils.MiniMessageTemplate; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.minestom.server.command.builder.Command; +import net.minestom.server.command.builder.arguments.ArgumentType; +import net.minestom.server.command.builder.suggestion.SuggestionEntry; +import net.minestom.server.entity.Player; + +public class ServerCommand extends Command { + + public ServerCommand() { + super("cytosis:server"); + try { + setCondition((sender, _) -> sender.hasPermission("cytosis.commands.server")); + setDefaultExecutor((sender, context) -> sender.sendMessage(MiniMessageTemplate.MM."You must specify a server!")); + var serverArgument = ArgumentType.Word("server"); + serverArgument.setCallback((sender, exception) -> sender.sendMessage(Component.text(STR."The server \{exception.getInput()} is invalid!", NamedTextColor.RED))); + serverArgument.setSuggestionCallback((_, _, suggestion) -> { + Logger.debug("this has been called"); + for (CytonicServer server : Cytosis.getCytonicNetwork().getServers()) { + suggestion.addEntry(new SuggestionEntry(server.id())); + Logger.debug(STR."command server id = \{server.id()}"); + } + }); + addSyntax(((sender, context) -> { + if (sender instanceof Player player) + if (player.hasPermission("cytosis.commands.server")) { + if (context.get(serverArgument).isEmpty()) { + StringBuilder builder = new StringBuilder(); + Cytosis.getCytonicNetwork().getServers().forEach(server -> builder.append(STR."\{server.id()} ")); + player.sendMessage(Component.text(builder.toString())); + return; + } + for (CytonicServer server : Cytosis.getCytonicNetwork().getServers()) { + if (server.id().equals(context.get(serverArgument))) { + player.sendMessage(Component.text(STR."Connecting to \{server.id()}", NamedTextColor.GREEN)); + Cytosis.getDatabaseManager().getRedisDatabase().sendPlayerToServer(player, server); + } + } + } + }), serverArgument); + } catch (Exception e) { + Logger.error("error", e); + } + } + +} diff --git a/src/main/java/net/cytonic/cytosis/data/MysqlDatabase.java b/src/main/java/net/cytonic/cytosis/data/MysqlDatabase.java index 520b385a..ec145313 100644 --- a/src/main/java/net/cytonic/cytosis/data/MysqlDatabase.java +++ b/src/main/java/net/cytonic/cytosis/data/MysqlDatabase.java @@ -67,6 +67,7 @@ public boolean isConnected() { /** * connects to the database + * * @return a future that completes when the connection is successful */ public CompletableFuture connect() { @@ -119,6 +120,7 @@ public void createTables() { /** * Gets the connection + * * @return the connection to the database */ private Connection getConnection() { @@ -300,8 +302,8 @@ public CompletableFuture getPlayerRank(@NotNull final UUID uuid) { * * @param uuid The player's UUID * @param rank The player's rank constant - * @throws IllegalStateException if the database isn't connected * @return a future that completes when the update is complete + * @throws IllegalStateException if the database isn't connected */ public CompletableFuture setPlayerRank(UUID uuid, PlayerRank rank) { if (!isConnected()) @@ -323,8 +325,9 @@ public CompletableFuture setPlayerRank(UUID uuid, PlayerRank rank) { /** * Add a chat message to the log - * @param uuid The UUID of the sender - * @param message The message to log + * + * @param uuid The UUID of the sender + * @param message The message to log */ public void addChat(UUID uuid, String message) { worker.submit(() -> { @@ -342,8 +345,9 @@ public void addChat(UUID uuid, String message) { /** * Adds an auditlog entry + * * @param entry The entry to add - * @return a future that completes when the entry is added + * @return a future that completes when the entry is added */ public CompletableFuture addAuditLogEntry(Entry entry) { if (!isConnected()) throw new IllegalStateException("The database must be connected to add an auditlog entry."); @@ -368,10 +372,11 @@ public CompletableFuture addAuditLogEntry(Entry entry) { /** * Bans a player - * @param uuid the player to ban - * @param reason The reason to ban the player + * + * @param uuid the player to ban + * @param reason The reason to ban the player * @param toExpire When the ban expires - * @return a future that completes when the player is banned + * @return a future that completes when the player is banned */ public CompletableFuture banPlayer(UUID uuid, String reason, Instant toExpire) { CompletableFuture future = new CompletableFuture<>(); @@ -435,8 +440,9 @@ public CompletableFuture isBanned(UUID uuid) { /** * Finds a player's UUID by name + * * @param name the player's name - * @return a future that completes with the player's UUID + * @return a future that completes with the player's UUID */ public CompletableFuture findUUIDByName(String name) { if (!isConnected()) throw new IllegalStateException("The database must be connected."); @@ -461,8 +467,9 @@ public CompletableFuture findUUIDByName(String name) { /** * Adds a or updates a player's name in the data + * * @param player The player to update - * @return a future that completes when the update is complete + * @return a future that completes when the update is complete */ public CompletableFuture addPlayer(Player player) { if (!isConnected()) throw new IllegalStateException("The database must be connected."); @@ -485,8 +492,9 @@ public CompletableFuture addPlayer(Player player) { /** * Unbans a player + * * @param uuid the player to unban - * @return a future that completes when the player is unbanned + * @return a future that completes when the player is unbanned */ public CompletableFuture unbanPlayer(UUID uuid) { if (!isConnected()) throw new IllegalStateException("The database must be connected."); @@ -507,7 +515,8 @@ public CompletableFuture unbanPlayer(UUID uuid) { /** * Sets a player's chat channel - * @param uuid the player + * + * @param uuid the player * @param chatChannel the chat channel to select */ public void setChatChannel(UUID uuid, ChatChannel chatChannel) { @@ -528,6 +537,7 @@ public void setChatChannel(UUID uuid, ChatChannel chatChannel) { /** * Gets a player's chat channel + * * @param uuid the player * @return a future that completes with the player's chat channel */ diff --git a/src/main/java/net/cytonic/cytosis/data/RedisDatabase.java b/src/main/java/net/cytonic/cytosis/data/RedisDatabase.java index cf39ec06..d3863768 100644 --- a/src/main/java/net/cytonic/cytosis/data/RedisDatabase.java +++ b/src/main/java/net/cytonic/cytosis/data/RedisDatabase.java @@ -2,12 +2,13 @@ import net.cytonic.cytosis.Cytosis; import net.cytonic.cytosis.config.CytosisSettings; +import net.cytonic.cytosis.data.objects.CytonicServer; import net.cytonic.cytosis.logging.Logger; import net.cytonic.cytosis.messaging.pubsub.PlayerLoginLogout; import net.cytonic.cytosis.messaging.pubsub.ServerStatus; import net.cytonic.cytosis.utils.Utils; +import net.minestom.server.entity.Player; import redis.clients.jedis.*; - import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -39,6 +40,10 @@ public class RedisDatabase { * Server startup / shutdown */ public static final String SERVER_STATUS_CHANNEL = "server_status"; + /** + * Send player channel + */ + public static final String SEND_PLAYER_CHANNEL = "player_send"; private final JedisPooled jedis; private final JedisPooled jedisPub; @@ -80,6 +85,11 @@ public void sendStartupMessage() { Logger.info("Server startup message sent!"); } + public void sendPlayerToServer(Player player, CytonicServer server) { + // formatting: |:| + jedisPub.publish(SEND_PLAYER_CHANNEL, STR."\{player.getUuid()}|:|\{server.id()}"); + } + /** * Disconnects from the redis server diff --git a/src/main/java/net/cytonic/cytosis/data/obj/CytonicServer.java b/src/main/java/net/cytonic/cytosis/data/objects/CytonicServer.java similarity index 94% rename from src/main/java/net/cytonic/cytosis/data/obj/CytonicServer.java rename to src/main/java/net/cytonic/cytosis/data/objects/CytonicServer.java index 81ff305a..337774f0 100644 --- a/src/main/java/net/cytonic/cytosis/data/obj/CytonicServer.java +++ b/src/main/java/net/cytonic/cytosis/data/objects/CytonicServer.java @@ -1,4 +1,4 @@ -package net.cytonic.cytosis.data.obj; +package net.cytonic.cytosis.data.objects; /** * A class that holds data about a Cytosis server diff --git a/src/main/java/net/cytonic/cytosis/messaging/pubsub/PlayerLoginLogout.java b/src/main/java/net/cytonic/cytosis/messaging/pubsub/PlayerLoginLogout.java index b34ad05f..5d1f809b 100644 --- a/src/main/java/net/cytonic/cytosis/messaging/pubsub/PlayerLoginLogout.java +++ b/src/main/java/net/cytonic/cytosis/messaging/pubsub/PlayerLoginLogout.java @@ -22,7 +22,7 @@ public PlayerLoginLogout() { * Consumes messages on the redis pub/sub interface to determine the online players * * @param channel The channel that was messaged - * @param message The connent of the message + * @param message The content of the message */ @Override public void onMessage(String channel, String message) { diff --git a/src/main/java/net/cytonic/cytosis/messaging/pubsub/ServerStatus.java b/src/main/java/net/cytonic/cytosis/messaging/pubsub/ServerStatus.java index 5ae7caf5..e626512d 100644 --- a/src/main/java/net/cytonic/cytosis/messaging/pubsub/ServerStatus.java +++ b/src/main/java/net/cytonic/cytosis/messaging/pubsub/ServerStatus.java @@ -3,7 +3,7 @@ import net.cytonic.cytosis.CytonicNetwork; import net.cytonic.cytosis.Cytosis; import net.cytonic.cytosis.data.RedisDatabase; -import net.cytonic.cytosis.data.obj.CytonicServer; +import net.cytonic.cytosis.data.objects.CytonicServer; import redis.clients.jedis.JedisPubSub; /** @@ -31,6 +31,7 @@ public void onMessage(String channel, String message) { if (network == null) return; // formatting: |:||:||:| String[] parts = message.split("\\|:\\|"); + if (parts[1].equalsIgnoreCase(Cytosis.SERVER_ID)) return; if (parts[0].equalsIgnoreCase("START")) { network.getServers().add(new CytonicServer(parts[2], parts[1], Integer.parseInt(parts[3]))); } else if (parts[0].equalsIgnoreCase("STOP")) {