[nolist] Merge pull request #31 from ajgeiss0702/dev
Java CI with Gradle / build (push) Failing after 6m40s
JavaDocs Generation / build (push) Failing after 19s
JavaDocs Generation / deploy (push) Has been skipped
Java CI with Gradle / deploy (push) Has been skipped
Java CI with Gradle / updater (push) Has been skipped
Deploy Release to Polymart/Modrinth / build (push) Failing after 15m26s

2.6.0
This commit is contained in:
ajgeiss0702
2023-10-21 11:43:55 -07:00
committed by GitHub
54 changed files with 1175 additions and 407 deletions
@@ -3,6 +3,8 @@ package us.ajg0702.queue.api;
import us.ajg0702.queue.api.events.utils.EventReceiver;
import us.ajg0702.queue.api.premium.Logic;
import us.ajg0702.queue.api.premium.LogicGetter;
import us.ajg0702.queue.api.premium.PermissionHookRegistry;
import us.ajg0702.queue.api.queueholders.QueueHolderRegistry;
import us.ajg0702.queue.api.spigot.AjQueueSpigotAPI;
import us.ajg0702.queue.api.util.QueueLogger;
import us.ajg0702.utils.common.Config;
@@ -12,6 +14,10 @@ import java.util.concurrent.ExecutorService;
public abstract class AjQueueAPI {
public static QueueHolderRegistry queueHolderRegistry = new QueueHolderRegistry();
public static PermissionHookRegistry permissionHookRegistry = new PermissionHookRegistry();
public static AjQueueAPI INSTANCE;
public static AjQueueSpigotAPI SPIGOT_INSTANCE;
@@ -40,6 +46,12 @@ public abstract class AjQueueAPI {
*/
public abstract void setTimeBetweenPlayers();
/**
* Gets the server time manager instance, which tracks when players last changed servers
* @return The server time manager instance
*/
public abstract ServerTimeManager getServerTimeManager();
/**
* Gets the ajQueue config
* @return the ajQueue config
@@ -115,6 +127,14 @@ public abstract class AjQueueAPI {
*/
public abstract void shutdown();
public static QueueHolderRegistry getQueueHolderRegistry() {
return queueHolderRegistry;
}
public static PermissionHookRegistry getPermissionHookRegistry() {
return permissionHookRegistry;
}
public abstract <E> void listen(Class<E> event, EventReceiver<E> handler);
public abstract ExecutorService getServersUpdateExecutor();
@@ -1,6 +0,0 @@
package us.ajg0702.queue.api;
public interface QueueHolder {
boolean isAvailable();
}
@@ -0,0 +1,12 @@
package us.ajg0702.queue.api;
import us.ajg0702.queue.api.players.AdaptedPlayer;
public interface ServerTimeManager {
/**
* Gets the time that the player specified was last seen switching servers
* @param player The player to check
* @return The time that they last switched servers, in milliseconds since midnight, January 1, 1970, UTC
*/
long getLastServerChange(AdaptedPlayer player);
}
@@ -1,6 +1,7 @@
package us.ajg0702.queue.api.players;
import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer;
import javax.annotation.Nullable;
import java.util.UUID;
@@ -68,4 +69,10 @@ public interface QueuePlayer {
* @return the max number of seconds this player can be offline before being removed from the queue
*/
int getMaxOfflineTime();
/**
* Gets the server that the player was in when they joined the queue
* @return the server that the player was in when they joined the queue
*/
AdaptedServer getInitialServer();
}
@@ -38,6 +38,8 @@ public interface Logic {
*/
PermissionGetter getPermissionGetter();
int getHighestPriority(QueueServer queueServer, AdaptedServer server, AdaptedPlayer player);
static int getUnJoinablePriorities(QueueServer queueServer, AdaptedServer server, AdaptedPlayer player) {
Config config = AjQueueAPI.getInstance().getConfig();
int highest = 0;
@@ -59,7 +61,10 @@ public interface Logic {
}
if(fulljoinPriority > 0) {
if(server.isFull() && server.canJoinFull(player)) {
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))) {
highest = Math.max(highest, fulljoinPriority);
}
}
@@ -0,0 +1,24 @@
package us.ajg0702.queue.api.premium;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class PermissionHookRegistry {
private final Map<String, PermissionHook> hooks = new HashMap<>();
public void register(PermissionHook... permissionHooks) {
for (PermissionHook hook : permissionHooks) {
if(hooks.containsKey(hook.getName())) {
throw new IllegalArgumentException("Hook " + hook.getName() + " is already registered!");
}
}
for (PermissionHook hook : permissionHooks) {
hooks.put(hook.getName(), hook);
}
}
public Collection<PermissionHook> getRegisteredHooks() {
return hooks.values();
}
}
@@ -0,0 +1,84 @@
package us.ajg0702.queue.api.queueholders;
import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.players.QueuePlayer;
import us.ajg0702.queue.api.queues.QueueServer;
import java.util.List;
import java.util.UUID;
public abstract class QueueHolder {
private final QueueServer queueServer;
public QueueHolder(QueueServer queueServer) {
this.queueServer = queueServer;
}
/**
* Returns the identifier of this QueueHolder
* Used by the server owner in order to tell ajQueue to use this QueueHolder
* @return a string that is very unlikely to be re-used by another QueueHolder
*/
public abstract String getIdentifier();
/**
* Adds a player to the end of the queue
* NOTE: Do not manually call this! Use the QueueManager to add players to queues
* @param player The QueuePlayer to add
*/
public abstract void addPlayer(QueuePlayer player);
/**
* Adds a player to the specified position in the queue
* NOTE: Do not manually call this! Use the QueueManager to add players to queues
* @param player The QueuePlayer to add
* @param position The position to add them to
*/
public abstract void addPlayer(QueuePlayer player, int position);
public void removePlayer(AdaptedPlayer player) {
removePlayer(player.getUniqueId());
}
public void removePlayer(UUID uuid) {
QueuePlayer player = findPlayer(uuid);
if(player == null) return;
removePlayer(player);
}
/**
* Removes a player from the queue
* @param player The player to remove
*/
public abstract void removePlayer(QueuePlayer player);
/**
* Finds the player with this uuid in this queue and returns the representative QueuePlayer
* @return The QueuePlayer representing the player, null if not found
*/
public abstract QueuePlayer findPlayer(UUID uuid);
/**
* Finds the player with this username in this queue and returns the representative QueuePlayer
* @return The QueuePlayer representing the player, null if not found
*/
public abstract QueuePlayer findPlayer(String name);
public QueuePlayer findPlayer(AdaptedPlayer player) {
return findPlayer(player.getUniqueId());
}
/**
* Returns the size of the queue
* @return The number of players in the queue
*/
public abstract int getQueueSize();
/**
* Get all players that are in the queue
* @return a list of players in the queue
*/
public abstract List<QueuePlayer> getAllPlayers();
}
@@ -0,0 +1,44 @@
package us.ajg0702.queue.api.queueholders;
import us.ajg0702.queue.api.AjQueueAPI;
import us.ajg0702.queue.api.queues.QueueServer;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class QueueHolderRegistry {
private Map<String, Class<? extends QueueHolder>> holders = new ConcurrentHashMap<>();
/**
* Register a QueueHolder that can be used
* @param holder The QueueHolder to register
*/
public void register(String identifier, Class<? extends QueueHolder> holder) {
holders.put(identifier, holder);
}
public QueueHolder getQueueHolder(QueueServer queueServer) {
String queueHolderName = AjQueueAPI.getInstance().getConfig().getString("queue-holder");
QueueHolder queueHolder = getQueueHolder(queueHolderName, queueServer);
if(queueHolder == null) {
AjQueueAPI.getInstance().getLogger().warn("Invalid queue-holder '" + queueHolderName + "'! Using the default one");
return getQueueHolder("default", queueServer);
}
return queueHolder;
}
public QueueHolder getQueueHolder(String identifier, QueueServer queueServer) {
Class<? extends QueueHolder> holder = holders.get(identifier);
if(holder == null) return null;
try {
return holder.getConstructor(QueueServer.class).newInstance(queueServer);
} catch(NoSuchMethodException e) {
throw new IllegalArgumentException("QueueHolder " + identifier + " is missing the required constructor!");
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
@@ -1,8 +1,9 @@
package us.ajg0702.queue.api.queues;
import org.jetbrains.annotations.Nullable;
import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.server.AdaptedServer;
public interface Balancer {
AdaptedServer getIdealServer(AdaptedPlayer player);
AdaptedServer getIdealServer(@Nullable AdaptedPlayer player);
}
@@ -3,10 +3,9 @@ package us.ajg0702.queue.api.queues;
import com.google.common.collect.ImmutableList;
import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.players.QueuePlayer;
import us.ajg0702.queue.api.queueholders.QueueHolder;
import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.api.server.AdaptedServerPing;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
@@ -19,7 +18,9 @@ public interface QueueServer {
/**
* Get the players who are queued.
* @return The players who are queued
* @deprecated It is recommended to not use this method unless you absolutely have to. If you have to, use getQueueHolder().getAllPlayers()
*/
@Deprecated
ImmutableList<QueuePlayer> getQueue();
/**
@@ -69,6 +70,18 @@ public interface QueueServer {
*/
boolean isJoinable(AdaptedPlayer p);
/**
* Gets the manually-set max player count for this server/group
* @return The manually-set max player count
*/
int getManualMaxPlayers();
/**
* Checks if the total number of players in this server/group is above the manually-set max player count
* @return If the server is at or above the manually-set player limit
*/
boolean isManuallyFull();
/**
* Pauses or unpauses a server
* @param paused true = paused, false = unpaused
@@ -209,6 +222,12 @@ public interface QueueServer {
*/
Balancer getBalancer();
/**
* Gets the QueueHolder for this queue
* @return the QueueHolder that holds the queue
*/
QueueHolder getQueueHolder();
/**
* elliot is bad
@@ -1,5 +1,6 @@
package us.ajg0702.queue.api.server;
import us.ajg0702.queue.api.AjQueueAPI;
import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.util.Handle;
import us.ajg0702.queue.api.util.QueueLogger;
@@ -52,7 +53,20 @@ public interface AdaptedServer extends Handle {
*/
int getOfflineTime();
boolean canJoinFull(AdaptedPlayer player);
default boolean canJoinFull(AdaptedPlayer player) {
return canJoinFull(player, getName());
}
static boolean canJoinFull(AdaptedPlayer player, String serverName) {
if(player == null) return true;
return
player.hasPermission("ajqueue.joinfull") ||
player.hasPermission("ajqueue.joinfullserver." + serverName) ||
player.hasPermission("ajqueue.joinfullandbypassserver." + serverName) ||
player.hasPermission("ajqueue.joinfullandbypass") ||
(AjQueueAPI.getInstance().isPremium() && AjQueueAPI.getInstance().getLogic().getPermissionGetter().hasUniqueFullBypass(player, serverName))
;
}
boolean justWentOnline();
@@ -75,14 +89,16 @@ public interface AdaptedServer extends Handle {
}
/**
* Gets if the last ping was successfull
* Gets if the last ping was successful
* (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();
return getLastPing().isPresent() && !shouldWaitAfterOnline();
}
boolean shouldWaitAfterOnline();
/**
* Gets the number of players currently online
* @return The number of players online
+1 -1
View File
@@ -12,7 +12,7 @@ repositories {
}
allprojects {
version = "2.5.0"
version = "2.6.0"
group = "us.ajg0702"
plugins.apply("java")
@@ -1,12 +1,13 @@
package us.ajg0702.queue.commands.commands.SlashServer;
import com.google.common.collect.ImmutableList;
import us.ajg0702.queue.api.commands.IBaseCommand;
import us.ajg0702.queue.api.commands.ICommandSender;
import us.ajg0702.queue.commands.BaseCommand;
import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.utils.common.Messages;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SlashServerCommand extends BaseCommand {
@@ -14,6 +15,10 @@ public class SlashServerCommand extends BaseCommand {
final QueueMain main;
final String server;
final String command;
private IBaseCommand moveCommand;
public SlashServerCommand(QueueMain main, String server) {
this.main = main;
this.server = server;
@@ -51,15 +56,14 @@ public class SlashServerCommand extends BaseCommand {
sender.sendMessage(getMessages().getComponent("errors.player-only"));
return;
}
if(main.getConfig().getBoolean("require-permission") && !sender.hasPermission("ajqueue.queue."+server)) {
sender.sendMessage(getMessages().getComponent("noperm"));
return;
if(moveCommand == null) {
moveCommand = main.getPlatformMethods().getCommands().get(0);
}
main.getQueueManager().addToQueue(main.getPlatformMethods().senderToPlayer(sender), server);
moveCommand.execute(sender, new String[]{server});
}
@Override
public List<String> autoComplete(ICommandSender sender, String[] args) {
return new ArrayList<>();
return Collections.emptyList();
}
}
@@ -11,6 +11,7 @@ import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.utils.common.Messages;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class LeaveCommand extends BaseCommand {
@@ -105,11 +106,12 @@ public class LeaveCommand extends BaseCommand {
@Override
public List<String> autoComplete(ICommandSender sender, String[] args) {
if(args.length > 1) return Collections.emptyList();
List<QueuePlayer> servers = main.getQueueManager().findPlayerInQueues(main.getPlatformMethods().senderToPlayer(sender));
List<String> serverNames = new ArrayList<>();
for(QueuePlayer queuePlayer : servers) {
serverNames.add(queuePlayer.getQueueServer().getName());
}
return serverNames;
return filterCompletion(serverNames, args[0]);
}
}
@@ -10,7 +10,7 @@ import us.ajg0702.queue.commands.BaseCommand;
import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.utils.common.Messages;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ListCommand extends BaseCommand {
@@ -79,6 +79,6 @@ public class ListCommand extends BaseCommand {
@Override
public List<String> autoComplete(ICommandSender sender, String[] args) {
return new ArrayList<>();
return Collections.emptyList();
}
}
@@ -81,10 +81,10 @@ public class Kick extends SubCommand {
@Override
public List<String> autoComplete(ICommandSender sender, String[] args) {
if(args.length == 1) {
return main.getPlatformMethods().getPlayerNames(false);
return filterCompletion(main.getPlatformMethods().getPlayerNames(false), args[0]);
}
if(args.length == 2) {
return main.getQueueManager().getServerNames();
return filterCompletion(main.getQueueManager().getServerNames(), args[1]);
}
return new ArrayList<>();
}
@@ -9,6 +9,7 @@ import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.utils.common.Messages;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class KickAll extends SubCommand {
@@ -65,9 +66,9 @@ public class KickAll extends SubCommand {
@Override
public List<String> autoComplete(ICommandSender sender, String[] args) {
if(args.length == 1) {
return main.getQueueManager().getServerNames();
return filterCompletion(main.getQueueManager().getServerNames(), args[0]);
}
return new ArrayList<>();
return Collections.emptyList();
}
}
@@ -104,6 +104,6 @@ public class ManageCommand extends BaseCommand {
commands.add(subCommand.getName());
commands.addAll(subCommand.getAliases());
}
return commands;
return filterCompletion(commands, args[0]);
}
}
@@ -77,11 +77,11 @@ public class Pause extends SubCommand {
if(args.length == 1) {
List<String> servers = new ArrayList<>(main.getQueueManager().getServerNames());
servers.add("all");
return servers;
return filterCompletion(servers, args[0]);
}
if(args.length == 2) {
return Arrays.asList("on", "off", "true", "false");
return filterCompletion(Arrays.asList("on", "off", "true", "false"), args[1]);
}
return new ArrayList<>();
return Collections.emptyList();
}
}
@@ -11,7 +11,7 @@ import us.ajg0702.queue.commands.SubCommand;
import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.utils.common.Messages;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
@@ -88,6 +88,6 @@ public class QueueList extends SubCommand {
@Override
public java.util.List<String> autoComplete(ICommandSender sender, String[] args) {
return new ArrayList<>();
return Collections.emptyList();
}
}
@@ -9,7 +9,7 @@ import us.ajg0702.queue.commands.SubCommand;
import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.utils.common.Messages;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Reload extends SubCommand {
@@ -63,6 +63,6 @@ public class Reload extends SubCommand {
@Override
public List<String> autoComplete(ICommandSender sender, String[] args) {
return new ArrayList<>();
return Collections.emptyList();
}
}
@@ -10,6 +10,7 @@ import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.utils.common.Messages;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Send extends SubCommand {
@@ -93,12 +94,12 @@ public class Send extends SubCommand {
if(args.length == 1) {
List<String> options = new ArrayList<>(main.getPlatformMethods().getServerNames());
options.addAll(main.getPlatformMethods().getPlayerNames(false));
return options;
return filterCompletion(options, args[0]);
}
if(args.length == 2) {
return main.getQueueManager().getServerNames();
return filterCompletion(main.getQueueManager().getServerNames(), args[1]);
}
return new ArrayList<>();
return Collections.emptyList();
}
@@ -26,7 +26,7 @@ public class PermissionList extends SubCommand {
@Override
public ImmutableList<String> getAliases() {
return ImmutableList.of();
return ImmutableList.of("permissionslist", "listpermissions", "listpermission");
}
@Override
@@ -8,10 +8,7 @@ import us.ajg0702.queue.commands.BaseCommand;
import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.utils.common.Messages;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class QueueCommand extends BaseCommand {
@@ -92,7 +89,7 @@ public class QueueCommand extends BaseCommand {
@Override
public List<String> autoComplete(ICommandSender sender, String[] args) {
if(!main.getConfig().getBoolean("tab-complete-queues")) {
return new ArrayList<>();
return Collections.emptyList();
}
if(args.length == 1) {
List<String> servers = filterCompletion(main.getQueueManager().getServerNames(), args[0]);
@@ -101,6 +98,6 @@ public class QueueCommand extends BaseCommand {
}
return servers;
}
return new ArrayList<>();
return Collections.emptyList();
}
}
@@ -0,0 +1,69 @@
package us.ajg0702.queue.common;
import com.google.common.collect.ImmutableList;
import us.ajg0702.queue.api.players.QueuePlayer;
import us.ajg0702.queue.api.queueholders.QueueHolder;
import us.ajg0702.queue.api.queues.QueueServer;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
public class DefaultQueueHolder extends QueueHolder {
List<QueuePlayer> queue = new CopyOnWriteArrayList<>();
public DefaultQueueHolder(QueueServer queueServer) {
super(queueServer);
}
@Override
public String getIdentifier() {
return "default";
}
@Override
public void addPlayer(QueuePlayer player) {
queue.add(player);
}
@Override
public void addPlayer(QueuePlayer player, int position) {
queue.add(position, player);
}
@Override
public void removePlayer(QueuePlayer player) {
queue.remove(player);
}
@Override
public QueuePlayer findPlayer(UUID uuid) {
for(QueuePlayer queuePlayer : queue) {
if(queuePlayer.getUniqueId().toString().equals(uuid.toString())) {
return queuePlayer;
}
}
return null;
}
@Override
public QueuePlayer findPlayer(String name) {
for(QueuePlayer queuePlayer : queue) {
if(queuePlayer.getName().equalsIgnoreCase(name)) {
return queuePlayer;
}
}
return null;
}
@Override
public int getQueueSize() {
return queue.size();
}
@Override
public List<QueuePlayer> getAllPlayers() {
return ImmutableList.copyOf(queue);
}
}
@@ -58,6 +58,8 @@ public class EventHandlerImpl implements EventHandler {
if(queues.size() > 0) {
main.getQueueManager().sendMessage(main.getQueueManager().getSingleServer(player).findPlayer(player));
}
main.serverTimeManager.playerChanged(player);
}
@Override
@@ -77,6 +79,7 @@ public class EventHandlerImpl implements EventHandler {
}
main.getQueueManager().clear(player);
QueueCommand.cooldowns.remove(player);
main.serverTimeManager.removePlayer(player);
}
@Override
@@ -108,11 +111,31 @@ public class EventHandlerImpl implements EventHandler {
String[] parts = s.split(":");
String from = parts[0];
QueueServer to = main.getQueueManager().findServer(parts[1]);
if(from.equalsIgnoreCase(serverName) && to != null) {
if(
from.equalsIgnoreCase(serverName) && to != null &&
(
!main.getConfig().getBoolean("require-queueserver-permission") ||
player.hasPermission("ajqueue.queueserver." + to.getName())
)
) {
int delay = Math.min(main.getConfig().getInt("queue-server-delay"), 3000);
Runnable task = () -> {
if(to.getServers().contains(player.getCurrentServer())) return;
main.getQueueManager().addToQueue(player, to);
};
Debug.info("Delaying queue-server by " + delay);
if(delay > 0) {
main.getTaskManager().executor.schedule(task, delay, TimeUnit.MILLISECONDS);
} else {
task.run();
}
}
}
}
main.serverTimeManager.playerChanged(player);
}
@@ -27,6 +27,14 @@ public class QueueMain extends AjQueueAPI {
}
private double timeBetweenPlayers;
protected ServerTimeManagerImpl serverTimeManager = new ServerTimeManagerImpl();
@Override
public ServerTimeManager getServerTimeManager() {
return serverTimeManager;
}
@Override
public double getTimeBetweenPlayers() {
return timeBetweenPlayers;
@@ -182,8 +190,6 @@ public class QueueMain extends AjQueueAPI {
this.platformMethods = platformMethods;
this.dataFolder = dataFolder;
constructMessages();
try {
config = new Config(dataFolder, new LogConverter(logger));
} catch (ConfigurateException e) {
@@ -192,6 +198,10 @@ public class QueueMain extends AjQueueAPI {
return;
}
constructMessages();
getQueueHolderRegistry().register("default", DefaultQueueHolder.class);
logic = logicGetter.constructLogic();
aliasManager = logicGetter.constructAliasManager(config);
@@ -230,6 +240,8 @@ public class QueueMain extends AjQueueAPI {
d.put("status.now-in-queue", "&aYou are now queued for {SERVER}! &7You are in position &f{POS}&7 of &f{LEN}&7.\n&7Type &f/leavequeue&7 or &f<click:run_command:/leavequeue {SERVERNAME}>click here</click>&7 to leave the queue!");
d.put("status.now-in-empty-queue", "");
d.put("status.sending-now", "&aSending you to &f{SERVER} &anow..");
d.put("status.making-room", "<gold>Making room for you..");
d.put("status.priority-increased", "<gold>You now have higher priority! <green>Moving you up in the queue..");
d.put("errors.server-not-exist", "&cThe server {SERVER} does not exist!");
d.put("errors.already-queued", "&cYou are already queued for that server!");
@@ -241,6 +253,10 @@ public class QueueMain extends AjQueueAPI {
d.put("errors.wrong-version.or", " or ");
d.put("errors.wrong-version.comma", ", ");
d.put("errors.too-fast-queue", "<red>You're queueing too fast!");
d.put("errors.kicked-to-make-room", "<red>You were moved to the lobby to make room for another player.");
d.put("errors.make-room-failed.player", "<red>Failed to make room for you in that server.");
d.put("errors.make-room-failed.admin", "<red>Failed to make room for you in that server. Check the console for more information.");
d.put("commands.leave-queue", "&aYou left the queue for {SERVER}!");
d.put("commands.reload", "&aConfig and messages reloaded successfully!");
@@ -322,6 +338,58 @@ public class QueueMain extends AjQueueAPI {
d.put("updater.fail", "<red>An error occurred while downloading the update. Check the console for more info.");
d.put("updater.already-downloaded", "<red>The update has already been downloaded.");
List<String> oldProtocolNames = config.getStringList("protocol-names");
for (String oldProtocolName : oldProtocolNames) {
String[] parts = oldProtocolName.split(":");
if(parts.length != 2) {
logger.warn("Invalid old (in the config) protocol name '" + oldProtocolName + "'. Skipping.");
continue;
}
String protocol = parts[0];
String name = parts[1];
d.put("protocol-names." + protocol, name);
}
d.putIfAbsent("protocol-names.763", "1.20.1");
d.putIfAbsent("protocol-names.762", "1.19.4");
d.putIfAbsent("protocol-names.761", "1.19.3");
d.putIfAbsent("protocol-names.760", "1.19.2");
d.putIfAbsent("protocol-names.759", "1.19");
d.putIfAbsent("protocol-names.758", "1.18.2");
d.putIfAbsent("protocol-names.757", "1.18.1");
d.putIfAbsent("protocol-names.756", "1.17.1");
d.putIfAbsent("protocol-names.755", "1.17");
d.putIfAbsent("protocol-names.754", "1.16.5");
d.putIfAbsent("protocol-names.753", "1.16.3");
d.putIfAbsent("protocol-names.751", "1.16.2");
d.putIfAbsent("protocol-names.736", "1.16.1");
d.putIfAbsent("protocol-names.735", "1.16");
d.putIfAbsent("protocol-names.578", "1.15.2");
d.putIfAbsent("protocol-names.575", "1.15.1");
d.putIfAbsent("protocol-names.573", "1.15");
d.putIfAbsent("protocol-names.498", "1.14.4");
d.putIfAbsent("protocol-names.490", "1.14.3");
d.putIfAbsent("protocol-names.485", "1.14.2");
d.putIfAbsent("protocol-names.480", "1.14.1");
d.putIfAbsent("protocol-names.477", "1.14");
d.putIfAbsent("protocol-names.404", "1.13.2");
d.putIfAbsent("protocol-names.401", "1.13.1");
d.putIfAbsent("protocol-names.393", "1.13");
d.putIfAbsent("protocol-names.340", "1.12.2");
d.putIfAbsent("protocol-names.338", "1.12.1");
d.putIfAbsent("protocol-names.335", "1.12");
d.putIfAbsent("protocol-names.316", "1.11.2");
d.putIfAbsent("protocol-names.315", "1.11");
d.putIfAbsent("protocol-names.210", "1.10.2");
d.putIfAbsent("protocol-names.110", "1.9.4");
d.putIfAbsent("protocol-names.109", "1.9.2");
d.putIfAbsent("protocol-names.108", "1.9.1");
d.putIfAbsent("protocol-names.107", "1.9");
d.putIfAbsent("protocol-names.47", "1.8.9");
d.putIfAbsent("protocol-names.5", "1.7.10");
messages = new Messages(dataFolder, new LogConverter(logger), d);
}
}
@@ -188,12 +188,14 @@ public class QueueManagerImpl implements QueueManager {
}
}
if(!server.isGroup() || !main.getConfig().getBoolean("allow-group-requeue")) {
List<AdaptedServer> notInServers = new ArrayList<>(server.getServers());
notInServers.removeIf(adaptedServer -> !adaptedServer.getName().equals(player.getServerName()));
if(notInServers.size() > 0) {
player.sendMessage(msgs.getComponent("errors.already-connected", "SERVER:"+server.getAlias()));
return false;
}
}
ImmutableList<QueueServer> beforeQueues = getPlayerQueues(player);
if(beforeQueues.size() > 0) {
@@ -438,13 +440,14 @@ public class QueueManagerImpl implements QueueManager {
"TIME:"+ TimeUtils.timeString(time, msgs.getString("format.time.mins"), msgs.getString("format.time.secs"))
);
Title title = Title.title(titleMessage, subTitleMessage, Title.Times.of(Duration.ZERO, Duration.ofSeconds(2L), Duration.ZERO));
Title title = Title.title(titleMessage, subTitleMessage, Title.Times.times(Duration.ZERO, Duration.ofSeconds(2L), Duration.ZERO));
player.showTitle(title);
}
}
}
protected final Map<AdaptedPlayer, Long> pausedAntiSpam = new ConcurrentHashMap<>();
private boolean skipPriorityCheck = true;
@Override
public void sendQueueEvents() {
@@ -467,7 +470,18 @@ public class QueueManagerImpl implements QueueManager {
}
return;
}
if(!getPlayerQueues(player).contains(to)) {
long lastSwitch = main.getServerTimeManager().getLastServerChange(player);
int delay = Math.min(Math.max(main.getConfig().getInt("queue-server-delay"), 0), 3000);
if(System.currentTimeMillis() - lastSwitch < delay + 1000 || !player.getCurrentServer().equals(from)) {
return;
}
if(
!getPlayerQueues(player).contains(to) &&
(
!main.getConfig().getBoolean("require-queueserver-permission") ||
player.hasPermission("ajqueue.queueserver." + to.getName())
)
) {
addToQueue(player, to);
}
});
@@ -481,6 +495,27 @@ public class QueueManagerImpl implements QueueManager {
main.getPlatformMethods().sendPluginMessage(player, "inqueueevent", "true");
}
}
if(main.getConfig().getBoolean("re-check-priority")) {
if(skipPriorityCheck) {
skipPriorityCheck = false;
} else {
for (QueueServer server : servers) {
for (QueuePlayer queuePlayer : server.getQueue()) {
if(queuePlayer.getPlayer() == null) continue;
AdaptedPlayer player = queuePlayer.getPlayer();
AdaptedServer ideal = server.getIdealServer(player);
int currentHighestPriority = main.getLogic().getHighestPriority(server, ideal, player);
if(queuePlayer.getPriority() >= currentHighestPriority) continue;
player.sendMessage(main.getMessages().getComponent("status.priority-increased"));
server.removePlayer(queuePlayer);
addToQueue(player, server);
}
}
}
}
}
@Override
@@ -568,9 +603,10 @@ public class QueueManagerImpl implements QueueManager {
final ConcurrentHashMap<AdaptedPlayer, Long> sendingNowAntiSpam = new ConcurrentHashMap<>();
final Map<QueuePlayer, Integer> sendingAttempts = new WeakHashMap<>();
final Map<QueuePlayer, Long> makeRoomAntispam = new WeakHashMap<>();
@Override
public void sendPlayers(QueueServer queueServer) {
public synchronized void sendPlayers(QueueServer queueServer) {
List<QueueServer> sendingServers;
if(queueServer == null) {
sendingServers = new ArrayList<>(servers);
@@ -603,7 +639,10 @@ public class QueueManagerImpl implements QueueManager {
continue;
}
if(selected.isFull() && !selected.canJoinFull(p.getPlayer())) continue;
if(
(selected.isFull() && !selected.canJoinFull(player)) ||
(server.isManuallyFull() && !AdaptedServer.canJoinFull(player, server.getName()))
) continue;
player.sendMessage(msgs.getComponent("status.sending-now", "SERVER:"+server.getAlias()));
Debug.info("Calling player.connect for " + player.getName() + "(send when back online)");
@@ -618,7 +657,9 @@ public class QueueManagerImpl implements QueueManager {
// If the first person int the queue is offline or already in the server, find the next online player in the queue
int i = 0;
while((nextPlayer == null || server.getServerNames().contains(nextPlayer.getServerName())) && i < server.getQueue().size()) {
List<String> excludableServers = new ArrayList<>(server.getServerNames());
if(nextQueuePlayer.getInitialServer() != null) excludableServers.remove(nextQueuePlayer.getInitialServer().getName());
while((nextPlayer == null || excludableServers.contains(nextPlayer.getServerName())) && i < server.getQueue().size()) {
if(nextPlayer != null) { // Remove them if they are already in the server
server.removePlayer(nextQueuePlayer);
if(server.getQueue().size() > i) {
@@ -650,7 +691,105 @@ public class QueueManagerImpl implements QueueManager {
if(!server.canAccess(nextPlayer)) continue;
if(selected.isFull() && !selected.canJoinFull(nextPlayer)) continue;
if(
(
(selected.isFull() && !selected.canJoinFull(nextPlayer)) ||
(server.isManuallyFull() && !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
)
) continue;
// ajqueue.make-room logic
if(
(
(selected.isFull() && !selected.canJoinFull(nextPlayer)) ||
(server.isManuallyFull() && !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
( // don't make room more than the minimum ping time
System.currentTimeMillis() - makeRoomAntispam.getOrDefault(nextQueuePlayer, 0L)
>= (main.getConfig().getDouble("minimum-ping-time") * 1e3)
)
) {
makeRoomAntispam.put(nextQueuePlayer, System.currentTimeMillis());
List<AdaptedPlayer> players = selected.getPlayers();
// first, we need to find what the lowest priority on the server is
int lowestPriority = Integer.MAX_VALUE;
for (AdaptedPlayer player : players) {
int priority = main.getLogic().getHighestPriority(server, selected, player);
if(priority < lowestPriority) lowestPriority = priority;
}
boolean kickLongest = main.getConfig().getBoolean("make-room-kick-longest-playtime");
long selectedTime = kickLongest ? Long.MAX_VALUE : 0;
AdaptedPlayer selectedPlayer = null;
for (AdaptedPlayer player : players) {
int priority = main.getLogic().getHighestPriority(server, selected, player);
if(priority > lowestPriority) continue; // don't select players with higher priorities
long switchTime = main.getServerTimeManager().getLastServerChange(player);
if(selectedPlayer == null) {
selectedPlayer = player;
selectedTime = switchTime;
continue;
}
if(kickLongest) {
if(switchTime < selectedTime) {
selectedTime = switchTime;
selectedPlayer = player;
}
} else {
if(switchTime > selectedTime) {
selectedTime = switchTime;
selectedPlayer = player;
}
}
}
if(selectedPlayer == null) {
main.getLogger().warn(
"Unable to find player to kick from " + selected.getName() + " " +
"to let " + nextPlayer.getName() + "join!"
);
} else {
Debug.info(
"Selected " + selectedPlayer.getName() + " " +
"to make room for " + nextPlayer.getName() + " in " + selected.getName()
);
String kickToName = main.getConfig().getString("make-room-kick-to");
AdaptedServer kickTo = main.getPlatformMethods().getServer(kickToName);
if(kickTo == null) {
main.getLogger().warn(
"Unable to make room due to '" + kickToName + "' not existing! " +
"Please configure make-room-kick-to in the config"
);
boolean isAdmin = nextPlayer.hasPermission("ajqueue.manage");
nextPlayer.sendMessage(
main.getMessages().getComponent(
isAdmin ? "errors.make-room-failed.admin" : "errors.make-room-failed.player"
)
);
} else {
selectedPlayer.connect(kickTo);
selectedPlayer.sendMessage(main.getMessages().getComponent("errors.kicked-to-make-room"));
if(main.getTimeBetweenPlayers() >= 1d) {
nextPlayer.sendMessage(main.getMessages().getComponent("status.making-room"));
}
continue;
}
}
}
if(main.getConfig().getBoolean("enable-bypasspaused-permission")) {
if(server.isPaused() && !nextPlayer.hasPermission("ajqueue.bypasspaused")) continue;
@@ -682,7 +821,7 @@ public class QueueManagerImpl implements QueueManager {
"title.sending-now.subtitle",
"SERVER:"+server.getAlias()
),
Title.Times.of(Duration.ZERO, Duration.ofSeconds(2L), Duration.ZERO)
Title.Times.times(Duration.ZERO, Duration.ofSeconds(2L), Duration.ZERO)
));
}
sendingNowAntiSpam.put(nextPlayer, System.currentTimeMillis());
@@ -0,0 +1,27 @@
package us.ajg0702.queue.common;
import us.ajg0702.queue.api.ServerTimeManager;
import us.ajg0702.queue.api.players.AdaptedPlayer;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class ServerTimeManagerImpl implements ServerTimeManager {
Map<UUID, Long> serverSwitches = new ConcurrentHashMap<>();
@Override
public long getLastServerChange(AdaptedPlayer player) {
return serverSwitches.get(player.getUniqueId());
}
public void playerChanged(AdaptedPlayer player) {
serverSwitches.put(player.getUniqueId(), System.currentTimeMillis());
}
public void removePlayer(AdaptedPlayer player) {
serverSwitches.remove(player.getUniqueId());
}
}
@@ -61,11 +61,14 @@ public class TaskManager {
TimeUnit.MILLISECONDS
);
int messageTime = main.getConfig().getInt("message-time");
if(messageTime > 0) {
messageTask = scheduleAtFixedRate(
main.getQueueManager()::sendMessages,
main.getConfig().getInt("message-time"),
messageTime,
TimeUnit.SECONDS
);
}
actionBarTask = scheduleAtFixedRate(
main.getQueueManager()::sendActionBars,
@@ -17,7 +17,7 @@ public class PlayerStatusHandler extends MessageHandler {
if(server == null) {
return ComResponse
.from("playerstatus")
.id(data)
.id(player.getUniqueId() + data)
.with("invalid_server");
}
if(!player.isConnected() || player.getServerName() == null) return null;
@@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable;
import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.players.QueuePlayer;
import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer;
import java.util.UUID;
@@ -21,6 +22,8 @@ public class QueuePlayerImpl implements QueuePlayer {
private final int maxOfflineTime;
private final AdaptedServer initialServer;
public int lastPosition;
public QueuePlayerImpl(UUID uuid, String name, QueueServer server, int highestPriority, int maxOfflineTime) {
@@ -42,6 +45,8 @@ public class QueuePlayerImpl implements QueuePlayer {
this.maxOfflineTime = maxOfflineTime;
initialServer = player != null ? player.getCurrentServer() : null;
lastPosition = getPosition();
}
@@ -106,6 +111,11 @@ public class QueuePlayerImpl implements QueuePlayer {
return maxOfflineTime;
}
@Override
public AdaptedServer getInitialServer() {
return initialServer;
}
private long leaveTime = 0;
public void setLeaveTime(long leaveTime) {
@@ -1,9 +1,11 @@
package us.ajg0702.queue.common.queues;
import com.google.common.collect.ImmutableList;
import us.ajg0702.queue.api.AjQueueAPI;
import us.ajg0702.queue.api.events.PositionChangeEvent;
import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.players.QueuePlayer;
import us.ajg0702.queue.api.queueholders.QueueHolder;
import us.ajg0702.queue.api.queues.Balancer;
import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer;
@@ -11,13 +13,12 @@ import us.ajg0702.queue.api.server.AdaptedServerPing;
import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.queue.common.players.QueuePlayerImpl;
import us.ajg0702.queue.common.queues.balancers.DefaultBalancer;
import us.ajg0702.queue.common.queues.balancers.FirstBalancer;
import us.ajg0702.queue.common.queues.balancers.MinigameBalancer;
import us.ajg0702.queue.common.utils.Debug;
import us.ajg0702.utils.common.Messages;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class QueueServerImpl implements QueueServer {
@@ -27,7 +28,7 @@ public class QueueServerImpl implements QueueServer {
private final List<AdaptedServer> servers;
private final List<QueuePlayer> queue = new ArrayList<>();
private final QueueHolder queueHolder = AjQueueAPI.getQueueHolderRegistry().getQueueHolder(this);
private List<Integer> supportedProtocols = new ArrayList<>();
@@ -37,6 +38,9 @@ public class QueueServerImpl implements QueueServer {
private long lastSentTime = 0;
private int manualMaxPlayers = Integer.MAX_VALUE;
public QueueServerImpl(String name, QueueMain main, AdaptedServer server, List<QueuePlayer> previousPlayers) {
this(name, main, Collections.singletonList(server), previousPlayers);
}
@@ -54,11 +58,13 @@ public class QueueServerImpl implements QueueServer {
String balancerType = type.substring(colon+1);
if(groupName.equals(name)) {
//noinspection SwitchStatementWithTooFewBranches
switch(balancerType.toLowerCase(Locale.ROOT)) {
case "minigame":
balancer = new MinigameBalancer(this, main);
break;
case "first":
balancer = new FirstBalancer(this, main);
break;
default:
balancerType = "default";
balancer = new DefaultBalancer(this, main);
@@ -72,6 +78,26 @@ public class QueueServerImpl implements QueueServer {
Debug.info("Using default balancer for "+name);
}
List<String> manualLimits = main.getConfig().getStringList("manual-max-players");
for (String manualLimit : manualLimits) {
String[] parts = manualLimit.split(":");
if(parts.length != 2) {
main.getLogger().warn("Invalid manual limit: " + manualLimit);
continue;
}
String limitFor = parts[0];
if(!limitFor.equals(name)) continue;
String limitStr = parts[1];
try {
manualMaxPlayers = Integer.parseInt(limitStr);
} catch(NumberFormatException e) {
main.getLogger().warn("Invalid limit number for " + limitFor);
}
break;
}
for(QueuePlayer queuePlayer : previousPlayers) {
if(queuePlayer.getPlayer() == null) {
addPlayer(
@@ -98,7 +124,7 @@ public class QueueServerImpl implements QueueServer {
@Override
public ImmutableList<QueuePlayer> getQueue() {
return ImmutableList.copyOf(queue);
return ImmutableList.copyOf(queueHolder.getAllPlayers());
}
@Override
@@ -118,11 +144,11 @@ public class QueueServerImpl implements QueueServer {
return msgs.getString("status.offline.paused");
}
if(p != null && server.isWhitelisted() && !server.getWhitelistedPlayers().contains(p.getUniqueId())) {
if(server.isWhitelisted() && (p == null || !server.getWhitelistedPlayers().contains(p.getUniqueId()))) {
return msgs.getString("status.offline.whitelisted");
}
if(server.isFull() && !server.canJoinFull(p)) {
if((server.isFull() && !server.canJoinFull(p)) || (isManuallyFull() && !AdaptedServer.canJoinFull(p, getName()))) {
return msgs.getString("status.offline.full");
}
@@ -154,11 +180,11 @@ public class QueueServerImpl implements QueueServer {
return "paused";
}
if(p != null && server.isWhitelisted() && !server.getWhitelistedPlayers().contains(p.getUniqueId())) {
if(server.isWhitelisted() && (p == null || !server.getWhitelistedPlayers().contains(p.getUniqueId()))) {
return "whitelisted";
}
if(server.isFull() && !server.canJoinFull(p)) {
if(((server.isFull() && !server.canJoinFull(p)) || (isManuallyFull() && !AdaptedServer.canJoinFull(p, getName())))) {
return "full";
}
@@ -185,11 +211,31 @@ public class QueueServerImpl implements QueueServer {
@Override
public boolean isJoinable(AdaptedPlayer p) {
if(isManuallyFull() && !AdaptedServer.canJoinFull(p, getName())) return false;
AdaptedServer server = getIdealServer(p);
if(server == null) return false;
return server.isJoinable(p) && !isPaused();
}
@Override
public int getManualMaxPlayers() {
return manualMaxPlayers;
}
@Override
public boolean isManuallyFull() {
int total = 0;
for (AdaptedServer server : servers) {
Optional<AdaptedServerPing> lastPing = server.getLastPing();
if(!lastPing.isPresent()) continue;
total += lastPing.get().getPlayerCount();
}
// Debug.info(total + " >= " + getManualMaxPlayers() + " = " + (total >= getManualMaxPlayers()));
return total >= getManualMaxPlayers();
}
@Override
public synchronized void setPaused(boolean paused) {
this.paused = paused;
@@ -201,9 +247,9 @@ public class QueueServerImpl implements QueueServer {
}
@Override
public synchronized void removePlayer(QueuePlayer player) {
public void removePlayer(QueuePlayer player) {
main.getQueueManager().getSendingAttempts().remove(player);
queue.remove(player);
queueHolder.removePlayer(player);
positionChange();
}
@@ -220,13 +266,13 @@ public class QueueServerImpl implements QueueServer {
}
@Override
public synchronized void addPlayer(QueuePlayer player, int position) {
if(!player.getQueueServer().equals(this) || queue.contains(player)) return;
public void addPlayer(QueuePlayer player, int position) {
if(!player.getQueueServer().equals(this) || queueHolder.findPlayer(player.getUniqueId()) != null) return;
if(position >= 0) {
queue.add(position, player);
queueHolder.addPlayer(player, position);
} else {
queue.add(player);
queueHolder.addPlayer(player);
}
positionChange();
}
@@ -271,6 +317,11 @@ public class QueueServerImpl implements QueueServer {
return ImmutableList.copyOf(names);
}
@Override
public boolean isOnline() {
return QueueServer.super.isOnline();
}
@Override
public boolean isGroup() {
return servers.size() > 1;
@@ -278,25 +329,15 @@ public class QueueServerImpl implements QueueServer {
@Override
public QueuePlayer findPlayer(String player) {
for(QueuePlayer queuePlayer : queue) {
if(queuePlayer.getName().equalsIgnoreCase(player)) {
return queuePlayer;
}
}
return null;
return queueHolder.findPlayer(player);
}
@Override
public QueuePlayer findPlayer(AdaptedPlayer player) {
return findPlayer(player.getUniqueId());
}
@Override
public synchronized QueuePlayer findPlayer(UUID uuid) {
for(QueuePlayer queuePlayer : queue) {
if(queuePlayer.getUniqueId().toString().equals(uuid.toString())) {
return queuePlayer;
}
}
return null;
public QueuePlayer findPlayer(UUID uuid) {
return queueHolder.findPlayer(uuid);
}
@Override
@@ -319,9 +360,14 @@ public class QueueServerImpl implements QueueServer {
return balancer;
}
@Override
public QueueHolder getQueueHolder() {
return queueHolder;
}
private void positionChange() {
main.getTaskManager().runNow(
() -> queue.forEach(queuePlayer -> {
() -> queueHolder.getAllPlayers().forEach(queuePlayer -> {
if(((QueuePlayerImpl) queuePlayer).lastPosition != queuePlayer.getPosition()) {
main.call(new PositionChangeEvent(queuePlayer));
}
@@ -1,15 +1,13 @@
package us.ajg0702.queue.common.queues.balancers;
import org.jetbrains.annotations.Nullable;
import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.queues.Balancer;
import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.api.server.AdaptedServerPing;
import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.queue.common.utils.Debug;
import us.ajg0702.utils.common.GenUtils;
import java.util.HashMap;
import java.util.List;
public class DefaultBalancer implements Balancer {
@@ -22,7 +20,13 @@ public class DefaultBalancer implements Balancer {
}
@Override
public AdaptedServer getIdealServer(AdaptedPlayer player) {
public AdaptedServer getIdealServer(@Nullable AdaptedPlayer player) {
AdaptedServer alreadyConnected;
if(player == null) {
alreadyConnected = null;
} else {
alreadyConnected = player.getCurrentServer();
}
List<AdaptedServer> servers = server.getServers();
AdaptedServer selected = null;
int selectednum = 0;
@@ -31,6 +35,7 @@ public class DefaultBalancer implements Balancer {
} else {
for(AdaptedServer sv : servers) {
if(!sv.isOnline()) continue;
if(sv.equals(alreadyConnected)) continue;
int online = sv.getPlayerCount();
if(selected == null) {
selected = sv;
@@ -0,0 +1,37 @@
package us.ajg0702.queue.common.queues.balancers;
import org.jetbrains.annotations.Nullable;
import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.queues.Balancer;
import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.common.QueueMain;
public class FirstBalancer implements Balancer {
private final QueueServer server;
private final QueueMain main;
public FirstBalancer(QueueServer server, QueueMain main) {
this.server = server;
this.main = main;
}
@Override
public AdaptedServer getIdealServer(@Nullable AdaptedPlayer player) {
AdaptedServer alreadyConnected;
if(player == null) {
alreadyConnected = null;
} else {
alreadyConnected = player.getCurrentServer();
}
for (AdaptedServer sv : server.getServers()) {
if(!sv.isOnline()) continue;
if(sv.equals(alreadyConnected)) continue;
if(!sv.isJoinable(player)) continue;
return sv;
}
// If all servers are unavailable, just select the first one
return server.getServers().get(0);
}
}
@@ -1,13 +1,15 @@
package us.ajg0702.queue.common.queues.balancers;
import org.jetbrains.annotations.Nullable;
import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.queues.Balancer;
import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.api.server.AdaptedServerPing;
import us.ajg0702.queue.common.QueueMain;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class MinigameBalancer implements Balancer {
@@ -19,7 +21,13 @@ public class MinigameBalancer implements Balancer {
}
@Override
public AdaptedServer getIdealServer(AdaptedPlayer player) {
public AdaptedServer getIdealServer(@Nullable AdaptedPlayer player) {
AdaptedServer alreadyConnected;
if(player == null) {
alreadyConnected = null;
} else {
alreadyConnected = player.getCurrentServer();
}
List<AdaptedServer> servers = server.getServers();
if(servers.size() == 1) {
return servers.get(0);
@@ -30,6 +38,7 @@ public class MinigameBalancer implements Balancer {
for(AdaptedServer si : svs) {
if(!si.isOnline()) continue;
if(si.equals(alreadyConnected)) continue;
int online = si.getPlayerCount();
int max = si.getMaxPlayers();
if(online < max && si.isJoinable(player)) {
@@ -28,6 +28,11 @@ public class FreeLogic implements Logic {
return null;
}
@Override
public int getHighestPriority(QueueServer queueServer, AdaptedServer server, AdaptedPlayer player) {
return player.hasPermission("ajqueue.priority") ? 1 : 0;
}
@Override
public boolean hasAnyBypass(AdaptedPlayer player, String server) {
return false;
+301 -234
View File
@@ -1,179 +1,66 @@
# Dont touch this number please
config-version: 35
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# _ ___ #
# (_) / _ \ #
# __ _ _ | | | | _ _ ___ _ _ ___ #
# / _` || || | | || | | | / _ \| | | | / _ \ #
# | (_| || |\ \/' /| |_| || __/| |_| || __/ #
# \__,_|| | \_/\_\ \__,_| \___| \__,_| \___| #
# _/ | #
# |__/ #
# #
# Welcome to the config for ajQueue! #
# #
# Make sure to read the comments above each option to know what that option does. #
# #
# If you have any questions, first make sure you've read the comment above the option, then #
# feel free to join my discord and ask there (invite link is on the plugin page) #
# #
# Happy configuring! #
# #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# This is the main config for ajQueue.
# If you have any questions, make sure to read the comment above the options first,
# then feel free to join my discord and ask for support.
# Discord invite link is on the plugin page.
# The time the server will wait between sending people in the queue
# The time the server will wait between sending people in the queue (in seconds, supports decimals)
# Default: 5
wait-time: 5.0
# The time that a server has to be offline to be marked as offline instead of restarting
# Default: 120
offline-time: 120
# The time the server will wait between sending players update messages on what position they are in the queue.
# The time ajQueue will wait between sending players update messages on
# what position they are in the queue, their ETA, and status of the queue (in seconds)
# You can set to any negative number to disable the messages
# Default: 10
message-time: 10
# If a player is in a server, you can have the plugin make them automatically join a queue for another server
# Example with the default values: Player joins the limbo server, they will auto-join the queue for the lobbys group
# Note that you dont have to use groups. Just put the name of a server to use a single server instead.
queue-servers:
- 'limbo:lobbys'
# Should the plugin send an actionbar to the player?
# The actionbar contains some info such as which server they are queued for, what position they are in, estimated time remaining, etc.
send-actionbar: true
# What kick reasons should cause the player to be removed from the queue?
# For example, if one of the below kick reasons is 'banned' and the player gets kicked when trying to connect to
# a server in a queue with a message saying "You are banned from this server!" then it will kick them from the queue too.
kick-reasons:
- 'banned'
- 'blacklisted'
# Should we completly kick the user from the server if they are in a queue-server
# and are kicked from the server with one of the above reasons?
# Note this will do nothing on servers that arent queue-servers
# (as in the config option queue-servers)
# Default: true
kick-kicked-players: true
# Should we remove a player from the queue if they move servers?
# This will remove the player from if they switch to any other server
# Default: false
remove-player-on-server-switch: false
# Should we wait until the server is done loading to load the servers?
# Enable this if you have a plugin that adds servers to the server list during startup.
# Default: false
wait-to-load-servers: false
# How long should we wait after the server finishes loading to load the server list?
# Only works if the above is enabled.
# This is in miliseconds so 1000 = 1 second
# Default: 500
wait-to-load-servers-delay: 500
# How often (in seconds) we should check for new servers to add queues for.
# If you dynamicly add servers, set this to something other than 0.
# To disable, set to 0
# Default: 0
reload-servers-interval: 0
# Should we require permissions for players to be able to join queues?
# If enabled, players will be required to have the permission ajqueue.queue.<server> to be able to join queues
# Replace <server> with the name of the server or group to let the player queue for
# Default: false
require-permission: false
# Should we let players join more than one queue?
# If enabled, players will be able to be in multiple queues at once.
# If disabled, players will be removed from the previous queue when joining a new queue
# Default: true
allow-multiple-queues: true
# If the player is queued for multiple servers, which server should we pick to use in things like placeholders and actionbars
# Options are first and last
# Default: last
multi-server-queue-pick: last
# THIS FEATURE IS ONLY AVAILABLE ON ajQueuePlus (https://www.spigotmc.org/resources/ajqueueplus.79123/)
# This will show players a different name than the actual proxy server name
# for example, instead of showing players "event-a", this option can make it appear as "Event A"
# With this example, you would use this: - "event-a:Event A"
# Note that currently players still have to use the normal names in queue commands and leave commands
# Format: "realname:Alias"
server-aliases:
- "event-a:Event A"
# How long should we wait after a server is online before sending players?
# The server will still show up as offline or restarting until this amount of time after its up
# Meant to let your server 'cool down' after lag from starting up
# In seconds
# Default: 1
wait-after-online: 1
# This is for helping with finding issues with the server pinged
# This will spam the console when enabled
# When this enabled, if servers are offline then it will spam errors. You can ignore them.
# Default: false
pinger-debug: false
# When a queue is paused, should we prevent players from joining it?
# Default: false
prevent-joining-paused: false
# When a server goes back online, should we send all players in the queue instantly?
# Default: false
send-all-when-back-online: false
# Require a permission for players to be able to join a queue from a server
# Require a permission for players to be able to join a queue from a server.
# If enabled, players will need the permission ajqueue.joinfrom.<server> to join queues.
# Replace <server> with the name of the server
# Default: false
joinfrom-server-permission: false
# Server groups are a group of servers that you can queue for. It will send you to the server that is the least full.
# If all servers in the group are full, it will act the same as it would when a single server is full.
# Same if all servers are offline. It will only send players to servers that are online.
# Format: "groupname:server1,server2,etc"
server-groups:
- "lobbys:lobby-1,lobby-2,lobby-3"
# Should we allow tab-completing in the /queue command?
# Default: true
tab-complete-queues: true
# Should we have no wait time for these servers?
# If the server is joinable, the plugin will attempt to send players who join these queues as soon as they join.
# If the server is not immidiatly joinable, they will have to wait for the normal wait-time
# This also works with group
# NOTE: Server names are caps sensitive
send-instantly:
- "lobbys"
# Should we log to the proxy console when a player fails to get sent to a server from the queue?
# Enable this if you are having an issue with one player stopping the queue
# Default: false
send-fail-debug: false
# After how many (unsuccessfull) attempts of sending the player should we remove them from the queue?
# Set to -1 to disable
# Default: 10
max-tries: 10
# Should we enable the ajqueue.bypasspaused permission?
# If enabled, anyone with the permission ajqueue.bypasspaused will be able to join paused servers
# Default: false
enable-bypasspaused-permission: false
# Should we check to make sure that people dont get sent quicker than wait-time?
# Default: true
check-last-player-sent-time: true
# Should we send debug info to the console when priority queue is used?
# This will print several lines to the console when a player joins a queue,
# so you should probably only use this for debugging purposes
# Default: false
priority-queue-debug: false
# What kick reasons should cause the player to be removed from the queue?
# This works on contains, so you only need to include a word or two from the kick message.
# For example, if one of the below kick reasons is 'banned' and the player gets kicked when trying to connect to
# a server in a queue with a message saying "You are banned from this server!" then it will kick them from the queue too.
kick-reasons:
- 'banned'
- 'blacklisted'
# When a player is kicked from a server, should we automatically add that player to the queue?
# You will still need to use another plugin to make sure the player doesnt get kicked from the proxy completly.
# On BungeeCord, you will still need to use another plugin to make sure the player doesn't get kicked from the proxy completely.
# Default: false
auto-add-to-queue-on-kick: false
# The delay for the above option.
@@ -182,19 +69,111 @@ auto-add-to-queue-on-kick: false
auto-add-to-queue-on-kick-delay: 1
# With what kick reasons should we auto-add the player to the queue
# This wont work if auto-add-to-queue-on-kick is disabled.
# This won't work if auto-add-to-queue-on-kick is disabled.
# If you set it to [], then all kick messages will cause the player to be added to the queue
# This works on contains, so you dont have to include the whole kick message, just a few words.
# This works on contains, so you don't have to include the whole kick message, just a few words.
auto-add-kick-reasons:
- "restarting"
- "closed"
# If a player is in a server, you can have the plugin make them automatically join a queue for another server
# Example with the default values: Player joins the limbo server, they will auto-join the queue for the lobbys group
# Note that you don't have to use groups. Just put the name of a server to use a single server instead.
# You do NOT have to set a queue server to use queues.
queue-servers:
- 'limbo:lobbys'
# How much should we delay queueing players in queue servers?
# You should only use this if you have issues with the instant sending.
# Set to 0 or any negative number to disable
# In milliseconds. Maximum value is 3000 (3 seconds)
# Default: 0
queue-server-delay: 0
# Should we completely kick the user from the server if they are in a queue-server
# and are kicked from the server with one of the above reasons?
# Note this will do nothing on servers that aren't queue-servers
# (as in the config option queue-servers)
# Default: true
kick-kicked-players: true
# This option allows you to manually set player caps for servers
# Note that this does NOT override the player cap returned by the server.
# Format: - '<server>:<max-players>'
# Example: - 'lobbys:50'
# The example above will limit the lobbys group to have a total of 50 players.
# This works on both groups and individual servers
manual-max-players: []
# Server groups are a group of servers that you can queue for. It will send you to the server that is the least full.
# If all servers in the group are full, it will act the same as it would when a single server is full.
# Same if all servers are offline. It will only send players to servers that are online.
# Format: "groupname:server1,server2,etc"
server-groups:
- "lobbys:lobby-1,lobby-2,lobby-3"
# What balancer should we use for groups?
# If a group is not specified here, then the default one is used
# Example: - "bedwars:minigame"
# The example above will set the bedwars group to use the minigame balancer
# Balancers:
# default - Will send the player to the server in the group with the least number of players
# minigame - Will send the player to the server with the most players, until that server is full, which it will then send to the next server
# first - Will send the player to the first available server in the group (as long as it is joinable)
balancer-types:
- "bedwars:minigame"
# If a player is in a server that is in a group and they re-queue for that group, should we allow it?
# false - prevent player from re-queueing; say "already connected" message
# true - let player re-queue; will send them to a server other than the one they're connected to
# Default: false
allow-group-requeue: false
# What priority should we give whitelisted players priority when the server is whitelisted?
# This will have no effect if the server isn't whitelisted
# If you set to 0, this will be disabled
# If you have the free version, set it to 1 to enable
give-whitelisted-players-priority: 0
# What priority should we give players that are able to bypass paused priority when the server is paused?
# This will have no effect if the server isn't paused
# If you set to 0, this will be disabled
# If you have the free version, set it to 1 to enable
give-pausedbypass-players-priority: 0
# What priority should we give players that are able to bypass full servers priority when the server is full?
# This will have no effect if the server isn't full
# If you are using make-room, this also applies to that
# If you set to 0, this will be disabled
# If you have the free version, set it to 1 to enable
give-fulljoin-players-priority: 0
# Should we remove a player from the queue if they move servers?
# This will remove the player from if they switch to any other server
# Default: false
remove-player-on-server-switch: false
# Should we enable the server command being a queue command?
# This may require extra setup on bungeecord. See the wiki:
# https://wiki.ajg0702.us/ajqueue/setup/replacing-server-command
# Default: false
enable-server-command: false
# What servers should we make slash server commands for?
# For example, if survival is in this list, then if a player executes /survival
# then they will be put in the queue for survival
# This works for both servers and groups
# If you have ajQueuePlus, you can also make aliases.
# For example, if you have a server called lobby, and you want people to be able to use /hub, you can use this:
# - "hub:lobby"
# If you have the free version, you can only put the server name, no aliases.
slash-servers: []
# Should we enable priority messages?
# Configure the priority messages in the option below.
# Default: false
@@ -209,11 +188,156 @@ priority-messages:
- "*:<green>Joining the queue with a priority of {PRIORITY}!"
- "100:<yellow>Wow! You have a priority of 100!"
# Should the plugin send a title to the player?
# The title shows what position the player is in the queue
# Default: false
send-title: false
# Should we log to the proxy console when a player fails to get sent to a server from the queue?
# Enable this if you are having an issue with one player stopping the queue
# Default: false
send-fail-debug: false
# Should the plugin send an actionbar to the player?
# The actionbar contains some info such as which server they are queued for, what position they are in, estimated time remaining, etc.
send-actionbar: true
# THIS FEATURE IS ONLY AVAILABLE ON ajQueuePlus (https://www.spigotmc.org/resources/ajqueueplus.79123/)
# This will show players a different name than the actual proxy server name
# for example, instead of showing players "event-a", this option can make it appear as "Event A"
# With this example, you would use this: - "event-a:Event A"
# Note that currently players still have to use the normal names in queue commands and leave commands
# Format: "realname:Alias"
server-aliases:
- "event-a:Event A"
# The time that a server has to be offline to be marked as offline instead of restarting (in seconds)
# Default: 120
offline-time: 120
# On velocity, should we end a player a message when they are kicked while trying to connect to a server with the queue?
# This has no effect on bungee, because the message is sent from bungee and there's no way to change that in ajQueue
# Default: false
velocity-kick-message: false
# Should we wait until the server is done loading to load the servers?
# Enable this if you have a plugin that adds servers to the server list during startup.
# Default: false
wait-to-load-servers: false
# How long should we wait after the server finishes loading to load the server list?
# Only works if the above is enabled.
# This is in milliseconds so 1000 = 1 second
# Default: 500
wait-to-load-servers-delay: 500
# How often (in seconds) we should check for new servers to add queues for.
# If you dynamically add servers, set this to something other than 0.
# To disable, set to 0
# Default: 0
reload-servers-interval: 0
# Should we let players join more than one queue?
# If enabled, players will be able to be in multiple queues at once.
# If disabled, players will be removed from the previous queue when joining a new queue
# Default: true
allow-multiple-queues: true
# If the player is queued for multiple servers, which server should we pick to use in things like placeholders and actionbars
# Options are first and last
# Default: last
multi-server-queue-pick: last
# How long should we wait after a server is online before sending players?
# The server will still show up as offline or restarting until this amount of time after its up
# Meant to let your server 'cool down' after lag from starting up
# In seconds
# Default: 1
wait-after-online: 1
# This is for helping with finding issues with the server pinged
# This will spam the console when enabled
# When this enabled, if servers are offline then it will spam errors. You can ignore them.
# Default: false
pinger-debug: false
# When a queue is paused, should we prevent players from joining it?
# (instead of having players wait in the queue until it's unpaused)
# Default: false
prevent-joining-paused: false
# When a server goes back online, should we send all players in the queue instantly?
# Default: false
send-all-when-back-online: false
# Should we allow tab-completing in the /queue command?
# Any server the player doesn't have permission for (require-permission)
# will not tab-complete
# Default: true
tab-complete-queues: true
# Should we have no wait time for these servers?
# If the server is joinable, the plugin will attempt to send players who join these queues as soon as they join.
# If the server is not immediately joinable, they will have to wait for the normal wait-time
# This also works with group
# NOTE: Server names are caps sensitive
send-instantly:
- "lobbys"
# Should we require permissions for queue-servers to work?
# If enabled, players will need to have the ajqueue.queueserver.<server> permission
# <server> being the target server
# Note that this will only affect queue-servers
# Default: false
require-queueserver-permission: false
# After how many (unsuccessful) attempts of sending the player should we remove them from the queue?
# Set to -1 to disable
# Default: 10
max-tries: 10
# What QueueHolder should we use?
# By default, the only QueueHolder available is 'default'
# But more may be available via addons (registered via the API)
queue-holder: default
# Should we enable the ajqueue.make-room permission?
# The make-room permission will force there to be room in a server.
# So, if a player with this permission queues for a server and has this permission,
# someone from the server will be moved to the lobby to make room
# This can be further configured using the next few options
# Default: false
enable-make-room-permission: false
# What server should the make-room permission move players to?
# Default: lobby
make-room-kick-to: lobby
# For the make-room permission, players with the lowest priority are kicked first.
# Of those players, this option decides which to kick.
# true - kick players who have been on the server the longest
# false - kick players who have been on the server the shortest
# Default: true
make-room-kick-longest-playtime: true
# Should we check every 4 seconds if a player has a higher priority permission than before
# If they do, they are removed and re-added to the queue (only if they would be put in a higher position)
# Default: false
re-check-priority: false
# Should we check to make sure that people don't get sent quicker than wait-time?
# Default: true
check-last-player-sent-time: true
# Should we send debug info to the console when priority queue is used?
# This will print several lines to the console when a player joins a queue,
# so you should probably only use this for debugging purposes
# Default: false
priority-queue-debug: false
# What protocols do servers support?
# The protocol version number list can be found here: https://wiki.vg/Protocol_version_numbers
# Format: server(s):protocol(s)
@@ -224,90 +348,9 @@ send-title: false
supported-protocols:
- "1.17:755,756"
# These are the protocol names the plugin should use.
# If you are on velocity, if the protocol is not listed here then the velocity
# api will be used to find the name of the protocol.
# If you are on bungee, only this list can be used.
protocol-names:
- "757:1.18.1"
- "756:1.17.1"
- "755:1.17"
- "754:1.16.5"
- "753:1.16.3"
- "751:1.16.2"
- "736:1.16.1"
- "735:1.16"
- "578:1.15.2"
- "575:1.15.1"
- "573:1.15"
- "498:1.14.4"
- "490:1.14.3"
- "485:1.14.2"
- "480:1.14.1"
- "477:1.14"
- "404:1.13.2"
- "401:1.13.1"
- "393:1.13"
- "340:1.12.2"
- "338:1.12.1"
- "335:1.12"
- "316:1.11.2"
- "315:1.11"
- "210:1.10.2"
- "110:1.9.4"
- "109:1.9.2"
- "108:1.9.1"
- "107:1.9"
- "47:1.8.9"
- "5:1.7.10"
# On velocity, should we end a player a message when they are kicked while trying to connect to a server with the queue?
# This has no effect on bungee, because the message is sent from bungee and theres no way to change that in ajQueue
# Default: false
velocity-kick-message: false
# Should the updater be enabled?
enable-updater: true
# What servers should we make slash server commands for?
# For example, if survival is in this list, then if a player executes /survival
# then they will be put in the queue for survival
# This works for both servers and groups
# If you have ajQueuePlus, you can also make aliases.
# For example, if you have a server called lobby, and you want people to be able to use /hub, you can use this:
# - "hub:lobby"
# If you have the free version, you can only put the server name, no aliases.
slash-servers: []
# What balancer should we use?
# If a group is not specified here, then the default one is used
# Example entry: - "bedwars:minigame"
# Balancers:
# default - Will send the player to the server in the group with the least number of players
# minigame - Will send the player to the server with the most players, until that server is full, which it will then send to the next server
balancer-types:
- "bedwars:minigame"
# What priority should we give whitelisted players priority when the server is whitelisted?
# This will have no effect if the server isnt whitelisted
# If you set to 0, this will be disabled
# If you have the free version, set it to 1 to enable
give-whitelisted-players-priority: 0
# What priority should we give players that are able to bypass paused priority when the server is paused?
# This will have no effect if the server isnt paused
# If you set to 0, this will be disabled
# If you have the free version, set it to 1 to enable
give-pausedbypass-players-priority: 0
# What priority should we give players that are able to bypass full servers priority when the server is full?
# This will have no effect if the server isnt full
# If you set to 0, this will be disabled
# If you have the free version, set it to 1 to enable
give-fulljoin-players-priority: 0
# Should we force players to be queued every few seconds for queue-servers?
# This will check every few seconds, and if a player in a queue-server is
# not in the queue for the target server, it will add them.
@@ -321,10 +364,34 @@ queue-command-cooldown: 3
# Should any server switch (including the initial join) count against the queue command cooldown?
include-server-switch-in-cooldown: false
# The minimum time between pinging the server.
# The minimum time between pinging the server. (in seconds)
# If ajQueue is pinging your backend servers too often, raise this number
minimum-ping-time: 1.0
# In ajQueuePlus, if your permission plugin isn't yet supported, you can use this workaround to
# be able to use levels 1-10 for priority, or 15, 30, 60, and 120 for stayqueued
# If you want more levels than that, contact aj to add support for your permission plugin if possible.
# Does nothing if you are not on ajQueuePlus, or if you have a supported permission plugin
plus-level-fallback: false
# Should we print some extra stuff to the console that might help aj diagnose some issues?
debug: false
# # # # # # # # # # # # # # # # # # # # #
# #
# End of config. Happy queue-ing :) #
# #
# # # # # # # # # # # # # # # # # # # # #
# Don't touch this number please
config-version: 44
# This is ONLY here so that they can be moved to messages.yml. Please edit these in messages.yml!
protocol-names: []
# ^ only edit these in messages.yml
@@ -106,23 +106,17 @@ public class BungeeServer implements AdaptedServer {
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") ||
(AjQueueAPI.getInstance().isPremium() && AjQueueAPI.getInstance().getLogic().getPermissionGetter().hasUniqueFullBypass(player, getName()))
;
}
@Override
public boolean justWentOnline() {
return System.currentTimeMillis()-lastOffline <= (AjQueueAPI.getInstance().getConfig().getDouble("wait-time") * 2 * 1000) && isOnline();
}
@Override
public boolean shouldWaitAfterOnline() {
return System.currentTimeMillis()-lastOffline <= (AjQueueAPI.getInstance().getConfig().getDouble("wait-after-online") * 2 * 1000) && getLastPing().isPresent();
}
@Override
public ServerInfo getHandle() {
return handle;
@@ -9,7 +9,6 @@ import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.api.server.AdaptedServerInfo;
import us.ajg0702.queue.api.server.AdaptedServerPing;
import us.ajg0702.queue.api.util.QueueLogger;
import us.ajg0702.queue.common.utils.Debug;
import us.ajg0702.queue.platforms.velocity.players.VelocityPlayer;
import java.util.ArrayList;
@@ -114,21 +113,13 @@ public class VelocityServer implements AdaptedServer {
}
@Override
public boolean canJoinFull(AdaptedPlayer player) {
if(player == null) return true;
Debug.info("on "+getName());
return
player.hasPermission("ajqueue.joinfull") ||
player.hasPermission("ajqueue.joinfullserver."+getName()) ||
player.hasPermission("ajqueue.joinfullandbypassserver."+getName()) ||
player.hasPermission("ajqueue.joinfullandbypass") ||
(AjQueueAPI.getInstance().isPremium() && AjQueueAPI.getInstance().getLogic().getPermissionGetter().hasUniqueFullBypass(player, getName()))
;
public boolean justWentOnline() {
return System.currentTimeMillis()-lastOffline <= (AjQueueAPI.getInstance().getConfig().getDouble("wait-time") * 2 * 1000) && isOnline();
}
@Override
public boolean justWentOnline() {
return System.currentTimeMillis()-lastOffline <= (AjQueueAPI.getInstance().getConfig().getDouble("wait-time") * 2 * 1000) && isOnline();
public boolean shouldWaitAfterOnline() {
return System.currentTimeMillis()-lastOffline <= (AjQueueAPI.getInstance().getConfig().getDouble("wait-after-online") * 2 * 1000) && getLastPing().isPresent();
}
@Override
@@ -18,6 +18,15 @@ public class PremiumLogic implements Logic {
return permissionGetter;
}
@Override
public int getHighestPriority(QueueServer queueServer, AdaptedServer server, AdaptedPlayer player) {
int normalPriority = permissionGetter.getPriority(player);
int serverPriority = permissionGetter.getServerPriotity(queueServer.getName(), player);
int unJoinablePriority = Logic.getUnJoinablePriorities(queueServer, server, player);
return Math.max(normalPriority, Math.max(serverPriority, unJoinablePriority));
}
private final PermissionGetter permissionGetter;
public PremiumLogic(QueueMain main) {
permissionGetter = new PermissionGetterImpl(main);
@@ -1,9 +1,11 @@
package us.ajg0702.queue.logic.permissions;
import us.ajg0702.queue.api.AjQueueAPI;
import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.premium.PermissionGetter;
import us.ajg0702.queue.api.premium.PermissionHook;
import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.queue.common.utils.Debug;
import us.ajg0702.queue.logic.permissions.hooks.AquaCoreHook;
import us.ajg0702.queue.logic.permissions.hooks.BuiltInHook;
import us.ajg0702.queue.logic.permissions.hooks.LuckPermsHook;
@@ -13,16 +15,15 @@ import java.util.*;
public class PermissionGetterImpl implements PermissionGetter {
private final List<PermissionHook> hooks;
private final QueueMain main;
private PermissionHook builtInHook;
public PermissionGetterImpl(QueueMain main) {
hooks = Arrays.asList(
new BuiltInHook(main),
AjQueueAPI.getPermissionHookRegistry().register(
new LuckPermsHook(main),
new UltraPermissionsHook(main),
new AquaCoreHook(main)
);
builtInHook = new BuiltInHook(main);
this.main = main;
}
@@ -30,16 +31,15 @@ public class PermissionGetterImpl implements PermissionGetter {
@Override
public PermissionHook getSelected() {
if(selected != null) return selected;
if(hooks == null) {
throw new IllegalStateException("Hooks are not initialized yet!");
}
for(PermissionHook hook : hooks) {
if(hook.canUse()) {
for(PermissionHook hook : AjQueueAPI.getPermissionHookRegistry().getRegisteredHooks()) {
boolean canUse = hook.canUse();
Debug.info(hook.getName() + " "+ canUse);
if(canUse) {
selected = hook;
}
}
if(selected == null) {
throw new IllegalStateException("All hooks are unusable!");
selected = builtInHook;
}
main.getLogger().info("Using "+selected.getName()+" for permissions.");
return selected;
@@ -5,6 +5,8 @@ import us.ajg0702.queue.common.QueueMain;
import us.ajg0702.queue.api.premium.PermissionHook;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class BuiltInHook implements PermissionHook {
@@ -26,9 +28,41 @@ public class BuiltInHook implements PermissionHook {
@Override
public List<String> getPermissions(AdaptedPlayer player) {
if(main.getPlatformMethods().getImplementationName().equals("velocity")) {
return new ArrayList<>();
if(main.getConfig().getBoolean("plus-level-fallback")) {
List<String> hasPermissions = new ArrayList<>();
for (String fallbackPermission : fallbackPermissions) {
if(player.hasPermission(fallbackPermission)) {
hasPermissions.add(fallbackPermission);
}
}
if(!main.getPlatformMethods().getImplementationName().equals("velocity")) {
hasPermissions.addAll(player.getPermissions());
}
return hasPermissions;
}
if(main.getPlatformMethods().getImplementationName().equals("velocity")) {
return Collections.emptyList();
}
return player.getPermissions();
}
private final List<String> fallbackPermissions = Arrays.asList(
"ajqueue.priority.1",
"ajqueue.priority.2",
"ajqueue.priority.3",
"ajqueue.priority.4",
"ajqueue.priority.5",
"ajqueue.priority.6",
"ajqueue.priority.7",
"ajqueue.priority.8",
"ajqueue.priority.9",
"ajqueue.priority.10",
"ajqueue.stayqueued.15",
"ajqueue.stayqueued.30",
"ajqueue.stayqueued.60",
"ajqueue.stayqueued.120"
);
}
@@ -110,10 +110,7 @@ public class SpigotMain extends JavaPlugin implements PluginMessageListener,List
}
if(subchannel.equals("inqueueevent")) {
String playername = in.readUTF();
Player p = Bukkit.getPlayer(playername);
if(p == null) return;
QueueScoreboardActivator e = new QueueScoreboardActivator(p);
QueueScoreboardActivator e = new QueueScoreboardActivator(player);
Bukkit.getPluginManager().callEvent(e);
return;
}
@@ -7,6 +7,7 @@ import us.ajg0702.queue.api.spigot.MessagedResponse;
import us.ajg0702.queue.spigot.SpigotMain;
import us.ajg0702.queue.spigot.communication.ResponseManager;
import java.util.Collection;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
@@ -113,7 +114,7 @@ public class SpigotAPI extends AjQueueSpigotAPI {
@Override
public Future<Integer> getPlayersInQueue(String queueName) {
Player p = Bukkit.getOnlinePlayers().iterator().next();
Player p = getSomePlayer();
CompletableFuture<Integer> future = new CompletableFuture<>();
@@ -121,6 +122,7 @@ public class SpigotAPI extends AjQueueSpigotAPI {
String responseString = response.getResponse();
if(responseString.equals("invalid_server")) {
future.completeExceptionally(new IllegalArgumentException(queueName + " does not exist!"));
return;
}
future.complete(Integer.valueOf(responseString));
});
@@ -137,17 +139,19 @@ public class SpigotAPI extends AjQueueSpigotAPI {
@Override
public Future<String> getServerStatusString(String queueName, UUID player) {
Player p = player == null ? Bukkit.getOnlinePlayers().iterator().next() : Bukkit.getPlayer(player);
Player p = player == null ? getSomePlayer() : Bukkit.getPlayer(player);
if(p == null) throw new IllegalArgumentException("Player must be online!");
String channel = player == null ? "status" : "playerstatus";
String id = player == null ? queueName : player + queueName;
CompletableFuture<String> future = new CompletableFuture<>();
responseManager.awaitResponse(queueName, channel, response -> {
responseManager.awaitResponse(id, channel, response -> {
String responseString = response.getResponse();
if(responseString.equals("invalid_server")) {
future.completeExceptionally(new IllegalArgumentException(queueName + " does not exist!"));
return;
}
future.complete(responseString);
});
@@ -172,4 +176,10 @@ public class SpigotAPI extends AjQueueSpigotAPI {
return future;
}
private Player getSomePlayer() {
Collection<? extends Player> players = Bukkit.getOnlinePlayers();
if(players.size() == 0) return null;
return players.iterator().next();
}
}
@@ -29,8 +29,8 @@ public class PlaceholderExpansion extends me.clip.placeholderapi.expansion.Place
placeholders.add(new PositionOf(plugin));
placeholders.add(new Queued(plugin));
placeholders.add(new QueuedFor(plugin));
placeholders.add(new Status(plugin));
placeholders.add(new StatusPlayer(plugin));
placeholders.add(new Status(plugin));
}
@@ -32,6 +32,7 @@ public class EstimatedTime extends Placeholder {
@Override
public String parse(Matcher matcher, OfflinePlayer p) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
if(!p.isOnline()) return;
try {
MessagedResponse<String> response = AjQueueSpigotAPI.getInstance()
.getEstimatedTime(p.getUniqueId())
@@ -40,9 +41,7 @@ public class EstimatedTime extends Placeholder {
cache.put(p.getUniqueId(), response.getEither());
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e);
}
} catch (TimeoutException | IllegalArgumentException ignored) {}
});
return cache.getOrDefault(p.getUniqueId(), "...");
@@ -31,6 +31,7 @@ public class InQueue extends Placeholder {
@Override
public String parse(Matcher matcher, OfflinePlayer p) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
if(!p.isOnline()) return;
try {
Boolean response = AjQueueSpigotAPI.getInstance()
.isInQueue(p.getUniqueId())
@@ -39,9 +40,7 @@ public class InQueue extends Placeholder {
cache.put(p.getUniqueId(), response + "");
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e);
}
} catch (TimeoutException | IllegalArgumentException ignored) {}
});
return cache.getOrDefault(p.getUniqueId(), "...");
@@ -32,6 +32,7 @@ public class Position extends Placeholder {
@Override
public String parse(Matcher matcher, OfflinePlayer p) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
if(!p.isOnline()) return;
try {
MessagedResponse<Integer> response = AjQueueSpigotAPI.getInstance()
.getPosition(p.getUniqueId())
@@ -40,9 +41,7 @@ public class Position extends Placeholder {
cache.put(p.getUniqueId(), response.getEither());
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e);
}
} catch (TimeoutException | IllegalArgumentException ignored) {}
});
return cache.getOrDefault(p.getUniqueId(), "...");
@@ -32,6 +32,7 @@ public class PositionOf extends Placeholder {
@Override
public String parse(Matcher matcher, OfflinePlayer p) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
if(!p.isOnline()) return;
try {
MessagedResponse<Integer> response = AjQueueSpigotAPI.getInstance()
.getTotalPositions(p.getUniqueId())
@@ -40,9 +41,7 @@ public class PositionOf extends Placeholder {
cache.put(p.getUniqueId(), response.getEither());
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e);
}
} catch (TimeoutException | IllegalArgumentException ignored) {}
});
return cache.getOrDefault(p.getUniqueId(), "...");
@@ -32,6 +32,7 @@ public class Queued extends Placeholder {
@Override
public String parse(Matcher matcher, OfflinePlayer p) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
if(!p.isOnline()) return;
try {
MessagedResponse<String> response = AjQueueSpigotAPI.getInstance()
.getQueueName(p.getUniqueId())
@@ -40,9 +41,7 @@ public class Queued extends Placeholder {
cache.put(p.getUniqueId(), response.getEither());
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e);
}
} catch (TimeoutException | IllegalArgumentException ignored) {}
});
return cache.getOrDefault(p.getUniqueId(), "...");
@@ -35,6 +35,7 @@ public class QueuedFor extends Placeholder {
String cached = cache.getOrDefault(queue, "...");
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
if(!p.isOnline()) return;
try {
Integer response = AjQueueSpigotAPI.getInstance()
.getPlayersInQueue(queue)
@@ -43,15 +44,13 @@ public class QueuedFor extends Placeholder {
cache.put(queue, response + "");
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e);
} catch (ExecutionException e) {
if(e.getCause() instanceof IllegalArgumentException) {
cache.put(queue, invalidMessage);
} else {
throw new RuntimeException(e);
}
}
} catch (TimeoutException ignored) {}
});
return cached;
@@ -35,6 +35,7 @@ public class Status extends Placeholder {
String cached = cache.getOrDefault(queue, "...");
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
if(!p.isOnline()) return;
try {
String response = AjQueueSpigotAPI.getInstance()
.getServerStatusString(queue)
@@ -43,15 +44,13 @@ public class Status extends Placeholder {
cache.put(queue, response);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e);
} catch (ExecutionException e) {
if(e.getCause() instanceof IllegalArgumentException) {
cache.put(queue, invalidMessage);
} else {
throw new RuntimeException(e);
}
}
} catch (TimeoutException | IllegalArgumentException ignored) {}
});
return cached;
@@ -35,7 +35,10 @@ public class StatusPlayer extends Placeholder {
String queue = matcher.group(1);
UUIDStringKey key = new UUIDStringKey(p.getUniqueId(), queue);
if(!p.isOnline()) return "You aren't online!";
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
if(!p.isOnline()) return;
try {
String response = AjQueueSpigotAPI.getInstance()
.getServerStatusString(queue, p.getUniqueId())
@@ -44,9 +47,7 @@ public class StatusPlayer extends Placeholder {
cache.put(key, response);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e);
}
} catch (TimeoutException | IllegalArgumentException ignored) {}
});
return cache.getOrDefault(key, "...");