diff --git a/README.md b/README.md index ca3914c..556f3b5 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,17 @@ [Spigot (premium)](https://www.spigotmc.org/resources/ajqueueplus.79123/) ajQueue is (as far as I can tell) the best queue plugin out there. -It was made because I wasn't satisfied with the existing queue plugins, all of them either being massively overpriced, -or lacking basic features +It was made because I wasn't satisfied with the existing queue plugins, +all of them either being massively overpriced, or lacking basic features # Contributing -As long as you don't break anything, i'll probably accept any merge requests you submit. -I like to have the least number of steps possible for server owners updating my plugin. +As long as you don't break anything, +i'll probably accept any merge requests you submit. +I like to have the least number of steps possible for server owners +updating my plugin. -If you need *any* help making your changes, feel free to contact me on discord. The invite link is on the plugin page ;) +If you need *any* help making your changes, feel free to contact me +on discord. The invite link is on the plugin page ;) + +# Note on compiling ajQueuePlus +If you want to compile ajQueuePlus, please read the readme file that is in libs/private \ No newline at end of file diff --git a/api/src/main/java/us/ajg0702/queue/api/Logic.java b/api/src/main/java/us/ajg0702/queue/api/premium/Logic.java similarity index 82% rename from api/src/main/java/us/ajg0702/queue/api/Logic.java rename to api/src/main/java/us/ajg0702/queue/api/premium/Logic.java index 781a944..b7aa8e4 100644 --- a/api/src/main/java/us/ajg0702/queue/api/Logic.java +++ b/api/src/main/java/us/ajg0702/queue/api/premium/Logic.java @@ -1,4 +1,4 @@ -package us.ajg0702.queue.api; +package us.ajg0702.queue.api.premium; import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.api.players.QueuePlayer; @@ -26,4 +26,10 @@ public interface Logic { * @return true if the player has been disconnected for too long and should be removed from the queue */ boolean playerDisconnectedTooLong(QueuePlayer player); + + /** + * Gets the permissionGetter. Only available on ajQueuePlus + * @return the permission getter + */ + PermissionGetter getPermissionGetter(); } diff --git a/api/src/main/java/us/ajg0702/queue/api/LogicGetter.java b/api/src/main/java/us/ajg0702/queue/api/premium/LogicGetter.java similarity index 65% rename from api/src/main/java/us/ajg0702/queue/api/LogicGetter.java rename to api/src/main/java/us/ajg0702/queue/api/premium/LogicGetter.java index af2b7e9..b8f5b6a 100644 --- a/api/src/main/java/us/ajg0702/queue/api/LogicGetter.java +++ b/api/src/main/java/us/ajg0702/queue/api/premium/LogicGetter.java @@ -1,6 +1,8 @@ -package us.ajg0702.queue.api; +package us.ajg0702.queue.api.premium; +import us.ajg0702.queue.api.AliasManager; import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.api.premium.Logic; import us.ajg0702.utils.common.Config; import java.util.List; @@ -10,4 +12,5 @@ public interface LogicGetter { Logic constructLogic(); AliasManager constructAliasManager(Config config); List getPermissions(AdaptedPlayer player); + PermissionGetter getPermissionGetter(); } diff --git a/api/src/main/java/us/ajg0702/queue/api/premium/PermissionGetter.java b/api/src/main/java/us/ajg0702/queue/api/premium/PermissionGetter.java new file mode 100644 index 0000000..d050a44 --- /dev/null +++ b/api/src/main/java/us/ajg0702/queue/api/premium/PermissionGetter.java @@ -0,0 +1,14 @@ +package us.ajg0702.queue.api.premium; + +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.api.premium.PermissionHook; + +public interface PermissionGetter { + PermissionHook getSelected(); + + int getMaxOfflineTime(AdaptedPlayer player); + + int getPriority(AdaptedPlayer player); + + int getServerPriotity(String server, AdaptedPlayer player); +} diff --git a/premium/src/main/java/us/ajg0702/queue/logic/permissions/PermissionHook.java b/api/src/main/java/us/ajg0702/queue/api/premium/PermissionHook.java similarity index 82% rename from premium/src/main/java/us/ajg0702/queue/logic/permissions/PermissionHook.java rename to api/src/main/java/us/ajg0702/queue/api/premium/PermissionHook.java index b9b7e97..94105e0 100644 --- a/premium/src/main/java/us/ajg0702/queue/logic/permissions/PermissionHook.java +++ b/api/src/main/java/us/ajg0702/queue/api/premium/PermissionHook.java @@ -1,4 +1,4 @@ -package us.ajg0702.queue.logic.permissions; +package us.ajg0702.queue.api.premium; import us.ajg0702.queue.api.players.AdaptedPlayer; diff --git a/build.gradle.kts b/build.gradle.kts index 98e255f..49d7b69 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ repositories { } allprojects { - version = "2.0.4-pre1" + version = "2.0.4-pre2" group = "us.ajg0702" plugins.apply("java") 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 1febb34..6a5c701 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 @@ -83,6 +83,7 @@ public class ManageCommand extends BaseCommand { if(args.length > 1) { for(ISubCommand subCommand : subCommands) { if(args[0].equalsIgnoreCase(subCommand.getName()) || subCommand.getAliases().contains(args[0].toLowerCase(Locale.ROOT))) { + if(!sender.hasPermission(subCommand.getPermission())) continue; return subCommand.autoComplete(sender, Arrays.copyOfRange(args, 1, args.length)); } } @@ -91,6 +92,7 @@ public class ManageCommand extends BaseCommand { List commands = new ArrayList<>(); for(ISubCommand subCommand : subCommands) { if(!subCommand.showInTabComplete()) continue; + if(!sender.hasPermission(subCommand.getPermission())) continue; commands.add(subCommand.getName()); commands.addAll(subCommand.getAliases()); } diff --git a/common/src/main/java/us/ajg0702/queue/commands/commands/manage/debug/PermissionList.java b/common/src/main/java/us/ajg0702/queue/commands/commands/manage/debug/PermissionList.java index a92a229..06b73eb 100644 --- a/common/src/main/java/us/ajg0702/queue/commands/commands/manage/debug/PermissionList.java +++ b/common/src/main/java/us/ajg0702/queue/commands/commands/manage/debug/PermissionList.java @@ -65,6 +65,11 @@ public class PermissionList extends SubCommand { if(!s.toLowerCase(Locale.ROOT).contains("ajqueue")) return; sender.sendMessage(Component.text(s)); }); + sender.sendMessage( + Component.text( + "Using: "+main.getLogicGetter().getPermissionGetter().getSelected().getName()) + .color(NamedTextColor.GOLD) + ); } @Override 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 3883959..5c4bc0a 100644 --- a/common/src/main/java/us/ajg0702/queue/common/QueueMain.java +++ b/common/src/main/java/us/ajg0702/queue/common/QueueMain.java @@ -2,6 +2,8 @@ package us.ajg0702.queue.common; import org.spongepowered.configurate.ConfigurateException; import us.ajg0702.queue.api.*; +import us.ajg0702.queue.api.premium.Logic; +import us.ajg0702.queue.api.premium.LogicGetter; import us.ajg0702.queue.api.util.QueueLogger; import us.ajg0702.queue.common.utils.LogConverter; import us.ajg0702.queue.logic.LogicGetterImpl; 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 e9403cc..6dc192f 100644 --- a/common/src/main/java/us/ajg0702/queue/common/QueueManagerImpl.java +++ b/common/src/main/java/us/ajg0702/queue/common/QueueManagerImpl.java @@ -312,6 +312,7 @@ public class QueueManagerImpl implements QueueManager { "TIME:"+ TimeUtils.timeString(time, msgs.getString("format.time.mins"), msgs.getString("format.time.secs")) )); } + } } } @@ -341,7 +342,7 @@ public class QueueManagerImpl implements QueueManager { "SERVER:"+server.getAlias(), "STATUS:"+status ); - Component subTitleMessage = msgs.getComponent("title.title", + Component subTitleMessage = msgs.getComponent("title.subtitle", "POS:"+pos, "LEN:"+server.getQueue().size(), "SERVER:"+server.getAlias(), diff --git a/common/src/main/java/us/ajg0702/queue/logic/FreeLogic.java b/common/src/main/java/us/ajg0702/queue/logic/FreeLogic.java index 6e26917..b9a902f 100644 --- a/common/src/main/java/us/ajg0702/queue/logic/FreeLogic.java +++ b/common/src/main/java/us/ajg0702/queue/logic/FreeLogic.java @@ -1,8 +1,9 @@ package us.ajg0702.queue.logic; -import us.ajg0702.queue.api.Logic; +import us.ajg0702.queue.api.premium.Logic; import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.api.players.QueuePlayer; +import us.ajg0702.queue.api.premium.PermissionGetter; import us.ajg0702.queue.api.queues.QueueServer; public class FreeLogic implements Logic { @@ -20,4 +21,9 @@ public class FreeLogic implements Logic { public boolean playerDisconnectedTooLong(QueuePlayer player) { return player.getMaxOfflineTime() < player.getTimeSinceOnline()*1000; } + + @Override + public PermissionGetter getPermissionGetter() { + return null; + } } diff --git a/common/src/main/java/us/ajg0702/queue/logic/LogicGetterImpl.java b/common/src/main/java/us/ajg0702/queue/logic/LogicGetterImpl.java index 37598cc..8a6a706 100644 --- a/common/src/main/java/us/ajg0702/queue/logic/LogicGetterImpl.java +++ b/common/src/main/java/us/ajg0702/queue/logic/LogicGetterImpl.java @@ -1,13 +1,15 @@ package us.ajg0702.queue.logic; import us.ajg0702.queue.api.AliasManager; -import us.ajg0702.queue.api.Logic; +import us.ajg0702.queue.api.premium.Logic; import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.api.premium.LogicGetter; +import us.ajg0702.queue.api.premium.PermissionGetter; import us.ajg0702.utils.common.Config; import java.util.List; -public class LogicGetterImpl implements us.ajg0702.queue.api.LogicGetter { +public class LogicGetterImpl implements LogicGetter { @Override public Logic constructLogic() { @@ -23,4 +25,9 @@ public class LogicGetterImpl implements us.ajg0702.queue.api.LogicGetter { public List getPermissions(AdaptedPlayer player) { return null; } + + @Override + public PermissionGetter getPermissionGetter() { + return null; + } } diff --git a/libs/public/AquaCoreAPI.jar b/libs/public/AquaCoreAPI.jar new file mode 100644 index 0000000..b50f85b Binary files /dev/null and b/libs/public/AquaCoreAPI.jar differ diff --git a/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/BungeeMethods.java b/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/BungeeMethods.java index 9a6ef6e..c09244e 100644 --- a/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/BungeeMethods.java +++ b/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/BungeeMethods.java @@ -5,6 +5,7 @@ import com.google.common.io.ByteStreams; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.connection.Server; import us.ajg0702.queue.api.PlatformMethods; import us.ajg0702.queue.api.commands.IBaseCommand; import us.ajg0702.queue.api.commands.ICommandSender; @@ -40,13 +41,15 @@ public class BungeeMethods implements PlatformMethods { ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeUTF(channel); out.writeUTF(player.getName()); - int length = data.length; for (String s : data) { out.writeUTF(s); } - - ((BungeePlayer) player).getHandle().getServer().sendData("ajqueue:tospigot", out.toByteArray()); + ProxiedPlayer proxiedPlayer = ((BungeePlayer) player).getHandle(); + if(proxiedPlayer == null) return; + Server server = proxiedPlayer.getServer(); + if(server == null) return; + server.sendData("ajqueue:tospigot", out.toByteArray()); } } diff --git a/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/BungeeQueue.java b/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/BungeeQueue.java index b92ea25..2aeae29 100644 --- a/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/BungeeQueue.java +++ b/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/BungeeQueue.java @@ -29,6 +29,7 @@ import us.ajg0702.queue.platforms.bungeecord.players.BungeePlayer; import us.ajg0702.queue.platforms.bungeecord.server.BungeeServer; import java.io.File; +import java.time.Duration; import java.util.Arrays; import java.util.List; diff --git a/premium/build.gradle.kts b/premium/build.gradle.kts index e81ddba..14d53f7 100644 --- a/premium/build.gradle.kts +++ b/premium/build.gradle.kts @@ -21,11 +21,12 @@ dependencies { compileOnly("com.google.guava:guava:30.1.1-jre") - compileOnly("us.ajg0702:ajUtils:1.1.9") + compileOnly("us.ajg0702:ajUtils:1.1.10") compileOnly("net.kyori:adventure-api:4.8.1") - compileOnly(fileTree(mapOf("dir" to "../libs", "include" to listOf("*.jar")))) + compileOnly(fileTree(mapOf("dir" to "../libs/private", "include" to listOf("*.jar")))) + compileOnly(fileTree(mapOf("dir" to "../libs/public", "include" to listOf("*.jar")))) compileOnly("net.luckperms:api:5.0") } diff --git a/premium/src/main/java/us/ajg0702/queue/logic/LogicGetterImpl.java b/premium/src/main/java/us/ajg0702/queue/logic/LogicGetterImpl.java index 1613779..36b111c 100644 --- a/premium/src/main/java/us/ajg0702/queue/logic/LogicGetterImpl.java +++ b/premium/src/main/java/us/ajg0702/queue/logic/LogicGetterImpl.java @@ -1,11 +1,11 @@ package us.ajg0702.queue.logic; import us.ajg0702.queue.api.AliasManager; -import us.ajg0702.queue.api.Logic; -import us.ajg0702.queue.api.LogicGetter; +import us.ajg0702.queue.api.premium.Logic; +import us.ajg0702.queue.api.premium.LogicGetter; import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.api.premium.PermissionGetter; import us.ajg0702.queue.common.QueueMain; -import us.ajg0702.queue.logic.permissions.PermissionGetter; import us.ajg0702.utils.common.Config; import java.util.List; @@ -31,4 +31,9 @@ public class LogicGetterImpl implements LogicGetter { if(logic == null) return null; return logic.getPermissionGetter().getSelected().getPermissions(player); } + + @Override + public PermissionGetter getPermissionGetter() { + return logic.getPermissionGetter(); + } } diff --git a/premium/src/main/java/us/ajg0702/queue/logic/PremiumLogic.java b/premium/src/main/java/us/ajg0702/queue/logic/PremiumLogic.java index 7cdd042..a9bcc87 100644 --- a/premium/src/main/java/us/ajg0702/queue/logic/PremiumLogic.java +++ b/premium/src/main/java/us/ajg0702/queue/logic/PremiumLogic.java @@ -1,14 +1,15 @@ package us.ajg0702.queue.logic; import com.google.common.collect.ImmutableList; -import us.ajg0702.queue.api.Logic; +import us.ajg0702.queue.api.premium.Logic; 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.util.QueueLogger; import us.ajg0702.queue.common.QueueMain; import us.ajg0702.queue.common.players.QueuePlayerImpl; -import us.ajg0702.queue.logic.permissions.PermissionGetter; +import us.ajg0702.queue.api.premium.PermissionGetter; +import us.ajg0702.queue.logic.permissions.PermissionGetterImpl; public class PremiumLogic implements Logic { @@ -18,7 +19,7 @@ public class PremiumLogic implements Logic { private final PermissionGetter permissionGetter; public PremiumLogic(QueueMain main) { - permissionGetter = new PermissionGetter(main); + permissionGetter = new PermissionGetterImpl(main); } @Override diff --git a/premium/src/main/java/us/ajg0702/queue/logic/permissions/PermissionGetter.java b/premium/src/main/java/us/ajg0702/queue/logic/permissions/PermissionGetterImpl.java similarity index 85% rename from premium/src/main/java/us/ajg0702/queue/logic/permissions/PermissionGetter.java rename to premium/src/main/java/us/ajg0702/queue/logic/permissions/PermissionGetterImpl.java index cd46361..6ca9d1a 100644 --- a/premium/src/main/java/us/ajg0702/queue/logic/permissions/PermissionGetter.java +++ b/premium/src/main/java/us/ajg0702/queue/logic/permissions/PermissionGetterImpl.java @@ -1,28 +1,33 @@ package us.ajg0702.queue.logic.permissions; 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.logic.permissions.hooks.AquaCoreHook; import us.ajg0702.queue.logic.permissions.hooks.BuiltInHook; import us.ajg0702.queue.logic.permissions.hooks.LuckPermsHook; import us.ajg0702.queue.logic.permissions.hooks.UltraPermissionsHook; import java.util.*; -public class PermissionGetter { +public class PermissionGetterImpl implements PermissionGetter { private final List hooks; private final QueueMain main; - public PermissionGetter(QueueMain main) { + public PermissionGetterImpl(QueueMain main) { hooks = Arrays.asList( new BuiltInHook(main), new LuckPermsHook(main), - new UltraPermissionsHook(main) + new UltraPermissionsHook(main), + new AquaCoreHook(main) ); this.main = main; } private PermissionHook selected; + @Override public PermissionHook getSelected() { if(selected != null) return selected; if(hooks == null) { @@ -40,14 +45,17 @@ public class PermissionGetter { return selected; } + @Override public int getMaxOfflineTime(AdaptedPlayer player) { return getHighestPermission(player, "ajqueue.stayqueued."); } + @Override public int getPriority(AdaptedPlayer player) { return getHighestPermission(player, "ajqueue.priority."); } + @Override public int getServerPriotity(String server, AdaptedPlayer player) { return getHighestPermission(player, "ajqueue.serverpriority."+server+"."); } diff --git a/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/AquaCoreHook.java b/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/AquaCoreHook.java new file mode 100644 index 0000000..328ce80 --- /dev/null +++ b/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/AquaCoreHook.java @@ -0,0 +1,51 @@ +package us.ajg0702.queue.logic.permissions.hooks; + +import me.activated.core.plugin.AquaCoreAPI; +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.api.premium.PermissionHook; + +import java.util.ArrayList; +import java.util.List; + +public class AquaCoreHook implements PermissionHook { + + private final QueueMain main; + public AquaCoreHook(QueueMain main) { + this.main = main; + } + + @Override + public String getName() { + return "AquaCore"; + } + + @Override + public boolean canUse() { + if(!main.getPlatformMethods().hasPlugin("AquaProxy") ) return false; + try { + if(AquaCoreAPI.INSTANCE == null) { + main.getLogger().warn("AquaCore is installed, but its INSTANCE returned null! Unable to hook into it."); + return false; + } + } catch(NoClassDefFoundError e) { + main.getLogger().warning("AquaCore seems to be installed, but its api doesnt seem to be!"); + return false; + } + return true; + } + + @Override + public List getPermissions(AdaptedPlayer player) { + AquaCoreAPI api = AquaCoreAPI.INSTANCE; + + List permissions = new ArrayList<>(); + + api.getPlayerData(player.getUniqueId()).getActiveGrants().forEach(grant -> { + if(!grant.isActiveSomewhere() || grant.hasExpired()) return; + permissions.addAll(grant.getRank().getAvailablePermissions()); + }); + + return permissions; + } +} diff --git a/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/BuiltInHook.java b/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/BuiltInHook.java index 80ad546..1ea1391 100644 --- a/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/BuiltInHook.java +++ b/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/BuiltInHook.java @@ -2,7 +2,7 @@ package us.ajg0702.queue.logic.permissions.hooks; import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.common.QueueMain; -import us.ajg0702.queue.logic.permissions.PermissionHook; +import us.ajg0702.queue.api.premium.PermissionHook; import java.util.ArrayList; import java.util.List; diff --git a/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/LuckPermsHook.java b/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/LuckPermsHook.java index 1b21b79..ed892ce 100644 --- a/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/LuckPermsHook.java +++ b/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/LuckPermsHook.java @@ -8,7 +8,7 @@ import net.luckperms.api.node.NodeType; import net.luckperms.api.query.QueryOptions; import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.common.QueueMain; -import us.ajg0702.queue.logic.permissions.PermissionHook; +import us.ajg0702.queue.api.premium.PermissionHook; import java.util.*; diff --git a/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/UltraPermissionsHook.java b/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/UltraPermissionsHook.java index 837dd7e..4aebd0f 100644 --- a/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/UltraPermissionsHook.java +++ b/premium/src/main/java/us/ajg0702/queue/logic/permissions/hooks/UltraPermissionsHook.java @@ -5,7 +5,7 @@ import me.TechsCode.UltraPermissions.UltraPermissionsAPI; import me.TechsCode.UltraPermissions.storage.objects.User; import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.common.QueueMain; -import us.ajg0702.queue.logic.permissions.PermissionHook; +import us.ajg0702.queue.api.premium.PermissionHook; import java.util.ArrayList; import java.util.List; @@ -27,7 +27,7 @@ public class UltraPermissionsHook implements PermissionHook { public boolean canUse() { if(!main.getPlatformMethods().hasPlugin("UltraPermissions") ) return false; if(UltraPermissions.getAPI() == null) { - main.getLogger().warn("UltraPermissions getApi() method returned null! Unable to hook into it."); + main.getLogger().warn("UltraPermissions is installed, but its getApi() method returned null! Unable to hook into it."); return false; } return true;