diff --git a/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/GenericPacket.java b/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/GenericPacket.java index e2266db83..b1e0cb904 100644 --- a/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/GenericPacket.java +++ b/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/GenericPacket.java @@ -1,7 +1,9 @@ package group.aelysium.rustyconnector.core.lib.packets; import com.google.gson.*; +import group.aelysium.rustyconnector.core.lib.packets.variants.LockServerPacket; import group.aelysium.rustyconnector.core.lib.packets.variants.CoordinateRequestQueuePacket; +import group.aelysium.rustyconnector.core.lib.packets.variants.UnlockServerPacket; import group.aelysium.rustyconnector.core.lib.packets.variants.SendPlayerPacket; import group.aelysium.rustyconnector.core.lib.packets.variants.ServerPingPacket; import group.aelysium.rustyconnector.core.lib.packets.variants.ServerPingResponsePacket; @@ -187,6 +189,8 @@ public GenericPacket buildReceived() { if (this.type == PacketType.PING_RESPONSE) return new ServerPingResponsePacket(this.protocolVersion, this.rawMessage, this.address, this.origin, this.parameters); if (this.type == PacketType.SEND_PLAYER) return new SendPlayerPacket(this.protocolVersion, this.rawMessage, this.address, this.origin, this.parameters); if (this.type == PacketType.COORDINATE_REQUEST_QUEUE) return new CoordinateRequestQueuePacket(this.protocolVersion, this.rawMessage, this.address, this.origin, this.parameters); + if (this.type == PacketType.UNLOCK_SERVER) return new UnlockServerPacket(this.address, this.origin, this.parameters); + if (this.type == PacketType.LOCK_SERVER) return new LockServerPacket(this.address, this.origin, this.parameters); throw new IllegalStateException("Invalid RedisMessage type encountered!"); } @@ -213,6 +217,8 @@ public GenericPacket buildSendable() { if(this.type == PacketType.PING_RESPONSE) return new ServerPingResponsePacket(this.address, this.origin, this.parameters); if(this.type == PacketType.SEND_PLAYER) return new SendPlayerPacket(this.address, this.origin, this.parameters); if(this.type == PacketType.COORDINATE_REQUEST_QUEUE) return new CoordinateRequestQueuePacket(this.address, this.origin, this.parameters); + if(this.type == PacketType.UNLOCK_SERVER) return new UnlockServerPacket(this.address, this.origin, this.parameters); + if(this.type == PacketType.LOCK_SERVER) return new LockServerPacket(this.address, this.origin, this.parameters); throw new IllegalStateException("Invalid RedisMessage type encountered!"); } diff --git a/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/PacketType.java b/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/PacketType.java index e33a2dd34..bbc60e3f4 100644 --- a/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/PacketType.java +++ b/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/PacketType.java @@ -32,12 +32,24 @@ public class PacketType { */ public static Mapping COORDINATE_REQUEST_QUEUE = new Mapping(300, "TPA_QUEUE_PLAYER"); + /** + * `Server > Proxy` | Tells the proxy to open a server. + */ + public static Mapping UNLOCK_SERVER = new Mapping(400, "UNLOCK_SERVER"); + + /** + * `Server > Proxy` | Tells the proxy to close a server. + */ + public static Mapping LOCK_SERVER = new Mapping(401, "LOCK_SERVER"); + public static List toList() { List list = new ArrayList<>(); list.add(PING); list.add(PING_RESPONSE); list.add(SEND_PLAYER); list.add(COORDINATE_REQUEST_QUEUE); + list.add(UNLOCK_SERVER); + list.add(LOCK_SERVER); return list; } diff --git a/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/variants/LockServerPacket.java b/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/variants/LockServerPacket.java new file mode 100644 index 000000000..f5572161d --- /dev/null +++ b/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/variants/LockServerPacket.java @@ -0,0 +1,54 @@ +package group.aelysium.rustyconnector.core.lib.packets.variants; + +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import group.aelysium.rustyconnector.core.lib.packets.GenericPacket; +import group.aelysium.rustyconnector.core.lib.packets.PacketOrigin; +import group.aelysium.rustyconnector.core.lib.packets.PacketType; +import io.lettuce.core.KeyValue; + +import java.net.InetSocketAddress; +import java.util.List; + +public class LockServerPacket extends GenericPacket { + private String serverName; + + public String serverName() { return this.serverName; } + + public LockServerPacket(InetSocketAddress address, PacketOrigin origin, List> parameters) { + super(PacketType.LOCK_SERVER, address, origin); + + parameters.forEach(entry -> { + String key = entry.getKey(); + JsonPrimitive value = entry.getValue(); + + if (key.equals(UnlockServerPacket.ValidParameters.SERVER_NAME)) { + this.serverName = value.getAsString(); + } + }); + } + public LockServerPacket(int messageVersion, String rawMessage, InetSocketAddress address, PacketOrigin origin, List> parameters) { + super(messageVersion, rawMessage, PacketType.LOCK_SERVER, address, origin); + + parameters.forEach(entry -> { + String key = entry.getKey(); + JsonPrimitive value = entry.getValue(); + + if (key.equals(UnlockServerPacket.ValidParameters.SERVER_NAME)) { + this.serverName = value.getAsString(); + } + }); + } + + @Override + public JsonObject toJSON() { + JsonObject object = super.toJSON(); + JsonObject parameters = new JsonObject(); + + parameters.add(UnlockServerPacket.ValidParameters.SERVER_NAME, new JsonPrimitive(this.serverName)); + + object.add(MasterValidParameters.PARAMETERS, parameters); + + return object; + } +} diff --git a/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/variants/UnlockServerPacket.java b/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/variants/UnlockServerPacket.java new file mode 100644 index 000000000..259bd2ad9 --- /dev/null +++ b/plugin/core/src/main/java/group/aelysium/rustyconnector/core/lib/packets/variants/UnlockServerPacket.java @@ -0,0 +1,66 @@ +package group.aelysium.rustyconnector.core.lib.packets.variants; + +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import group.aelysium.rustyconnector.core.lib.packets.GenericPacket; +import group.aelysium.rustyconnector.core.lib.packets.PacketOrigin; +import group.aelysium.rustyconnector.core.lib.packets.PacketType; +import io.lettuce.core.KeyValue; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; + +public class UnlockServerPacket extends GenericPacket { + private String serverName; + + public String serverName() { return this.serverName; } + + public UnlockServerPacket(InetSocketAddress address, PacketOrigin origin, List> parameters) { + super(PacketType.UNLOCK_SERVER, address, origin); + + parameters.forEach(entry -> { + String key = entry.getKey(); + JsonPrimitive value = entry.getValue(); + + if (key.equals(ValidParameters.SERVER_NAME)) { + this.serverName = value.getAsString(); + } + }); + } + public UnlockServerPacket(int messageVersion, String rawMessage, InetSocketAddress address, PacketOrigin origin, List> parameters) { + super(messageVersion, rawMessage, PacketType.UNLOCK_SERVER, address, origin); + + parameters.forEach(entry -> { + String key = entry.getKey(); + JsonPrimitive value = entry.getValue(); + + if (key.equals(ValidParameters.SERVER_NAME)) { + this.serverName = value.getAsString(); + } + }); + } + + @Override + public JsonObject toJSON() { + JsonObject object = super.toJSON(); + JsonObject parameters = new JsonObject(); + + parameters.add(ValidParameters.SERVER_NAME, new JsonPrimitive(this.serverName)); + + object.add(MasterValidParameters.PARAMETERS, parameters); + + return object; + } + + public interface ValidParameters { + String SERVER_NAME = "s"; + + static List toList() { + List list = new ArrayList<>(); + list.add(SERVER_NAME); + + return list; + } + } +} diff --git a/plugin/core/src/main/resources/en_us/language.yml b/plugin/core/src/main/resources/en_us/language.yml index fb8a3dfc5..229410031 100644 --- a/plugin/core/src/main/resources/en_us/language.yml +++ b/plugin/core/src/main/resources/en_us/language.yml @@ -98,9 +98,12 @@ velocity: scalar_family: panel: no_registered_servers: "There are no registered servers." + no_locked_servers: "There are no locked servers." + no_unlocked_servers: "There are no unlocked servers." info: - " ---| Online Players: " - " ---| Registered Servers: " + - " ---| Joinable Servers: " - " ---| Parent Family: " - " ---| Load Balancing:" - " | - Algorithm: " @@ -111,15 +114,19 @@ velocity: commands: sort: "Will cause the family to completely resort itself in accordance with it's load balancing algorithm." reset_index: "Will reset the family's input to the first server in the family." + locked: "Shows all locked servers instead of unlocked." static_family: residence: missing: "The server you were meant to be connected to is unavailable! In the meantime you've been connected to a fallback server!" blocked_join_attempt: "The server you were meant to be connected to is unavailable! Please try again later!" panel: - no_registered_servers: "There are no registered servers." + no_registered_servers: "There are no registered servers." + no_locked_servers: "There are no locked servers." + no_unlocked_servers: "There are no unlocked servers." info: - " ---| Online Players: " - " ---| Registered Servers: " + - " ---| Joinable Servers: " - " ---| Parent Family: " - " ---| Resident Server Expiration: " - " ---| Load Balancing:" @@ -131,6 +138,7 @@ velocity: commands: sort: "Will cause the family to completely resort itself in accordance with it's load balancing algorithm." reset_index: "Will reset the family's input to the first server in the family." + locked: "Shows all locked servers instead of unlocked." party: receiver_invite_query: query: "Hey! wants you to join their party!" diff --git a/plugin/paper/src/main/java/group/aelysium/rustyconnector/plugin/paper/commands/CommandRusty.java b/plugin/paper/src/main/java/group/aelysium/rustyconnector/plugin/paper/commands/CommandRusty.java index a207b2228..c8f28bdd3 100644 --- a/plugin/paper/src/main/java/group/aelysium/rustyconnector/plugin/paper/commands/CommandRusty.java +++ b/plugin/paper/src/main/java/group/aelysium/rustyconnector/plugin/paper/commands/CommandRusty.java @@ -24,6 +24,8 @@ public static void create(PaperCommandManager manager) { manager.command(messageList(manager)); manager.command(messageGet(manager)); manager.command(send(manager)); + manager.command(unlock(manager)); + manager.command(lock(manager)); } private static Command.Builder messageGet(PaperCommandManager manager) { @@ -114,4 +116,46 @@ private static Command.Builder send(PaperCommandManager unlock(PaperCommandManager manager) { + Tinder api = Tinder.get(); + PluginLogger logger = api.logger(); + + final Command.Builder builder = api.commandManager().commandBuilder("rc", "/rc"); + + return builder.literal("unlock") + .senderType(ConsoleCommandSender.class) + .handler(context -> manager.taskRecipe().begin(context) + .asynchronous(commandContext -> { + try { + api.services().packetBuilder().unlockServer(); + logger.log("Unlocking server."); + } catch (NullPointerException e) { + PaperLang.RC_SEND_USAGE.send(logger); + } catch (Exception e) { + logger.log("An error stopped us from processing the request!", e); + } + }).execute()); + } + + private static Command.Builder lock(PaperCommandManager manager) { + Tinder api = Tinder.get(); + PluginLogger logger = api.logger(); + + final Command.Builder builder = api.commandManager().commandBuilder("rc", "/rc"); + + return builder.literal("lock") + .senderType(ConsoleCommandSender.class) + .handler(context -> manager.taskRecipe().begin(context) + .asynchronous(commandContext -> { + try { + api.services().packetBuilder().lockServer(); + logger.log("Locking server."); + } catch (NullPointerException e) { + PaperLang.RC_SEND_USAGE.send(logger); + } catch (Exception e) { + logger.log("An error stopped us from processing the request!", e); + } + }).execute()); + } } \ No newline at end of file diff --git a/plugin/paper/src/main/java/group/aelysium/rustyconnector/plugin/paper/lib/services/PacketBuilderService.java b/plugin/paper/src/main/java/group/aelysium/rustyconnector/plugin/paper/lib/services/PacketBuilderService.java index 2f22a383c..4065386f3 100644 --- a/plugin/paper/src/main/java/group/aelysium/rustyconnector/plugin/paper/lib/services/PacketBuilderService.java +++ b/plugin/paper/src/main/java/group/aelysium/rustyconnector/plugin/paper/lib/services/PacketBuilderService.java @@ -3,6 +3,8 @@ import group.aelysium.rustyconnector.core.lib.packets.GenericPacket; import group.aelysium.rustyconnector.core.lib.packets.PacketOrigin; import group.aelysium.rustyconnector.core.lib.packets.PacketType; +import group.aelysium.rustyconnector.core.lib.packets.variants.LockServerPacket; +import group.aelysium.rustyconnector.core.lib.packets.variants.UnlockServerPacket; import group.aelysium.rustyconnector.core.lib.packets.variants.SendPlayerPacket; import group.aelysium.rustyconnector.core.lib.packets.variants.ServerPingPacket; import group.aelysium.rustyconnector.core.lib.lang.Lang; @@ -56,6 +58,40 @@ public void sendToOtherFamily(Player player, String familyName) { api.flame().backbone().connection().orElseThrow().publish(message); } + /** + * Tells the proxy to open the server running the command. + */ + public void unlockServer() { + Tinder api = Tinder.get(); + ServerInfoService serverInfoService = api.services().serverInfo(); + + UnlockServerPacket message = (UnlockServerPacket) new GenericPacket.Builder() + .setType(PacketType.UNLOCK_SERVER) + .setOrigin(PacketOrigin.SERVER) + .setAddress(serverInfoService.address()) + .setParameter(UnlockServerPacket.ValidParameters.SERVER_NAME, serverInfoService.name()) + .buildSendable(); + + api.flame().backbone().connection().orElseThrow().publish(message); + } + + /** + * Tells the proxy to close the server running the command. + */ + public void lockServer() { + Tinder api = Tinder.get(); + ServerInfoService serverInfoService = api.services().serverInfo(); + + LockServerPacket message = (LockServerPacket) new GenericPacket.Builder() + .setType(PacketType.LOCK_SERVER) + .setOrigin(PacketOrigin.SERVER) + .setAddress(serverInfoService.address()) + .setParameter(UnlockServerPacket.ValidParameters.SERVER_NAME, serverInfoService.name()) + .buildSendable(); + + api.flame().backbone().connection().orElseThrow().publish(message); + } + @Override public void kill() {} } diff --git a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/central/Flame.java b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/central/Flame.java index 9371b1cf9..207bb8574 100644 --- a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/central/Flame.java +++ b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/central/Flame.java @@ -49,7 +49,9 @@ import group.aelysium.rustyconnector.plugin.velocity.lib.load_balancing.LoadBalancingService; import group.aelysium.rustyconnector.plugin.velocity.lib.magic_link.MagicLinkService; import group.aelysium.rustyconnector.plugin.velocity.lib.magic_link.handlers.MagicLinkPingHandler; +import group.aelysium.rustyconnector.plugin.velocity.lib.message.handling.LockServerHandler; import group.aelysium.rustyconnector.plugin.velocity.lib.message.handling.SendPlayerHandler; +import group.aelysium.rustyconnector.plugin.velocity.lib.message.handling.UnlockServerHandler; import group.aelysium.rustyconnector.plugin.velocity.lib.parties.PartyService; import group.aelysium.rustyconnector.plugin.velocity.lib.parties.config.PartyConfig; import group.aelysium.rustyconnector.plugin.velocity.lib.players.PlayerService; @@ -354,6 +356,8 @@ public Callable connectors(AESCryptor cryptor, MessageCacheService cac Map handlers = new HashMap<>(); handlers.put(PacketType.PING, new MagicLinkPingHandler()); handlers.put(PacketType.SEND_PLAYER, new SendPlayerHandler()); + handlers.put(PacketType.LOCK_SERVER, new LockServerHandler()); + handlers.put(PacketType.UNLOCK_SERVER, new UnlockServerHandler()); connectorsService.messengers().forEach(connector -> { if(connector.connection().isEmpty()) return; diff --git a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/central/command/CommandRusty.java b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/central/command/CommandRusty.java index 5abc86143..74111379f 100644 --- a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/central/command/CommandRusty.java +++ b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/central/command/CommandRusty.java @@ -190,6 +190,25 @@ public static BrigadierCommand create(Flame flame, PluginLogger logger) { return 1; }) ) + .then(LiteralArgumentBuilder.literal("locked") + .executes(context -> { + try { + String familyName = context.getArgument("familyName", String.class); + BaseServerFamily family = flame.services().familyService().find(familyName); + if(family == null) throw new NullPointerException(); + + if(family instanceof ScalarServerFamily) + VelocityLang.RC_SCALAR_FAMILY_INFO_LOCKED.send(logger, (ScalarServerFamily) family); + if(family instanceof StaticServerFamily) + VelocityLang.RC_STATIC_FAMILY_INFO_LOCKED.send(logger, (StaticServerFamily) family); + } catch (NullPointerException e) { + VelocityLang.RC_FAMILY_ERROR.send(logger,"A family with that name doesn't exist!"); + } catch (Exception e) { + VelocityLang.RC_FAMILY_ERROR.send(logger,"Something prevented us from doing that!\n"+e.getMessage()); + } + return 1; + }) + ) ) ) .then(LiteralArgumentBuilder.literal("parties") diff --git a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/family/bases/BaseServerFamily.java b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/family/bases/BaseServerFamily.java index 011f65674..8a851627b 100644 --- a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/family/bases/BaseServerFamily.java +++ b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/family/bases/BaseServerFamily.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; import java.util.List; import java.util.Objects; diff --git a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/family/bases/PlayerFocusedServerFamily.java b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/family/bases/PlayerFocusedServerFamily.java index 793456238..7999b7fee 100644 --- a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/family/bases/PlayerFocusedServerFamily.java +++ b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/family/bases/PlayerFocusedServerFamily.java @@ -27,6 +27,8 @@ public abstract class PlayerFocusedServerFamily extends BaseServerFamily lockedServers = new ArrayList<>(); protected PlayerFocusedServerFamily(String name, Whitelist whitelist, Class clazz, boolean weighted, boolean persistence, int attempts, String parentName) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { super(name); @@ -88,7 +90,7 @@ public Whitelist whitelist() { return api.services().whitelistService().find(this.whitelist); } - public long serverCount() { return this.loadBalancer.size(); } + public long serverCount() { return this.registeredServers().size(); } @Override public long playerCount() { @@ -100,9 +102,14 @@ public long playerCount() { @Override public List registeredServers() { - return this.loadBalancer.dump(); + List servers = new ArrayList<>(); + servers.addAll(this.loadBalancer.dump()); + servers.addAll(this.lockedServers); + return servers; } + public List lockedServers() { return this.lockedServers;} + @Override public void addServer(PlayerServer server) { this.loadBalancer.add(server); @@ -111,6 +118,28 @@ public void addServer(PlayerServer server) { @Override public void removeServer(PlayerServer server) { this.loadBalancer.remove(server); + this.lockedServers.remove(server); + } + + public void unlockServer(PlayerServer server) { + if (!this.lockedServers.contains(server)) return; + this.lockedServers.remove(server); + this.loadBalancer.add(server); + + this.loadBalancer.completeSort(); + } + + public void lockServer(PlayerServer server) { + if (!this.loadBalancer.dump().contains(server)) return; + this.loadBalancer.remove(server); + this.lockedServers.add(server); + + this.loadBalancer.completeSort(); + } + + public boolean joinable(PlayerServer server) { + if (!this.registeredServers().contains(server)) return false; + return !this.lockedServers.contains(server); } @Override diff --git a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/lang/VelocityLang.java b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/lang/VelocityLang.java index 2ceed7551..28f4199f8 100644 --- a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/lang/VelocityLang.java +++ b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/lang/VelocityLang.java @@ -371,7 +371,8 @@ public final static JoinConfiguration newlines() { if(family.registeredServers() == null) servers = resolver().get("velocity.family.scalar_family.panel.no_registered_servers"); else if(family.registeredServers().size() == 0) servers = resolver().get("velocity.family.scalar_family.panel.no_registered_servers"); - else for (PlayerServer server : family.registeredServers()) { + else if(family.loadBalancer().size() == 0) servers = resolver().get("velocity.family.scalar_family.panel.no_unlocked_servers"); + else for (PlayerServer server : family.loadBalancer().dump()) { if(family.loadBalancer().index() == i) servers = servers.append( text(" ---| "+(i + 1)+". ["+server.registeredServer().getServerInfo().getName()+"]" + @@ -409,6 +410,7 @@ else for (PlayerServer server : family.registeredServers()) { "velocity.family.scalar_family.panel.info", LanguageResolver.tagHandler("player_count", family.playerCount()), LanguageResolver.tagHandler("server_count", family.serverCount()), + LanguageResolver.tagHandler("joinable_count", family.loadBalancer().size()), LanguageResolver.tagHandler("parent_family_name", parentFamilyName), LanguageResolver.tagHandler("balancing_algorithm", family.loadBalancer()), LanguageResolver.tagHandler("weighted", family.isWeighted()), @@ -426,6 +428,74 @@ else for (PlayerServer server : family.registeredServers()) { text("/rc family resetIndex", GOLD), resolver().get("velocity.family.scalar_family.panel.commands.reset_index"), SPACING, + text("/rc family locked", GOLD), + resolver().get("velocity.family.scalar_family.panel.commands.locked"), + SPACING, + servers, + SPACING, + BORDER + ); + }; + + public final static ParameterizedMessage1 RC_SCALAR_FAMILY_INFO_LOCKED = (family) -> { + Component servers = text(""); + int i = 0; + + if(family.registeredServers() == null) servers = resolver().get("velocity.family.scalar_family.panel.no_registered_servers"); + else if(family.registeredServers().size() == 0) servers = resolver().get("velocity.family.scalar_family.panel.no_registered_servers"); + else if(family.lockedServers().size() == 0) servers = resolver().get("velocity.family.scalar_family.panel.no_locked_servers"); + else for (PlayerServer server : family.lockedServers()) { + servers = servers.append( + text(" ---| "+(i + 1)+". ["+server.registeredServer().getServerInfo().getName()+"]" + + "("+ AddressUtil.addressToString(server.registeredServer().getServerInfo().getAddress()) +") " + + "["+server.playerCount()+" ("+server.softPlayerCap()+" <> "+server.hardPlayerCap()+") w-"+server.weight()+"]" + , RED)); + + servers = servers.append(newline()); + + i++; + } + + RootServerFamily rootFamily = Tinder.get().services().familyService().rootFamily(); + String parentFamilyName = rootFamily.name(); + try { + parentFamilyName = Objects.requireNonNull(family.parent().get()).name(); + } catch (Exception ignore) {} + if(family.equals(rootFamily)) parentFamilyName = "none"; + + return join( + newlines(), + BORDER, + SPACING, + ASCIIAlphabet.generate(family.name(), AQUA), + SPACING, + BORDER, + SPACING, + resolver().getArray( + "velocity.family.scalar_family.panel.info", + LanguageResolver.tagHandler("player_count", family.playerCount()), + LanguageResolver.tagHandler("server_count", family.serverCount()), + LanguageResolver.tagHandler("joinable_count", family.loadBalancer().size()), + LanguageResolver.tagHandler("parent_family_name", parentFamilyName), + LanguageResolver.tagHandler("balancing_algorithm", family.loadBalancer()), + LanguageResolver.tagHandler("weighted", family.isWeighted()), + LanguageResolver.tagHandler("persistence", family.loadBalancer().persistent()), + LanguageResolver.tagHandler("persistence_attempts", family.loadBalancer().attempts()) + ), + SPACING, + BORDER, + SPACING, + resolver().get("velocity.family.scalar_family.panel.registered_servers"), + SPACING, + text("/rc family sort", GOLD), + resolver().get("velocity.family.scalar_family.panel.commands.sort"), + SPACING, + text("/rc family resetIndex", GOLD), + resolver().get("velocity.family.scalar_family.panel.commands.reset_index"), + SPACING, + text("/rc family locked", GOLD), + resolver().get("velocity.family.scalar_family.panel.commands.locked"), + SPACING, servers, SPACING, BORDER @@ -438,7 +508,8 @@ else for (PlayerServer server : family.registeredServers()) { if(family.registeredServers() == null) servers = resolver().get("velocity.family.static_family.panel.no_registered_servers"); else if(family.registeredServers().size() == 0) servers = resolver().get("velocity.family.static_family.panel.no_registered_servers"); - else for (PlayerServer server : family.registeredServers()) { + else if(family.loadBalancer().size() == 0) servers = resolver().get("velocity.family.static_family.panel.no_unlocked_servers"); + else for (PlayerServer server : family.loadBalancer().dump()) { if(family.loadBalancer().index() == i) servers = servers.append( text(" ---| "+(i + 1)+". ["+server.registeredServer().getServerInfo().getName()+"]" + @@ -480,6 +551,7 @@ else for (PlayerServer server : family.registeredServers()) { "velocity.family.static_family.panel.info", LanguageResolver.tagHandler("player_count", family.playerCount()), LanguageResolver.tagHandler("server_count", family.serverCount()), + LanguageResolver.tagHandler("joinable_count", family.loadBalancer().size()), LanguageResolver.tagHandler("parent_family_name", parentFamilyName), LanguageResolver.tagHandler("residence_expiration", homeServerExpiration), LanguageResolver.tagHandler("balancing_algorithm", family.loadBalancer()), @@ -498,6 +570,79 @@ else for (PlayerServer server : family.registeredServers()) { text("/rc family resetIndex", GOLD), resolver().get("velocity.family.static_family.panel.commands.reset_index"), SPACING, + text("/rc family locked", GOLD), + resolver().get("velocity.family.static_family.panel.commands.locked"), + SPACING, + servers, + SPACING, + BORDER + ); + }; + + public final static ParameterizedMessage1 RC_STATIC_FAMILY_INFO_LOCKED = (family) -> { + Component servers = text(""); + int i = 0; + + if(family.registeredServers() == null) servers = resolver().get("velocity.family.static_family.panel.no_registered_servers"); + else if(family.registeredServers().size() == 0) servers = resolver().get("velocity.family.static_family.panel.no_registered_servers"); + else if(family.lockedServers().size() == 0) servers = resolver().get("velocity.family.static_family.panel.no_locked_servers"); + else for (PlayerServer server : family.lockedServers()) { + servers = servers.append( + text(" ---| "+(i + 1)+". ["+server.registeredServer().getServerInfo().getName()+"]" + + "("+ AddressUtil.addressToString(server.registeredServer().getServerInfo().getAddress()) +") " + + "["+server.playerCount()+" ("+server.softPlayerCap()+" <> "+server.hardPlayerCap()+") w-"+server.weight()+"]" + , RED)); + + servers = servers.append(newline()); + + i++; + } + + RootServerFamily rootFamily = Tinder.get().services().familyService().rootFamily(); + String parentFamilyName = rootFamily.name(); + try { + parentFamilyName = Objects.requireNonNull(family.parent().get()).name(); + } catch (Exception ignore) {} + if(family.equals(rootFamily)) parentFamilyName = "none"; + + LiquidTimestamp expiration = family.homeServerExpiration(); + String homeServerExpiration = "NEVER"; + if(expiration != null) homeServerExpiration = expiration.toString(); + + return join( + newlines(), + BORDER, + SPACING, + ASCIIAlphabet.generate(family.name(), AQUA), + SPACING, + BORDER, + SPACING, + resolver().getArray( + "velocity.family.static_family.panel.info", + LanguageResolver.tagHandler("player_count", family.playerCount()), + LanguageResolver.tagHandler("server_count", family.serverCount()), + LanguageResolver.tagHandler("joinable_count", family.loadBalancer().size()), + LanguageResolver.tagHandler("parent_family_name", parentFamilyName), + LanguageResolver.tagHandler("residence_expiration", homeServerExpiration), + LanguageResolver.tagHandler("balancing_algorithm", family.loadBalancer()), + LanguageResolver.tagHandler("weighted", family.isWeighted()), + LanguageResolver.tagHandler("persistence", family.loadBalancer().persistent()), + LanguageResolver.tagHandler("persistence_attempts", family.loadBalancer().attempts()) + ), + SPACING, + BORDER, + SPACING, + resolver().get("velocity.family.static_family.panel.registered_servers"), + SPACING, + text("/rc family sort", GOLD), + resolver().get("velocity.family.static_family.panel.commands.sort"), + SPACING, + text("/rc family resetIndex", GOLD), + resolver().get("velocity.family.static_family.panel.commands.reset_index"), + SPACING, + text("/rc family locked", GOLD), + resolver().get("velocity.family.static_family.panel.commands.locked"), + SPACING, servers, SPACING, BORDER diff --git a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/load_balancing/LoadBalancer.java b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/load_balancing/LoadBalancer.java index 4979f8a92..ac94da9fe 100644 --- a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/load_balancing/LoadBalancer.java +++ b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/load_balancing/LoadBalancer.java @@ -32,8 +32,8 @@ public boolean weighted() { public PlayerServer current() { PlayerServer item; if(this.index >= this.size()) { - item = this.items.get(this.index); this.index = 0; + item = this.items.get(this.index); } else item = this.items.get(this.index); assert item != null; diff --git a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/message/handling/LockServerHandler.java b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/message/handling/LockServerHandler.java new file mode 100644 index 000000000..574d85d3c --- /dev/null +++ b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/message/handling/LockServerHandler.java @@ -0,0 +1,25 @@ +package group.aelysium.rustyconnector.plugin.velocity.lib.message.handling; + +import com.velocitypowered.api.proxy.server.ServerInfo; +import group.aelysium.rustyconnector.core.lib.packets.GenericPacket; +import group.aelysium.rustyconnector.core.lib.packets.PacketHandler; +import group.aelysium.rustyconnector.core.lib.packets.variants.LockServerPacket; +import group.aelysium.rustyconnector.plugin.velocity.central.Tinder; +import group.aelysium.rustyconnector.plugin.velocity.lib.family.bases.PlayerFocusedServerFamily; +import group.aelysium.rustyconnector.plugin.velocity.lib.server.PlayerServer; + +public class LockServerHandler extends PacketHandler { + @Override + public void execute(GenericPacket genericPacket) throws Exception { + LockServerPacket packet = (LockServerPacket) genericPacket; + Tinder api = Tinder.get(); + + ServerInfo serverInfo = new ServerInfo(packet.serverName(), packet.address()); + PlayerServer server = api.services().serverService().search(serverInfo); + + if (server != null) { + PlayerFocusedServerFamily family = (PlayerFocusedServerFamily) server.family(); + family.lockServer(server); + } + } +} diff --git a/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/message/handling/UnlockServerHandler.java b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/message/handling/UnlockServerHandler.java new file mode 100644 index 000000000..e8b8e20ae --- /dev/null +++ b/plugin/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/message/handling/UnlockServerHandler.java @@ -0,0 +1,25 @@ +package group.aelysium.rustyconnector.plugin.velocity.lib.message.handling; + +import com.velocitypowered.api.proxy.server.ServerInfo; +import group.aelysium.rustyconnector.core.lib.packets.GenericPacket; +import group.aelysium.rustyconnector.core.lib.packets.PacketHandler; +import group.aelysium.rustyconnector.core.lib.packets.variants.UnlockServerPacket; +import group.aelysium.rustyconnector.plugin.velocity.central.Tinder; +import group.aelysium.rustyconnector.plugin.velocity.lib.family.bases.PlayerFocusedServerFamily; +import group.aelysium.rustyconnector.plugin.velocity.lib.server.PlayerServer; + +public class UnlockServerHandler extends PacketHandler { + @Override + public void execute(GenericPacket genericPacket) throws Exception { + UnlockServerPacket packet = (UnlockServerPacket) genericPacket; + Tinder api = Tinder.get(); + + ServerInfo serverInfo = new ServerInfo(packet.serverName(), packet.address()); + PlayerServer server = api.services().serverService().search(serverInfo); + + if (server != null) { + PlayerFocusedServerFamily family = (PlayerFocusedServerFamily) server.family(); + family.unlockServer(server); + } + } +} diff --git a/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/boot_loader/BootLoader.java b/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/boot_loader/BootLoader.java deleted file mode 100644 index e18366b96..000000000 --- a/velocity/src/main/java/group/aelysium/rustyconnector/plugin/velocity/lib/boot_loader/BootLoader.java +++ /dev/null @@ -1,23 +0,0 @@ -package group.aelysium.rustyconnector.plugin.velocity.lib.boot_loader; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; - -public class BootLoader { - private int amount = 0; - - public void incrementFive() { - this.amount = this.amount + 5; - if(this.amount > 100) this.amount = 100; - } - - public Component print() { - StringBuilder filled = new StringBuilder(); - StringBuilder empty = new StringBuilder(); - for (int i = 0; i < 20; i++) { - if(i < this.amount * 0.1) filled.append("█"); - else empty.append("-"); - } - return Component.text("Loading: ["+filled + empty+"] "+this.amount+"%", NamedTextColor.GRAY); - } -}