diff --git a/api/src/main/java/us/ajg0702/queue/api/QueueManager.java b/api/src/main/java/us/ajg0702/queue/api/QueueManager.java index c4fbc9a..ccc3062 100644 --- a/api/src/main/java/us/ajg0702/queue/api/QueueManager.java +++ b/api/src/main/java/us/ajg0702/queue/api/QueueManager.java @@ -5,7 +5,7 @@ import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.api.players.QueuePlayer; import us.ajg0702.queue.api.queues.QueueServer; -import java.util.HashMap; +import java.util.Map; public interface QueueManager { @@ -133,5 +133,5 @@ public interface QueueManager { void clear(AdaptedPlayer player); - HashMap getSendingAttempts(); + Map getSendingAttempts(); } diff --git a/build.gradle.kts b/build.gradle.kts index e67f162..3b76dd3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ repositories { } allprojects { - version = "2.2.2" + version = "2.2.3" group = "us.ajg0702" plugins.apply("java") diff --git a/common/src/main/java/us/ajg0702/queue/commands/commands/SlashServer/SlashServerCommand.java b/common/src/main/java/us/ajg0702/queue/commands/commands/SlashServer/SlashServerCommand.java index 061e9d6..8d4dbc6 100644 --- a/common/src/main/java/us/ajg0702/queue/commands/commands/SlashServer/SlashServerCommand.java +++ b/common/src/main/java/us/ajg0702/queue/commands/commands/SlashServer/SlashServerCommand.java @@ -45,7 +45,7 @@ public class SlashServerCommand extends BaseCommand { sender.sendMessage(getMessages().getComponent("errors.player-only")); return; } - if(main.getConfig().getBoolean("require-permission") && !sender.hasPermission("ajqueue.queue."+args[0])) { + if(main.getConfig().getBoolean("require-permission") && !sender.hasPermission("ajqueue.queue."+server)) { sender.sendMessage(getMessages().getComponent("noperm")); return; } diff --git a/common/src/main/java/us/ajg0702/queue/commands/commands/manage/KickAll.java b/common/src/main/java/us/ajg0702/queue/commands/commands/manage/KickAll.java new file mode 100644 index 0000000..88cb327 --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/commands/commands/manage/KickAll.java @@ -0,0 +1,74 @@ +package us.ajg0702.queue.commands.commands.manage; + +import com.google.common.collect.ImmutableList; +import us.ajg0702.queue.api.commands.ICommandSender; +import us.ajg0702.queue.api.players.QueuePlayer; +import us.ajg0702.queue.api.queues.QueueServer; +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 KickAll extends SubCommand { + + final QueueMain main; + public KickAll(QueueMain main) { + this.main = main; + } + + @Override + public String getName() { + return "kickall"; + } + + @Override + public ImmutableList getAliases() { + return ImmutableList.of(); + } + + @Override + public String getPermission() { + return "ajqueue.manage.kickall"; + } + + @Override + public Messages getMessages() { + return main.getMessages(); + } + + @Override + public void execute(ICommandSender sender, String[] args) { + if(!checkPermission(sender)) return; + + if(args.length < 1) { + sender.sendMessage(getMessages().getComponent("commands.kickall.usage")); + return; + } + + QueueServer server = main.getQueueManager().findServer(args[0]); + List kickPlayers = new ArrayList<>(server.getQueue()); + + for(QueuePlayer player : kickPlayers) { + player.getQueueServer().removePlayer(player); + } + + sender.sendMessage(getMessages().getComponent( + "commands.kickall.success", + "SERVER:"+args[0], + "NUM:"+kickPlayers.size(), + "s:"+ (kickPlayers.size() == 1 ? "" : "s") + )); + } + + @Override + public List autoComplete(ICommandSender sender, String[] args) { + if(args.length == 1) { + return main.getQueueManager().getServerNames(); + } + return new ArrayList<>(); + } +} + diff --git a/common/src/main/java/us/ajg0702/queue/commands/commands/manage/ManageCommand.java b/common/src/main/java/us/ajg0702/queue/commands/commands/manage/ManageCommand.java index 632c000..586adce 100644 --- a/common/src/main/java/us/ajg0702/queue/commands/commands/manage/ManageCommand.java +++ b/common/src/main/java/us/ajg0702/queue/commands/commands/manage/ManageCommand.java @@ -21,17 +21,22 @@ public class ManageCommand extends BaseCommand { public ManageCommand(QueueMain main) { this.main = main; - addSubCommand(new Reload(main)); + //debug commands + addSubCommand(new Protocol(main)); + addSubCommand(new ISP(main)); + addSubCommand(new PermissionList(main)); addSubCommand(new Tasks(main)); addSubCommand(new Version(main)); + addSubCommand(new Whitelist(main)); + + //normal commands + addSubCommand(new Reload(main)); addSubCommand(new Pause(main)); - addSubCommand(new ISP(main)); addSubCommand(new QueueList(main)); addSubCommand(new Send(main)); - addSubCommand(new PermissionList(main)); - addSubCommand(new Whitelist(main)); addSubCommand(new Update(main)); addSubCommand(new Kick(main)); + addSubCommand(new KickAll(main)); } diff --git a/common/src/main/java/us/ajg0702/queue/commands/commands/manage/debug/Protocol.java b/common/src/main/java/us/ajg0702/queue/commands/commands/manage/debug/Protocol.java new file mode 100644 index 0000000..173a1ea --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/commands/commands/manage/debug/Protocol.java @@ -0,0 +1,56 @@ +package us.ajg0702.queue.commands.commands.manage.debug; + +import com.google.common.collect.ImmutableList; +import net.kyori.adventure.text.Component; +import us.ajg0702.queue.api.commands.ICommandSender; +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.List; + +public class Protocol extends SubCommand { + + final QueueMain main; + public Protocol(QueueMain main) { + this.main = main; + } + + @Override + public String getName() { + return "protocol"; + } + + @Override + public ImmutableList getAliases() { + return ImmutableList.of(); + } + + @Override + public boolean showInTabComplete() { + return false; + } + + @Override + public String getPermission() { + return null; + } + + @Override + public Messages getMessages() { + return main.getMessages(); + } + + @Override + public void execute(ICommandSender sender, String[] args) { + if(!checkPermission(sender)) return; + if(!sender.isPlayer()) return; + sender.sendMessage(Component.text(main.getPlatformMethods().senderToPlayer(sender).getProtocolVersion())); + } + + @Override + public List autoComplete(ICommandSender sender, String[] args) { + return new ArrayList<>(); + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/EventHandlerImpl.java b/common/src/main/java/us/ajg0702/queue/common/EventHandlerImpl.java index 7787dc8..3d9dddf 100644 --- a/common/src/main/java/us/ajg0702/queue/common/EventHandlerImpl.java +++ b/common/src/main/java/us/ajg0702/queue/common/EventHandlerImpl.java @@ -12,7 +12,7 @@ import us.ajg0702.queue.api.queues.QueueServer; import us.ajg0702.queue.api.server.AdaptedServer; import us.ajg0702.queue.commands.commands.PlayerSender; import us.ajg0702.queue.common.players.QueuePlayerImpl; -import us.ajg0702.queue.common.utils.Debugger; +import us.ajg0702.queue.common.utils.Debug; import java.io.ByteArrayInputStream; import java.io.DataInputStream; @@ -181,7 +181,7 @@ public class EventHandlerImpl implements EventHandler { String plainReason = PlainTextComponentSerializer.plainText().serialize(reason); - Debugger.debug(player.getName()+" kicked! Moving: "+moving+" from: "+from.getName()+" plainReason: "+plainReason ); + Debug.info(player.getName()+" kicked! Moving: "+moving+" from: "+from.getName()+" plainReason: "+plainReason ); if(!moving && main.getConfig().getBoolean("send-fail-debug")) { main.getLogger().warning("Failed to send "+player.getName()+" to "+from.getName()+". Kicked with reason: "+plainReason); @@ -219,6 +219,7 @@ public class EventHandlerImpl implements EventHandler { List kickReasons = main.getConfig().getStringList("kick-reasons"); boolean kickPlayer = main.getConfig().getBoolean("kick-kicked-players"); if(kickPlayer) { + Debug.info("Initially kicking player"); List svs = main.getConfig().getStringList("queue-servers"); boolean found = false; for(String s : svs) { @@ -226,12 +227,15 @@ public class EventHandlerImpl implements EventHandler { String[] parts = s.split(":"); String fromName = parts[0]; QueueServer toServer = main.getQueueManager().findServer(parts[1]); - if(fromName.equalsIgnoreCase(server.getName()) && toServer != null && toServer.equals(server)) { + if(toServer == null) continue; + Debug.info("fromName equals: "+fromName.equalsIgnoreCase(player.getServerName())+" ("+fromName+" = "+player.getServerName()+") toServer equals: "+toServer.equals(server)); + if(fromName.equalsIgnoreCase(player.getServerName()) && toServer.equals(server)) { found = true; } } kickPlayer = found; } + Debug.info("Kick player: "+kickPlayer); for(String kickReason : kickReasons) { if(plainReason.toLowerCase().contains(kickReason.toLowerCase())) { diff --git a/common/src/main/java/us/ajg0702/queue/common/QueueMain.java b/common/src/main/java/us/ajg0702/queue/common/QueueMain.java index 9837fc9..e8e64b0 100644 --- a/common/src/main/java/us/ajg0702/queue/common/QueueMain.java +++ b/common/src/main/java/us/ajg0702/queue/common/QueueMain.java @@ -214,6 +214,8 @@ public class QueueMain extends AjQueueAPI { d.put("commands.kick.no-player", "&cCould not find {PLAYER}! Make sure they are in a queue!"); d.put("commands.kick.unknown-server", "&cCould not find queue {QUEUE}. Make sure you spelled it correctly!"); d.put("commands.kick.success", "Kicked {PLAYER} from {NUM} queue{s}!"); + d.put("commands.kickall.usage", "Usage: /ajqueue kickall "); + d.put("commands.kickall.success", "Kicked {NUM} player{s} from {SERVER}!"); d.put("noperm", "&cYou do not have permission to do this!"); 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 85afa69..b9089a3 100644 --- a/common/src/main/java/us/ajg0702/queue/common/QueueManagerImpl.java +++ b/common/src/main/java/us/ajg0702/queue/common/QueueManagerImpl.java @@ -11,7 +11,7 @@ import us.ajg0702.queue.api.queues.QueueServer; import us.ajg0702.queue.api.server.AdaptedServer; import us.ajg0702.queue.common.players.QueuePlayerImpl; import us.ajg0702.queue.common.queues.QueueServerImpl; -import us.ajg0702.queue.common.utils.Debugger; +import us.ajg0702.queue.common.utils.Debug; import us.ajg0702.utils.common.Messages; import us.ajg0702.utils.common.TimeUtils; @@ -91,15 +91,15 @@ public class QueueManagerImpl implements QueueManager { @Override public boolean addToQueue(AdaptedPlayer player, QueueServer server) { if(player == null || server == null) { - Debugger.debug("addToQueue method called, but something is null"); + Debug.info("addToQueue method called, but something is null"); return false; } if(!player.isConnected()) { - Debugger.debug("addToQueue method called, but player is not connected"); + Debug.info("addToQueue method called, but player is not connected"); return false; } - Debugger.debug("addToQueue method called for "+player.getName()+" to "+server.getName()); + Debug.info("addToQueue method called for "+player.getName()+" to "+server.getName()); if(main.getConfig().getBoolean("joinfrom-server-permission") && !player.hasPermission("ajqueue.joinfrom."+player.getServerName())) { player.sendMessage(msgs.getComponent("errors.deny-joining-from-server")); @@ -522,7 +522,7 @@ public class QueueManagerImpl implements QueueManager { final ConcurrentHashMap sendingNowAntiSpam = new ConcurrentHashMap<>(); - final HashMap sendingAttempts = new HashMap<>(); + final Map sendingAttempts = new WeakHashMap<>(); @Override public void sendPlayers(QueueServer queueServer) { @@ -600,7 +600,7 @@ public class QueueManagerImpl implements QueueManager { if(server.isPaused() && !nextPlayer.hasPermission("ajqueue.bypasspaused")) continue; } else if(server.isPaused()) { continue; } - int tries = sendingAttempts.get(nextQueuePlayer) == null ? 0 : sendingAttempts.get(nextQueuePlayer); + int tries = sendingAttempts.getOrDefault(nextQueuePlayer, 0); int maxTries = main.getConfig().getInt("max-tries"); if(tries >= maxTries && maxTries > 0) { server.removePlayer(nextQueuePlayer); @@ -628,7 +628,7 @@ public class QueueManagerImpl implements QueueManager { nextPlayer.connect(selected); server.addPlayer(selected); if(main.getConfig().getBoolean("debug")) { - Debugger.debug(selected.getName()+" player count is now set to "+ server.getLastPings().get(selected).getPlayerCount()); + Debug.info(selected.getName()+" player count is now set to "+ server.getLastPings().get(selected).getPlayerCount()); } } } @@ -678,7 +678,7 @@ public class QueueManagerImpl implements QueueManager { } @Override - public HashMap getSendingAttempts() { + public Map getSendingAttempts() { return sendingAttempts; } } 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 7751f18..0362452 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 @@ -11,14 +11,12 @@ 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.MinigameBalancer; -import us.ajg0702.queue.common.utils.Debugger; +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.ExecutionException; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; public class QueueServerImpl implements QueueServer { @@ -50,13 +48,13 @@ public class QueueServerImpl implements QueueServer { balancerType = "default"; balancer = new DefaultBalancer(this, main); } - Debugger.debug("Using "+balancerType.toLowerCase(Locale.ROOT)+" balancer for "+name); + Debug.info("Using "+balancerType.toLowerCase(Locale.ROOT)+" balancer for "+name); break; } } if(balancer == null) { balancer = new DefaultBalancer(this, main); - Debugger.debug("Using default balancer for "+name); + Debug.info("Using default balancer for "+name); } for(QueuePlayer queuePlayer : previousPlayers) { @@ -331,6 +329,7 @@ public class QueueServerImpl implements QueueServer { @Override public synchronized void removePlayer(QueuePlayer player) { + main.getQueueManager().getSendingAttempts().remove(player); queue.remove(player); } @@ -427,7 +426,7 @@ public class QueueServerImpl implements QueueServer { @Override public AdaptedServer getIdealServer(AdaptedPlayer player) { - Debugger.debug(getBalancer().toString()); + Debug.info(getBalancer().toString()); return getBalancer().getIdealServer(player); } diff --git a/common/src/main/java/us/ajg0702/queue/common/utils/Debugger.java b/common/src/main/java/us/ajg0702/queue/common/utils/Debug.java similarity index 77% rename from common/src/main/java/us/ajg0702/queue/common/utils/Debugger.java rename to common/src/main/java/us/ajg0702/queue/common/utils/Debug.java index 46a78c8..8c77664 100644 --- a/common/src/main/java/us/ajg0702/queue/common/utils/Debugger.java +++ b/common/src/main/java/us/ajg0702/queue/common/utils/Debug.java @@ -2,8 +2,8 @@ package us.ajg0702.queue.common.utils; import us.ajg0702.queue.api.AjQueueAPI; -public class Debugger { - public static void debug(String message) { +public class Debug { + public static void info(String message) { AjQueueAPI api = AjQueueAPI.getInstance(); if(!api.getConfig().getBoolean("debug")) return; api.getLogger().info("[debug] "+message); diff --git a/platforms/bungeecord/build.gradle.kts b/platforms/bungeecord/build.gradle.kts index e7beaa6..b58820d 100644 --- a/platforms/bungeecord/build.gradle.kts +++ b/platforms/bungeecord/build.gradle.kts @@ -9,6 +9,7 @@ repositories { //mavenLocal() maven { url = uri("https://repo.ajg0702.us") } maven { url = uri("https://nexus.velocitypowered.com/repository/maven-public/") } + maven { url = uri("https://repo.viaversion.com/") } mavenCentral() } @@ -24,6 +25,8 @@ dependencies { implementation("net.kyori:adventure-platform-bungeecord:4.0.0") compileOnly("net.kyori:adventure-text-serializer-plain:4.0.0-SNAPSHOT") + compileOnly("com.viaversion:viaversion-api:4.2.0-SNAPSHOT") + implementation("org.bstats:bstats-bungeecord:2.2.1") implementation(project(":common")) diff --git a/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/players/BungeePlayer.java b/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/players/BungeePlayer.java index d4fb41d..f443692 100644 --- a/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/players/BungeePlayer.java +++ b/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/players/BungeePlayer.java @@ -1,5 +1,6 @@ package us.ajg0702.queue.platforms.bungeecord.players; +import com.viaversion.viaversion.api.Via; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.sound.Sound; @@ -13,7 +14,7 @@ import net.md_5.bungee.api.connection.ProxiedPlayer; import org.jetbrains.annotations.NotNull; import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.api.server.AdaptedServer; -import us.ajg0702.queue.common.utils.Debugger; +import us.ajg0702.queue.common.utils.Debug; import us.ajg0702.queue.platforms.bungeecord.BungeeQueue; import us.ajg0702.queue.platforms.bungeecord.server.BungeeServer; @@ -79,8 +80,11 @@ public class BungeePlayer implements AdaptedPlayer, Audience { final ProxiedPlayer handle; + private final boolean viaAvailable; + public BungeePlayer(ProxiedPlayer player) { handle = player; + viaAvailable = isClassAvailable("com.viaversion.viaversion.api.Via"); } @Override @@ -123,12 +127,15 @@ public class BungeePlayer implements AdaptedPlayer, Audience { @Override public void connect(AdaptedServer server) { - Debugger.debug("Attempting to send "+getName()+" to "+server.getName()); + Debug.info("Attempting to send "+getName()+" to "+server.getName()); handle.connect(((BungeeServer) server).getHandle()); } @Override public int getProtocolVersion() { + if(viaAvailable) { + return Via.getAPI().getPlayerVersion(handle.getUniqueId()); + } return handle.getPendingConnection().getVersion(); } @@ -155,4 +162,14 @@ public class BungeePlayer implements AdaptedPlayer, Audience { private Audience getAudience() { return BungeeQueue.adventure().player(handle); } + + + private static boolean isClassAvailable(String className) { + try { + Class.forName(className); + } catch(Exception e) { + return false; + } + return true; + } } diff --git a/platforms/velocity/build.gradle.kts b/platforms/velocity/build.gradle.kts index 88c2f04..07f38ad 100644 --- a/platforms/velocity/build.gradle.kts +++ b/platforms/velocity/build.gradle.kts @@ -9,6 +9,7 @@ repositories { //mavenLocal() maven { url = uri("https://repo.ajg0702.us") } maven { url = uri("https://nexus.velocitypowered.com/repository/maven-public/") } + maven { url = uri("https://repo.viaversion.com/") } mavenCentral() } @@ -21,6 +22,8 @@ dependencies { annotationProcessor("com.velocitypowered:velocity-api:3.0.0") implementation("net.kyori:adventure-text-minimessage:4.0.0-SNAPSHOT") + compileOnly("com.viaversion:viaversion-api:4.2.0-SNAPSHOT") + implementation("org.bstats:bstats-velocity:2.2.1") implementation(project(":common")) diff --git a/platforms/velocity/src/main/java/us/ajg0702/queue/platforms/velocity/players/VelocityPlayer.java b/platforms/velocity/src/main/java/us/ajg0702/queue/platforms/velocity/players/VelocityPlayer.java index a742860..8ba4cdb 100644 --- a/platforms/velocity/src/main/java/us/ajg0702/queue/platforms/velocity/players/VelocityPlayer.java +++ b/platforms/velocity/src/main/java/us/ajg0702/queue/platforms/velocity/players/VelocityPlayer.java @@ -3,6 +3,7 @@ package us.ajg0702.queue.platforms.velocity.players; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.server.RegisteredServer; +import com.viaversion.viaversion.api.Via; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.sound.Sound; @@ -14,7 +15,7 @@ import org.jetbrains.annotations.NotNull; import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.api.server.AdaptedServer; import us.ajg0702.queue.common.QueueMain; -import us.ajg0702.queue.common.utils.Debugger; +import us.ajg0702.queue.common.utils.Debug; import java.util.List; import java.util.Optional; @@ -73,8 +74,11 @@ public class VelocityPlayer implements AdaptedPlayer, Audience { final Player handle; + private final boolean viaAvailable; + public VelocityPlayer(Player player) { handle = player; + viaAvailable = isClassAvailable("com.viaversion.viaversion.api.Via"); } @Override @@ -118,7 +122,7 @@ public class VelocityPlayer implements AdaptedPlayer, Audience { @Override public void connect(AdaptedServer server) { - Debugger.debug("Attempting to send "+getName()+" to "+server.getName()); + Debug.info("Attempting to send "+getName()+" to "+server.getName()); handle.createConnectionRequest((RegisteredServer) server.getHandle()).connect().thenAcceptAsync( result -> { if(!result.isSuccessful()) { @@ -166,6 +170,9 @@ public class VelocityPlayer implements AdaptedPlayer, Audience { @Override public int getProtocolVersion() { + if(viaAvailable) { + return Via.getAPI().getPlayerVersion(handle.getUniqueId()); + } return handle.getProtocolVersion().getProtocol(); } @@ -188,4 +195,14 @@ public class VelocityPlayer implements AdaptedPlayer, Audience { public Player getHandle() { return handle; } + + + private static boolean isClassAvailable(String className) { + try { + Class.forName(className); + } catch(Exception e) { + return false; + } + return true; + } } diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/SpigotMain.java b/spigot/src/main/java/us/ajg0702/queue/spigot/SpigotMain.java index 78124c9..d72db5f 100644 --- a/spigot/src/main/java/us/ajg0702/queue/spigot/SpigotMain.java +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/SpigotMain.java @@ -201,6 +201,10 @@ public class SpigotMain extends JavaPlugin implements PluginMessageListener,List @EventHandler(priority = EventPriority.HIGH) public void onServerPing(ServerListPingEvent e) { + if(config == null) { + getLogger().warning("Server ping before plugin load!"); + return; + } if(!config.getBoolean("take-over-motd-for-whitelist")) return; if(!Bukkit.hasWhitelist()) return;