diff --git a/api/src/main/java/us/ajg0702/queue/api/premium/Logic.java b/api/src/main/java/us/ajg0702/queue/api/premium/Logic.java index 9dc7bf7f..a32a2d27 100644 --- a/api/src/main/java/us/ajg0702/queue/api/premium/Logic.java +++ b/api/src/main/java/us/ajg0702/queue/api/premium/Logic.java @@ -64,7 +64,7 @@ static int getUnJoinablePriorities(QueueServer queueServer, AdaptedServer server boolean hasMakeRoom = player.hasPermission("ajqueue.make-room") && AjQueueAPI.getInstance().getConfig().getBoolean("enable-make-room-permission"); if( (server.isFull() && (server.canJoinFull(player) || hasMakeRoom)) || - (queueServer.isManuallyFull() && (AdaptedServer.canJoinFull(player, queueServer.getName()) || hasMakeRoom))) { + ((queueServer.isManuallyFull() || queueServer.isDynamicallyFull()) && (AdaptedServer.canJoinFull(player, queueServer.getName()) || hasMakeRoom))) { highest = Math.max(highest, fulljoinPriority); } } diff --git a/api/src/main/java/us/ajg0702/queue/api/queues/QueueServer.java b/api/src/main/java/us/ajg0702/queue/api/queues/QueueServer.java index 47654df4..4c6f1887 100644 --- a/api/src/main/java/us/ajg0702/queue/api/queues/QueueServer.java +++ b/api/src/main/java/us/ajg0702/queue/api/queues/QueueServer.java @@ -1,6 +1,7 @@ package us.ajg0702.queue.api.queues; import com.google.common.collect.ImmutableList; +import org.jetbrains.annotations.Nullable; import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.api.players.QueuePlayer; import us.ajg0702.queue.api.queueholders.QueueHolder; @@ -81,6 +82,30 @@ public interface QueueServer { */ boolean isManuallyFull(); + /** + * Checks if the total number of players in this server/group is above the dynamically-set max player count + * @return If the server is at or above the dynamically-set player limit + */ + boolean isDynamicallyFull(); + + /** + * Sets the dynamic max player cap for this server/group. This is used for temporarily lowering the max player count of a server/group. + * @param amount the new dynamic max player count. Negative values will be ignored, behaving as resetDynamicMax + */ + void setDynamicMax(int amount); + + /** + * Gets the dynamic max (null when no max is set) + * @return integer (0 or larger) or null if no dynamic max is set + */ + @Nullable + Integer getDynamicMax(); + + /** + * Resets the dynamic max player cap for this server/group. This will make it so the dynamic player cap is no longer a consideration. + */ + void resetDynamicMax(); + /** * Pauses or unpauses a server * @param paused true = paused, false = unpaused diff --git a/common/src/main/java/us/ajg0702/queue/common/QueueManagerImpl.java b/common/src/main/java/us/ajg0702/queue/common/QueueManagerImpl.java index 9283b5de..10a708d3 100644 --- a/common/src/main/java/us/ajg0702/queue/common/QueueManagerImpl.java +++ b/common/src/main/java/us/ajg0702/queue/common/QueueManagerImpl.java @@ -875,7 +875,7 @@ public synchronized void sendPlayers(QueueServer queueServer) { if( (selected.isFull() && !selected.canJoinFull(player)) || - (server.isManuallyFull() && !AdaptedServer.canJoinFull(player, server.getName())) + ((server.isManuallyFull() || server.isDynamicallyFull()) && !AdaptedServer.canJoinFull(player, server.getName())) ) continue; player.sendMessage(msgs.getComponent("status.sending-now", "SERVER:"+server.getAlias())); @@ -945,12 +945,12 @@ public synchronized void sendPlayers(QueueServer queueServer) { if( ( (selected.isFull() && !selected.canJoinFull(nextPlayer)) || - (server.isManuallyFull() && !AdaptedServer.canJoinFull(nextPlayer, server.getName())) + ((server.isManuallyFull() || server.isDynamicallyFull()) && !AdaptedServer.canJoinFull(nextPlayer, server.getName())) ) && !( nextPlayer.hasPermission("ajqueue.make-room") && main.getConfig().getBoolean("enable-make-room-permission") && - (!server.isGroup() || server.isManuallyFull()) // only use make-room on groups if the server is manually full + (!server.isGroup() || server.isManuallyFull() || server.isDynamicallyFull()) // only use make-room on groups if the server is manually or dynamically full ) ) continue; @@ -959,11 +959,11 @@ public synchronized void sendPlayers(QueueServer queueServer) { if( ( (selected.isFull() && !selected.canJoinFull(nextPlayer)) || - (server.isManuallyFull() && !AdaptedServer.canJoinFull(nextPlayer, server.getName())) + ((server.isManuallyFull() || server.isDynamicallyFull()) && !AdaptedServer.canJoinFull(nextPlayer, server.getName())) ) && main.getConfig().getBoolean("enable-make-room-permission") && nextPlayer.hasPermission("ajqueue.make-room") && - (!server.isGroup() || server.isManuallyFull()) && // only use make-room on groups if the server is manually full + (!server.isGroup() || server.isManuallyFull() || server.isDynamicallyFull()) && // only use make-room on groups if the server is manually or dynamically full ( // don't make room more than the minimum ping time System.currentTimeMillis() - makeRoomAntispam.getOrDefault(nextQueuePlayer, 0L) >= (main.getConfig().getDouble("minimum-ping-time") * 1e3) diff --git a/common/src/main/java/us/ajg0702/queue/common/queues/QueueServerImpl.java b/common/src/main/java/us/ajg0702/queue/common/queues/QueueServerImpl.java index c595861e..9b88c0b2 100644 --- a/common/src/main/java/us/ajg0702/queue/common/queues/QueueServerImpl.java +++ b/common/src/main/java/us/ajg0702/queue/common/queues/QueueServerImpl.java @@ -1,6 +1,7 @@ package us.ajg0702.queue.common.queues; import com.google.common.collect.ImmutableList; +import org.jetbrains.annotations.Nullable; import us.ajg0702.queue.api.AjQueueAPI; import us.ajg0702.queue.api.events.PositionChangeEvent; import us.ajg0702.queue.api.players.AdaptedPlayer; @@ -43,6 +44,7 @@ public class QueueServerImpl implements QueueServer { private double averageSendTime = 0; private int manualMaxPlayers = Integer.MAX_VALUE; + private Integer dynamicMaxPlayers = null; private QueueType lastQueueSend = QueueType.STANDARD; private int sendCount = 0; @@ -164,7 +166,7 @@ public String getStatusString(AdaptedPlayer p) { return msgs.getString("status.offline.whitelisted"); } - if((server.isFull() && !server.canJoinFull(p)) || (isManuallyFull() && !AdaptedServer.canJoinFull(p, getName()))) { + if((server.isFull() && !server.canJoinFull(p)) || ((isManuallyFull() || isDynamicallyFull()) && !AdaptedServer.canJoinFull(p, getName()))) { return msgs.getString("status.offline.full"); } @@ -200,7 +202,7 @@ public String getStatus(AdaptedPlayer p) { return "whitelisted"; } - if(((server.isFull() && !server.canJoinFull(p)) || (isManuallyFull() && !AdaptedServer.canJoinFull(p, getName())))) { + if(((server.isFull() && !server.canJoinFull(p)) || ((isManuallyFull() || isDynamicallyFull()) && !AdaptedServer.canJoinFull(p, getName())))) { return "full"; } @@ -273,7 +275,7 @@ public boolean isJoinable(AdaptedPlayer p) { @Override public boolean isJoinable(AdaptedPlayer p, boolean ignoreFull) { - if(!ignoreFull && isManuallyFull() && !AdaptedServer.canJoinFull(p, getName())) return false; + if(!ignoreFull && (isManuallyFull() || isDynamicallyFull()) && !AdaptedServer.canJoinFull(p, getName())) return false; AdaptedServer server = getIdealServer(p); if(server == null) return false; return server.isJoinable(p, ignoreFull) && !isPaused(); @@ -298,6 +300,38 @@ public boolean isManuallyFull() { return total >= getManualMaxPlayers(); } + @Override + public boolean isDynamicallyFull() { + if (this.dynamicMaxPlayers == null) { + return false; + } + int total = 0; + for (AdaptedServer server : servers) { + Optional lastPing = server.getLastPing(); + if(!lastPing.isPresent()) continue; + total += lastPing.get().getPlayerCount(); + } + return total >= this.dynamicMaxPlayers; + } + + @Override + public void setDynamicMax(int amount) { + if (amount < 0) { + this.resetDynamicMax(); + } + this.dynamicMaxPlayers = amount; + } + + @Override + public @Nullable Integer getDynamicMax() { + return this.dynamicMaxPlayers; + } + + @Override + public void resetDynamicMax() { + this.dynamicMaxPlayers = null; + } + @Override public synchronized void setPaused(boolean paused) { this.paused = paused;