Move server ping cache storage to the AdaptedServer instance

This commit is contained in:
ajgeiss0702
2022-08-15 13:41:32 -07:00
parent 6a99349718
commit 478f2cf78d
23 changed files with 549 additions and 409 deletions
@@ -73,7 +73,7 @@ public interface PlatformMethods {
*/ */
AdaptedServer getServer(String name); AdaptedServer getServer(String name);
List<AdaptedServer> getServers(); List<? extends AdaptedServer> getServers();
String getProtocolName(int protocol); String getProtocolName(int protocol);
} }
@@ -4,6 +4,7 @@ import us.ajg0702.queue.api.AjQueueAPI;
import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.players.QueuePlayer; import us.ajg0702.queue.api.players.QueuePlayer;
import us.ajg0702.queue.api.queues.QueueServer; import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.utils.common.Config; import us.ajg0702.utils.common.Config;
@SuppressWarnings({"SameReturnValue", "unused"}) @SuppressWarnings({"SameReturnValue", "unused"})
@@ -17,10 +18,12 @@ public interface Logic {
/** /**
* The priority logic that is executed if the plugin is premium. * The priority logic that is executed if the plugin is premium.
* @param server The server/group name that is being queued for *
* @param queueServer The server/group name that is being queued for
* @param player The player that is being queued * @param player The player that is being queued
* @param server The server/group name that is being queued for
*/ */
QueuePlayer priorityLogic(QueueServer server, AdaptedPlayer player); QueuePlayer priorityLogic(QueueServer queueServer, AdaptedPlayer player, AdaptedServer server);
/** /**
* The logic for checking if a player has been disconnected for too long * The logic for checking if a player has been disconnected for too long
@@ -35,7 +38,7 @@ public interface Logic {
*/ */
PermissionGetter getPermissionGetter(); PermissionGetter getPermissionGetter();
static int getUnJoinablePriorities(QueueServer server, AdaptedPlayer player) { static int getUnJoinablePriorities(QueueServer queueServer, AdaptedServer server, AdaptedPlayer player) {
Config config = AjQueueAPI.getInstance().getConfig(); Config config = AjQueueAPI.getInstance().getConfig();
int highest = 0; int highest = 0;
@@ -50,7 +53,7 @@ public interface Logic {
} }
if(bypassPausedPriotity > 0) { if(bypassPausedPriotity > 0) {
if(server.isPaused() && (player.hasPermission("ajqueue.bypasspaused"))) { if(queueServer.isPaused() && (player.hasPermission("ajqueue.bypasspaused"))) {
highest = Math.max(highest, bypassPausedPriotity); highest = Math.max(highest, bypassPausedPriotity);
} }
} }
@@ -50,17 +50,6 @@ public interface QueueServer {
*/ */
String getStatus(); String getStatus();
/**
* Sends a server ping and uses the response to update online status, player count status, and whitelist status
*/
void updatePing();
/**
* Gets the time the server has been offline, in miliseconds
* @return The number of miliseconds the server has been offline for
*/
int getOfflineTime();
/** /**
* Gets how long since the last person was sent * Gets how long since the last person was sent
* @return The number of miliseconds since the last person was sent * @return The number of miliseconds since the last person was sent
@@ -73,30 +62,6 @@ public interface QueueServer {
*/ */
void setLastSentTime(long lastSentTime); void setLastSentTime(long lastSentTime);
/**
* Gets if the server is whitelisted or not
* @return True if whitelisted, false if not
*/
boolean isWhitelisted();
/**
* Sets if the server is whitelisted or not
*/
void setWhitelisted(boolean whitelisted);
/**
* Gets the list of players who are whitelisted
* @return The list of player UUIDs who are whitelisted
*/
ImmutableList<UUID> getWhitelistedPlayers();
/**
* Sets the list of UUIDs that are whitelisted
*/
void setWhitelistedPlayers(List<UUID> whitelistedPlayers);
/** /**
* Checks if the server is joinable by a player * Checks if the server is joinable by a player
* @param p The player to see if they can join * @param p The player to see if they can join
@@ -116,24 +81,6 @@ public interface QueueServer {
*/ */
boolean isPaused(); boolean isPaused();
/**
* Checks if the server is online
* @return True if the server is online, false if not
*/
boolean isOnline();
/**
* Checks if the server went online within the time set in the config
* @return If the sevrer just came online
*/
boolean justWentOnline();
/**
* Checks if the server is full
* @return If the server is full
*/
boolean isFull();
/** /**
* Removes a player from the queue * Removes a player from the queue
* @param player The player to remove * @param player The player to remove
@@ -199,6 +146,16 @@ public interface QueueServer {
*/ */
ImmutableList<String> getServerNames(); ImmutableList<String> getServerNames();
/**
* Returns true if at least one server in the group is online
* @return true if the server is online
*/
default boolean isOnline() {
for (AdaptedServer server : getServers()) {
if(server.isOnline()) return true;
}
return false;
}
/** /**
* Returns if this server is a group * Returns if this server is a group
@@ -232,12 +189,6 @@ public interface QueueServer {
*/ */
AdaptedServer getIdealServer(AdaptedPlayer player); AdaptedServer getIdealServer(AdaptedPlayer player);
/**
* Gets the last server pings
* @return The last server pings for this server/group
*/
HashMap<AdaptedServer, AdaptedServerPing> getLastPings();
/** /**
* Gets the protocol versions this queue supports. * Gets the protocol versions this queue supports.
* A blank list means all protocols are supported. * A blank list means all protocols are supported.
@@ -258,26 +209,6 @@ public interface QueueServer {
*/ */
Balancer getBalancer(); Balancer getBalancer();
/**
* Checks if the player can join this server even if its full
* @param player The player
* @return If the player can join this server if its full
*/
boolean canJoinFull(AdaptedPlayer player);
/**
* Adds one to the player count for a server (temporarily until the next server ping)
*/
void addPlayer(AdaptedServer server);
/**
* Sets if this server is online.
* Note that this is overrided by the pinger, so if you set
* this, it will most likely be temporary
* @param online whether the server is online or not
*/
void setOnline(boolean online);
/** /**
* elliot is bad * elliot is bad
@@ -2,8 +2,9 @@ package us.ajg0702.queue.api.server;
import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.util.Handle; import us.ajg0702.queue.api.util.Handle;
import us.ajg0702.queue.api.util.QueueLogger;
import java.util.List; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@@ -25,7 +26,13 @@ public interface AdaptedServer extends Handle {
* Pings the server and gets info back * Pings the server and gets info back
* @return A CompletableFuture with the ServerPing * @return A CompletableFuture with the ServerPing
*/ */
CompletableFuture<AdaptedServerPing> ping(); default CompletableFuture<AdaptedServerPing> ping() {
return ping(false, null);
}
CompletableFuture<AdaptedServerPing> ping(boolean debug, QueueLogger logger);
Optional<AdaptedServerPing> getLastPing();
/** /**
* If the player can access the server * If the player can access the server
@@ -38,4 +45,102 @@ public interface AdaptedServer extends Handle {
boolean canAccess(AdaptedPlayer player); boolean canAccess(AdaptedPlayer player);
List<AdaptedPlayer> getPlayers(); List<AdaptedPlayer> getPlayers();
/**
* Gets the number of seconds this server has been offline
* @return The number of seconds this server has been offline
*/
int getOfflineTime();
boolean canJoinFull(AdaptedPlayer player);
boolean justWentOnline();
default boolean isJoinable(AdaptedPlayer player) {
if(player != null) {
if (isWhitelisted() && !getWhitelistedPlayers().contains(player.getUniqueId())) {
return false;
}
if (isFull() && !canJoinFull(player)) {
return false;
}
}
return isOnline() &&
canAccess(player);
}
default boolean isFull() {
if(!getLastPing().isPresent()) return false;
return getLastPing().get().getPlayerCount() >= getLastPing().get().getMaxPlayers();
}
/**
* Gets if the last ping was successfull
* (which almost always means the server is online)
* @return If the server is determined to be online or not
*/
default boolean isOnline() {
return getLastPing().isPresent();
}
/**
* Gets the number of players currently online
* @return The number of players online
*/
default int getPlayerCount() {
if(!getLastPing().isPresent()) return 0;
AdaptedServerPing ping = getLastPing().get();
return ping.getPlayerCount();
}
/**
* Gets the maximum number of players that can join this server.
* @return The maximum number of players that can join this server
*/
default int getMaxPlayers() {
if(!getLastPing().isPresent()) return 0;
AdaptedServerPing ping = getLastPing().get();
return ping.getMaxPlayers();
}
/**
* Temporarly adds one player to the player count
*/
default void addPlayer() {
if(!getLastPing().isPresent()) return;
getLastPing().get().addPlayer();
}
/**
* Checks if the spigot-side reports that the server is whitelisted
* @return True if the server is whitelisted
*/
default boolean isWhitelisted() {
if(!getLastPing().isPresent()) return false;
return getLastPing().get().getPlainDescription().contains("ajQueue;whitelisted=");
}
/**
* (if the server is whitelisted) returns the list of players that are whitelisted
* @return The list of players that are whitelisted
*/
default List<UUID> getWhitelistedPlayers() {
if(!getLastPing().isPresent()) return Collections.emptyList();
if(!isWhitelisted()) return Collections.emptyList();
List<UUID> uuids = new ArrayList<>();
for(String uuid : getLastPing().get().getPlainDescription().substring(20).split(",")) {
if(uuid.isEmpty()) continue;
UUID parsedUUID;
try {
parsedUUID = UUID.fromString(uuid);
} catch(IllegalArgumentException ignored) {
continue;
}
uuids.add(parsedUUID);
}
return uuids;
}
} }
@@ -12,7 +12,7 @@ public interface AdaptedServerPing extends Handle {
Component getDescriptionComponent(); Component getDescriptionComponent();
/** /**
* Gets the description stripped of any color or styling * Gets the description (aka MOTD) stripped of any color or styling
* @return The description, but no colors * @return The description, but no colors
*/ */
String getPlainDescription(); String getPlainDescription();
@@ -33,4 +33,10 @@ public interface AdaptedServerPing extends Handle {
* Temporarly adds one player to the player count * Temporarly adds one player to the player count
*/ */
void addPlayer(); void addPlayer();
/**
* Returns an epoch timestamp of when this ping was <bold>sent</bold>.
* @return A long of an epoch timestamp
*/
long getFetchedTime();
} }
@@ -8,4 +8,10 @@ public interface QueueLogger extends UtilsLogger {
void info(String message); void info(String message);
void error(String message); void error(String message);
void severe(String message); void severe(String message);
void warn(String message, Throwable t);
void warning(String message, Throwable t);
void info(String message, Throwable t);
void error(String message, Throwable t);
void severe(String message, Throwable t);
} }
@@ -3,6 +3,7 @@ package us.ajg0702.queue.commands.commands.manage.debug;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import us.ajg0702.queue.api.commands.ICommandSender; import us.ajg0702.queue.api.commands.ICommandSender;
import us.ajg0702.queue.api.queues.QueueServer; import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.commands.SubCommand; import us.ajg0702.queue.commands.SubCommand;
import us.ajg0702.queue.common.QueueMain; import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.utils.common.Messages; import us.ajg0702.utils.common.Messages;
@@ -48,7 +49,7 @@ public class Whitelist extends SubCommand {
sender.sendMessage(main.getMessages().toComponent("<red>Not enough args!")); sender.sendMessage(main.getMessages().toComponent("<red>Not enough args!"));
return; return;
} }
QueueServer server = main.getQueueManager().findServer(args[0]); AdaptedServer server = main.getPlatformMethods().getServer(args[0]);
if(server == null) { if(server == null) {
sender.sendMessage(main.getMessages().toComponent("<red>Server not found")); sender.sendMessage(main.getMessages().toComponent("<red>Server not found"));
return; return;
@@ -37,7 +37,7 @@ public class QueueManagerImpl implements QueueManager {
public List<QueueServer> buildServers() { public List<QueueServer> buildServers() {
List<QueueServer> result = new ArrayList<>(); List<QueueServer> result = new ArrayList<>();
List<AdaptedServer> servers = main.getPlatformMethods().getServers(); List<? extends AdaptedServer> servers = main.getPlatformMethods().getServers();
for(AdaptedServer server : servers) { for(AdaptedServer server : servers) {
QueueServer previousServer = main.getQueueManager().findServer(server.getName()); QueueServer previousServer = main.getQueueManager().findServer(server.getName());
@@ -49,9 +49,6 @@ public class QueueManagerImpl implements QueueManager {
if(previousServer != null) { if(previousServer != null) {
queueServer.setPaused(previousServer.isPaused()); queueServer.setPaused(previousServer.isPaused());
queueServer.setLastSentTime(previousServer.getLastSentTime()); queueServer.setLastSentTime(previousServer.getLastSentTime());
queueServer.setOnline(previousServer.isOnline());
queueServer.setWhitelisted(previousServer.isWhitelisted());
queueServer.setWhitelistedPlayers(previousServer.getWhitelistedPlayers());
} }
result.add(queueServer); result.add(queueServer);
} }
@@ -162,12 +159,13 @@ public class QueueManagerImpl implements QueueManager {
ImmutableList<QueuePlayer> list = server.getQueue(); ImmutableList<QueuePlayer> list = server.getQueue();
QueuePlayer queuePlayer; QueuePlayer queuePlayer;
AdaptedServer ideal = server.getIdealServer(player);
if(main.isPremium()) { if(main.isPremium()) {
queuePlayer = main.getLogic().priorityLogic(server, player); queuePlayer = main.getLogic().priorityLogic(server, player, ideal);
} else { } else {
int priority = player.hasPermission("ajqueue.priority") || int priority = player.hasPermission("ajqueue.priority") ||
player.hasPermission("ajqueue.serverpriority."+server.getName()) ? 1 : 0; player.hasPermission("ajqueue.serverpriority."+server.getName()) ? 1 : 0;
priority = Math.max(priority, Logic.getUnJoinablePriorities(server, player) > 0 ? 1 : 0); priority = Math.max(priority, Logic.getUnJoinablePriorities(server, ideal, player) > 0 ? 1 : 0);
int maxOfflineTime = player.hasPermission("ajqueue.stayqueued") ? 60 : 0; int maxOfflineTime = player.hasPermission("ajqueue.stayqueued") ? 60 : 0;
queuePlayer = new QueuePlayerImpl(player, server, priority, maxOfflineTime); queuePlayer = new QueuePlayerImpl(player, server, priority, maxOfflineTime);
if( if(
@@ -327,7 +325,7 @@ public class QueueManagerImpl implements QueueManager {
groupServers.add(found.getServers().get(0)); groupServers.add(found.getServers().get(0));
} }
if(servers.size() == 0) { if(groupServers.size() == 0) {
main.getLogger().warning("Server group '"+groupName+"' has no servers! Ignoring it."); main.getLogger().warning("Server group '"+groupName+"' has no servers! Ignoring it.");
continue; continue;
} }
@@ -349,7 +347,6 @@ public class QueueManagerImpl implements QueueManager {
if(!main.getConfig().getBoolean("send-actionbar")) return; if(!main.getConfig().getBoolean("send-actionbar")) return;
for(QueueServer server : servers) { for(QueueServer server : servers) {
String status = server.getStatusString();
for(QueuePlayer queuePlayer : server.getQueue()) { for(QueuePlayer queuePlayer : server.getQueue()) {
int pos = queuePlayer.getPosition(); int pos = queuePlayer.getPosition();
@@ -361,6 +358,8 @@ public class QueueManagerImpl implements QueueManager {
AdaptedPlayer player = queuePlayer.getPlayer(); AdaptedPlayer player = queuePlayer.getPlayer();
if(player == null) continue; if(player == null) continue;
String status = server.getStatusString(player);
QueueServer singleServer = getSingleServer(player); QueueServer singleServer = getSingleServer(player);
if(singleServer == null || !singleServer.equals(server)) continue; if(singleServer == null || !singleServer.equals(server)) continue;
@@ -512,8 +511,8 @@ public class QueueManagerImpl implements QueueManager {
+((ThreadPoolExecutor) pool).getActiveCount()+" threads"); +((ThreadPoolExecutor) pool).getActiveCount()+" threads");
} }
try { try {
for(QueueServer server : servers) { for(AdaptedServer server : main.getPlatformMethods().getServers()) {
pool.submit(server::updatePing); pool.submit(() -> server.ping(main.getConfig().getBoolean("pinger-debug"), main.getLogger()));
} }
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -556,22 +555,25 @@ public class QueueManagerImpl implements QueueManager {
server.removePlayer(queuePlayer); server.removePlayer(queuePlayer);
} }
} }
if(!server.isOnline()) continue; if(!server.isOnline()) continue;
if(server.getQueue().size() == 0) continue; if(server.getQueue().size() == 0) continue;
if(main.getConfig().getBoolean("send-all-when-back-online") && server.justWentOnline() && server.isOnline()) { if(!server.isGroup() && main.getConfig().getBoolean("send-all-when-back-online") && server.getServers().get(0).justWentOnline()) {
for(QueuePlayer p : server.getQueue()) { for(QueuePlayer p : server.getQueue()) {
AdaptedPlayer player = p.getPlayer(); AdaptedPlayer player = p.getPlayer();
if(player == null) continue; if(player == null) continue;
if(server.isFull() && !server.canJoinFull(p.getPlayer())) continue;
AdaptedServer selected = server.getIdealServer(player); AdaptedServer selected = server.getIdealServer(player);
if(selected == null) { if(selected == null) {
main.getLogger().severe("Could not find ideal server for server/group '"+server.getName()+"'!"); main.getLogger().severe("Could not find ideal server for server '"+server.getName()+"'!");
continue; continue;
} }
if(selected.isFull() && !selected.canJoinFull(p.getPlayer())) continue;
player.sendMessage(msgs.getComponent("status.sending-now", "SERVER:"+server.getAlias())); player.sendMessage(msgs.getComponent("status.sending-now", "SERVER:"+server.getAlias()));
player.connect(selected); player.connect(selected);
} }
@@ -606,11 +608,17 @@ public class QueueManagerImpl implements QueueManager {
if(nextPlayer == null) continue; // None of the players in the queue are online if(nextPlayer == null) continue; // None of the players in the queue are online
if(server.isWhitelisted() && !server.getWhitelistedPlayers().contains(nextPlayer.getUniqueId())) continue; AdaptedServer selected = server.getIdealServer(nextPlayer);
if(selected == null) {
main.getLogger().severe("Could not find ideal server for server/group '"+server.getName()+"'");
continue;
}
if(selected.isWhitelisted() && !selected.getWhitelistedPlayers().contains(nextPlayer.getUniqueId())) continue;
if(!server.canAccess(nextPlayer)) continue; if(!server.canAccess(nextPlayer)) continue;
if(server.isFull() && !server.canJoinFull(nextPlayer)) continue; if(selected.isFull() && !selected.canJoinFull(nextPlayer)) continue;
if(main.getConfig().getBoolean("enable-bypasspaused-permission")) { if(main.getConfig().getBoolean("enable-bypasspaused-permission")) {
if(server.isPaused() && !nextPlayer.hasPermission("ajqueue.bypasspaused")) continue; if(server.isPaused() && !nextPlayer.hasPermission("ajqueue.bypasspaused")) continue;
@@ -648,17 +656,11 @@ public class QueueManagerImpl implements QueueManager {
sendingNowAntiSpam.put(nextPlayer, System.currentTimeMillis()); sendingNowAntiSpam.put(nextPlayer, System.currentTimeMillis());
} }
AdaptedServer selected = server.getIdealServer(nextPlayer);
if(selected == null) {
main.getLogger().severe("Could not find ideal server for server/group '"+server.getName()+"'");
continue;
}
server.setLastSentTime(System.currentTimeMillis()); server.setLastSentTime(System.currentTimeMillis());
nextPlayer.connect(selected); nextPlayer.connect(selected);
server.addPlayer(selected); selected.addPlayer();
if(main.getConfig().getBoolean("debug")) { Debug.info(selected.getName()+" player count is now set to "+ selected.getPlayerCount());
Debug.info(selected.getName()+" player count is now set to "+ server.getLastPings().get(selected).getPlayerCount());
}
} }
} }
@@ -22,6 +22,20 @@ public class QueueServerImpl implements QueueServer {
private final String name; private final String name;
private final QueueMain main;
private final List<AdaptedServer> servers;
private final List<QueuePlayer> queue = new ArrayList<>();
private List<Integer> supportedProtocols = new ArrayList<>();
private Balancer balancer;
private boolean paused;
private long lastSentTime = 0;
public QueueServerImpl(String name, QueueMain main, AdaptedServer server, List<QueuePlayer> previousPlayers) { public QueueServerImpl(String name, QueueMain main, AdaptedServer server, List<QueuePlayer> previousPlayers) {
this(name, main, Collections.singletonList(server), previousPlayers); this(name, main, Collections.singletonList(server), previousPlayers);
} }
@@ -81,40 +95,6 @@ public class QueueServerImpl implements QueueServer {
} }
} }
private final QueueMain main;
private final HashMap<AdaptedServer, AdaptedServerPing> pings = new HashMap<>();
private final List<AdaptedServer> servers;
private final List<QueuePlayer> queue = new ArrayList<>();
private List<Integer> supportedProtocols = new ArrayList<>();
private Balancer balancer;
private int playerCount;
private int maxPlayers;
private boolean online;
private boolean paused;
private long lastUpdate = 0;
private int offlineTime = 0;
private long lastSentTime = 0;
private long lastOffline;
boolean whitelisted = false;
List<UUID> whitelistedUUIDs = new ArrayList<>();
@Override @Override
public ImmutableList<QueuePlayer> getQueue() { public ImmutableList<QueuePlayer> getQueue() {
return ImmutableList.copyOf(queue); return ImmutableList.copyOf(queue);
@@ -123,12 +103,13 @@ public class QueueServerImpl implements QueueServer {
@Override @Override
public String getStatusString(AdaptedPlayer p) { public String getStatusString(AdaptedPlayer p) {
Messages msgs = main.getMessages(); Messages msgs = main.getMessages();
AdaptedServer server = getIdealServer(p);
if(getOfflineTime() > main.getConfig().getInt("offline-time")) { if(server.getOfflineTime() > main.getConfig().getInt("offline-time")) {
return msgs.getString("status.offline.offline"); return msgs.getString("status.offline.offline");
} }
if(!isOnline()) { if(!server.isOnline()) {
return msgs.getString("status.offline.restarting"); return msgs.getString("status.offline.restarting");
} }
@@ -136,11 +117,11 @@ public class QueueServerImpl implements QueueServer {
return msgs.getString("status.offline.paused"); return msgs.getString("status.offline.paused");
} }
if(p != null && isWhitelisted() && !getWhitelistedPlayers().contains(p.getUniqueId())) { if(p != null && server.isWhitelisted() && !server.getWhitelistedPlayers().contains(p.getUniqueId())) {
return msgs.getString("status.offline.whitelisted"); return msgs.getString("status.offline.whitelisted");
} }
if(isFull() && !canJoinFull(p)) { if(server.isFull() && !server.canJoinFull(p)) {
return msgs.getString("status.offline.full"); return msgs.getString("status.offline.full");
} }
@@ -159,11 +140,12 @@ public class QueueServerImpl implements QueueServer {
@Override @Override
public String getStatus(AdaptedPlayer p) { public String getStatus(AdaptedPlayer p) {
if(getOfflineTime() > main.getConfig().getInt("offline-time")) { AdaptedServer server = getIdealServer(p);
if(server.getOfflineTime() > main.getConfig().getInt("offline-time")) {
return "offline"; return "offline";
} }
if(!isOnline()) { if(!server.isOnline()) {
return "restarting"; return "restarting";
} }
@@ -171,11 +153,11 @@ public class QueueServerImpl implements QueueServer {
return "paused"; return "paused";
} }
if(p != null && isWhitelisted() && !getWhitelistedPlayers().contains(p.getUniqueId())) { if(p != null && server.isWhitelisted() && !server.getWhitelistedPlayers().contains(p.getUniqueId())) {
return "whitelisted"; return "whitelisted";
} }
if(isFull() && !canJoinFull(p)) { if(server.isFull() && !server.canJoinFull(p)) {
return "full"; return "full";
} }
@@ -188,101 +170,7 @@ public class QueueServerImpl implements QueueServer {
@Override @Override
public String getStatus() { public String getStatus() {
return null; return getStatus(null);
}
@Override
public void updatePing() {
boolean pingerDebug = main.getConfig().getBoolean("pinger-debug");
HashMap<AdaptedServer, CompletableFuture<AdaptedServerPing>> pingsFutures = new HashMap<>();
for(AdaptedServer server : servers) {
if(pingerDebug) {
main.getLogger().info("[pinger] ["+server.getServerInfo().getName()+"] sending ping");
}
pingsFutures.put(server, server.ping());
}
int i = 0;
for(AdaptedServer server : pingsFutures.keySet()) {
CompletableFuture<AdaptedServerPing> futurePing = pingsFutures.get(server);
AdaptedServerPing ping = null;
try {
ping = futurePing.get(5, TimeUnit.SECONDS);
} catch (Exception e) {
if(pingerDebug) {
main.getLogger().info("[pinger] ["+server.getServerInfo().getName()+"] offline:");
e.printStackTrace();
}
}
if(ping != null && pingerDebug) {
main.getLogger().info("[pinger] ["+server.getServerInfo().getName()+"] online. motd: "+ping.getPlainDescription()+" players: "+ping.getPlayerCount()+"/"+ping.getMaxPlayers());
} else if(ping == null && pingerDebug) {
main.getLogger().info("[pinger] ["+server.getServerInfo().getName()+"] offline (unknown)");
}
pings.put(server, ping);
i++;
if(i == servers.size()) {
int onlineCount = 0;
playerCount = 0;
maxPlayers = 0;
for(AdaptedServer pingedServer : pings.keySet()) {
AdaptedServerPing serverPing = pings.get(pingedServer);
if(serverPing == null || serverPing.getPlainDescription() == null) {
if(serverPing != null) {
pings.put(pingedServer, null);
}
continue;
}
if(serverPing.getPlainDescription().contains("ajQueue;whitelisted=")) {
if(servers.size() > 1) continue;
setWhitelisted(true);
List<UUID> uuids = new ArrayList<>();
for(String uuid : serverPing.getPlainDescription().substring(20).split(",")) {
if(uuid.isEmpty()) continue;
UUID parsedUUID;
try {
parsedUUID = UUID.fromString(uuid);
} catch(IllegalArgumentException e) {
main.getLogger().warn("UUID '"+uuid+"' in whitelist of "+getName()+" is invalid! "+e.getMessage());
continue;
}
uuids.add(parsedUUID);
}
setWhitelistedPlayers(uuids);
} else {
setWhitelisted(false);
}
onlineCount++;
playerCount += serverPing.getPlayerCount();
maxPlayers += serverPing.getMaxPlayers();
}
online = onlineCount > 0;
if(lastUpdate == -1) {
lastUpdate = System.currentTimeMillis();
offlineTime = 0;
} else {
int timesincelast = (int) Math.round((System.currentTimeMillis() - lastUpdate*1.0)/1000);
lastUpdate = System.currentTimeMillis();
if(!online) {
offlineTime += timesincelast;
} else {
offlineTime = 0;
}
}
}
if(pingerDebug) {
main.getLogger().info("[pinger] ["+server.getServerInfo().getName()+"] Finished");
}
}
}
@Override
public int getOfflineTime() {
return offlineTime;
} }
@Override @Override
@@ -294,39 +182,11 @@ public class QueueServerImpl implements QueueServer {
this.lastSentTime = lastSentTime; this.lastSentTime = lastSentTime;
} }
@Override
public boolean isWhitelisted() {
return whitelisted;
}
@Override
public void setWhitelisted(boolean whitelisted) {
this.whitelisted = whitelisted;
}
@Override
public ImmutableList<UUID> getWhitelistedPlayers() {
return ImmutableList.copyOf(whitelistedUUIDs);
}
@Override
public synchronized void setWhitelistedPlayers(List<UUID> whitelistedPlayers) {
whitelistedUUIDs = whitelistedPlayers;
}
@Override @Override
public boolean isJoinable(AdaptedPlayer p) { public boolean isJoinable(AdaptedPlayer p) {
if(p != null) { AdaptedServer server = getIdealServer(p);
if (isWhitelisted() && !whitelistedUUIDs.contains(p.getUniqueId())) { if(server == null) return false;
return false; return server.isJoinable(p) && !isPaused();
}
if (isFull() && !canJoinFull(p)) {
return false;
}
}
return isOnline() &&
canAccess(p) &&
!isPaused();
} }
@Override @Override
@@ -339,28 +199,6 @@ public class QueueServerImpl implements QueueServer {
return paused; return paused;
} }
@Override
public boolean isOnline() {
if(System.currentTimeMillis()-lastOffline <= (main.getConfig().getInt("wait-after-online")*1000) && online) {
return false;
}
if(!online) {
lastOffline = System.currentTimeMillis();
}
return online;
}
@Override
public boolean justWentOnline() {
return System.currentTimeMillis()-lastOffline <= (main.getConfig().getDouble("wait-time")) && online;
}
@Override
public boolean isFull() {
if(!isOnline()) return false;
return playerCount >= maxPlayers;
}
@Override @Override
public synchronized void removePlayer(QueuePlayer player) { public synchronized void removePlayer(QueuePlayer player) {
main.getQueueManager().getSendingAttempts().remove(player); main.getQueueManager().getSendingAttempts().remove(player);
@@ -460,15 +298,9 @@ public class QueueServerImpl implements QueueServer {
@Override @Override
public AdaptedServer getIdealServer(AdaptedPlayer player) { public AdaptedServer getIdealServer(AdaptedPlayer player) {
Debug.info(getBalancer().toString());
return getBalancer().getIdealServer(player); return getBalancer().getIdealServer(player);
} }
@Override
public HashMap<AdaptedServer, AdaptedServerPing> getLastPings() {
return new HashMap<>(pings);
}
@Override @Override
public List<Integer> getSupportedProtocols() { public List<Integer> getSupportedProtocols() {
return new ArrayList<>(supportedProtocols); return new ArrayList<>(supportedProtocols);
@@ -484,26 +316,4 @@ public class QueueServerImpl implements QueueServer {
return balancer; return balancer;
} }
@Override
public boolean canJoinFull(AdaptedPlayer player) {
if(player == null) return true;
return
player.hasPermission("ajqueue.joinfull") ||
player.hasPermission("ajqueue.joinfullserver."+name) ||
player.hasPermission("ajqueue.joinfullandbypassserver."+name) ||
player.hasPermission("ajqueue.joinfullandbypass") ||
(main.isPremium() && main.getLogic().getPermissionGetter().hasUniqueFullBypass(player, name))
;
}
@Override
public void addPlayer(AdaptedServer server) {
if(!pings.containsKey(server)) throw new IllegalArgumentException("Server is not in this group!");
pings.get(server).addPlayer();
}
@Override
public void setOnline(boolean online) {
this.online = online;
}
} }
@@ -6,9 +6,11 @@ import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer; import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.api.server.AdaptedServerPing; import us.ajg0702.queue.api.server.AdaptedServerPing;
import us.ajg0702.queue.common.QueueMain; import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.queue.common.utils.Debug;
import us.ajg0702.utils.common.GenUtils; import us.ajg0702.utils.common.GenUtils;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
public class DefaultBalancer implements Balancer { public class DefaultBalancer implements Balancer {
@@ -21,29 +23,28 @@ public class DefaultBalancer implements Balancer {
@Override @Override
public AdaptedServer getIdealServer(AdaptedPlayer player) { public AdaptedServer getIdealServer(AdaptedPlayer player) {
HashMap<AdaptedServer, AdaptedServerPing> serverInfos = server.getLastPings(); List<AdaptedServer> servers = server.getServers();
AdaptedServer selected = null; AdaptedServer selected = null;
int selectednum = 0; int selectednum = 0;
if(serverInfos.keySet().size() == 1) { if(servers.size() == 1) {
selected = serverInfos.keySet().iterator().next(); selected = servers.get(0);
} else { } else {
for(AdaptedServer si : serverInfos.keySet()) { for(AdaptedServer sv : servers) {
AdaptedServerPing sp = serverInfos.get(si); if(!sv.isOnline()) continue;
if(sp == null) continue; int online = sv.getPlayerCount();
int online = sp.getPlayerCount();
if(selected == null) { if(selected == null) {
selected = si; selected = sv;
selectednum = online; selectednum = online;
continue; continue;
} }
if(selectednum > online && main.getQueueManager().findServer(si.getName()).isJoinable(player)) { if(selectednum > online && main.getQueueManager().findServer(sv.getName()).isJoinable(player)) {
selected = si; selected = sv;
selectednum = online; selectednum = online;
} }
} }
} }
if(selected == null && serverInfos.size() > 0) { if(selected == null && servers.size() > 0) {
selected = serverInfos.keySet().iterator().next(); selected = servers.get(0);
} }
if(selected == null) { if(selected == null) {
main.getLogger().warning("Unable to find ideal server, using random server from group."); main.getLogger().warning("Unable to find ideal server, using random server from group.");
@@ -20,34 +20,23 @@ public class MinigameBalancer implements Balancer {
@Override @Override
public AdaptedServer getIdealServer(AdaptedPlayer player) { public AdaptedServer getIdealServer(AdaptedPlayer player) {
HashMap<AdaptedServer, AdaptedServerPing> serverInfos = server.getLastPings(); List<AdaptedServer> servers = server.getServers();
if(serverInfos.keySet().size() == 1) { if(servers.size() == 1) {
return serverInfos.keySet().iterator().next(); return servers.get(0);
} else { } else {
List<Map.Entry<AdaptedServer, AdaptedServerPing>> servers = new ArrayList<>(serverInfos.entrySet()); List<AdaptedServer> svs = new ArrayList<>(servers);
servers.sort(Comparator.comparingInt(o -> { svs.sort(Comparator.comparingInt(o -> ((AdaptedServer)o).getPlayerCount()).reversed());
@SuppressWarnings("unchecked")
Map.Entry<AdaptedServer, AdaptedServerPing> e = (Map.Entry<AdaptedServer, AdaptedServerPing>) o;
AdaptedServerPing value = e.getValue();
if(value == null) return -1;
return value.getPlayerCount();
}).reversed());
LinkedHashMap<AdaptedServer, AdaptedServerPing> sortedServers = new LinkedHashMap<>();
for(Map.Entry<AdaptedServer, AdaptedServerPing> entry : servers) {
sortedServers.put(entry.getKey(), entry.getValue());
}
for(AdaptedServer si : sortedServers.keySet()) { for(AdaptedServer si : svs) {
AdaptedServerPing sp = sortedServers.get(si); if(!si.isOnline()) continue;
if(sp == null) continue; int online = si.getPlayerCount();
int online = sp.getPlayerCount(); int max = si.getMaxPlayers();
int max = sp.getMaxPlayers();
if(online < max) { if(online < max) {
return si; return si;
} }
} }
return new ArrayList<AdaptedServer>(sortedServers.keySet().size()).get(sortedServers.keySet().size()-1); return svs.get(svs.size()-1);
} }
} }
} }
@@ -5,6 +5,7 @@ import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.players.QueuePlayer; import us.ajg0702.queue.api.players.QueuePlayer;
import us.ajg0702.queue.api.premium.PermissionGetter; import us.ajg0702.queue.api.premium.PermissionGetter;
import us.ajg0702.queue.api.queues.QueueServer; import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer;
public class FreeLogic implements Logic { public class FreeLogic implements Logic {
@Override @Override
@@ -13,7 +14,7 @@ public class FreeLogic implements Logic {
} }
@Override @Override
public QueuePlayer priorityLogic(QueueServer server, AdaptedPlayer player) { public QueuePlayer priorityLogic(QueueServer queueServer, AdaptedPlayer player, AdaptedServer server) {
return null; return null;
} }
@@ -2,6 +2,7 @@ package us.ajg0702.queue.platforms.bungeecord;
import us.ajg0702.queue.api.util.QueueLogger; import us.ajg0702.queue.api.util.QueueLogger;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
public class BungeeLogger implements QueueLogger { public class BungeeLogger implements QueueLogger {
@@ -36,4 +37,29 @@ public class BungeeLogger implements QueueLogger {
public void severe(String message) { public void severe(String message) {
logger.severe(message); logger.severe(message);
} }
@Override
public void warn(String message, Throwable t) {
logger.log(Level.WARNING, message, t);
}
@Override
public void warning(String message, Throwable t) {
logger.log(Level.WARNING, message, t);
}
@Override
public void info(String message, Throwable t) {
logger.log(Level.INFO, message, t);
}
@Override
public void error(String message, Throwable t) {
logger.log(Level.SEVERE, message, t);
}
@Override
public void severe(String message, Throwable t) {
logger.log(Level.SEVERE, message, t);
}
} }
@@ -113,18 +113,44 @@ public class BungeeMethods implements PlatformMethods {
@Override @Override
public AdaptedServer getServer(String name) { public AdaptedServer getServer(String name) {
ServerInfo server = proxyServer.getServerInfo(name); List<? extends AdaptedServer> servers = getServers();
if(server == null) return null; for (AdaptedServer server : servers) {
return new BungeeServer(server); if(server.getName().equals(name)) return server;
}
return null;
} }
List<BungeeServer> serverList = new ArrayList<>();
@Override @Override
public List<AdaptedServer> getServers() { public List<? extends AdaptedServer> getServers() {
List<AdaptedServer> result = new ArrayList<>(); for (ServerInfo serverInfo : proxyServer.getServers().values()) {
boolean found = false;
for(BungeeServer sv : new ArrayList<>(serverList)) {
if(sv.getHandle().equals(serverInfo)) {
found = true;
break;
}
}
if(found) continue;
proxyServer.getServers().forEach((s, serverInfo) -> result.add(new BungeeServer(serverInfo))); serverList.add(new BungeeServer(serverInfo, plugin.getMain()));
}
return result; for(BungeeServer sv : new ArrayList<>(serverList)) {
boolean found = false;
for (ServerInfo serverInfo : proxyServer.getServers().values()) {
if(sv.getHandle().equals(serverInfo)) {
found = true;
break;
}
}
if(found) continue;
serverList.remove(sv);
}
return serverList;
} }
@Override @Override
@@ -145,7 +145,7 @@ public class BungeeQueue extends Plugin implements Listener, Implementation {
Component reason = BungeeComponentSerializer.get().deserialize(e.getKickReasonComponent()); Component reason = BungeeComponentSerializer.get().deserialize(e.getKickReasonComponent());
main.getEventHandler().onServerKick( main.getEventHandler().onServerKick(
new BungeePlayer(e.getPlayer()), new BungeePlayer(e.getPlayer()),
new BungeeServer(e.getKickedFrom()), new BungeeServer(e.getKickedFrom(), main),
reason, reason,
false false
); );
@@ -167,4 +167,8 @@ public class BungeeQueue extends Plugin implements Listener, Implementation {
getProxy().getPluginManager() getProxy().getPluginManager()
.registerCommand(this, bungeeCommand); .registerCommand(this, bungeeCommand);
} }
public QueueMain getMain() {
return main;
}
} }
@@ -6,20 +6,33 @@ import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.server.AdaptedServer; import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.api.server.AdaptedServerInfo; import us.ajg0702.queue.api.server.AdaptedServerInfo;
import us.ajg0702.queue.api.server.AdaptedServerPing; import us.ajg0702.queue.api.server.AdaptedServerPing;
import us.ajg0702.queue.api.util.QueueLogger;
import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.queue.platforms.bungeecord.players.BungeePlayer; import us.ajg0702.queue.platforms.bungeecord.players.BungeePlayer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class BungeeServer implements AdaptedServer { public class BungeeServer implements AdaptedServer {
final ServerInfo handle; private final ServerInfo handle;
final BungeeServerInfo serverInfo; private final BungeeServerInfo serverInfo;
public BungeeServer(ServerInfo handle) { private AdaptedServerPing lastPing = null;
private AdaptedServerPing lastSuccessfullPing = null;
private long lastOffline;
private int offlineTime = 0;
private final QueueMain main;
public BungeeServer(ServerInfo handle, QueueMain main) {
this.handle = handle; this.handle = handle;
serverInfo = new BungeeServerInfo(handle); serverInfo = new BungeeServerInfo(handle);
this.main = main;
} }
@Override @Override
@@ -33,19 +46,48 @@ public class BungeeServer implements AdaptedServer {
} }
@Override @Override
public CompletableFuture<AdaptedServerPing> ping() { public CompletableFuture<AdaptedServerPing> ping(boolean debug, QueueLogger logger) {
CompletableFuture<AdaptedServerPing> future = new CompletableFuture<>(); CompletableFuture<AdaptedServerPing> future = new CompletableFuture<>();
long sent = System.currentTimeMillis();
if(debug) logger.info("[pinger] [" + getName() + "] sending ping");
handle.ping((pp, error) -> { handle.ping((pp, error) -> {
if(error != null) { if(error != null) {
long lastOnline = lastSuccessfullPing == null ? 0 : lastSuccessfullPing.getFetchedTime();
offlineTime = (int) Math.min(sent - lastOnline, Integer.MAX_VALUE);
lastOffline = sent;
future.completeExceptionally(error); future.completeExceptionally(error);
lastPing = null;
if(debug) logger.info("[pinger] [" + getName() + "] offline:", error);
return; return;
} }
future.complete(new BungeeServerPing(pp)); offlineTime = 0;
BungeeServerPing ping = new BungeeServerPing(pp, sent);
lastSuccessfullPing = ping;
if(debug) logger.info(
"[pinger] [" + getName() + "] online. motd: "+ping.getPlainDescription()+" " +
" players: "+ping.getPlayerCount()+"/"+ping.getMaxPlayers()
);
future.complete(ping);
lastPing = ping;
}); });
return future; return future;
} }
@Override
public Optional<AdaptedServerPing> getLastPing() {
return Optional.ofNullable(lastPing);
}
@Override @Override
public boolean canAccess(AdaptedPlayer player) { public boolean canAccess(AdaptedPlayer player) {
return handle.canAccess((ProxiedPlayer) player.getHandle()); return handle.canAccess((ProxiedPlayer) player.getHandle());
@@ -58,8 +100,43 @@ public class BungeeServer implements AdaptedServer {
return players; return players;
} }
@Override
public int getOfflineTime() {
return offlineTime;
}
@Override
public boolean canJoinFull(AdaptedPlayer player) {
if(player == null) return true;
return
player.hasPermission("ajqueue.joinfull") ||
player.hasPermission("ajqueue.joinfullserver."+getName()) ||
player.hasPermission("ajqueue.joinfullandbypassserver."+getName()) ||
player.hasPermission("ajqueue.joinfullandbypass") ||
(main.isPremium() && main.getLogic().getPermissionGetter().hasUniqueFullBypass(player, getName()))
;
}
@Override
public boolean justWentOnline() {
return System.currentTimeMillis()-lastOffline <= (main.getConfig().getDouble("wait-time")) && isOnline();
}
@Override @Override
public ServerInfo getHandle() { public ServerInfo getHandle() {
return handle; return handle;
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof BungeeServer)) return false;
BungeeServer that = (BungeeServer) o;
return getHandle().equals(that.getHandle());
}
@Override
public int hashCode() {
return Objects.hash(getHandle());
}
} }
@@ -9,9 +9,11 @@ import us.ajg0702.queue.api.server.AdaptedServerPing;
public class BungeeServerPing implements AdaptedServerPing { public class BungeeServerPing implements AdaptedServerPing {
final ServerPing handle; final ServerPing handle;
private final long sent;
public BungeeServerPing(ServerPing handle) { public BungeeServerPing(ServerPing handle, long sent) {
this.handle = handle; this.handle = handle;
this.sent = sent;
} }
@Override @Override
@@ -45,6 +47,11 @@ public class BungeeServerPing implements AdaptedServerPing {
add++; add++;
} }
@Override
public long getFetchedTime() {
return sent;
}
@Override @Override
public ServerPing getHandle() { public ServerPing getHandle() {
return handle; return handle;
@@ -36,4 +36,29 @@ public class VelocityLogger implements QueueLogger {
public void severe(String message) { public void severe(String message) {
logger.error(message); logger.error(message);
} }
@Override
public void warn(String message, Throwable t) {
logger.warn(message, t);
}
@Override
public void warning(String message, Throwable t) {
logger.warn(message, t);
}
@Override
public void info(String message, Throwable t) {
logger.info(message, t);
}
@Override
public void error(String message, Throwable t) {
logger.error(message, t);
}
@Override
public void severe(String message, Throwable t) {
logger.error(message, t);
}
} }
@@ -17,6 +17,7 @@ import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.server.AdaptedServer; import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.api.util.QueueLogger; import us.ajg0702.queue.api.util.QueueLogger;
import us.ajg0702.queue.commands.commands.PlayerSender; import us.ajg0702.queue.commands.commands.PlayerSender;
import us.ajg0702.queue.common.utils.Debug;
import us.ajg0702.queue.platforms.velocity.players.VelocityPlayer; import us.ajg0702.queue.platforms.velocity.players.VelocityPlayer;
import us.ajg0702.queue.platforms.velocity.server.VelocityServer; import us.ajg0702.queue.platforms.velocity.server.VelocityServer;
@@ -134,19 +135,48 @@ public class VelocityMethods implements PlatformMethods {
@Override @Override
public AdaptedServer getServer(String name) { public AdaptedServer getServer(String name) {
Optional<RegisteredServer> server = proxyServer.getServer(name); List<? extends AdaptedServer> servers = getServers();
if(!server.isPresent()) return null; for (AdaptedServer server : servers) {
return new VelocityServer(server.get()); if(server.getName().equals(name)) return server;
} }
return null;
}
List<VelocityServer> serverList = new ArrayList<>();
@Override @Override
public List<AdaptedServer> getServers() { public List<? extends AdaptedServer> getServers() {
List<AdaptedServer> result = new ArrayList<>();
proxyServer.getAllServers().forEach(registeredServer -> result.add(new VelocityServer(registeredServer))); for (RegisteredServer registeredServer : proxyServer.getAllServers()) {
boolean found = false;
for(VelocityServer sv : new ArrayList<>(serverList)) {
if(sv.getHandle().equals(registeredServer)) {
found = true;
break;
}
}
if(found) continue;
return result; Debug.info("Added "+registeredServer.getServerInfo().getName());
serverList.add(new VelocityServer(registeredServer, plugin.getMain()));
}
for(VelocityServer sv : new ArrayList<>(serverList)) {
boolean found = false;
for (RegisteredServer registeredServer : proxyServer.getAllServers()) {
if(sv.getHandle().equals(registeredServer)) {
found = true;
break;
}
}
if(found) continue;
Debug.info("Removed "+sv.getName());
serverList.remove(sv);
}
return serverList;
} }
@Override @Override
@@ -144,7 +144,7 @@ public class VelocityQueue implements Implementation {
Optional<Component> reasonOptional = e.getServerKickReason(); Optional<Component> reasonOptional = e.getServerKickReason();
main.getEventHandler().onServerKick( main.getEventHandler().onServerKick(
new VelocityPlayer(e.getPlayer()), new VelocityPlayer(e.getPlayer()),
new VelocityServer(e.getServer()), new VelocityServer(e.getServer(), main),
reasonOptional.orElseGet(() -> Component.text("Proxy lost connection")), reasonOptional.orElseGet(() -> Component.text("Proxy lost connection")),
// According to Tux on discord, velocity doesnt give a reason when the proxy loses connection to the connected server // According to Tux on discord, velocity doesnt give a reason when the proxy loses connection to the connected server
e.kickedDuringServerConnect() e.kickedDuringServerConnect()
@@ -165,4 +165,8 @@ public class VelocityQueue implements Implementation {
new VelocityCommand(main, (BaseCommand) command) new VelocityCommand(main, (BaseCommand) command)
); );
} }
public QueueMain getMain() {
return main;
}
} }
@@ -7,17 +7,31 @@ import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.server.AdaptedServer; import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.api.server.AdaptedServerInfo; import us.ajg0702.queue.api.server.AdaptedServerInfo;
import us.ajg0702.queue.api.server.AdaptedServerPing; import us.ajg0702.queue.api.server.AdaptedServerPing;
import us.ajg0702.queue.api.util.QueueLogger;
import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.queue.platforms.velocity.players.VelocityPlayer; import us.ajg0702.queue.platforms.velocity.players.VelocityPlayer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class VelocityServer implements AdaptedServer { public class VelocityServer implements AdaptedServer {
private final RegisteredServer handle; private final RegisteredServer handle;
public VelocityServer(RegisteredServer handle) {
private AdaptedServerPing lastPing = null;
private AdaptedServerPing lastSuccessfullPing = null;
private long lastOffline = 0;
private int offlineTime = 0;
private final QueueMain main;
public VelocityServer(RegisteredServer handle, QueueMain main) {
this.handle = handle; this.handle = handle;
this.main = main;
} }
@Override @Override
@@ -31,22 +45,51 @@ public class VelocityServer implements AdaptedServer {
} }
@Override @Override
public CompletableFuture<AdaptedServerPing> ping() { public CompletableFuture<AdaptedServerPing> ping(boolean debug, QueueLogger logger) {
CompletableFuture<AdaptedServerPing> future = new CompletableFuture<>(); CompletableFuture<AdaptedServerPing> future = new CompletableFuture<>();
long sent = System.currentTimeMillis();
CompletableFuture<ServerPing> serverPing = handle.ping(); CompletableFuture<ServerPing> serverPing = handle.ping();
if(debug) logger.info("[pinger] [" + getName() + "] sending ping");
serverPing.thenRunAsync(() -> { serverPing.thenRunAsync(() -> {
AdaptedServerPing aPing; VelocityServerPing ping;
try { try {
aPing = new VelocityServerPing(serverPing.get()); ping = new VelocityServerPing(serverPing.get(), sent);
} catch (Throwable e) { } catch (Throwable e) {
long lastOnline = lastSuccessfullPing == null ? 0 : lastSuccessfullPing.getFetchedTime();
offlineTime = (int) Math.min(sent - lastOnline, Integer.MAX_VALUE);
lastOffline = sent;
future.completeExceptionally(e); future.completeExceptionally(e);
lastPing = null;
if(debug) logger.info("[pinger] [" + getName() + "] offline:", e);
return; return;
} }
future.complete(aPing);
offlineTime = 0;
lastSuccessfullPing = ping;
if(debug) logger.info(
"[pinger] [" + getName() + "] online. motd: "+ping.getPlainDescription()+" " +
" players: "+ping.getPlayerCount()+"/"+ping.getMaxPlayers()
);
future.complete(ping);
lastPing = ping;
}); });
return future; return future;
} }
@Override
public Optional<AdaptedServerPing> getLastPing() {
return Optional.ofNullable(lastPing);
}
@Override @Override
public boolean canAccess(AdaptedPlayer player) { public boolean canAccess(AdaptedPlayer player) {
return true; return true;
@@ -61,8 +104,43 @@ public class VelocityServer implements AdaptedServer {
return players; return players;
} }
@Override
public int getOfflineTime() {
return offlineTime;
}
@Override
public boolean canJoinFull(AdaptedPlayer player) {
if(player == null) return true;
return
player.hasPermission("ajqueue.joinfull") ||
player.hasPermission("ajqueue.joinfullserver."+getName()) ||
player.hasPermission("ajqueue.joinfullandbypassserver."+getName()) ||
player.hasPermission("ajqueue.joinfullandbypass") ||
(main.isPremium() && main.getLogic().getPermissionGetter().hasUniqueFullBypass(player, getName()))
;
}
@Override
public boolean justWentOnline() {
return System.currentTimeMillis()-lastOffline <= (main.getConfig().getDouble("wait-time")) && isOnline();
}
@Override @Override
public RegisteredServer getHandle() { public RegisteredServer getHandle() {
return handle; return handle;
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof VelocityServer)) return false;
VelocityServer that = (VelocityServer) o;
return getHandle().equals(that.getHandle());
}
@Override
public int hashCode() {
return Objects.hash(getHandle());
}
} }
@@ -8,8 +8,10 @@ import us.ajg0702.queue.api.server.AdaptedServerPing;
public class VelocityServerPing implements AdaptedServerPing { public class VelocityServerPing implements AdaptedServerPing {
private final ServerPing handle; private final ServerPing handle;
public VelocityServerPing(ServerPing handle) { private final long sent;
public VelocityServerPing(ServerPing handle, long sent) {
this.handle = handle; this.handle = handle;
this.sent = sent;
} }
@Override @Override
@@ -39,6 +41,11 @@ public class VelocityServerPing implements AdaptedServerPing {
add++; add++;
} }
@Override
public long getFetchedTime() {
return sent;
}
@Override @Override
public ServerPing getHandle() { public ServerPing getHandle() {
return handle; return handle;
@@ -5,6 +5,7 @@ import us.ajg0702.queue.api.premium.Logic;
import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.players.QueuePlayer; import us.ajg0702.queue.api.players.QueuePlayer;
import us.ajg0702.queue.api.queues.QueueServer; import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.api.util.QueueLogger; import us.ajg0702.queue.api.util.QueueLogger;
import us.ajg0702.queue.common.QueueMain; import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.queue.common.players.QueuePlayerImpl; import us.ajg0702.queue.common.players.QueuePlayerImpl;
@@ -28,7 +29,7 @@ public class PremiumLogic implements Logic {
} }
@Override @Override
public QueuePlayer priorityLogic(QueueServer server, AdaptedPlayer player) { public QueuePlayer priorityLogic(QueueServer queueServer, AdaptedPlayer player, AdaptedServer server) {
int maxOfflineTime = permissionGetter.getMaxOfflineTime(player); int maxOfflineTime = permissionGetter.getMaxOfflineTime(player);
QueueMain main = QueueMain.getInstance(); QueueMain main = QueueMain.getInstance();
@@ -38,32 +39,32 @@ public class PremiumLogic implements Logic {
if( if(
player.hasPermission("ajqueue.bypass") || player.hasPermission("ajqueue.bypass") ||
player.hasPermission("ajqueue.serverbypass."+server.getName()) || player.hasPermission("ajqueue.serverbypass."+ queueServer.getName()) ||
player.hasPermission("ajqueue.joinfullandbypassserver."+server.getName()) || player.hasPermission("ajqueue.joinfullandbypassserver."+ queueServer.getName()) ||
player.hasPermission("ajqueue.joinfullandbypass") || player.hasPermission("ajqueue.joinfullandbypass") ||
permissionGetter.hasContextBypass(player, server.getName()) || permissionGetter.hasContextBypass(player, queueServer.getName()) ||
(main.isPremium() && main.getLogic().getPermissionGetter().hasUniqueFullBypass(player, server.getName())) (main.isPremium() && main.getLogic().getPermissionGetter().hasUniqueFullBypass(player, queueServer.getName()))
) { ) {
if(debug) { if(debug) {
logger.info("[priority] "+player.getName()+" bypass"); logger.info("[priority] "+player.getName()+" bypass");
} }
QueuePlayer queuePlayer = new QueuePlayerImpl(player, server, Integer.MAX_VALUE, maxOfflineTime); QueuePlayer queuePlayer = new QueuePlayerImpl(player, queueServer, Integer.MAX_VALUE, maxOfflineTime);
server.addPlayer(queuePlayer, 0); queueServer.addPlayer(queuePlayer, 0);
main.getQueueManager().sendPlayers(server); main.getQueueManager().sendPlayers(queueServer);
return queuePlayer; return queuePlayer;
} }
int priority = permissionGetter.getPriority(player); int priority = permissionGetter.getPriority(player);
int serverPriority = permissionGetter.getServerPriotity(server.getName(), player); int serverPriority = permissionGetter.getServerPriotity(queueServer.getName(), player);
if(debug) { if(debug) {
logger.info("[priority] Using "+permissionGetter.getSelected().getName()+" for permissions"); logger.info("[priority] Using "+permissionGetter.getSelected().getName()+" for permissions");
} }
int highestPriority = Math.max(priority, serverPriority); int highestPriority = Math.max(priority, serverPriority);
highestPriority = Math.max(highestPriority, Logic.getUnJoinablePriorities(server, player)); highestPriority = Math.max(highestPriority, Logic.getUnJoinablePriorities(queueServer, server, player));
QueuePlayer queuePlayer = new QueuePlayerImpl(player, server, highestPriority, maxOfflineTime); QueuePlayer queuePlayer = new QueuePlayerImpl(player, queueServer, highestPriority, maxOfflineTime);
if(debug) { if(debug) {
logger.info("[priority] "+player.getName()+" highestPriority: "+highestPriority); logger.info("[priority] "+player.getName()+" highestPriority: "+highestPriority);
@@ -75,11 +76,11 @@ public class PremiumLogic implements Logic {
if(debug) { if(debug) {
logger.info("[priority] "+player.getName()+" No priority" ); logger.info("[priority] "+player.getName()+" No priority" );
} }
server.addPlayer(queuePlayer); queueServer.addPlayer(queuePlayer);
return queuePlayer; return queuePlayer;
} }
ImmutableList<QueuePlayer> list = server.getQueue(); ImmutableList<QueuePlayer> list = queueServer.getQueue();
for(int i = 0; i < list.size(); i++) { for(int i = 0; i < list.size(); i++) {
QueuePlayer pl = list.get(i); QueuePlayer pl = list.get(i);
@@ -87,7 +88,7 @@ public class PremiumLogic implements Logic {
if (debug) { if (debug) {
logger.info("[priority] " + player.getName() + " Adding to: " + i); logger.info("[priority] " + player.getName() + " Adding to: " + i);
} }
server.addPlayer(queuePlayer, i); queueServer.addPlayer(queuePlayer, i);
return queuePlayer; return queuePlayer;
} }
} }
@@ -96,7 +97,7 @@ public class PremiumLogic implements Logic {
if(debug) { if(debug) {
logger.info("[priority] "+player.getName()+" Cant go infront of anyone" ); logger.info("[priority] "+player.getName()+" Cant go infront of anyone" );
} }
server.addPlayer(queuePlayer); queueServer.addPlayer(queuePlayer);
return queuePlayer; return queuePlayer;
} }