mirror of
https://github.com/lucko/LuckPerms.git
synced 2025-09-01 18:32:33 +02:00
Implement jar-in-jar loader system (#2899)
This fixes an issue that prevented LuckPerms from loading on Java 16
This commit is contained in:
@@ -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:.*'))
|
||||
}
|
||||
|
||||
|
29
bungee/loader/build.gradle
Normal file
29
bungee/loader/build.gradle
Normal file
@@ -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
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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();
|
||||
}
|
||||
|
||||
}
|
@@ -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"]
|
@@ -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));
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -42,7 +42,7 @@ public class BungeeSenderFactory extends SenderFactory<LPBungeePlugin, CommandSe
|
||||
|
||||
public BungeeSenderFactory(LPBungeePlugin plugin) {
|
||||
super(plugin);
|
||||
this.audiences = BungeeAudiences.create(plugin.getBootstrap());
|
||||
this.audiences = BungeeAudiences.create(plugin.getLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -26,21 +26,22 @@
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import me.lucko.luckperms.bungee.util.RedisBungeeUtil;
|
||||
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.JavaPluginLogger;
|
||||
import me.lucko.luckperms.common.plugin.logging.PluginLogger;
|
||||
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
|
||||
|
||||
import net.luckperms.api.platform.Platform;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import net.md_5.bungee.api.plugin.PluginDescription;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
@@ -50,11 +51,13 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Bootstrap plugin for LuckPerms running on BungeeCord.
|
||||
*/
|
||||
public class LPBungeeBootstrap extends Plugin implements LuckPermsBootstrap {
|
||||
public class LPBungeeBootstrap implements LuckPermsBootstrap, LoaderBootstrap {
|
||||
private final Plugin loader;
|
||||
|
||||
/**
|
||||
* The plugin logger
|
||||
@@ -67,9 +70,9 @@ public class LPBungeeBootstrap extends Plugin 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
|
||||
@@ -88,14 +91,24 @@ public class LPBungeeBootstrap extends Plugin implements LuckPermsBootstrap {
|
||||
// if the plugin has been loaded on an incompatible version
|
||||
private boolean incompatibleVersion = false;
|
||||
|
||||
public LPBungeeBootstrap() {
|
||||
public LPBungeeBootstrap(Plugin loader) {
|
||||
this.loader = loader;
|
||||
|
||||
this.schedulerAdapter = new BungeeSchedulerAdapter(this);
|
||||
this.classLoader = new ReflectionClassLoader(this);
|
||||
this.classPathAppender = new JarInJarClassPathAppender(getClass().getClassLoader());
|
||||
this.plugin = new LPBungeePlugin(this);
|
||||
}
|
||||
|
||||
// provide adapters
|
||||
|
||||
public Plugin getLoader() {
|
||||
return this.loader;
|
||||
}
|
||||
|
||||
public ProxyServer getProxy() {
|
||||
return this.loader.getProxy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginLogger getPluginLogger() {
|
||||
if (this.logger == null) {
|
||||
@@ -110,15 +123,15 @@ public class LPBungeeBootstrap extends Plugin implements LuckPermsBootstrap {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginClassLoader getPluginClassLoader() {
|
||||
return this.classLoader;
|
||||
public ClassPathAppender getClassPathAppender() {
|
||||
return this.classPathAppender;
|
||||
}
|
||||
|
||||
// lifecycle
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.logger = new JavaPluginLogger(getLogger());
|
||||
this.logger = new JavaPluginLogger(this.loader.getLogger());
|
||||
|
||||
if (checkIncompatibleVersion()) {
|
||||
this.incompatibleVersion = true;
|
||||
@@ -135,16 +148,17 @@ public class LPBungeeBootstrap extends Plugin implements LuckPermsBootstrap {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
if (this.incompatibleVersion) {
|
||||
getLogger().severe("----------------------------------------------------------------------");
|
||||
getLogger().severe("Your proxy version is not compatible with this build of LuckPerms. :(");
|
||||
getLogger().severe("");
|
||||
getLogger().severe("This is most likely because you are using an old/outdated version of BungeeCord.");
|
||||
getLogger().severe("If you need 1.7 support, replace your BungeeCord.jar file with the latest build of");
|
||||
getLogger().severe("'Travertine' from here:");
|
||||
getLogger().severe("==> 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
|
||||
|
@@ -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<QueryOptions> getQueryOptionsForUser(User user) {
|
||||
return this.bootstrap.getPlayer(user.getUniqueId()).map(player -> this.contextManager.getQueryOptions(player));
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user