package com.lifeknight.relaymcbungeemain.utilities; import com.lifeknight.relaymcbungeemain.Main; import com.lifeknight.relaymcbungeemain.network.MessageServerHandler; import com.lifeknight.relaymcbungeemain.player.SmartPlayer; import com.lifeknight.relaymcbungeemain.queue.GameServer; import com.lifeknight.relaymcbungeemain.queue.ServerDetails; import com.lifeknight.relayutils.RelayUtils; import com.lifeknight.relayutils.basic.Miscellaneous; import com.lifeknight.relayutils.game.GameDetails; import com.lifeknight.relayutils.game.MainGame; import com.lifeknight.relayutils.network.Command; import com.lifeknight.relayutils.network.Recipient; import com.lifeknight.relayutils.utilities.ComponentBuilder; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.hover.content.Text; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.ProxiedPlayer; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; public class Server { public static final List SERVERS = new ArrayList<>(); private final String name; private final MainGame mainGame; private final ServerType serverType; private int memoryGB = 3; private boolean availableForPlayers = true; private boolean messageClientActive; public Server(String name, MainGame mainGame, ServerType serverType) { this.name = name; this.mainGame = mainGame; this.serverType = serverType; SERVERS.add(this); } public static void removeServer(ServerInfo serverInfo) { SERVERS.remove(getServer(serverInfo)); Main.save(); } public static boolean allHubsAreFull() { for (Server hubServer : Server.getHubServers()) { if (hubServer.hasSufficientSpace()) { return false; } } return true; } public String getName() { return this.name; } public boolean isHub() { return serverType == ServerType.HUB; } public ServerInfo getServerInfo() { ServerInfo serverInfo = ProxyServer.getInstance().getServerInfo(this.name); if (serverInfo == null && this.isHub()) { Main.warn("Null serverinfo for %s", this.name); } return serverInfo; } public Recipient getRecipient() { return Recipient.getRecipient(this.name); } public int getPlayerCount() { return this.getServerInfo() == null ? 0 : this.getServerInfo().getPlayers().size(); } public boolean isEmpty() { return this.getPlayerCount() == 0; } private static final List IGNORABLE = Miscellaneous.getList(MainGame.DUELS); public boolean isViable(int playerCount) { if (IGNORABLE.contains(this.mainGame)) { return true; } if (RelayUtils.testing) { return true; } if (this.getPlayerCount() == 0) { return true; } if (this.isHub()) { return this.getPlayerCount() + playerCount <= RelayUtils.HUB_DEFAULT_MAX_SIZE; } if (this.mainGame == MainGame.MANHUNT) { return (this.getPlayerCount() + playerCount <= 6); } return (this.getPlayerCount() + playerCount <= 32); } public MainGame getMainGame() { return this.mainGame; } public int getMemoryGB() { return this.memoryGB; } public void setMemoryGB(int memoryGB) { this.memoryGB = memoryGB; } public InetSocketAddress getSocketAddress() { return this.getServerInfo() == null ? null : (InetSocketAddress) this.getServerInfo().getSocketAddress(); } public Server getHub() { if (this.isHub()) { return getServerOfType(null, false); } return getServerOfType(this.mainGame, false); } public String getNameForInfo() { return this.mainGame == null ? "Main" : this.mainGame.getName(); } public void sendMessage(Command command, Object... arguments) { if (this.isMessageClientActive()) { MessageUtils.createAndSend(this.getRecipient(), command, arguments); } else { Main.warn("Attempted to send %s message to %s, message client inactive.", command, this.name); } } public boolean canSend() { return this.isActive() && this.hasServerInfo() && this.hasSufficientSpace(); } public boolean hasSufficientSpace() { if (this.isHub()) { return this.getPlayerCount() < RelayUtils.HUB_DEFAULT_MAX_SIZE; } return true; } public boolean hasServerInfo() { return this.getServerInfo() != null; } public void setAvailableForPlayers(boolean availableForPlayers) { this.availableForPlayers = availableForPlayers; } public boolean isActive() { return this.availableForPlayers && this.messageClientActive; } public boolean isMessageClientActive() { return this.messageClientActive && MessageServerHandler.CHANNELS.containsKey(this.name); } public void setMessageClientActive(boolean messageClientActive) { this.messageClientActive = messageClientActive; } public void start() { Main.info("Sent instructions via pterodactyl to start server %s.", this.getName()); } public static Server getServer(String name) { if (name == null) { return null; } return Miscellaneous.match(SERVERS, server -> name.equalsIgnoreCase(server.name)); } public static Server getServer(ServerInfo serverInfo) { if (serverInfo == null) { return null; } for (Server server : SERVERS) { if (serverInfo.equals(server.getServerInfo())) return server; } return new Server(serverInfo.getName(), null, ServerType.LIMBO); } public static Server getServerFromIP(String ip) { int port = 25565; if (ip.contains(":")) { String[] data = ip.split(":"); try { port = Integer.parseInt(data[1]); } catch (Exception exception) { Main.error("Could not parse port: %s", ip); } ip = data[0]; } ProxyServer proxyServer = ProxyServer.getInstance(); if (proxyServer.getServers() != null) { for (ServerInfo serverInfo : ProxyServer.getInstance().getServers().values()) { InetSocketAddress serverAddress = (InetSocketAddress) serverInfo.getSocketAddress(); if (serverAddress != null) { InetAddress inetAddress = serverAddress.getAddress(); if (inetAddress != null) { String ip2 = inetAddress.getHostAddress(); if (ip.equals(ip2) && port == serverAddress.getPort()) { return getServer(serverInfo); } } } } } return null; } public static void clear() { SERVERS.clear(); } public static List getAvailableServersOfType(MainGame mainGame, boolean gameSever) { List applicableServers = new ArrayList<>(); for (Server server : SERVERS) { if (!server.isLimbo() && server.canSend() && server.mainGame == mainGame && ((gameSever && !server.isHub()) || (!gameSever && server.isHub()))) { applicableServers.add(server); } } if (applicableServers.isEmpty() && mainGame != null) { //Main.info("Applicable servers empty (1): %s %s", mainGame, gameSever); applicableServers = getAvailableServersOfType(null, false); } if (applicableServers.isEmpty()) { //Main.info("Applicable servers empty (2): %s %s", mainGame, gameSever); for (Server server : SERVERS) { if (!server.isLimbo() && server.messageClientActive && server.availableForPlayers && server.mainGame == mainGame && ((gameSever && !server.isHub()) || (!gameSever && server.isHub()))) { applicableServers.add(server); } } } return applicableServers; } public static List getServersOfType(MainGame mainGame, boolean gameSever) { return Miscellaneous.filter(SERVERS, server -> server.mainGame == mainGame && ((gameSever && !server.isHub()) || (!gameSever && server.isHub()))); } public static Server getServerOfType(MainGame mainGame, boolean gameServer) { return Miscellaneous.getFirstEntry(getAvailableServersOfType(mainGame, gameServer)); } public static List getHubServers() { List hubServers = new ArrayList<>(); for (Server server : SERVERS) { if (server.isHub()) { Miscellaneous.addIfAbsent(hubServers, server); } } return hubServers; } public static List getGameServers() { List gameServers = new ArrayList<>(); for (Server server : SERVERS) { if (!server.isHub()) { Miscellaneous.addIfAbsent(gameServers, server); } } return gameServers; } public static void create(String name, MainGame mainGame, ServerType serverType) { if (getServer(name) == null) { new Server(name, mainGame, serverType); } } public int getAvailability() { if (!this.availableForPlayers || !this.messageClientActive) { return 0; } if (this.isHub()) { if (this.getPlayerCount() >= RelayUtils.HUB_DEFAULT_MAX_SIZE) { return 1; } else if (this.getPlayerCount() >= RelayUtils.HUB_EXTENDED_MAX_SIZE) { return 0; } return -1; } GameServer gameServer = GameServer.getGameServer(this.getRecipient()); if (gameServer != null) { ServerDetails serverDetails = gameServer.getServerDetails(); double fullCount = 0; double used = 0; for (GameDetails gameDetail : serverDetails.gameDetails) { if (!gameDetail.isAvailable()) { used++; } fullCount++; } if (used / fullCount >= 0.75) { return 1; } else if (used / fullCount >= 0.25) { return 0; } return -1; } return 0; } public BaseComponent getComponent() { ComponentBuilder componentBuilder = new ComponentBuilder(" "); TextComponent hover = new TextComponent(RelayUtils.format("%s[%s%s%s] ", ChatColor.GRAY, this.getChatColorForName(), this.getName(), ChatColor.GRAY)); hover.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new BaseComponent[]{this.getHover()}))); componentBuilder.appendComponent(hover); List players = this.getPlayers(); for (int i = 0; i < players.size(); i++) { SmartPlayer smartPlayer = players.get(i); componentBuilder.command(smartPlayer.getFormattedNameColor() + smartPlayer.getName(), "/spectate " + smartPlayer.getName(), "Spectate " + smartPlayer.getFormattedName() + ChatColor.WHITE + "."); if (i != players.size() - 1) { componentBuilder.append(", "); } } return componentBuilder.getResult(); } public BaseComponent getHover() { if (this.isHub()) { return new ComponentBuilder("%s%d%s/%d", this.getChatColorForName().toString(), this.getPlayerCount(), ChatColor.WHITE, RelayUtils.HUB_DEFAULT_MAX_SIZE).getResult(); } GameServer gameServer = GameServer.getGameServer(this.getRecipient()); if (gameServer != null) { return gameServer.getServerDetails().getComponent(); } return new TextComponent(this.getPlayerCount() + " players"); } public List getProxiedPlayers() { return this.getServerInfo() == null ? new ArrayList<>() : Miscellaneous.getList(this.getServerInfo().getPlayers()); } public List getPlayers() { return Miscellaneous.processList(this.getProxiedPlayers(), SmartPlayer::getSmartPlayer); } public ChatColor getChatColorForName() { return switch (this.getAvailability()) { case -1 -> ChatColor.GREEN; case 0 -> ChatColor.YELLOW; default -> ChatColor.RED; }; } public static Server getLimboServer() { Server best = null; for (Server limboServer : getLimboServers()) { if (limboServer.messageClientActive && limboServer.availableForPlayers) { if (best == null || limboServer.getPlayerCount() < best.getPlayerCount()) { best = limboServer; } } } if (best != null) { return best; } return Miscellaneous.getRandomEntry(getLimboServers()); } public static List getLimboServers() { return Miscellaneous.filter(SERVERS, server -> server.serverType == ServerType.LIMBO); } public boolean isLimbo() { return this.serverType == ServerType.LIMBO; } }