diff --git a/bukkit-legacy/build.gradle b/bukkit-legacy/build.gradle index aabccbbeb..fd18427ce 100644 --- a/bukkit-legacy/build.gradle +++ b/bukkit-legacy/build.gradle @@ -3,7 +3,7 @@ plugins { } dependencies { - compile project(path: ':bukkit', configuration: 'shadow') + compile project(path: ':bukkit:loader', configuration: 'shadow') compile 'com.google.code.gson:gson:2.7' compile 'com.google.guava:guava:19.0' } @@ -12,7 +12,6 @@ shadowJar { archiveName = "LuckPerms-Bukkit-Legacy-${project.ext.fullVersion}.jar" dependencies { - include(dependency('net.luckperms:.*')) include(dependency('me.lucko.luckperms:.*')) include(dependency('com.google.guava:guava:.*')) include(dependency('com.google.code.gson:gson:.*')) diff --git a/bukkit/build.gradle b/bukkit/build.gradle index e785456d3..145621cdd 100644 --- a/bukkit/build.gradle +++ b/bukkit/build.gradle @@ -9,6 +9,7 @@ repositories { dependencies { compile project(':common') + compileOnly project(':common:loader-utils') compileOnly 'com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT' compileOnly 'me.lucko:adventure-platform-bukkit:4.0.0' // re: this artifact - see note in common/build.gradle @@ -19,18 +20,10 @@ dependencies { compileOnly 'lilypad.client.connect:api:0.0.1-SNAPSHOT' } -processResources { - from(sourceSets.main.resources.srcDirs) { - expand 'pluginVersion': project.ext.fullVersion - include 'plugin.yml' - } -} - shadowJar { - archiveName = "LuckPerms-Bukkit-${project.ext.fullVersion}.jar" + archiveName = 'luckperms-bukkit.jarinjar' dependencies { - include(dependency('net.luckperms:.*')) include(dependency('me.lucko.luckperms:.*')) } diff --git a/bukkit/loader/build.gradle b/bukkit/loader/build.gradle new file mode 100644 index 000000000..f6c56513b --- /dev/null +++ b/bukkit/loader/build.gradle @@ -0,0 +1,33 @@ +plugins { + id 'com.github.johnrengelman.shadow' +} + +repositories { + maven { url 'https://papermc.io/repo/repository/maven-public/' } +} + +dependencies { + compileOnly 'com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT' + + compile project(':api') + compile project(':common:loader-utils') +} + +processResources { + from(sourceSets.main.resources.srcDirs) { + expand 'pluginVersion': project.ext.fullVersion + include 'plugin.yml' + } +} + +shadowJar { + archiveName = "LuckPerms-Bukkit-${project.ext.fullVersion}.jar" + + from { + project(':bukkit').tasks.shadowJar.archiveFile + } +} + +artifacts { + archives shadowJar +} \ No newline at end of file diff --git a/bukkit/loader/src/main/java/me/lucko/luckperms/bukkit/loader/BukkitLoaderPlugin.java b/bukkit/loader/src/main/java/me/lucko/luckperms/bukkit/loader/BukkitLoaderPlugin.java new file mode 100644 index 000000000..4f149edc4 --- /dev/null +++ b/bukkit/loader/src/main/java/me/lucko/luckperms/bukkit/loader/BukkitLoaderPlugin.java @@ -0,0 +1,59 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.bukkit.loader; + +import me.lucko.luckperms.common.loader.JarInJarClassLoader; +import me.lucko.luckperms.common.loader.LoaderBootstrap; + +import org.bukkit.plugin.java.JavaPlugin; + +public class BukkitLoaderPlugin extends JavaPlugin { + private static final String JAR_NAME = "luckperms-bukkit.jarinjar"; + private static final String BOOTSTRAP_CLASS = "me.lucko.luckperms.bukkit.LPBukkitBootstrap"; + + private final LoaderBootstrap plugin; + + public BukkitLoaderPlugin() { + JarInJarClassLoader loader = new JarInJarClassLoader(getClass().getClassLoader(), JAR_NAME); + this.plugin = loader.instantiatePlugin(BOOTSTRAP_CLASS, JavaPlugin.class, this); + } + + @Override + public void onLoad() { + this.plugin.onLoad(); + } + + @Override + public void onEnable() { + this.plugin.onEnable(); + } + + @Override + public void onDisable() { + this.plugin.onDisable(); + } + +} diff --git a/bukkit/src/main/resources/plugin.yml b/bukkit/loader/src/main/resources/plugin.yml similarity index 94% rename from bukkit/src/main/resources/plugin.yml rename to bukkit/loader/src/main/resources/plugin.yml index 1307287fb..708025aee 100644 --- a/bukkit/src/main/resources/plugin.yml +++ b/bukkit/loader/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ version: ${pluginVersion} description: A permissions plugin author: Luck website: https://luckperms.net -main: me.lucko.luckperms.bukkit.LPBukkitBootstrap +main: me.lucko.luckperms.bukkit.loader.BukkitLoaderPlugin load: STARTUP # Mark the plugin as 1.13 compatible to avoid CB having to perform quite as much unnecessary diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitCommandExecutor.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitCommandExecutor.java index 25e9940d4..70d36f3a4 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitCommandExecutor.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitCommandExecutor.java @@ -73,7 +73,7 @@ public class BukkitCommandExecutor extends CommandManager implements TabExecutor public void register() { this.command.setExecutor(this); this.command.setTabCompleter(this); - this.plugin.getBootstrap().getServer().getPluginManager().registerEvents(this, this.plugin.getBootstrap()); + this.plugin.getBootstrap().getServer().getPluginManager().registerEvents(this, this.plugin.getLoader()); } @Override diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitEventBus.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitEventBus.java index cb6219c4a..cc22fe414 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitEventBus.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitEventBus.java @@ -39,7 +39,7 @@ public class BukkitEventBus extends AbstractEventBus implements Listener // register listener LPBukkitBootstrap bootstrap = plugin.getBootstrap(); - bootstrap.getServer().getPluginManager().registerEvents(this, bootstrap); + bootstrap.getServer().getPluginManager().registerEvents(this, bootstrap.getLoader()); } @Override diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSchedulerAdapter.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSchedulerAdapter.java index eddb3f639..93095e3bf 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSchedulerAdapter.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSchedulerAdapter.java @@ -34,7 +34,7 @@ public class BukkitSchedulerAdapter extends AbstractJavaScheduler implements Sch private final Executor sync; public BukkitSchedulerAdapter(LPBukkitBootstrap bootstrap) { - this.sync = r -> bootstrap.getServer().getScheduler().scheduleSyncDelayedTask(bootstrap, r); + this.sync = r -> bootstrap.getServer().getScheduler().scheduleSyncDelayedTask(bootstrap.getLoader(), r); } @Override diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSenderFactory.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSenderFactory.java index 81ca7140b..9f1081597 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSenderFactory.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSenderFactory.java @@ -44,7 +44,7 @@ public class BukkitSenderFactory extends SenderFactory https://ci.lucko.me/job/LuckPerms/"); - getLogger().severe("----------------------------------------------------------------------"); - getServer().getPluginManager().disablePlugin(this); + Logger logger = this.loader.getLogger(); + logger.severe("----------------------------------------------------------------------"); + logger.severe("Your server version is not compatible with this build of LuckPerms. :("); + logger.severe(""); + logger.severe("If your server is running 1.8, please update to 1.8.8 or higher."); + logger.severe("If your server is running 1.7.10, please download the Bukkit-Legacy version of LuckPerms from here:"); + logger.severe("==> https://ci.lucko.me/job/LuckPerms/"); + logger.severe("----------------------------------------------------------------------"); + getServer().getPluginManager().disablePlugin(this.loader); return; } @@ -162,7 +175,7 @@ public class LPBukkitBootstrap extends JavaPlugin implements LuckPermsBootstrap this.plugin.enable(); // schedule a task to update the 'serverStarting' flag - getServer().getScheduler().runTask(this, () -> this.serverStarting = false); + getServer().getScheduler().runTask(this.loader, () -> this.serverStarting = false); } finally { this.enableLatch.countDown(); } @@ -200,7 +213,7 @@ public class LPBukkitBootstrap extends JavaPlugin implements LuckPermsBootstrap @Override public String getVersion() { - return getDescription().getVersion(); + return this.loader.getDescription().getVersion(); } @Override @@ -227,12 +240,7 @@ public class LPBukkitBootstrap extends JavaPlugin implements LuckPermsBootstrap @Override public Path getDataDirectory() { - return getDataFolder().toPath().toAbsolutePath(); - } - - @Override - public InputStream getResourceStream(String path) { - return getResource(path); + return this.loader.getDataFolder().toPath().toAbsolutePath(); } @Override diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java index ef2d01683..8d9736769 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java @@ -73,8 +73,8 @@ import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.ServicePriority; +import org.bukkit.plugin.java.JavaPlugin; -import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -109,6 +109,10 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin { return this.bootstrap; } + public JavaPlugin getLoader() { + return this.bootstrap.getLoader(); + } + @Override protected void setupSenderFactory() { this.senderFactory = new BukkitSenderFactory(this); @@ -127,14 +131,14 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin { @Override protected ConfigurationAdapter provideConfigurationAdapter() { - return new BukkitConfigAdapter(this, resolveConfig()); + return new BukkitConfigAdapter(this, resolveConfig("config.yml").toFile()); } @Override protected void registerPlatformListeners() { this.connectionListener = new BukkitConnectionListener(this); - this.bootstrap.getServer().getPluginManager().registerEvents(this.connectionListener, this.bootstrap); - this.bootstrap.getServer().getPluginManager().registerEvents(new BukkitPlatformListener(this), this.bootstrap); + this.bootstrap.getServer().getPluginManager().registerEvents(this.connectionListener, this.bootstrap.getLoader()); + this.bootstrap.getServer().getPluginManager().registerEvents(new BukkitPlatformListener(this), this.bootstrap.getLoader()); } @Override @@ -144,7 +148,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin { @Override protected void registerCommands() { - PluginCommand command = this.bootstrap.getCommand("luckperms"); + PluginCommand command = this.bootstrap.getLoader().getCommand("luckperms"); if (command == null) { getLogger().severe("Unable to register /luckperms command with the server"); return; @@ -187,7 +191,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin { this.contextManager = new BukkitContextManager(this); BukkitPlayerCalculator playerCalculator = new BukkitPlayerCalculator(this); - this.bootstrap.getServer().getPluginManager().registerEvents(playerCalculator, this.bootstrap); + this.bootstrap.getServer().getPluginManager().registerEvents(playerCalculator, this.bootstrap.getLoader()); this.contextManager.registerCalculator(playerCalculator); } @@ -206,7 +210,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin { // schedule another injection after all plugins have loaded // the entire pluginmanager instance is replaced by some plugins :( - this.bootstrap.getServer().getScheduler().runTaskLaterAsynchronously(this.bootstrap, injector, 1); + this.bootstrap.getServer().getScheduler().runTaskLaterAsynchronously(this.bootstrap.getLoader(), injector, 1); } /* @@ -221,7 +225,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin { * - https://hub.spigotmc.org/jira/browse/SPIGOT-5546 * - https://github.com/PaperMC/Paper/pull/3509 */ - PluginManagerUtil.injectDependency(this.bootstrap.getServer().getPluginManager(), this.bootstrap.getName(), "Vault"); + PluginManagerUtil.injectDependency(this.bootstrap.getServer().getPluginManager(), this.bootstrap.getLoader().getName(), "Vault"); // Provide vault support tryVaultHook(false); @@ -251,7 +255,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin { @Override protected void registerApiOnPlatform(LuckPerms api) { - this.bootstrap.getServer().getServicesManager().register(LuckPerms.class, api, this.bootstrap, ServicePriority.Normal); + this.bootstrap.getServer().getServicesManager().register(LuckPerms.class, api, this.bootstrap.getLoader(), ServicePriority.Normal); } @Override @@ -276,7 +280,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin { // remove all operators on startup if they're disabled if (!getConfiguration().get(ConfigKeys.OPS_ENABLED)) { - this.bootstrap.getServer().getScheduler().runTaskAsynchronously(this.bootstrap, () -> { + this.bootstrap.getServer().getScheduler().runTaskAsynchronously(this.bootstrap.getLoader(), () -> { for (OfflinePlayer player : this.bootstrap.getServer().getOperators()) { player.setOp(false); } @@ -351,15 +355,6 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin { } } - private File resolveConfig() { - File configFile = new File(this.bootstrap.getDataFolder(), "config.yml"); - if (!configFile.exists()) { - this.bootstrap.getDataFolder().mkdirs(); - this.bootstrap.saveResource("config.yml", false); - } - return configFile; - } - private static boolean classExists(String className) { try { Class.forName(className); diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/brigadier/LuckPermsBrigadier.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/brigadier/LuckPermsBrigadier.java index dc41dd742..8c8eaf348 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/brigadier/LuckPermsBrigadier.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/brigadier/LuckPermsBrigadier.java @@ -44,7 +44,7 @@ public final class LuckPermsBrigadier { private LuckPermsBrigadier() {} public static void register(LPBukkitPlugin plugin, Command pluginCommand) throws Exception { - Commodore commodore = CommodoreProvider.getCommodore(plugin.getBootstrap()); + Commodore commodore = CommodoreProvider.getCommodore(plugin.getLoader()); try (InputStream is = plugin.getBootstrap().getResourceStream("luckperms.commodore")) { if (is == null) { throw new Exception("Brigadier command data missing from jar"); diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/LuckPermsPermissionAttachment.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/LuckPermsPermissionAttachment.java index 3624658dc..0a9f10ac0 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/LuckPermsPermissionAttachment.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/LuckPermsPermissionAttachment.java @@ -287,7 +287,7 @@ public class LuckPermsPermissionAttachment extends PermissionAttachment { @Override public @NonNull Plugin getPlugin() { - return this.owner != null ? this.owner : this.permissible.getPlugin().getBootstrap(); + return this.owner != null ? this.owner : this.permissible.getPlugin().getLoader(); } @Override diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/listeners/BukkitConnectionListener.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/listeners/BukkitConnectionListener.java index b2abf075f..3da6280c7 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/listeners/BukkitConnectionListener.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/listeners/BukkitConnectionListener.java @@ -239,7 +239,7 @@ public class BukkitConnectionListener extends AbstractConnectionListener impleme // perform unhooking from bukkit objects 1 tick later. // this allows plugins listening after us on MONITOR to still have intact permissions data - this.plugin.getBootstrap().getServer().getScheduler().runTaskLater(this.plugin.getBootstrap(), () -> { + this.plugin.getBootstrap().getServer().getScheduler().runTaskLater(this.plugin.getLoader(), () -> { // Remove the custom permissible try { PermissibleInjector.uninject(player, true); diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/messaging/PluginMessageMessenger.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/messaging/PluginMessageMessenger.java index 915e066c3..9cf47f71d 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/messaging/PluginMessageMessenger.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/messaging/PluginMessageMessenger.java @@ -58,14 +58,14 @@ public class PluginMessageMessenger implements Messenger, PluginMessageListener } public void init() { - this.plugin.getBootstrap().getServer().getMessenger().registerOutgoingPluginChannel(this.plugin.getBootstrap(), CHANNEL); - this.plugin.getBootstrap().getServer().getMessenger().registerIncomingPluginChannel(this.plugin.getBootstrap(), CHANNEL, this); + this.plugin.getBootstrap().getServer().getMessenger().registerOutgoingPluginChannel(this.plugin.getLoader(), CHANNEL); + this.plugin.getBootstrap().getServer().getMessenger().registerIncomingPluginChannel(this.plugin.getLoader(), CHANNEL, this); } @Override public void close() { - this.plugin.getBootstrap().getServer().getMessenger().unregisterIncomingPluginChannel(this.plugin.getBootstrap(), CHANNEL); - this.plugin.getBootstrap().getServer().getMessenger().unregisterOutgoingPluginChannel(this.plugin.getBootstrap(), CHANNEL); + this.plugin.getBootstrap().getServer().getMessenger().unregisterIncomingPluginChannel(this.plugin.getLoader(), CHANNEL); + this.plugin.getBootstrap().getServer().getMessenger().unregisterOutgoingPluginChannel(this.plugin.getLoader(), CHANNEL); } @Override @@ -83,10 +83,10 @@ public class PluginMessageMessenger implements Messenger, PluginMessageListener return; } - p.sendPluginMessage(PluginMessageMessenger.this.plugin.getBootstrap(), CHANNEL, data); + p.sendPluginMessage(PluginMessageMessenger.this.plugin.getLoader(), CHANNEL, data); cancel(); } - }.runTaskTimer(this.plugin.getBootstrap(), 1L, 100L); + }.runTaskTimer(this.plugin.getLoader(), 1L, 100L); } @Override diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultHookManager.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultHookManager.java index 6b0570df2..01afcd591 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultHookManager.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultHookManager.java @@ -61,8 +61,8 @@ public class VaultHookManager { } final ServicesManager sm = this.plugin.getBootstrap().getServer().getServicesManager(); - sm.register(Permission.class, this.permission, this.plugin.getBootstrap(), ServicePriority.High); - sm.register(Chat.class, this.chat, this.plugin.getBootstrap(), ServicePriority.High); + sm.register(Permission.class, this.permission, this.plugin.getLoader(), ServicePriority.High); + sm.register(Chat.class, this.chat, this.plugin.getLoader(), ServicePriority.High); } catch (Exception e) { this.plugin.getLogger().severe("Error occurred whilst hooking into Vault.", e); diff --git a/bungee/build.gradle b/bungee/build.gradle index 29ebf6806..b07246622 100644 --- a/bungee/build.gradle +++ b/bungee/build.gradle @@ -4,24 +4,17 @@ plugins { dependencies { compile project(':common') + compileOnly project(':common:loader-utils') compileOnly 'net.md-5:bungeecord-api:1.15-SNAPSHOT' compileOnly 'me.lucko:adventure-platform-bungeecord:4.0.0' // re: this artifact - see note in common/build.gradle compileOnly 'com.imaginarycode.minecraft:RedisBungee:0.4' } -processResources { - from(sourceSets.main.resources.srcDirs) { - expand 'pluginVersion': project.ext.fullVersion - include 'plugin.yml' - } -} - shadowJar { - archiveName = "LuckPerms-Bungee-${project.ext.fullVersion}.jar" + archiveName = 'luckperms-bungee.jarinjar' dependencies { - include(dependency('net.luckperms:.*')) include(dependency('me.lucko.luckperms:.*')) } diff --git a/bungee/loader/build.gradle b/bungee/loader/build.gradle new file mode 100644 index 000000000..80f237a8e --- /dev/null +++ b/bungee/loader/build.gradle @@ -0,0 +1,29 @@ +plugins { + id 'com.github.johnrengelman.shadow' +} + +dependencies { + compileOnly 'net.md-5:bungeecord-api:1.15-SNAPSHOT' + + compile project(':api') + compile project(':common:loader-utils') +} + +processResources { + from(sourceSets.main.resources.srcDirs) { + expand 'pluginVersion': project.ext.fullVersion + include 'plugin.yml' + } +} + +shadowJar { + archiveName = "LuckPerms-Bungee-${project.ext.fullVersion}.jar" + + from { + project(':bungee').tasks.shadowJar.archiveFile + } +} + +artifacts { + archives shadowJar +} \ No newline at end of file diff --git a/bungee/loader/src/main/java/me/lucko/luckperms/bungee/loader/BungeeLoaderPlugin.java b/bungee/loader/src/main/java/me/lucko/luckperms/bungee/loader/BungeeLoaderPlugin.java new file mode 100644 index 000000000..48167204d --- /dev/null +++ b/bungee/loader/src/main/java/me/lucko/luckperms/bungee/loader/BungeeLoaderPlugin.java @@ -0,0 +1,59 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.bungee.loader; + +import me.lucko.luckperms.common.loader.JarInJarClassLoader; +import me.lucko.luckperms.common.loader.LoaderBootstrap; + +import net.md_5.bungee.api.plugin.Plugin; + +public class BungeeLoaderPlugin extends Plugin { + private static final String JAR_NAME = "luckperms-bungee.jarinjar"; + private static final String BOOTSTRAP_CLASS = "me.lucko.luckperms.bungee.LPBungeeBootstrap"; + + private final LoaderBootstrap plugin; + + public BungeeLoaderPlugin() { + JarInJarClassLoader loader = new JarInJarClassLoader(getClass().getClassLoader(), JAR_NAME); + this.plugin = loader.instantiatePlugin(BOOTSTRAP_CLASS, Plugin.class, this); + } + + @Override + public void onLoad() { + this.plugin.onLoad(); + } + + @Override + public void onEnable() { + this.plugin.onEnable(); + } + + @Override + public void onDisable() { + this.plugin.onDisable(); + } + +} diff --git a/bungee/src/main/resources/plugin.yml b/bungee/loader/src/main/resources/plugin.yml similarity index 67% rename from bungee/src/main/resources/plugin.yml rename to bungee/loader/src/main/resources/plugin.yml index e099ed097..7b71717d3 100644 --- a/bungee/src/main/resources/plugin.yml +++ b/bungee/loader/src/main/resources/plugin.yml @@ -2,5 +2,5 @@ name: LuckPerms version: ${pluginVersion} description: A permissions plugin author: Luck -main: me.lucko.luckperms.bungee.LPBungeeBootstrap +main: me.lucko.luckperms.bungee.loader.BungeeLoaderPlugin softDepends: ["RedisBungee"] diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeCommandExecutor.java b/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeCommandExecutor.java index 10ae728d6..b40d75e6d 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeCommandExecutor.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeCommandExecutor.java @@ -73,7 +73,7 @@ public class BungeeCommandExecutor extends Command implements TabExecutor { public void register() { ProxyServer proxy = this.plugin.getBootstrap().getProxy(); - proxy.getPluginManager().registerCommand(this.plugin.getBootstrap(), this); + proxy.getPluginManager().registerCommand(this.plugin.getLoader(), this); // don't allow players to execute the slash aliases - these are just for the console. proxy.getDisabledCommands().addAll(Arrays.asList(SLASH_ALIASES)); diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSchedulerAdapter.java b/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSchedulerAdapter.java index 7b4074627..573bfd886 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSchedulerAdapter.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSchedulerAdapter.java @@ -45,7 +45,7 @@ public class BungeeSchedulerAdapter implements SchedulerAdapter { public BungeeSchedulerAdapter(LPBungeeBootstrap bootstrap) { this.bootstrap = bootstrap; - this.executor = r -> bootstrap.getProxy().getScheduler().runAsync(bootstrap, r); + this.executor = r -> bootstrap.getProxy().getScheduler().runAsync(bootstrap.getLoader(), r); } @Override @@ -60,14 +60,14 @@ public class BungeeSchedulerAdapter implements SchedulerAdapter { @Override public SchedulerTask asyncLater(Runnable task, long delay, TimeUnit unit) { - ScheduledTask t = this.bootstrap.getProxy().getScheduler().schedule(this.bootstrap, task, delay, unit); + ScheduledTask t = this.bootstrap.getProxy().getScheduler().schedule(this.bootstrap.getLoader(), task, delay, unit); this.tasks.add(t); return t::cancel; } @Override public SchedulerTask asyncRepeating(Runnable task, long interval, TimeUnit unit) { - ScheduledTask t = this.bootstrap.getProxy().getScheduler().schedule(this.bootstrap, task, interval, interval, unit); + ScheduledTask t = this.bootstrap.getProxy().getScheduler().schedule(this.bootstrap.getLoader(), task, interval, interval, unit); this.tasks.add(t); return t::cancel; } diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSenderFactory.java b/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSenderFactory.java index e5090dc86..34300a344 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSenderFactory.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSenderFactory.java @@ -42,7 +42,7 @@ public class BungeeSenderFactory extends SenderFactory https://papermc.io/downloads#Travertine"); - getLogger().severe(""); - getLogger().severe("The proxy will now shutdown."); - getLogger().severe("----------------------------------------------------------------------"); + Logger logger = this.loader.getLogger(); + logger.severe("----------------------------------------------------------------------"); + logger.severe("Your proxy version is not compatible with this build of LuckPerms. :("); + logger.severe(""); + logger.severe("This is most likely because you are using an old/outdated version of BungeeCord."); + logger.severe("If you need 1.7 support, replace your BungeeCord.jar file with the latest build of"); + logger.severe("'Travertine' from here:"); + logger.severe("==> https://papermc.io/downloads#Travertine"); + logger.severe(""); + logger.severe("The proxy will now shutdown."); + logger.severe("----------------------------------------------------------------------"); getProxy().stop(); return; } @@ -180,7 +194,7 @@ public class LPBungeeBootstrap extends Plugin implements LuckPermsBootstrap { @Override public String getVersion() { - return getDescription().getVersion(); + return this.loader.getDescription().getVersion(); } @Override @@ -207,12 +221,7 @@ public class LPBungeeBootstrap extends Plugin implements LuckPermsBootstrap { @Override public Path getDataDirectory() { - return getDataFolder().toPath().toAbsolutePath(); - } - - @Override - public InputStream getResourceStream(String path) { - return getResourceAsStream(path); + return this.loader.getDataFolder().toPath().toAbsolutePath(); } @Override diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeePlugin.java b/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeePlugin.java index fce7987e6..51dfc7ef4 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeePlugin.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeePlugin.java @@ -51,11 +51,8 @@ import me.lucko.luckperms.common.tasks.ExpireTemporaryTask; import net.luckperms.api.LuckPerms; import net.luckperms.api.query.QueryOptions; +import net.md_5.bungee.api.plugin.Plugin; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -84,6 +81,10 @@ public class LPBungeePlugin extends AbstractLuckPermsPlugin { return this.bootstrap; } + public Plugin getLoader() { + return this.bootstrap.getLoader(); + } + @Override protected void setupSenderFactory() { this.senderFactory = new BungeeSenderFactory(this); @@ -99,14 +100,14 @@ public class LPBungeePlugin extends AbstractLuckPermsPlugin { @Override protected ConfigurationAdapter provideConfigurationAdapter() { - return new BungeeConfigAdapter(this, resolveConfig()); + return new BungeeConfigAdapter(this, resolveConfig("config.yml").toFile()); } @Override protected void registerPlatformListeners() { this.connectionListener = new BungeeConnectionListener(this); - this.bootstrap.getProxy().getPluginManager().registerListener(this.bootstrap, this.connectionListener); - this.bootstrap.getProxy().getPluginManager().registerListener(this.bootstrap, new BungeePermissionCheckListener(this)); + this.bootstrap.getProxy().getPluginManager().registerListener(this.bootstrap.getLoader(), this.connectionListener); + this.bootstrap.getProxy().getPluginManager().registerListener(this.bootstrap.getLoader(), new BungeePermissionCheckListener(this)); } @Override @@ -141,7 +142,7 @@ public class LPBungeePlugin extends AbstractLuckPermsPlugin { this.contextManager = new BungeeContextManager(this); BungeePlayerCalculator playerCalculator = new BungeePlayerCalculator(this); - this.bootstrap.getProxy().getPluginManager().registerListener(this.bootstrap, playerCalculator); + this.bootstrap.getProxy().getPluginManager().registerListener(this.bootstrap.getLoader(), playerCalculator); this.contextManager.registerCalculator(playerCalculator); if (this.bootstrap.getProxy().getPluginManager().getPlugin("RedisBungee") != null) { @@ -175,21 +176,6 @@ public class LPBungeePlugin extends AbstractLuckPermsPlugin { } - private File resolveConfig() { - File configFile = new File(this.bootstrap.getDataFolder(), "config.yml"); - - if (!configFile.exists()) { - this.bootstrap.getDataFolder().mkdirs(); - try (InputStream is = this.bootstrap.getResourceAsStream("config.yml")) { - Files.copy(is, configFile.toPath()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - return configFile; - } - @Override public Optional getQueryOptionsForUser(User user) { return this.bootstrap.getPlayer(user.getUniqueId()).map(player -> this.contextManager.getQueryOptions(player)); diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/listeners/BungeeConnectionListener.java b/bungee/src/main/java/me/lucko/luckperms/bungee/listeners/BungeeConnectionListener.java index cf581e0d5..413512975 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/listeners/BungeeConnectionListener.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/listeners/BungeeConnectionListener.java @@ -76,7 +76,7 @@ public class BungeeConnectionListener extends AbstractConnectionListener impleme /* registers the plugins intent to modify this events state going forward. this will prevent the event from completing until we're finished handling. */ - e.registerIntent(this.plugin.getBootstrap()); + e.registerIntent(this.plugin.getLoader()); this.plugin.getBootstrap().getScheduler().executeAsync(() -> { /* Actually process the login for the connection. @@ -106,7 +106,7 @@ public class BungeeConnectionListener extends AbstractConnectionListener impleme } // finally, complete our intent to modify state, so the proxy can continue handling the connection. - e.completeIntent(this.plugin.getBootstrap()); + e.completeIntent(this.plugin.getLoader()); }); } @@ -134,7 +134,7 @@ public class BungeeConnectionListener extends AbstractConnectionListener impleme e.getPlayer().disconnect(BungeeComponentSerializer.get().serialize(reason)); } else { // just send a message - this.plugin.getBootstrap().getProxy().getScheduler().schedule(this.plugin.getBootstrap(), () -> { + this.plugin.getBootstrap().getProxy().getScheduler().schedule(this.plugin.getLoader(), () -> { if (!player.isConnected()) { return; } diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/PluginMessageMessenger.java b/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/PluginMessageMessenger.java index 4b06cce22..6eee535b0 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/PluginMessageMessenger.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/PluginMessageMessenger.java @@ -59,7 +59,7 @@ public class PluginMessageMessenger implements Messenger, Listener { public void init() { ProxyServer proxy = this.plugin.getBootstrap().getProxy(); - proxy.getPluginManager().registerListener(this.plugin.getBootstrap(), this); + proxy.getPluginManager().registerListener(this.plugin.getLoader(), this); proxy.registerChannel(CHANNEL); } diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/RedisBungeeMessenger.java b/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/RedisBungeeMessenger.java index eede99df5..5360a7cce 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/RedisBungeeMessenger.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/RedisBungeeMessenger.java @@ -58,7 +58,7 @@ public class RedisBungeeMessenger implements Messenger, Listener { this.redisBungee = RedisBungee.getApi(); this.redisBungee.registerPubSubChannels(CHANNEL); - this.plugin.getBootstrap().getProxy().getPluginManager().registerListener(this.plugin.getBootstrap(), this); + this.plugin.getBootstrap().getProxy().getPluginManager().registerListener(this.plugin.getLoader(), this); } @Override diff --git a/common/build.gradle b/common/build.gradle index f1edd15e7..ba5d577f3 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -11,6 +11,8 @@ dependencies { compile project(':api') compile 'org.checkerframework:checker-qual:3.8.0' + compileOnly project(':common:loader-utils') + compileOnly 'org.slf4j:slf4j-api:1.7.30' compileOnly 'org.apache.logging.log4j:log4j-api:2.14.0' diff --git a/common/loader-utils/build.gradle b/common/loader-utils/build.gradle new file mode 100644 index 000000000..17f637455 --- /dev/null +++ b/common/loader-utils/build.gradle @@ -0,0 +1 @@ +// nothing special to do here (yet)! diff --git a/common/loader-utils/src/main/java/me/lucko/luckperms/common/loader/JarInJarClassLoader.java b/common/loader-utils/src/main/java/me/lucko/luckperms/common/loader/JarInJarClassLoader.java new file mode 100644 index 000000000..381952a3e --- /dev/null +++ b/common/loader-utils/src/main/java/me/lucko/luckperms/common/loader/JarInJarClassLoader.java @@ -0,0 +1,140 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.common.loader; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; + +/** + * Classloader that can load a jar from within another jar file. + * + *

The "loader" jar contains the loading code & public API classes, + * and is class-loaded by the platform.

+ * + *

The inner "plugin" jar contains the plugin itself, and is class-loaded + * by the loading code & this classloader.

+ */ +public class JarInJarClassLoader extends URLClassLoader { + static { + ClassLoader.registerAsParallelCapable(); + } + + /** + * Creates a new jar-in-jar class loader. + * + * @param loaderClassLoader the loader plugin's classloader (setup and created by the platform) + * @param jarResourcePath the path to the jar-in-jar resource within the loader jar + * @throws LoadingException if something unexpectedly bad happens + */ + public JarInJarClassLoader(ClassLoader loaderClassLoader, String jarResourcePath) throws LoadingException { + super(new URL[]{extractJar(loaderClassLoader, jarResourcePath)}, loaderClassLoader); + } + + public void addJarToClasspath(URL url) { + addURL(url); + } + + /** + * Creates a new plugin instance. + * + * @param bootstrapClass the name of the bootstrap plugin class + * @param loaderPluginType the type of the loader plugin, the only parameter of the bootstrap + * plugin constructor + * @param loaderPlugin the loader plugin instance + * @param the type of the loader plugin + * @return the instantiated bootstrap plugin + */ + public LoaderBootstrap instantiatePlugin(String bootstrapClass, Class loaderPluginType, T loaderPlugin) throws LoadingException { + Class plugin; + try { + plugin = loadClass(bootstrapClass).asSubclass(LoaderBootstrap.class); + } catch (ReflectiveOperationException e) { + throw new LoadingException("Unable to load bootstrap class", e); + } + + Constructor constructor; + try { + constructor = plugin.getConstructor(loaderPluginType); + } catch (ReflectiveOperationException e) { + throw new LoadingException("Unable to get bootstrap constructor", e); + } + + try { + return constructor.newInstance(loaderPlugin); + } catch (ReflectiveOperationException e) { + throw new LoadingException("Unable to create bootstrap plugin instance", e); + } + } + + /** + * Extracts the "jar-in-jar" from the loader plugin into a temporary file, + * then returns a URL that can be used by the {@link JarInJarClassLoader}. + * + * @param loaderClassLoader the classloader for the "host" loader plugin + * @param jarResourcePath the inner jar resource path + * @return a URL to the extracted file + */ + private static URL extractJar(ClassLoader loaderClassLoader, String jarResourcePath) throws LoadingException { + // get the jar-in-jar resource + URL jarInJar = loaderClassLoader.getResource(jarResourcePath); + if (jarInJar == null) { + throw new LoadingException("Could not locate jar-in-jar"); + } + + // create a temporary file + // on posix systems by default this is only read/writable by the process owner + Path path; + try { + path = Files.createTempFile("luckperms-jarinjar", ".jar.tmp"); + } catch (IOException e) { + throw new LoadingException("Unable to create a temporary file", e); + } + + // mark that the file should be deleted on exit + path.toFile().deleteOnExit(); + + // copy the jar-in-jar to the temporary file path + try (InputStream in = jarInJar.openStream()) { + Files.copy(in, path, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + throw new LoadingException("Unable to copy jar-in-jar to temporary path", e); + } + + try { + return path.toUri().toURL(); + } catch (MalformedURLException e) { + throw new LoadingException("Unable to get URL from path", e); + } + } + +} diff --git a/common/loader-utils/src/main/java/me/lucko/luckperms/common/loader/LoaderBootstrap.java b/common/loader-utils/src/main/java/me/lucko/luckperms/common/loader/LoaderBootstrap.java new file mode 100644 index 000000000..875a2b153 --- /dev/null +++ b/common/loader-utils/src/main/java/me/lucko/luckperms/common/loader/LoaderBootstrap.java @@ -0,0 +1,39 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.common.loader; + +/** + * Minimal bootstrap plugin, called by the loader plugin. + */ +public interface LoaderBootstrap { + + void onLoad(); + + void onEnable(); + + void onDisable(); + +} diff --git a/common/loader-utils/src/main/java/me/lucko/luckperms/common/loader/LoadingException.java b/common/loader-utils/src/main/java/me/lucko/luckperms/common/loader/LoadingException.java new file mode 100644 index 000000000..27017d8b0 --- /dev/null +++ b/common/loader-utils/src/main/java/me/lucko/luckperms/common/loader/LoadingException.java @@ -0,0 +1,41 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.common.loader; + +/** + * Runtime exception used if there is a problem during loading + */ +public class LoadingException extends RuntimeException { + + public LoadingException(String message) { + super(message); + } + + public LoadingException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyManager.java b/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyManager.java index 22899d219..7cbee16a8 100644 --- a/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyManager.java @@ -150,7 +150,7 @@ public class DependencyManager { this.loaded.put(dependency, file); if (this.registry.shouldAutoLoad(dependency)) { - this.plugin.getBootstrap().getPluginClassLoader().addJarToClasspath(file); + this.plugin.getBootstrap().getClassPathAppender().addJarToClasspath(file); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/extension/SimpleExtensionManager.java b/common/src/main/java/me/lucko/luckperms/common/extension/SimpleExtensionManager.java index bad891dda..2d698ac98 100644 --- a/common/src/main/java/me/lucko/luckperms/common/extension/SimpleExtensionManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/extension/SimpleExtensionManager.java @@ -136,7 +136,7 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable { throw new IllegalArgumentException("class is null"); } - this.plugin.getBootstrap().getPluginClassLoader().addJarToClasspath(path); + this.plugin.getBootstrap().getClassPathAppender().addJarToClasspath(path); Class extensionClass; try { diff --git a/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java b/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java index 28ee1850d..841aee48e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java @@ -60,6 +60,10 @@ import net.luckperms.api.LuckPerms; import okhttp3.OkHttpClient; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.time.Duration; import java.time.Instant; import java.time.LocalDate; @@ -265,6 +269,24 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin { ); } + protected Path resolveConfig(String fileName) { + Path configFile = getBootstrap().getDataDirectory().resolve(fileName); + if (!Files.exists(configFile)) { + try { + Files.createDirectories(configFile.getParent()); + } catch (IOException e) { + // ignore + } + + try (InputStream is = getBootstrap().getResourceStream(fileName)) { + Files.copy(is, configFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return configFile; + } + protected abstract void setupSenderFactory(); protected abstract ConfigurationAdapter provideConfigurationAdapter(); protected abstract void registerPlatformListeners(); diff --git a/common/src/main/java/me/lucko/luckperms/common/plugin/bootstrap/LuckPermsBootstrap.java b/common/src/main/java/me/lucko/luckperms/common/plugin/bootstrap/LuckPermsBootstrap.java index 77dc2d69a..2680ab00e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/plugin/bootstrap/LuckPermsBootstrap.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/bootstrap/LuckPermsBootstrap.java @@ -25,7 +25,7 @@ package me.lucko.luckperms.common.plugin.bootstrap; -import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader; +import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender; import me.lucko.luckperms.common.plugin.logging.PluginLogger; import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter; @@ -66,11 +66,11 @@ public interface LuckPermsBootstrap { SchedulerAdapter getScheduler(); /** - * Gets a {@link PluginClassLoader} for this instance + * Gets a {@link ClassPathAppender} for this bootstrap plugin * - * @return a classloader + * @return a class path appender */ - PluginClassLoader getPluginClassLoader(); + ClassPathAppender getClassPathAppender(); /** * Returns a countdown latch which {@link CountDownLatch#countDown() counts down} @@ -159,7 +159,9 @@ public interface LuckPermsBootstrap { * @param path the path of the file * @return the file as an input stream */ - InputStream getResourceStream(String path); + default InputStream getResourceStream(String path) { + return getClass().getClassLoader().getResourceAsStream(path); + } /** * Gets a player object linked to this User. The returned object must be the same type diff --git a/common/src/main/java/me/lucko/luckperms/common/dependencies/classloader/PluginClassLoader.java b/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ClassPathAppender.java similarity index 88% rename from common/src/main/java/me/lucko/luckperms/common/dependencies/classloader/PluginClassLoader.java rename to common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ClassPathAppender.java index 7665b0829..5adf9690c 100644 --- a/common/src/main/java/me/lucko/luckperms/common/dependencies/classloader/PluginClassLoader.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ClassPathAppender.java @@ -23,14 +23,14 @@ * SOFTWARE. */ -package me.lucko.luckperms.common.dependencies.classloader; +package me.lucko.luckperms.common.plugin.classpath; import java.nio.file.Path; /** - * Represents the plugins classloader + * Interface which allows access to add URLs to the plugin classpath at runtime. */ -public interface PluginClassLoader { +public interface ClassPathAppender { void addJarToClasspath(Path file); diff --git a/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/JarInJarClassPathAppender.java b/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/JarInJarClassPathAppender.java new file mode 100644 index 000000000..9dd74ea63 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/JarInJarClassPathAppender.java @@ -0,0 +1,51 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.common.plugin.classpath; + +import me.lucko.luckperms.common.loader.JarInJarClassLoader; + +import java.net.MalformedURLException; +import java.nio.file.Path; + +public class JarInJarClassPathAppender implements ClassPathAppender { + private final JarInJarClassLoader classLoader; + + public JarInJarClassPathAppender(ClassLoader classLoader) { + if (!(classLoader instanceof JarInJarClassLoader)) { + throw new IllegalArgumentException("Loader is not a JarInJarClassLoader: " + classLoader.getClass().getName()); + } + this.classLoader = (JarInJarClassLoader) classLoader; + } + + @Override + public void addJarToClasspath(Path file) { + try { + this.classLoader.addJarToClasspath(file.toUri().toURL()); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/common/src/main/java/me/lucko/luckperms/common/dependencies/classloader/ReflectionClassLoader.java b/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ReflectionClassPathAppender.java similarity index 89% rename from common/src/main/java/me/lucko/luckperms/common/dependencies/classloader/ReflectionClassLoader.java rename to common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ReflectionClassPathAppender.java index e68cc43d7..ebb175227 100644 --- a/common/src/main/java/me/lucko/luckperms/common/dependencies/classloader/ReflectionClassLoader.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ReflectionClassPathAppender.java @@ -23,19 +23,18 @@ * SOFTWARE. */ -package me.lucko.luckperms.common.dependencies.classloader; +package me.lucko.luckperms.common.plugin.classpath; import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.nio.file.Path; -public class ReflectionClassLoader implements PluginClassLoader { - +@Deprecated // TODO: no longer works on Java 16 - Sponge needs to switch to JarInJar or find an API to add to classpath at runtime +public class ReflectionClassPathAppender implements ClassPathAppender { private static final Method ADD_URL_METHOD; static { @@ -58,7 +57,7 @@ public class ReflectionClassLoader implements PluginClassLoader { private final URLClassLoader classLoader; - public ReflectionClassLoader(LuckPermsBootstrap bootstrap) throws IllegalStateException { + public ReflectionClassPathAppender(LuckPermsBootstrap bootstrap) throws IllegalStateException { ClassLoader classLoader = bootstrap.getClass().getClassLoader(); if (classLoader instanceof URLClassLoader) { this.classLoader = (URLClassLoader) classLoader; @@ -71,7 +70,7 @@ public class ReflectionClassLoader implements PluginClassLoader { public void addJarToClasspath(Path file) { try { ADD_URL_METHOD.invoke(this.classLoader, file.toUri().toURL()); - } catch (IllegalAccessException | InvocationTargetException | MalformedURLException e) { + } catch (ReflectiveOperationException | MalformedURLException e) { throw new RuntimeException(e); } } @@ -92,7 +91,7 @@ public class ReflectionClassLoader implements PluginClassLoader { Method addOpensMethod = moduleClass.getMethod("addOpens", String.class, moduleClass); Object urlClassLoaderModule = getModuleMethod.invoke(URLClassLoader.class); - Object thisModule = getModuleMethod.invoke(ReflectionClassLoader.class); + Object thisModule = getModuleMethod.invoke(ReflectionClassPathAppender.class); addOpensMethod.invoke(urlClassLoaderModule, URLClassLoader.class.getPackage().getName(), thisModule); } diff --git a/fabric/src/main/java/me/lucko/luckperms/fabric/FabricClassLoader.java b/fabric/src/main/java/me/lucko/luckperms/fabric/FabricClassPathAppender.java similarity index 93% rename from fabric/src/main/java/me/lucko/luckperms/fabric/FabricClassLoader.java rename to fabric/src/main/java/me/lucko/luckperms/fabric/FabricClassPathAppender.java index 819250dc3..88403a80d 100644 --- a/fabric/src/main/java/me/lucko/luckperms/fabric/FabricClassLoader.java +++ b/fabric/src/main/java/me/lucko/luckperms/fabric/FabricClassPathAppender.java @@ -25,14 +25,14 @@ package me.lucko.luckperms.fabric; -import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader; +import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender; import net.fabricmc.loader.launch.common.FabricLauncherBase; import java.net.MalformedURLException; import java.nio.file.Path; -public class FabricClassLoader implements PluginClassLoader { +public class FabricClassPathAppender implements ClassPathAppender { @Override public void addJarToClasspath(Path file) { diff --git a/fabric/src/main/java/me/lucko/luckperms/fabric/LPFabricBootstrap.java b/fabric/src/main/java/me/lucko/luckperms/fabric/LPFabricBootstrap.java index 2a34f5433..215b37381 100644 --- a/fabric/src/main/java/me/lucko/luckperms/fabric/LPFabricBootstrap.java +++ b/fabric/src/main/java/me/lucko/luckperms/fabric/LPFabricBootstrap.java @@ -27,8 +27,8 @@ package me.lucko.luckperms.fabric; import com.mojang.authlib.GameProfile; -import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader; import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap; +import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender; import me.lucko.luckperms.common.plugin.logging.Log4jPluginLogger; import me.lucko.luckperms.common.plugin.logging.PluginLogger; import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter; @@ -76,9 +76,9 @@ public final class LPFabricBootstrap implements LuckPermsBootstrap, DedicatedSer private final SchedulerAdapter schedulerAdapter; /** - * The plugin class loader. + * The plugin class path appender */ - private final PluginClassLoader classLoader; + private final ClassPathAppender classPathAppender; /** * The plugin instance @@ -102,7 +102,7 @@ public final class LPFabricBootstrap implements LuckPermsBootstrap, DedicatedSer public LPFabricBootstrap() { this.logger = new Log4jPluginLogger(LogManager.getLogger(MODID)); this.schedulerAdapter = new FabricSchedulerAdapter(this); - this.classLoader = new FabricClassLoader(); + this.classPathAppender = new FabricClassPathAppender(); this.plugin = new LPFabricPlugin(this); } @@ -119,8 +119,8 @@ public final class LPFabricBootstrap implements LuckPermsBootstrap, DedicatedSer } @Override - public PluginClassLoader getPluginClassLoader() { - return this.classLoader; + public ClassPathAppender getClassPathAppender() { + return this.classPathAppender; } // lifecycle diff --git a/fabric/src/main/java/me/lucko/luckperms/fabric/LPFabricPlugin.java b/fabric/src/main/java/me/lucko/luckperms/fabric/LPFabricPlugin.java index bca58808d..edd045ad2 100644 --- a/fabric/src/main/java/me/lucko/luckperms/fabric/LPFabricPlugin.java +++ b/fabric/src/main/java/me/lucko/luckperms/fabric/LPFabricPlugin.java @@ -41,7 +41,6 @@ import me.lucko.luckperms.common.sender.DummySender; import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.tasks.CacheHousekeepingTask; import me.lucko.luckperms.common.tasks.ExpireTemporaryTask; -import me.lucko.luckperms.common.util.MoreFiles; import me.lucko.luckperms.fabric.context.FabricContextManager; import me.lucko.luckperms.fabric.context.FabricPlayerCalculator; import me.lucko.luckperms.fabric.listeners.FabricConnectionListener; @@ -55,10 +54,6 @@ import net.luckperms.api.LuckPerms; import net.luckperms.api.query.QueryOptions; import net.minecraft.server.MinecraftServer; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -112,20 +107,7 @@ public class LPFabricPlugin extends AbstractLuckPermsPlugin { @Override protected ConfigurationAdapter provideConfigurationAdapter() { - Path configPath = this.getBootstrap().getConfigDirectory().resolve("luckperms.conf"); - - if (!Files.exists(configPath)) { - try { - MoreFiles.createDirectoriesIfNotExists(this.bootstrap.getConfigDirectory()); - try (InputStream is = this.getBootstrap().getResourceStream("luckperms.conf")) { - Files.copy(is, configPath); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - return new FabricConfigAdapter(this, configPath); + return new FabricConfigAdapter(this, resolveConfig("luckperms.conf")); } @Override diff --git a/nukkit/build.gradle b/nukkit/build.gradle index 1397f6599..a8c3a3aa1 100644 --- a/nukkit/build.gradle +++ b/nukkit/build.gradle @@ -9,22 +9,15 @@ repositories { dependencies { compile project(':common') + compileOnly project(':common:loader-utils') compileOnly 'cn.nukkit:nukkit:1.0-SNAPSHOT' } -processResources { - from(sourceSets.main.resources.srcDirs) { - expand 'pluginVersion': project.ext.fullVersion - include 'plugin.yml' - } -} - shadowJar { - archiveName = "LuckPerms-Nukkit-${project.ext.fullVersion}.jar" + archiveName = 'luckperms-nukkit.jarinjar' dependencies { - include(dependency('net.luckperms:.*')) include(dependency('me.lucko.luckperms:.*')) } diff --git a/nukkit/loader/build.gradle b/nukkit/loader/build.gradle new file mode 100644 index 000000000..a0dcb2bc6 --- /dev/null +++ b/nukkit/loader/build.gradle @@ -0,0 +1,34 @@ +plugins { + id 'com.github.johnrengelman.shadow' +} + +repositories { + mavenLocal() + maven { url 'https://repo.nukkitx.com/main/' } +} + +dependencies { + compileOnly 'cn.nukkit:nukkit:1.0-SNAPSHOT' + + compile project(':api') + compile project(':common:loader-utils') +} + +processResources { + from(sourceSets.main.resources.srcDirs) { + expand 'pluginVersion': project.ext.fullVersion + include 'plugin.yml' + } +} + +shadowJar { + archiveName = "LuckPerms-Nukkit-${project.ext.fullVersion}.jar" + + from { + project(':nukkit').tasks.shadowJar.archiveFile + } +} + +artifacts { + archives shadowJar +} \ No newline at end of file diff --git a/nukkit/loader/src/main/java/me/lucko/luckperms/nukkit/loader/NukkitLoaderPlugin.java b/nukkit/loader/src/main/java/me/lucko/luckperms/nukkit/loader/NukkitLoaderPlugin.java new file mode 100644 index 000000000..8f8cb1abc --- /dev/null +++ b/nukkit/loader/src/main/java/me/lucko/luckperms/nukkit/loader/NukkitLoaderPlugin.java @@ -0,0 +1,59 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.nukkit.loader; + +import me.lucko.luckperms.common.loader.JarInJarClassLoader; +import me.lucko.luckperms.common.loader.LoaderBootstrap; + +import cn.nukkit.plugin.PluginBase; + +public class NukkitLoaderPlugin extends PluginBase { + private static final String JAR_NAME = "luckperms-nukkit.jarinjar"; + private static final String BOOTSTRAP_CLASS = "me.lucko.luckperms.nukkit.LPNukkitBootstrap"; + + private final LoaderBootstrap plugin; + + public NukkitLoaderPlugin() { + JarInJarClassLoader loader = new JarInJarClassLoader(getClass().getClassLoader(), JAR_NAME); + this.plugin = loader.instantiatePlugin(BOOTSTRAP_CLASS, PluginBase.class, this); + } + + @Override + public void onLoad() { + this.plugin.onLoad(); + } + + @Override + public void onEnable() { + this.plugin.onEnable(); + } + + @Override + public void onDisable() { + this.plugin.onDisable(); + } + +} diff --git a/nukkit/src/main/resources/plugin.yml b/nukkit/loader/src/main/resources/plugin.yml similarity index 82% rename from nukkit/src/main/resources/plugin.yml rename to nukkit/loader/src/main/resources/plugin.yml index 2f40ed8c0..0ab32a8b2 100644 --- a/nukkit/src/main/resources/plugin.yml +++ b/nukkit/loader/src/main/resources/plugin.yml @@ -5,7 +5,7 @@ description: A permissions plugin author: Luck website: https://luckperms.net -main: me.lucko.luckperms.nukkit.LPNukkitBootstrap +main: me.lucko.luckperms.nukkit.loader.NukkitLoaderPlugin load: STARTUP commands: diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitBootstrap.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitBootstrap.java index 9920d0134..497f1d020 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitBootstrap.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitBootstrap.java @@ -25,17 +25,18 @@ package me.lucko.luckperms.nukkit; -import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader; -import me.lucko.luckperms.common.dependencies.classloader.ReflectionClassLoader; +import me.lucko.luckperms.common.loader.LoaderBootstrap; import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap; +import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender; +import me.lucko.luckperms.common.plugin.classpath.JarInJarClassPathAppender; import me.lucko.luckperms.common.plugin.logging.PluginLogger; import net.luckperms.api.platform.Platform; import cn.nukkit.Player; +import cn.nukkit.Server; import cn.nukkit.plugin.PluginBase; -import java.io.InputStream; import java.nio.file.Path; import java.time.Instant; import java.util.ArrayList; @@ -48,7 +49,8 @@ import java.util.concurrent.CountDownLatch; /** * Bootstrap plugin for LuckPerms running on Nukkit. */ -public class LPNukkitBootstrap extends PluginBase implements LuckPermsBootstrap { +public class LPNukkitBootstrap implements LuckPermsBootstrap, LoaderBootstrap { + private final PluginBase loader; /** * The plugin logger @@ -61,9 +63,9 @@ public class LPNukkitBootstrap extends PluginBase implements LuckPermsBootstrap private final NukkitSchedulerAdapter schedulerAdapter; /** - * The plugin classloader + * The plugin class path appender */ - private final PluginClassLoader classLoader; + private final ClassPathAppender classPathAppender; /** * The plugin instance @@ -79,14 +81,24 @@ public class LPNukkitBootstrap extends PluginBase implements LuckPermsBootstrap private final CountDownLatch loadLatch = new CountDownLatch(1); private final CountDownLatch enableLatch = new CountDownLatch(1); - public LPNukkitBootstrap() { + public LPNukkitBootstrap(PluginBase loader) { + this.loader = loader; + this.schedulerAdapter = new NukkitSchedulerAdapter(this); - this.classLoader = new ReflectionClassLoader(this); + this.classPathAppender = new JarInJarClassPathAppender(getClass().getClassLoader()); this.plugin = new LPNukkitPlugin(this); } // provide adapters + public PluginBase getLoader() { + return this.loader; + } + + public Server getServer() { + return this.loader.getServer(); + } + @Override public PluginLogger getPluginLogger() { if (this.logger == null) { @@ -101,15 +113,15 @@ public class LPNukkitBootstrap extends PluginBase implements LuckPermsBootstrap } @Override - public PluginClassLoader getPluginClassLoader() { - return this.classLoader; + public ClassPathAppender getClassPathAppender() { + return this.classPathAppender; } // lifecycle @Override public void onLoad() { - this.logger = new NukkitPluginLogger(getLogger()); + this.logger = new NukkitPluginLogger(this.loader.getLogger()); try { this.plugin.load(); @@ -147,7 +159,7 @@ public class LPNukkitBootstrap extends PluginBase implements LuckPermsBootstrap @Override public String getVersion() { - return getDescription().getVersion(); + return this.loader.getDescription().getVersion(); } @Override @@ -174,12 +186,7 @@ public class LPNukkitBootstrap extends PluginBase implements LuckPermsBootstrap @Override public Path getDataDirectory() { - return getDataFolder().toPath().toAbsolutePath(); - } - - @Override - public InputStream getResourceStream(String path) { - return getResource(path); + return this.loader.getDataFolder().toPath().toAbsolutePath(); } @Override diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitPlugin.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitPlugin.java index ed7e28e3d..266ed5a86 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitPlugin.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitPlugin.java @@ -64,12 +64,11 @@ import net.luckperms.api.query.QueryOptions; import cn.nukkit.Player; import cn.nukkit.command.PluginCommand; import cn.nukkit.permission.Permission; +import cn.nukkit.plugin.PluginBase; import cn.nukkit.plugin.PluginManager; import cn.nukkit.plugin.service.ServicePriority; import cn.nukkit.utils.Config; -import java.io.File; -import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; @@ -100,6 +99,10 @@ public class LPNukkitPlugin extends AbstractLuckPermsPlugin { return this.bootstrap; } + public PluginBase getLoader() { + return this.bootstrap.getLoader(); + } + @Override protected void setupSenderFactory() { this.senderFactory = new NukkitSenderFactory(this); @@ -107,14 +110,14 @@ public class LPNukkitPlugin extends AbstractLuckPermsPlugin { @Override protected ConfigurationAdapter provideConfigurationAdapter() { - return new NukkitConfigAdapter(this, resolveConfig()); + return new NukkitConfigAdapter(this, resolveConfig("config.yml").toFile()); } @Override protected void registerPlatformListeners() { this.connectionListener = new NukkitConnectionListener(this); - this.bootstrap.getServer().getPluginManager().registerEvents(this.connectionListener, this.bootstrap); - this.bootstrap.getServer().getPluginManager().registerEvents(new NukkitPlatformListener(this), this.bootstrap); + this.bootstrap.getServer().getPluginManager().registerEvents(this.connectionListener, this.bootstrap.getLoader()); + this.bootstrap.getServer().getPluginManager().registerEvents(new NukkitPlatformListener(this), this.bootstrap.getLoader()); } @Override @@ -146,7 +149,7 @@ public class LPNukkitPlugin extends AbstractLuckPermsPlugin { this.contextManager = new NukkitContextManager(this); NukkitPlayerCalculator playerCalculator = new NukkitPlayerCalculator(this); - this.bootstrap.getServer().getPluginManager().registerEvents(playerCalculator, this.bootstrap); + this.bootstrap.getServer().getPluginManager().registerEvents(playerCalculator, this.bootstrap.getLoader()); this.contextManager.registerCalculator(playerCalculator); } @@ -165,7 +168,7 @@ public class LPNukkitPlugin extends AbstractLuckPermsPlugin { // schedule another injection after all plugins have loaded // the entire pluginmanager instance is replaced by some plugins :( - this.bootstrap.getServer().getScheduler().scheduleDelayedTask(this.bootstrap, injector, 1, true); + this.bootstrap.getServer().getScheduler().scheduleDelayedTask(this.bootstrap.getLoader(), injector, 1, true); } } @@ -176,7 +179,7 @@ public class LPNukkitPlugin extends AbstractLuckPermsPlugin { @Override protected void registerApiOnPlatform(LuckPerms api) { - this.bootstrap.getServer().getServiceManager().register(LuckPerms.class, api, this.bootstrap, ServicePriority.NORMAL); + this.bootstrap.getServer().getServiceManager().register(LuckPerms.class, api, this.bootstrap.getLoader(), ServicePriority.NORMAL); } @Override @@ -262,33 +265,6 @@ public class LPNukkitPlugin extends AbstractLuckPermsPlugin { new PermissibleMonitoringInjector(this, PermissibleMonitoringInjector.Mode.UNINJECT).run(); } - public void refreshAutoOp(Player player) { - if (!getConfiguration().get(ConfigKeys.AUTO_OP)) { - return; - } - - User user = getUserManager().getIfLoaded(player.getUniqueId()); - boolean value; - - if (user != null) { - Map permData = user.getCachedData().getPermissionData(this.contextManager.getQueryOptions(player)).getPermissionMap(); - value = permData.getOrDefault("luckperms.autoop", false); - } else { - value = false; - } - - player.setOp(value); - } - - private File resolveConfig() { - File configFile = new File(this.bootstrap.getDataFolder(), "config.yml"); - if (!configFile.exists()) { - this.bootstrap.getDataFolder().mkdirs(); - this.bootstrap.saveResource("config.yml", false); - } - return configFile; - } - @Override public Optional getQueryOptionsForUser(User user) { return this.bootstrap.getPlayer(user.getUniqueId()).map(player -> this.contextManager.getQueryOptions(player)); diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitCommandExecutor.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitCommandExecutor.java index 3622e8bbd..c4622f50c 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitCommandExecutor.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitCommandExecutor.java @@ -52,7 +52,7 @@ public class NukkitCommandExecutor extends CommandManager implements CommandExec public void register() { this.command.setExecutor(this); - this.plugin.getBootstrap().getServer().getPluginManager().registerEvents(this, this.plugin.getBootstrap()); + this.plugin.getBootstrap().getServer().getPluginManager().registerEvents(this, this.plugin.getLoader()); } @Override diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitEventBus.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitEventBus.java index f072d7645..aea3613c0 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitEventBus.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitEventBus.java @@ -39,7 +39,7 @@ public class NukkitEventBus extends AbstractEventBus implements Listener // register listener LPNukkitBootstrap bootstrap = plugin.getBootstrap(); - bootstrap.getServer().getPluginManager().registerEvents(this, bootstrap); + bootstrap.getServer().getPluginManager().registerEvents(this, bootstrap.getLoader()); } @Override diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitSchedulerAdapter.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitSchedulerAdapter.java index 0b29bf3dd..8e33cb687 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitSchedulerAdapter.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitSchedulerAdapter.java @@ -34,7 +34,7 @@ public class NukkitSchedulerAdapter extends AbstractJavaScheduler implements Sch private final Executor sync; public NukkitSchedulerAdapter(LPNukkitBootstrap bootstrap) { - this.sync = r -> bootstrap.getServer().getScheduler().scheduleTask(bootstrap, r, false); + this.sync = r -> bootstrap.getServer().getScheduler().scheduleTask(bootstrap.getLoader(), r, false); } @Override diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/LuckPermsPermissionAttachment.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/LuckPermsPermissionAttachment.java index f9da6795f..36e44ed42 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/LuckPermsPermissionAttachment.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/LuckPermsPermissionAttachment.java @@ -316,7 +316,7 @@ public class LuckPermsPermissionAttachment extends PermissionAttachment { @Override public Plugin getPlugin() { - return this.owner != null ? this.owner : this.permissible.getPlugin().getBootstrap(); + return this.owner != null ? this.owner : this.permissible.getPlugin().getLoader(); } @Override diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/listeners/NukkitConnectionListener.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/listeners/NukkitConnectionListener.java index 2539c4da6..c6e3aa732 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/listeners/NukkitConnectionListener.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/listeners/NukkitConnectionListener.java @@ -204,7 +204,7 @@ public class NukkitConnectionListener extends AbstractConnectionListener impleme // perform unhooking from nukkit objects 1 tick later. // this allows plugins listening after us on MONITOR to still have intact permissions data - this.plugin.getBootstrap().getServer().getScheduler().scheduleDelayedTask(this.plugin.getBootstrap(), () -> { + this.plugin.getBootstrap().getServer().getScheduler().scheduleDelayedTask(this.plugin.getLoader(), () -> { // Remove the custom permissible try { PermissibleInjector.uninject(player, true); diff --git a/settings.gradle b/settings.gradle index 01e87906c..86bc1ba89 100644 --- a/settings.gradle +++ b/settings.gradle @@ -13,11 +13,15 @@ rootProject.name = 'luckperms' include ( 'api', 'common', + 'common:loader-utils', 'bukkit', + 'bukkit:loader', 'bukkit-legacy', 'bungee', + 'bungee:loader', 'fabric', 'nukkit', + 'nukkit:loader', 'sponge', 'sponge:sponge-service', 'sponge:sponge-service-api6', 'sponge:sponge-service-api7', 'velocity' ) diff --git a/sponge/build.gradle b/sponge/build.gradle index 022455fb1..9162e0a90 100644 --- a/sponge/build.gradle +++ b/sponge/build.gradle @@ -63,13 +63,3 @@ shadowJar { artifacts { archives shadowJar } - -// Only used occasionally for deployment - not needed for normal builds. -/* -apply plugin: 'signing' - -signing { - useGpgCmd() - sign configurations.archives -} -*/ diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongeBootstrap.java b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongeBootstrap.java index 736ec78ac..fae255ed2 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongeBootstrap.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongeBootstrap.java @@ -27,9 +27,9 @@ package me.lucko.luckperms.sponge; import com.google.inject.Inject; -import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader; -import me.lucko.luckperms.common.dependencies.classloader.ReflectionClassLoader; import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap; +import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender; +import me.lucko.luckperms.common.plugin.classpath.ReflectionClassPathAppender; import me.lucko.luckperms.common.plugin.logging.PluginLogger; import me.lucko.luckperms.common.plugin.logging.Slf4jPluginLogger; import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter; @@ -56,7 +56,6 @@ import org.spongepowered.api.scheduler.SpongeExecutorService; import org.spongepowered.api.scheduler.SynchronousExecutor; import java.io.IOException; -import java.io.InputStream; import java.nio.file.Path; import java.time.Instant; import java.util.ArrayList; @@ -95,9 +94,9 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { private final SchedulerAdapter schedulerAdapter; /** - * The plugin classloader + * The plugin class path appender */ - private final PluginClassLoader classLoader; + private final ClassPathAppender classPathAppender; /** * The plugin instance @@ -142,7 +141,7 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { this.logger = new Slf4jPluginLogger(logger); this.spongeScheduler = Sponge.getScheduler(); this.schedulerAdapter = new SpongeSchedulerAdapter(this, this.spongeScheduler, syncExecutor, asyncExecutor); - this.classLoader = new ReflectionClassLoader(this); + this.classPathAppender = new ReflectionClassPathAppender(this); this.plugin = new LPSpongePlugin(this); } @@ -159,8 +158,8 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { } @Override - public PluginClassLoader getPluginClassLoader() { - return this.classLoader; + public ClassPathAppender getClassPathAppender() { + return this.classPathAppender; } // lifecycle @@ -266,11 +265,6 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { return this.configDirectory.toAbsolutePath(); } - @Override - public InputStream getResourceStream(String path) { - return getClass().getClassLoader().getResourceAsStream(path); - } - @Override public Optional getPlayer(UUID uniqueId) { return getServer().flatMap(s -> s.getPlayer(uniqueId)); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java index 7b7bf6576..beb342527 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java @@ -41,7 +41,6 @@ import me.lucko.luckperms.common.sender.DummySender; import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.tasks.CacheHousekeepingTask; import me.lucko.luckperms.common.tasks.ExpireTemporaryTask; -import me.lucko.luckperms.common.util.MoreFiles; import me.lucko.luckperms.sponge.calculator.SpongeCalculatorFactory; import me.lucko.luckperms.sponge.commands.SpongeParentCommand; import me.lucko.luckperms.sponge.context.SpongeContextManager; @@ -67,10 +66,6 @@ import net.luckperms.api.query.QueryOptions; import org.spongepowered.api.service.permission.PermissionDescription; import org.spongepowered.api.service.permission.PermissionService; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -123,7 +118,7 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin { @Override protected ConfigurationAdapter provideConfigurationAdapter() { - return new SpongeConfigAdapter(this, resolveConfig()); + return new SpongeConfigAdapter(this, resolveConfig("luckperms.conf")); } @Override @@ -236,22 +231,6 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin { this.service.invalidateAllCaches(); } - private Path resolveConfig() { - Path path = this.bootstrap.getConfigDirectory().resolve("luckperms.conf"); - if (!Files.exists(path)) { - try { - MoreFiles.createDirectoriesIfNotExists(this.bootstrap.getConfigDirectory()); - try (InputStream is = getClass().getClassLoader().getResourceAsStream("luckperms.conf")) { - Files.copy(is, path); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - return path; - } - @Override public Optional getQueryOptionsForUser(User user) { return this.bootstrap.getPlayer(user.getUniqueId()).map(player -> this.contextManager.getQueryOptions(player)); @@ -273,7 +252,7 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin { return new DummySender(this, Sender.CONSOLE_UUID, Sender.CONSOLE_NAME) { @Override public void sendMessage(Component message) { - LPSpongePlugin.this.bootstrap.getPluginLogger().info(LegacyComponentSerializer.legacySection().serialize(TranslationManager.render(message))); + LPSpongePlugin.this.getLogger().info(LegacyComponentSerializer.legacySection().serialize(TranslationManager.render(message))); } }; } diff --git a/velocity/src/main/java/me/lucko/luckperms/velocity/LPVelocityBootstrap.java b/velocity/src/main/java/me/lucko/luckperms/velocity/LPVelocityBootstrap.java index 3a264f8d6..6dc3a9209 100644 --- a/velocity/src/main/java/me/lucko/luckperms/velocity/LPVelocityBootstrap.java +++ b/velocity/src/main/java/me/lucko/luckperms/velocity/LPVelocityBootstrap.java @@ -35,8 +35,8 @@ import com.velocitypowered.api.plugin.annotation.DataDirectory; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ProxyServer; -import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader; import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap; +import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender; import me.lucko.luckperms.common.plugin.logging.PluginLogger; import me.lucko.luckperms.common.plugin.logging.Slf4jPluginLogger; import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter; @@ -45,7 +45,6 @@ import net.luckperms.api.platform.Platform; import org.slf4j.Logger; -import java.io.InputStream; import java.nio.file.Path; import java.time.Instant; import java.util.ArrayList; @@ -79,9 +78,9 @@ public class LPVelocityBootstrap implements LuckPermsBootstrap { private final SchedulerAdapter schedulerAdapter; /** - * The plugin classloader + * The plugin class path appender */ - private final PluginClassLoader classLoader; + private final ClassPathAppender classPathAppender; /** * The plugin instance @@ -108,7 +107,7 @@ public class LPVelocityBootstrap implements LuckPermsBootstrap { public LPVelocityBootstrap(Logger logger) { this.logger = new Slf4jPluginLogger(logger); this.schedulerAdapter = new VelocitySchedulerAdapter(this); - this.classLoader = new VelocityClassLoader(this); + this.classPathAppender = new VelocityClassPathAppender(this); this.plugin = new LPVelocityPlugin(this); } @@ -125,8 +124,8 @@ public class LPVelocityBootstrap implements LuckPermsBootstrap { } @Override - public PluginClassLoader getPluginClassLoader() { - return this.classLoader; + public ClassPathAppender getClassPathAppender() { + return this.classPathAppender; } // lifecycle @@ -202,11 +201,6 @@ public class LPVelocityBootstrap implements LuckPermsBootstrap { return this.configDirectory.toAbsolutePath(); } - @Override - public InputStream getResourceStream(String path) { - return getClass().getClassLoader().getResourceAsStream(path); - } - @Override public Optional getPlayer(UUID uniqueId) { return this.proxy.getPlayer(uniqueId); diff --git a/velocity/src/main/java/me/lucko/luckperms/velocity/LPVelocityPlugin.java b/velocity/src/main/java/me/lucko/luckperms/velocity/LPVelocityPlugin.java index d2d63e1e9..321a9f75c 100644 --- a/velocity/src/main/java/me/lucko/luckperms/velocity/LPVelocityPlugin.java +++ b/velocity/src/main/java/me/lucko/luckperms/velocity/LPVelocityPlugin.java @@ -41,7 +41,6 @@ import me.lucko.luckperms.common.plugin.util.AbstractConnectionListener; import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.tasks.CacheHousekeepingTask; import me.lucko.luckperms.common.tasks.ExpireTemporaryTask; -import me.lucko.luckperms.common.util.MoreFiles; import me.lucko.luckperms.velocity.calculator.VelocityCalculatorFactory; import me.lucko.luckperms.velocity.context.VelocityContextManager; import me.lucko.luckperms.velocity.context.VelocityPlayerCalculator; @@ -52,10 +51,6 @@ import me.lucko.luckperms.velocity.messaging.VelocityMessagingFactory; import net.luckperms.api.LuckPerms; import net.luckperms.api.query.QueryOptions; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -101,7 +96,7 @@ public class LPVelocityPlugin extends AbstractLuckPermsPlugin { @Override protected ConfigurationAdapter provideConfigurationAdapter() { - return new VelocityConfigAdapter(this, resolveConfig()); + return new VelocityConfigAdapter(this, resolveConfig("config.yml")); } @Override @@ -169,22 +164,6 @@ public class LPVelocityPlugin extends AbstractLuckPermsPlugin { } - private Path resolveConfig() { - Path path = this.bootstrap.getConfigDirectory().resolve("config.yml"); - if (!Files.exists(path)) { - try { - MoreFiles.createDirectoriesIfNotExists(this.bootstrap.getConfigDirectory()); - try (InputStream is = getClass().getClassLoader().getResourceAsStream("config.yml")) { - Files.copy(is, path); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - return path; - } - @Override public Optional getQueryOptionsForUser(User user) { return this.bootstrap.getPlayer(user.getUniqueId()).map(player -> this.contextManager.getQueryOptions(player)); diff --git a/velocity/src/main/java/me/lucko/luckperms/velocity/VelocityClassLoader.java b/velocity/src/main/java/me/lucko/luckperms/velocity/VelocityClassPathAppender.java similarity index 88% rename from velocity/src/main/java/me/lucko/luckperms/velocity/VelocityClassLoader.java rename to velocity/src/main/java/me/lucko/luckperms/velocity/VelocityClassPathAppender.java index 620a9538d..ec961bc35 100644 --- a/velocity/src/main/java/me/lucko/luckperms/velocity/VelocityClassLoader.java +++ b/velocity/src/main/java/me/lucko/luckperms/velocity/VelocityClassPathAppender.java @@ -25,14 +25,14 @@ package me.lucko.luckperms.velocity; -import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader; +import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender; import java.nio.file.Path; -public class VelocityClassLoader implements PluginClassLoader { +public class VelocityClassPathAppender implements ClassPathAppender { private final LPVelocityBootstrap bootstrap; - public VelocityClassLoader(LPVelocityBootstrap bootstrap) { + public VelocityClassPathAppender(LPVelocityBootstrap bootstrap) { this.bootstrap = bootstrap; }