Extract common plugin behaviour into an abstract class

This commit is contained in:
Luck 2018-03-03 16:26:27 +00:00
parent cd5447de38
commit 68e4d36f40
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
98 changed files with 2310 additions and 2177 deletions

View File

@ -45,7 +45,7 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
public class BukkitSchedulerAdapter implements SchedulerAdapter {
private final LPBukkitPlugin plugin;
private final LPBukkitBootstrap bootstrap;
private final ExecutorService asyncFallback;
private final Executor asyncBukkit;
@ -56,8 +56,8 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet();
public BukkitSchedulerAdapter(LPBukkitPlugin plugin) {
this.plugin = plugin;
public BukkitSchedulerAdapter(LPBukkitBootstrap bootstrap) {
this.bootstrap = bootstrap;
this.sync = new SyncExecutor();
this.asyncFallback = new FallbackAsyncExecutor();
@ -66,7 +66,7 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
}
private BukkitScheduler scheduler() {
return this.plugin.getServer().getScheduler();
return this.bootstrap.getServer().getScheduler();
}
@Override
@ -81,26 +81,26 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
@Override
public SchedulerTask asyncRepeating(Runnable runnable, long intervalTicks) {
SchedulerTask task = new BukkitSchedulerTask(scheduler().runTaskTimerAsynchronously(this.plugin, runnable, intervalTicks, intervalTicks));
SchedulerTask task = new BukkitSchedulerTask(scheduler().runTaskTimerAsynchronously(this.bootstrap, runnable, intervalTicks, intervalTicks));
this.tasks.add(task);
return task;
}
@Override
public SchedulerTask syncRepeating(Runnable runnable, long intervalTicks) {
SchedulerTask task = new BukkitSchedulerTask(scheduler().runTaskTimer(this.plugin, runnable, intervalTicks, intervalTicks));
SchedulerTask task = new BukkitSchedulerTask(scheduler().runTaskTimer(this.bootstrap, runnable, intervalTicks, intervalTicks));
this.tasks.add(task);
return task;
}
@Override
public SchedulerTask asyncLater(Runnable runnable, long delayTicks) {
return new BukkitSchedulerTask(scheduler().runTaskLaterAsynchronously(this.plugin, runnable, delayTicks));
return new BukkitSchedulerTask(scheduler().runTaskLaterAsynchronously(this.bootstrap, runnable, delayTicks));
}
@Override
public SchedulerTask syncLater(Runnable runnable, long delayTicks) {
return new BukkitSchedulerTask(scheduler().runTaskLater(this.plugin, runnable, delayTicks));
return new BukkitSchedulerTask(scheduler().runTaskLater(this.bootstrap, runnable, delayTicks));
}
@Override
@ -142,14 +142,14 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
private final class SyncExecutor implements Executor {
@Override
public void execute(@Nonnull Runnable runnable) {
BukkitSchedulerAdapter.this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(BukkitSchedulerAdapter.this.plugin, runnable);
BukkitSchedulerAdapter.this.bootstrap.getServer().getScheduler().scheduleSyncDelayedTask(BukkitSchedulerAdapter.this.bootstrap, runnable);
}
}
private final class AsyncExecutor implements Executor {
@Override
public void execute(@Nonnull Runnable runnable) {
if (BukkitSchedulerAdapter.this.useFallback || !BukkitSchedulerAdapter.this.plugin.isEnabled()) {
if (BukkitSchedulerAdapter.this.useFallback || !BukkitSchedulerAdapter.this.bootstrap.isEnabled()) {
BukkitSchedulerAdapter.this.asyncFallback.execute(runnable);
} else {
BukkitSchedulerAdapter.this.asyncBukkit.execute(runnable);
@ -160,7 +160,7 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
private final class BukkitAsyncExecutor implements Executor {
@Override
public void execute(@Nonnull Runnable runnable) {
BukkitSchedulerAdapter.this.plugin.getServer().getScheduler().runTaskAsynchronously(BukkitSchedulerAdapter.this.plugin, runnable);
BukkitSchedulerAdapter.this.bootstrap.getServer().getScheduler().runTaskAsynchronously(BukkitSchedulerAdapter.this.bootstrap, runnable);
}
}

View File

@ -79,7 +79,7 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> {
}
// otherwise, send the message sync
getPlugin().getScheduler().doSync(new SyncMessengerAgent(sender, s));
getPlugin().getBootstrap().getScheduler().doSync(new SyncMessengerAgent(sender, s));
}
@Override

View File

@ -0,0 +1,255 @@
/*
* 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.bukkit;
import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.bukkit.compat.NullSafeConsoleCommandSender;
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 org.bukkit.Server;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.InputStream;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Stream;
import javax.annotation.Nullable;
/**
* Bootstrap plugin for LuckPerms running on Bukkit.
*/
public class LPBukkitBootstrap extends JavaPlugin implements LuckPermsBootstrap {
/**
* A scheduler adapter for the platform
*/
private final BukkitSchedulerAdapter schedulerAdapter;
/**
* The plugin classloader
*/
private final PluginClassLoader classLoader;
/**
* A null-safe console instance which delegates to the server logger
* if {@link Server#getConsoleSender()} returns null.
*/
private final ConsoleCommandSender console;
/**
* The plugin instance
*/
private final LPBukkitPlugin plugin;
/**
* The time when the plugin was enabled
*/
private long startTime;
// load/enable latches
private final CountDownLatch loadLatch = new CountDownLatch(1);
private final CountDownLatch enableLatch = new CountDownLatch(1);
// if the plugin has been loaded on an incompatible version
private boolean incompatibleVersion = false;
public LPBukkitBootstrap() {
this.schedulerAdapter = new BukkitSchedulerAdapter(this);
this.classLoader = new ReflectionClassLoader(this);
this.console = new NullSafeConsoleCommandSender(getServer());
this.plugin = new LPBukkitPlugin(this);
}
// provide adapters
@Override
public BukkitSchedulerAdapter getScheduler() {
return this.schedulerAdapter;
}
@Override
public PluginClassLoader getPluginClassLoader() {
return this.classLoader;
}
public ConsoleCommandSender getConsole() {
return this.console;
}
// lifecycle
@Override
public void onLoad() {
if (checkIncompatibleVersion()) {
this.incompatibleVersion = true;
return;
}
try {
this.plugin.load();
} finally {
this.loadLatch.countDown();
}
}
@Override
public void onEnable() {
if (this.incompatibleVersion) {
getLogger().severe("----------------------------------------------------------------------");
getLogger().severe("Your server version is not compatible with this build of LuckPerms. :(");
getLogger().severe("");
getLogger().severe("If your server is running 1.8, please update to 1.8.8 or higher.");
getLogger().severe("If your server is running 1.7.10, please download the Bukkit-Legacy version of LuckPerms from here:");
getLogger().severe("==> https://ci.lucko.me/job/LuckPermsLegacy/");
getLogger().severe("----------------------------------------------------------------------");
getServer().getPluginManager().disablePlugin(this);
return;
}
this.startTime = System.currentTimeMillis();
try {
this.plugin.enable();
} finally {
this.enableLatch.countDown();
}
}
@Override
public void onDisable() {
if (this.incompatibleVersion) {
return;
}
this.plugin.disable();
}
@Override
public CountDownLatch getEnableLatch() {
return this.enableLatch;
}
@Override
public CountDownLatch getLoadLatch() {
return this.loadLatch;
}
// provide information about the plugin
@Override
public String getVersion() {
return getDescription().getVersion();
}
@Override
public long getStartupTime() {
return this.startTime;
}
// provide information about the platform
@Override
public PlatformType getType() {
return PlatformType.BUKKIT;
}
@Override
public String getServerBrand() {
return getServer().getName();
}
@Override
public String getServerVersion() {
return getServer().getVersion() + " - " + getServer().getBukkitVersion();
}
@Override
public String getServerName() {
return getServer().getServerName();
}
@Override
public File getDataDirectory() {
return getDataFolder();
}
@Override
public InputStream getResourceStream(String path) {
return getResource(path);
}
@Nullable
@Override
public Player getPlayer(UUID uuid) {
return getServer().getPlayer(uuid);
}
@Override
public Optional<UUID> lookupUuid(String username) {
try {
//noinspection deprecation
return Optional.ofNullable(getServer().getOfflinePlayer(username)).flatMap(p -> Optional.ofNullable(p.getUniqueId()));
} catch (Exception e) {
e.printStackTrace();
return Optional.empty();
}
}
@Override
public int getPlayerCount() {
return getServer().getOnlinePlayers().size();
}
@Override
public Stream<String> getPlayerList() {
return getServer().getOnlinePlayers().stream().map(Player::getName);
}
@Override
public Stream<UUID> getOnlinePlayers() {
return getServer().getOnlinePlayers().stream().map(Player::getUniqueId);
}
@Override
public boolean isPlayerOnline(UUID uuid) {
Player player = getServer().getPlayer(uuid);
return player != null && player.isOnline();
}
private static boolean checkIncompatibleVersion() {
try {
Class.forName("com.google.gson.JsonElement");
return false;
} catch (ClassNotFoundException e) {
return true;
}
}
}

View File

@ -27,9 +27,7 @@ package me.lucko.luckperms.bukkit;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.bukkit.calculators.BukkitCalculatorFactory;
import me.lucko.luckperms.bukkit.compat.NullSafeConsoleCommandSender;
import me.lucko.luckperms.bukkit.contexts.BukkitContextManager;
import me.lucko.luckperms.bukkit.contexts.WorldCalculator;
import me.lucko.luckperms.bukkit.listeners.BukkitConnectionListener;
@ -45,210 +43,114 @@ import me.lucko.luckperms.bukkit.model.server.LPDefaultsMap;
import me.lucko.luckperms.bukkit.model.server.LPPermissionMap;
import me.lucko.luckperms.bukkit.model.server.LPSubscriptionMap;
import me.lucko.luckperms.bukkit.vault.VaultHookManager;
import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiRegistrationUtil;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.buffers.UpdateTaskBuffer;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.CommandPermission;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.AbstractConfiguration;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.contexts.LuckPermsCalculator;
import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.dependencies.DependencyRegistry;
import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader;
import me.lucko.luckperms.common.dependencies.classloader.ReflectionClassLoader;
import me.lucko.luckperms.common.event.EventFactory;
import me.lucko.luckperms.common.inheritance.InheritanceHandler;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.NoopLocaleManager;
import me.lucko.luckperms.common.locale.SimpleLocaleManager;
import me.lucko.luckperms.common.logging.Logger;
import me.lucko.luckperms.common.logging.SenderLogger;
import me.lucko.luckperms.common.listener.ConnectionListener;
import me.lucko.luckperms.common.managers.group.StandardGroupManager;
import me.lucko.luckperms.common.managers.track.StandardTrackManager;
import me.lucko.luckperms.common.managers.user.StandardUserManager;
import me.lucko.luckperms.common.messaging.InternalMessagingService;
import me.lucko.luckperms.common.messaging.MessagingFactory;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.storage.StorageFactory;
import me.lucko.luckperms.common.storage.StorageType;
import me.lucko.luckperms.common.storage.dao.file.FileWatcher;
import me.lucko.luckperms.common.plugin.AbstractLuckPermsPlugin;
import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
import me.lucko.luckperms.common.tasks.UpdateTask;
import me.lucko.luckperms.common.treeview.PermissionVault;
import me.lucko.luckperms.common.verbose.VerboseHandler;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
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.io.InputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Stream;
/**
* LuckPerms implementation for the Bukkit API.
*/
public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
public class LPBukkitPlugin extends AbstractLuckPermsPlugin {
private final LPBukkitBootstrap bootstrap;
private long startTime;
private BukkitSchedulerAdapter scheduler;
private BukkitSenderFactory senderFactory;
private BukkitConnectionListener connectionListener;
private BukkitCommandExecutor commandManager;
private VaultHookManager vaultHookManager = null;
private LuckPermsConfiguration configuration;
private StandardUserManager userManager;
private StandardGroupManager groupManager;
private StandardTrackManager trackManager;
private Storage storage;
private FileWatcher fileWatcher = null;
private InternalMessagingService messagingService = null;
private LuckPermsApiProvider apiProvider;
private EventFactory eventFactory;
private Logger log;
private ConsoleCommandSender console;
private ContextManager<Player> contextManager;
private LPSubscriptionMap subscriptionMap;
private LPPermissionMap permissionMap;
private LPDefaultsMap defaultPermissionMap;
private LocaleManager localeManager;
private PluginClassLoader pluginClassLoader;
private DependencyManager dependencyManager;
private InheritanceHandler inheritanceHandler;
private CachedStateManager cachedStateManager;
private ContextManager<Player> contextManager;
private CalculatorFactory calculatorFactory;
private BufferedRequest<Void> updateTaskBuffer;
private CountDownLatch enableLatch = new CountDownLatch(1);
private VerboseHandler verboseHandler;
private BukkitSenderFactory senderFactory;
private PermissionVault permissionVault;
private LogDispatcher logDispatcher;
private Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
private VaultHookManager vaultHookManager = null;
private boolean invalidVersion = false;
@Override
public void onLoad() {
if (checkInvalidVersion()) {
this.invalidVersion = true;
return;
public LPBukkitPlugin(LPBukkitBootstrap bootstrap) {
this.bootstrap = bootstrap;
}
// setup minimal functionality in order to load initial dependencies
this.console = new NullSafeConsoleCommandSender(getServer());
this.scheduler = new BukkitSchedulerAdapter(this);
this.localeManager = new NoopLocaleManager();
@Override
public LPBukkitBootstrap getBootstrap() {
return this.bootstrap;
}
@Override
protected void setupSenderFactory() {
this.senderFactory = new BukkitSenderFactory(this);
this.log = new SenderLogger(this, getConsoleSender());
this.pluginClassLoader = new ReflectionClassLoader(this);
this.dependencyManager = new DependencyManager(this);
this.dependencyManager.loadDependencies(DependencyRegistry.GLOBAL_DEPENDENCIES);
}
@Override
public void onEnable() {
if (this.invalidVersion) {
getLogger().severe("----------------------------------------------------------------------");
getLogger().severe("Your server version is not compatible with this build of LuckPerms. :(");
getLogger().severe("");
getLogger().severe("If your server is running 1.8, please update to 1.8.8 or higher.");
getLogger().severe("If your server is running 1.7.10, please download the Bukkit-Legacy version of LuckPerms from here:");
getLogger().severe("==> https://ci.lucko.me/job/LuckPermsLegacy/");
getLogger().severe("----------------------------------------------------------------------");
getServer().getPluginManager().disablePlugin(this);
return;
protected ConfigurationAdapter provideConfigurationAdapter() {
return new BukkitConfigAdapter(this, resolveConfig());
}
try {
enable();
} finally {
// count down the latch when onEnable has been called
// we don't care about the result here
this.enableLatch.countDown();
}
@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);
}
private void enable() {
this.startTime = System.currentTimeMillis();
sendStartupBanner(getConsoleSender());
this.verboseHandler = new VerboseHandler(this.scheduler.asyncBukkit());
this.permissionVault = new PermissionVault(this.scheduler.asyncBukkit());
this.logDispatcher = new LogDispatcher(this);
getLog().info("Loading configuration...");
this.configuration = new AbstractConfiguration(this, new BukkitConfigAdapter(this, resolveConfig("config.yml")));
this.configuration.loadAll();
StorageFactory storageFactory = new StorageFactory(this);
Set<StorageType> storageTypes = storageFactory.getRequiredTypes(StorageType.H2);
this.dependencyManager.loadStorageDependencies(storageTypes);
// register events
BukkitConnectionListener connectionListener = new BukkitConnectionListener(this);
getServer().getPluginManager().registerEvents(connectionListener, this);
getServer().getPluginManager().registerEvents(new BukkitPlatformListener(this), this);
if (getConfiguration().get(ConfigKeys.WATCH_FILES)) {
this.fileWatcher = new FileWatcher(this);
getScheduler().asyncRepeating(this.fileWatcher, 30L);
@Override
protected MessagingFactory<?> provideMessagingFactory() {
return new BukkitMessagingFactory(this);
}
// initialise datastore
this.storage = storageFactory.getInstance(StorageType.H2);
// initialise messaging
this.messagingService = new BukkitMessagingFactory(this).getInstance();
// setup the update task buffer
this.updateTaskBuffer = new UpdateTaskBuffer(this);
// load locale
this.localeManager = new SimpleLocaleManager();
this.localeManager.tryLoad(this, new File(getDataFolder(), "lang.yml"));
// register commands
@Override
protected void registerCommands() {
this.commandManager = new BukkitCommandExecutor(this);
PluginCommand main = getServer().getPluginCommand("luckperms");
PluginCommand main = this.bootstrap.getServer().getPluginCommand("luckperms");
main.setExecutor(this.commandManager);
main.setTabCompleter(this.commandManager);
main.setDescription("Manage permissions");
main.setAliases(Arrays.asList("lp", "perm", "perms", "permission", "permissions"));
}
// load internal managers
getLog().info("Loading internal permission managers...");
this.inheritanceHandler = new InheritanceHandler(this);
@Override
protected void setupManagers() {
this.userManager = new StandardUserManager(this);
this.groupManager = new StandardGroupManager(this);
this.trackManager = new StandardTrackManager(this);
this.calculatorFactory = new BukkitCalculatorFactory(this);
this.cachedStateManager = new CachedStateManager();
}
// setup context manager
@Override
protected CalculatorFactory provideCalculatorFactory() {
return new BukkitCalculatorFactory(this);
}
@Override
protected void setupContextManager() {
this.contextManager = new BukkitContextManager(this);
this.contextManager.registerCalculator(new WorldCalculator(this));
this.contextManager.registerStaticCalculator(new LuckPermsCalculator(getConfiguration()));
}
@Override
protected void setupPlatformHooks() {
// inject our own custom permission maps
Runnable[] injectors = new Runnable[]{
new InjectorSubscriptionMap(this),
@ -262,46 +164,47 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
// schedule another injection after all plugins have loaded
// the entire pluginmanager instance is replaced by some plugins :(
this.scheduler.asyncLater(injector, 1L);
this.bootstrap.getScheduler().asyncLater(injector, 1L);
}
// Provide vault support
tryVaultHook(false);
// register with the LP API
this.apiProvider = new LuckPermsApiProvider(this);
// setup event factory
this.eventFactory = new EventFactory(this, this.apiProvider);
ApiRegistrationUtil.registerProvider(this.apiProvider);
getServer().getServicesManager().register(LuckPermsApi.class, this.apiProvider, this, ServicePriority.Normal);
// schedule update tasks
int mins = getConfiguration().get(ConfigKeys.SYNC_TIME);
if (mins > 0) {
long ticks = mins * 60 * 20;
this.scheduler.asyncRepeating(() -> this.updateTaskBuffer.request(), ticks);
}
this.scheduler.asyncLater(() -> this.updateTaskBuffer.request(), 40L);
// run an update instantly.
getLog().info("Performing initial data load...");
public void tryVaultHook(boolean force) {
if (this.vaultHookManager != null) {
return; // already hooked
}
try {
new UpdateTask(this, true).run();
if (force || this.bootstrap.getServer().getPluginManager().isPluginEnabled("Vault")) {
this.vaultHookManager = new VaultHookManager();
this.vaultHookManager.hook(this);
getLogger().info("Registered Vault permission & chat hook.");
}
} catch (Exception e) {
this.vaultHookManager = null;
getLogger().severe("Error occurred whilst hooking into Vault.");
e.printStackTrace();
}
}
@Override
protected void registerApiOnPlatform(LuckPermsApi api) {
this.bootstrap.getServer().getServicesManager().register(LuckPermsApi.class, api, this.bootstrap, ServicePriority.Normal);
}
// register tasks
this.scheduler.asyncRepeating(new ExpireTemporaryTask(this), 60L);
this.scheduler.asyncRepeating(new CacheHousekeepingTask(this), 2400L);
@Override
protected void registerHousekeepingTasks() {
this.bootstrap.getScheduler().asyncRepeating(new ExpireTemporaryTask(this), 60L);
this.bootstrap.getScheduler().asyncRepeating(new CacheHousekeepingTask(this), 2400L);
}
@Override
protected void performFinalSetup() {
// register permissions
try {
PluginManager pm = getServer().getPluginManager();
PluginManager pm = this.bootstrap.getServer().getPluginManager();
PermissionDefault permDefault = getConfiguration().get(ConfigKeys.COMMANDS_ALLOW_OP) ? PermissionDefault.OP : PermissionDefault.FALSE;
for (CommandPermission p : CommandPermission.values()) {
@ -312,19 +215,19 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
}
if (!getConfiguration().get(ConfigKeys.OPS_ENABLED)) {
this.scheduler.doSync(() -> getServer().getOperators().forEach(o -> o.setOp(false)));
this.bootstrap.getScheduler().doSync(() -> this.bootstrap.getServer().getOperators().forEach(o -> o.setOp(false)));
}
// replace the temporary executor when the Bukkit one starts
getServer().getScheduler().runTaskAsynchronously(this, () -> this.scheduler.setUseFallback(false));
this.bootstrap.getServer().getScheduler().runTaskAsynchronously(this.bootstrap, () -> this.bootstrap.getScheduler().setUseFallback(false));
// Load any online users (in the case of a reload)
for (Player player : getServer().getOnlinePlayers()) {
this.scheduler.doAsync(() -> {
for (Player player : this.bootstrap.getServer().getOnlinePlayers()) {
this.bootstrap.getScheduler().doAsync(() -> {
try {
User user = connectionListener.loadUser(player.getUniqueId(), player.getName());
User user = this.connectionListener.loadUser(player.getUniqueId(), player.getName());
if (user != null) {
this.scheduler.doSync(() -> {
this.bootstrap.getScheduler().doSync(() -> {
try {
LPPermissible lpPermissible = new LPPermissible(player, user, this);
PermissibleInjector.inject(player, lpPermissible);
@ -338,24 +241,18 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
}
});
}
getLog().info("Successfully enabled. (took " + (System.currentTimeMillis() - this.startTime) + "ms)");
}
@Override
public void onDisable() {
if (this.invalidVersion) {
return;
protected void performEarlyDisableTasks() {
// Switch back to the fallback executor, the bukkit one won't allow new tasks
this.bootstrap.getScheduler().setUseFallback(true);
}
// Switch back to the fallback executor, the bukkit one won't allow new tasks
this.scheduler.setUseFallback(true);
this.permissionVault.shutdown();
this.verboseHandler.shutdown();
@Override
protected void removePlatformHooks() {
// uninject from players
for (Player player : getServer().getOnlinePlayers()) {
for (Player player : this.bootstrap.getServer().getOnlinePlayers()) {
try {
PermissibleInjector.unInject(player, false);
} catch (Exception e) {
@ -378,50 +275,10 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
InjectorPermissionMap.uninject();
InjectorDefaultsMap.uninject();
getLog().info("Closing storage...");
this.storage.shutdown();
if (this.fileWatcher != null) {
this.fileWatcher.close();
}
if (this.messagingService != null) {
getLog().info("Closing messaging service...");
this.messagingService.close();
}
ApiRegistrationUtil.unregisterProvider();
getServer().getServicesManager().unregisterAll(this);
// unhook vault
if (this.vaultHookManager != null) {
this.vaultHookManager.unhook(this);
}
getLog().info("Shutting down internal scheduler...");
this.scheduler.shutdown();
// Bukkit will do this again when #onDisable completes, but we do it early to prevent NPEs elsewhere.
getServer().getScheduler().cancelTasks(this);
HandlerList.unregisterAll(this);
getLog().info("Goodbye!");
}
public void tryVaultHook(boolean force) {
if (this.vaultHookManager != null) {
return; // already hooked
}
try {
if (force || getServer().getPluginManager().isPluginEnabled("Vault")) {
this.vaultHookManager = new VaultHookManager();
this.vaultHookManager.hook(this);
getLog().info("Registered Vault permission & chat hook.");
}
} catch (Exception e) {
this.vaultHookManager = null;
getLog().severe("Error occurred whilst hooking into Vault.");
e.printStackTrace();
}
}
public void refreshAutoOp(User user, Player player) {
@ -436,15 +293,69 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
}
}
private File resolveConfig(String file) {
File configFile = new File(getDataFolder(), file);
private File resolveConfig() {
File configFile = new File(this.bootstrap.getDataFolder(), "config.yml");
if (!configFile.exists()) {
getDataFolder().mkdirs();
saveResource("config.yml", false);
this.bootstrap.getDataFolder().mkdirs();
this.bootstrap.saveResource("config.yml", false);
}
return configFile;
}
return configFile;
@Override
public Optional<Contexts> getContextForUser(User user) {
Player player = this.bootstrap.getPlayer(user.getUuid());
if (player == null) {
return Optional.empty();
}
return Optional.of(this.contextManager.getApplicableContexts(player));
}
@Override
public Stream<Sender> getOnlineSenders() {
return Stream.concat(
Stream.of(getConsoleSender()),
this.bootstrap.getServer().getOnlinePlayers().stream().map(p -> getSenderFactory().wrap(p))
);
}
@Override
public Sender getConsoleSender() {
return getSenderFactory().wrap(this.bootstrap.getConsole());
}
public BukkitSenderFactory getSenderFactory() {
return this.senderFactory;
}
@Override
public ConnectionListener getConnectionListener() {
return this.connectionListener;
}
@Override
public BukkitCommandExecutor getCommandManager() {
return this.commandManager;
}
@Override
public StandardUserManager getUserManager() {
return this.userManager;
}
@Override
public StandardGroupManager getGroupManager() {
return this.groupManager;
}
@Override
public StandardTrackManager getTrackManager() {
return this.trackManager;
}
@Override
public ContextManager<Player> getContextManager() {
return this.contextManager;
}
public LPSubscriptionMap getSubscriptionMap() {
@ -471,250 +382,4 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
this.defaultPermissionMap = defaultPermissionMap;
}
@Override
public Optional<InternalMessagingService> getMessagingService() {
return Optional.ofNullable(this.messagingService);
}
@Override
public void setMessagingService(InternalMessagingService messagingService) {
if (this.messagingService == null) {
this.messagingService = messagingService;
}
}
@Override
public Optional<FileWatcher> getFileWatcher() {
return Optional.ofNullable(this.fileWatcher);
}
@Override
public String getVersion() {
return getDescription().getVersion();
}
@Override
public PlatformType getServerType() {
return PlatformType.BUKKIT;
}
@Override
public String getServerBrand() {
return getServer().getName();
}
@Override
public String getServerVersion() {
return getServer().getVersion() + " - " + getServer().getBukkitVersion();
}
@Override
public String getServerName() {
return getServer().getServerName();
}
@Override
public File getDataDirectory() {
return super.getDataFolder();
}
@Override
public InputStream getResourceStream(String path) {
return getResource(path);
}
@Override
public Player getPlayer(User user) {
return getServer().getPlayer(user.getUuid());
}
@Override
public Optional<UUID> lookupUuid(String username) {
try {
//noinspection deprecation
return Optional.ofNullable(getServer().getOfflinePlayer(username)).flatMap(p -> Optional.ofNullable(p.getUniqueId()));
} catch (Exception e) {
e.printStackTrace();
return Optional.empty();
}
}
@Override
public Optional<Contexts> getContextForUser(User user) {
Player player = getPlayer(user);
if (player == null) {
return Optional.empty();
}
return Optional.of(this.contextManager.getApplicableContexts(player));
}
@Override
public int getPlayerCount() {
return getServer().getOnlinePlayers().size();
}
@Override
public Stream<String> getPlayerList() {
return getServer().getOnlinePlayers().stream().map(Player::getName);
}
@Override
public Stream<UUID> getOnlinePlayers() {
return getServer().getOnlinePlayers().stream().map(Player::getUniqueId);
}
@Override
public boolean isPlayerOnline(UUID external) {
Player player = getServer().getPlayer(external);
return player != null && player.isOnline();
}
@Override
public Stream<Sender> getOnlineSenders() {
return Stream.concat(
Stream.of(getConsoleSender()),
getServer().getOnlinePlayers().stream().map(p -> getSenderFactory().wrap(p))
);
}
@Override
public Sender getConsoleSender() {
return getSenderFactory().wrap(this.console);
}
private static boolean checkInvalidVersion() {
try {
Class.forName("com.google.gson.JsonElement");
return false;
} catch (ClassNotFoundException e) {
return true;
}
}
@Override
public long getStartTime() {
return this.startTime;
}
@Override
public BukkitSchedulerAdapter getScheduler() {
return this.scheduler;
}
@Override
public BukkitCommandExecutor getCommandManager() {
return this.commandManager;
}
public VaultHookManager getVaultHookManager() {
return this.vaultHookManager;
}
@Override
public LuckPermsConfiguration getConfiguration() {
return this.configuration;
}
@Override
public StandardUserManager getUserManager() {
return this.userManager;
}
@Override
public StandardGroupManager getGroupManager() {
return this.groupManager;
}
@Override
public StandardTrackManager getTrackManager() {
return this.trackManager;
}
@Override
public Storage getStorage() {
return this.storage;
}
@Override
public LuckPermsApiProvider getApiProvider() {
return this.apiProvider;
}
@Override
public EventFactory getEventFactory() {
return this.eventFactory;
}
@Override
public Logger getLog() {
return this.log;
}
@Override
public LocaleManager getLocaleManager() {
return this.localeManager;
}
@Override
public PluginClassLoader getPluginClassLoader() {
return this.pluginClassLoader;
}
@Override
public DependencyManager getDependencyManager() {
return this.dependencyManager;
}
@Override
public CachedStateManager getCachedStateManager() {
return this.cachedStateManager;
}
@Override
public ContextManager<Player> getContextManager() {
return this.contextManager;
}
@Override
public InheritanceHandler getInheritanceHandler() {
return this.inheritanceHandler;
}
@Override
public CalculatorFactory getCalculatorFactory() {
return this.calculatorFactory;
}
@Override
public BufferedRequest<Void> getUpdateTaskBuffer() {
return this.updateTaskBuffer;
}
public CountDownLatch getEnableLatch() {
return this.enableLatch;
}
@Override
public VerboseHandler getVerboseHandler() {
return this.verboseHandler;
}
public BukkitSenderFactory getSenderFactory() {
return this.senderFactory;
}
@Override
public PermissionVault getPermissionVault() {
return this.permissionVault;
}
@Override
public LogDispatcher getLogDispatcher() {
return this.logDispatcher;
}
@Override
public Set<UUID> getUniqueConnections() {
return this.uniqueConnections;
}
}

View File

@ -29,9 +29,9 @@ import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.bukkit.model.permissible.LPPermissible;
import me.lucko.luckperms.bukkit.model.permissible.PermissibleInjector;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.listener.AbstractConnectionListener;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.utils.AbstractLoginListener;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -47,7 +47,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class BukkitConnectionListener extends AbstractLoginListener implements Listener {
public class BukkitConnectionListener extends AbstractConnectionListener implements Listener {
private final LPBukkitPlugin plugin;
private final Set<UUID> deniedAsyncLogin = Collections.synchronizedSet(new HashSet<>());
@ -66,16 +66,16 @@ public class BukkitConnectionListener extends AbstractLoginListener implements L
/* wait for the plugin to enable. because these events are fired async, they can be called before
the plugin has enabled. */
try {
this.plugin.getEnableLatch().await(60, TimeUnit.SECONDS);
this.plugin.getBootstrap().getEnableLatch().await(60, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
this.plugin.getLog().info("Processing pre-login for " + e.getUniqueId() + " - " + e.getName());
this.plugin.getLogger().info("Processing pre-login for " + e.getUniqueId() + " - " + e.getName());
}
this.plugin.getUniqueConnections().add(e.getUniqueId());
recordConnection(e.getUniqueId());
/* Actually process the login for the connection.
We do this here to delay the login until the data is ready.
@ -90,7 +90,7 @@ public class BukkitConnectionListener extends AbstractLoginListener implements L
User user = loadUser(e.getUniqueId(), e.getName());
this.plugin.getEventFactory().handleUserLoginProcess(e.getUniqueId(), e.getName(), user);
} catch (Exception ex) {
this.plugin.getLog().severe("Exception occurred whilst loading data for " + e.getUniqueId() + " - " + e.getName());
this.plugin.getLogger().severe("Exception occurred whilst loading data for " + e.getUniqueId() + " - " + e.getName());
ex.printStackTrace();
// deny the connection
@ -110,7 +110,7 @@ public class BukkitConnectionListener extends AbstractLoginListener implements L
// This is a problem, as they were denied at low priority, but are now being allowed.
if (e.getLoginResult() == AsyncPlayerPreLoginEvent.Result.ALLOWED) {
this.plugin.getLog().severe("Player connection was re-allowed for " + e.getUniqueId());
this.plugin.getLogger().severe("Player connection was re-allowed for " + e.getUniqueId());
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, "");
}
}
@ -124,7 +124,7 @@ public class BukkitConnectionListener extends AbstractLoginListener implements L
final Player player = e.getPlayer();
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
this.plugin.getLog().info("Processing login for " + player.getUniqueId() + " - " + player.getName());
this.plugin.getLogger().info("Processing login for " + player.getUniqueId() + " - " + player.getName());
}
final User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId());
@ -133,7 +133,7 @@ public class BukkitConnectionListener extends AbstractLoginListener implements L
if (user == null) {
this.deniedLogin.add(e.getPlayer().getUniqueId());
this.plugin.getLog().warn("User " + player.getUniqueId() + " - " + player.getName() + " doesn't have data pre-loaded. - denying login.");
this.plugin.getLogger().warn("User " + player.getUniqueId() + " - " + player.getName() + " doesn't have data pre-loaded. - denying login.");
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.asString(this.plugin.getLocaleManager()));
return;
}
@ -166,7 +166,7 @@ public class BukkitConnectionListener extends AbstractLoginListener implements L
// This is a problem, as they were denied at low priority, but are now being allowed.
if (e.getResult() == PlayerLoginEvent.Result.ALLOWED) {
this.plugin.getLog().severe("Player connection was re-allowed for " + e.getPlayer().getUniqueId());
this.plugin.getLogger().severe("Player connection was re-allowed for " + e.getPlayer().getUniqueId());
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, "");
}
}
@ -202,7 +202,7 @@ public class BukkitConnectionListener extends AbstractLoginListener implements L
this.plugin.getUserManager().getHouseKeeper().registerUsage(player.getUniqueId());
// force a clear of transient nodes
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId());
if (user != null) {
user.clearTransientNodes();

View File

@ -49,8 +49,8 @@ public class BukkitMessagingFactory extends MessagingFactory<LPBukkitPlugin> {
e.printStackTrace();
}
} else if (messagingType.equals("lilypad")) {
if (getPlugin().getServer().getPluginManager().getPlugin("LilyPad-Connect") == null) {
getPlugin().getLog().warn("LilyPad-Connect plugin not present.");
if (getPlugin().getBootstrap().getServer().getPluginManager().getPlugin("LilyPad-Connect") == null) {
getPlugin().getLogger().warn("LilyPad-Connect plugin not present.");
} else {
try {
return new LuckPermsMessagingService(getPlugin(), new LilyPadMessengerProvider());

View File

@ -58,14 +58,14 @@ public class BungeeMessenger implements Messenger, PluginMessageListener {
}
public void init() {
this.plugin.getServer().getMessenger().registerOutgoingPluginChannel(this.plugin, CHANNEL);
this.plugin.getServer().getMessenger().registerIncomingPluginChannel(this.plugin, CHANNEL, this);
this.plugin.getBootstrap().getServer().getMessenger().registerOutgoingPluginChannel(this.plugin.getBootstrap(), CHANNEL);
this.plugin.getBootstrap().getServer().getMessenger().registerIncomingPluginChannel(this.plugin.getBootstrap(), CHANNEL, this);
}
@Override
public void close() {
this.plugin.getServer().getMessenger().unregisterIncomingPluginChannel(this.plugin, CHANNEL);
this.plugin.getServer().getMessenger().unregisterOutgoingPluginChannel(this.plugin, CHANNEL);
this.plugin.getBootstrap().getServer().getMessenger().unregisterIncomingPluginChannel(this.plugin.getBootstrap(), CHANNEL);
this.plugin.getBootstrap().getServer().getMessenger().unregisterOutgoingPluginChannel(this.plugin.getBootstrap(), CHANNEL);
}
@Override
@ -73,7 +73,7 @@ public class BungeeMessenger implements Messenger, PluginMessageListener {
new BukkitRunnable() {
@Override
public void run() {
Collection<? extends Player> players = BungeeMessenger.this.plugin.getServer().getOnlinePlayers();
Collection<? extends Player> players = BungeeMessenger.this.plugin.getBootstrap().getServer().getOnlinePlayers();
Player p = Iterables.getFirst(players, null);
if (p == null) {
return;
@ -84,10 +84,10 @@ public class BungeeMessenger implements Messenger, PluginMessageListener {
byte[] data = out.toByteArray();
p.sendPluginMessage(BungeeMessenger.this.plugin, CHANNEL, data);
p.sendPluginMessage(BungeeMessenger.this.plugin.getBootstrap(), CHANNEL, data);
cancel();
}
}.runTaskTimer(this.plugin, 1L, 100L);
}.runTaskTimer(this.plugin.getBootstrap(), 1L, 100L);
}
@Override

View File

@ -58,7 +58,7 @@ public class LilyPadMessenger implements Messenger {
}
public void init() {
this.connect = this.plugin.getServer().getServicesManager().getRegistration(Connect.class).getProvider();
this.connect = this.plugin.getBootstrap().getServer().getServicesManager().getRegistration(Connect.class).getProvider();
this.connect.registerEvents(this);
}
@ -87,7 +87,7 @@ public class LilyPadMessenger implements Messenger {
@EventListener
public void onMessage(MessageEvent event) {
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
try {
String channel = event.getChannel();

View File

@ -219,7 +219,7 @@ public class LPPermissible extends PermissibleBase {
}
LPPermissionAttachment ret = addAttachment(plugin);
if (getPlugin().getServer().getScheduler().scheduleSyncDelayedTask(plugin, ret::remove, ticks) == -1) {
if (getPlugin().getBootstrap().getServer().getScheduler().scheduleSyncDelayedTask(plugin, ret::remove, ticks) == -1) {
ret.remove();
throw new RuntimeException("Could not add PermissionAttachment to " + this.player + " for plugin " + plugin.getDescription().getFullName() + ": Scheduler returned -1");
}

View File

@ -276,7 +276,7 @@ public class LPPermissionAttachment extends PermissionAttachment {
@Override
public Plugin getPlugin() {
return this.owner != null ? this.owner : this.permissible.getPlugin();
return this.owner != null ? this.owner : this.permissible.getPlugin().getBootstrap();
}
@Override

View File

@ -81,7 +81,7 @@ public class PermissibleMonitoringInjector implements Runnable {
}
private void injectConsole() throws Exception {
ConsoleCommandSender consoleSender = this.plugin.getServer().getConsoleSender();
ConsoleCommandSender consoleSender = this.plugin.getBootstrap().getServer().getConsoleSender();
// get the ServerCommandSender class
Class<?> serverCommandSenderClass = ReflectionUtil.obcClass("command.ServerCommandSender");

View File

@ -69,18 +69,18 @@ public class InjectorDefaultsMap implements Runnable {
this.plugin.setDefaultPermissionMap(ret);
}
} catch (Exception e) {
this.plugin.getLog().severe("Exception occurred whilst injecting LuckPerms Default Permission map.");
this.plugin.getLogger().severe("Exception occurred whilst injecting LuckPerms Default Permission map.");
e.printStackTrace();
}
}
private LPDefaultsMap inject() throws Exception {
Objects.requireNonNull(DEFAULT_PERMISSIONS_FIELD, "DEFAULT_PERMISSIONS_FIELD");
PluginManager pluginManager = this.plugin.getServer().getPluginManager();
PluginManager pluginManager = this.plugin.getBootstrap().getServer().getPluginManager();
if (!(pluginManager instanceof SimplePluginManager)) {
this.plugin.getLog().severe("PluginManager instance is not a 'SimplePluginManager', instead: " + pluginManager.getClass());
this.plugin.getLog().severe("Unable to inject LuckPerms Default Permission map.");
this.plugin.getLogger().severe("PluginManager instance is not a 'SimplePluginManager', instead: " + pluginManager.getClass());
this.plugin.getLogger().severe("Unable to inject LuckPerms Default Permission map.");
return null;
}

View File

@ -68,18 +68,18 @@ public class InjectorPermissionMap implements Runnable {
this.plugin.setPermissionMap(ret);
}
} catch (Exception e) {
this.plugin.getLog().severe("Exception occurred whilst injecting LuckPerms Permission map.");
this.plugin.getLogger().severe("Exception occurred whilst injecting LuckPerms Permission map.");
e.printStackTrace();
}
}
private LPPermissionMap inject() throws Exception {
Objects.requireNonNull(PERMISSIONS_FIELD, "PERMISSIONS_FIELD");
PluginManager pluginManager = this.plugin.getServer().getPluginManager();
PluginManager pluginManager = this.plugin.getBootstrap().getServer().getPluginManager();
if (!(pluginManager instanceof SimplePluginManager)) {
this.plugin.getLog().severe("PluginManager instance is not a 'SimplePluginManager', instead: " + pluginManager.getClass());
this.plugin.getLog().severe("Unable to inject LuckPerms Permission map.");
this.plugin.getLogger().severe("PluginManager instance is not a 'SimplePluginManager', instead: " + pluginManager.getClass());
this.plugin.getLogger().severe("Unable to inject LuckPerms Permission map.");
return null;
}

View File

@ -67,18 +67,18 @@ public class InjectorSubscriptionMap implements Runnable {
this.plugin.setSubscriptionMap(ret);
}
} catch (Exception e) {
this.plugin.getLog().severe("Exception occurred whilst injecting LuckPerms Permission Subscription map.");
this.plugin.getLogger().severe("Exception occurred whilst injecting LuckPerms Permission Subscription map.");
e.printStackTrace();
}
}
private LPSubscriptionMap inject() throws Exception {
Objects.requireNonNull(PERM_SUBS_FIELD, "PERM_SUBS_FIELD");
PluginManager pluginManager = this.plugin.getServer().getPluginManager();
PluginManager pluginManager = this.plugin.getBootstrap().getServer().getPluginManager();
if (!(pluginManager instanceof SimplePluginManager)) {
this.plugin.getLog().severe("PluginManager instance is not a 'SimplePluginManager', instead: " + pluginManager.getClass());
this.plugin.getLog().severe("Unable to inject LuckPerms Permission Subscription map.");
this.plugin.getLogger().severe("PluginManager instance is not a 'SimplePluginManager', instead: " + pluginManager.getClass());
this.plugin.getLogger().severe("Unable to inject LuckPerms Permission Subscription map.");
return null;
}

View File

@ -207,7 +207,7 @@ public final class LPSubscriptionMap extends HashMap<String, Map<Permissible, Bo
@Override
public Set<Permissible> keySet() {
// gather players (LPPermissibles)
Set<Permissible> players = LPSubscriptionMap.this.plugin.getServer().getOnlinePlayers().stream()
Set<Permissible> players = LPSubscriptionMap.this.plugin.getBootstrap().getServer().getOnlinePlayers().stream()
.filter(player -> player.isPermissionSet(this.permission))
.collect(Collectors.toSet());

View File

@ -270,7 +270,7 @@ public class VaultChatHook extends AbstractVaultChat {
return this.plugin.getConfiguration().get(ConfigKeys.VAULT_DEBUG);
}
private void logMsg(String format, Object... args) {
this.plugin.getLog().info("[VAULT-CHAT] " + String.format(format, args)
this.plugin.getLogger().info("[VAULT-CHAT] " + String.format(format, args)
.replace(CommandManager.SECTION_CHAR, '$')
.replace(CommandManager.AMPERSAND_CHAR, '$')
);

View File

@ -56,9 +56,9 @@ public class VaultHookManager {
this.chatHook = new VaultChatHook(plugin, this.permissionHook);
}
final ServicesManager sm = plugin.getServer().getServicesManager();
sm.register(Permission.class, this.permissionHook, plugin, ServicePriority.High);
sm.register(Chat.class, this.chatHook, plugin, ServicePriority.High);
final ServicesManager sm = plugin.getBootstrap().getServer().getServicesManager();
sm.register(Permission.class, this.permissionHook, plugin.getBootstrap(), ServicePriority.High);
sm.register(Chat.class, this.chatHook, plugin.getBootstrap(), ServicePriority.High);
} catch (Exception e) {
e.printStackTrace();
@ -71,7 +71,7 @@ public class VaultHookManager {
* @param plugin the plugin
*/
public void unhook(LPBukkitPlugin plugin) {
final ServicesManager sm = plugin.getServer().getServicesManager();
final ServicesManager sm = plugin.getBootstrap().getServer().getServicesManager();
if (this.permissionHook != null) {
sm.unregister(Permission.class, this.permissionHook);

View File

@ -327,7 +327,7 @@ public class VaultPermissionHook extends AbstractVaultPermission {
return this.plugin.getConfiguration().get(ConfigKeys.VAULT_DEBUG);
}
private void logMsg(String format, Object... args) {
this.plugin.getLog().info("[VAULT-PERMS] " + String.format(format, args)
this.plugin.getLogger().info("[VAULT-PERMS] " + String.format(format, args)
.replace(CommandManager.SECTION_CHAR, '$')
.replace(CommandManager.AMPERSAND_CHAR, '$')
);
@ -337,7 +337,7 @@ public class VaultPermissionHook extends AbstractVaultPermission {
Contexts contextForLookup(User user, String world) {
MutableContextSet context;
Player player = user == null ? null : this.plugin.getPlayer(user);
Player player = user == null ? null : this.plugin.getBootstrap().getPlayer(user.getUuid());
if (player != null) {
context = this.plugin.getContextManager().getApplicableContext(player).mutableCopy();
} else {
@ -402,11 +402,11 @@ public class VaultPermissionHook extends AbstractVaultPermission {
void holderSave(PermissionHolder holder) {
if (holder.getType().isUser()) {
User u = (User) holder;
this.plugin.getStorage().saveUser(u).thenRunAsync(() -> u.getRefreshBuffer().request(), this.plugin.getScheduler().async());
this.plugin.getStorage().saveUser(u).thenRunAsync(() -> u.getRefreshBuffer().request(), this.plugin.getBootstrap().getScheduler().async());
}
if (holder.getType().isGroup()) {
Group g = (Group) holder;
this.plugin.getStorage().saveGroup(g).thenRunAsync(() -> this.plugin.getUpdateTaskBuffer().request(), this.plugin.getScheduler().async());
this.plugin.getStorage().saveGroup(g).thenRunAsync(() -> this.plugin.getUpdateTaskBuffer().request(), this.plugin.getBootstrap().getScheduler().async());
}
}

View File

@ -4,7 +4,7 @@ description: A permissions plugin
author: Luck
website: https://github.com/lucko/LuckPerms
main: me.lucko.luckperms.bukkit.LPBukkitPlugin
main: me.lucko.luckperms.bukkit.LPBukkitBootstrap
load: STARTUP
# This means that all plugins that (soft-)depend on Vault, depend on LuckPerms too.

View File

@ -50,18 +50,18 @@ public class BungeeSchedulerAdapter implements SchedulerAdapter {
return ticks * MILLISECONDS_PER_TICK;
}
private final LPBungeePlugin plugin;
private final LPBungeeBootstrap bootstrap;
private final Executor asyncExecutor;
private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet();
public BungeeSchedulerAdapter(LPBungeePlugin plugin) {
this.plugin = plugin;
this.asyncExecutor = r -> plugin.getProxy().getScheduler().runAsync(plugin, r);
public BungeeSchedulerAdapter(LPBungeeBootstrap bootstrap) {
this.bootstrap = bootstrap;
this.asyncExecutor = r -> bootstrap.getProxy().getScheduler().runAsync(bootstrap, r);
}
private TaskScheduler scheduler() {
return this.plugin.getProxy().getScheduler();
return this.bootstrap.getProxy().getScheduler();
}
@Override
@ -87,7 +87,7 @@ public class BungeeSchedulerAdapter implements SchedulerAdapter {
@Override
public SchedulerTask asyncRepeating(Runnable runnable, long intervalTicks) {
long millis = ticksToMillis(intervalTicks);
SchedulerTask task = new BungeeSchedulerTask(scheduler().schedule(this.plugin, runnable, millis, millis, TimeUnit.MILLISECONDS));
SchedulerTask task = new BungeeSchedulerTask(scheduler().schedule(this.bootstrap, runnable, millis, millis, TimeUnit.MILLISECONDS));
this.tasks.add(task);
return task;
}
@ -99,7 +99,7 @@ public class BungeeSchedulerAdapter implements SchedulerAdapter {
@Override
public SchedulerTask asyncLater(Runnable runnable, long delayTicks) {
return new BungeeSchedulerTask(scheduler().schedule(this.plugin, runnable, ticksToMillis(delayTicks), TimeUnit.MILLISECONDS));
return new BungeeSchedulerTask(scheduler().schedule(this.bootstrap, runnable, ticksToMillis(delayTicks), TimeUnit.MILLISECONDS));
}
@Override

View File

@ -0,0 +1,208 @@
/*
* 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;
import me.lucko.luckperms.api.platform.PlatformType;
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.plugin.SchedulerAdapter;
import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Plugin;
import java.io.File;
import java.io.InputStream;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Stream;
import javax.annotation.Nullable;
/**
* Bootstrap plugin for LuckPerms running on BungeeCord.
*/
public class LPBungeeBootstrap extends Plugin implements LuckPermsBootstrap {
/**
* A scheduler adapter for the platform
*/
private final SchedulerAdapter schedulerAdapter;
/**
* The plugin classloader
*/
private final PluginClassLoader classLoader;
/**
* The plugin instance
*/
private final LPBungeePlugin plugin;
/**
* The time when the plugin was enabled
*/
private long startTime;
// load/enable latches
private final CountDownLatch loadLatch = new CountDownLatch(1);
private final CountDownLatch enableLatch = new CountDownLatch(1);
public LPBungeeBootstrap() {
this.schedulerAdapter = new BungeeSchedulerAdapter(this);
this.classLoader = new ReflectionClassLoader(this);
this.plugin = new LPBungeePlugin(this);
}
// provide adapters
@Override
public SchedulerAdapter getScheduler() {
return this.schedulerAdapter;
}
@Override
public PluginClassLoader getPluginClassLoader() {
return this.classLoader;
}
// lifecycle
@Override
public void onLoad() {
try {
this.plugin.load();
} finally {
this.loadLatch.countDown();
}
}
@Override
public void onEnable() {
this.startTime = System.currentTimeMillis();
try {
this.plugin.enable();
} finally {
this.enableLatch.countDown();
}
}
@Override
public void onDisable() {
this.plugin.disable();
}
@Override
public CountDownLatch getEnableLatch() {
return this.enableLatch;
}
@Override
public CountDownLatch getLoadLatch() {
return this.loadLatch;
}
// provide information about the plugin
@Override
public String getVersion() {
return getDescription().getVersion();
}
@Override
public long getStartupTime() {
return this.startTime;
}
// provide information about the platform
@Override
public PlatformType getType() {
return PlatformType.BUNGEE;
}
@Override
public String getServerBrand() {
return getProxy().getName();
}
@Override
public String getServerVersion() {
return getProxy().getVersion();
}
@Override
public File getDataDirectory() {
return getDataFolder();
}
@Override
public InputStream getResourceStream(String path) {
return getResourceAsStream(path);
}
@Nullable
@Override
public ProxiedPlayer getPlayer(UUID uuid) {
return getProxy().getPlayer(uuid);
}
@Override
public Optional<UUID> lookupUuid(String username) {
if (getProxy().getPluginManager().getPlugin("RedisBungee") != null) {
try {
return RedisBungeeUtil.lookupUuid(username);
} catch (Throwable t) {
t.printStackTrace();
}
}
return Optional.empty();
}
@Override
public int getPlayerCount() {
return getProxy().getOnlineCount();
}
@Override
public Stream<String> getPlayerList() {
return getProxy().getPlayers().stream().map(ProxiedPlayer::getName);
}
@Override
public Stream<UUID> getOnlinePlayers() {
return getProxy().getPlayers().stream().map(ProxiedPlayer::getUniqueId);
}
@Override
public boolean isPlayerOnline(UUID uuid) {
ProxiedPlayer player = getProxy().getPlayer(uuid);
return player != null && player.isConnected();
}
}

View File

@ -26,7 +26,7 @@
package me.lucko.luckperms.bungee;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.bungee.calculators.BungeeCalculatorFactory;
import me.lucko.luckperms.bungee.contexts.BackendServerCalculator;
import me.lucko.luckperms.bungee.contexts.BungeeContextManager;
@ -34,235 +34,133 @@ import me.lucko.luckperms.bungee.contexts.RedisBungeeCalculator;
import me.lucko.luckperms.bungee.listeners.BungeeConnectionListener;
import me.lucko.luckperms.bungee.listeners.BungeePermissionCheckListener;
import me.lucko.luckperms.bungee.messaging.BungeeMessagingFactory;
import me.lucko.luckperms.bungee.util.RedisBungeeUtil;
import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiRegistrationUtil;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.buffers.UpdateTaskBuffer;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.AbstractConfiguration;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.contexts.LuckPermsCalculator;
import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.dependencies.DependencyRegistry;
import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader;
import me.lucko.luckperms.common.dependencies.classloader.ReflectionClassLoader;
import me.lucko.luckperms.common.event.EventFactory;
import me.lucko.luckperms.common.inheritance.InheritanceHandler;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.NoopLocaleManager;
import me.lucko.luckperms.common.locale.SimpleLocaleManager;
import me.lucko.luckperms.common.logging.Logger;
import me.lucko.luckperms.common.logging.SenderLogger;
import me.lucko.luckperms.common.listener.ConnectionListener;
import me.lucko.luckperms.common.managers.group.StandardGroupManager;
import me.lucko.luckperms.common.managers.track.StandardTrackManager;
import me.lucko.luckperms.common.managers.user.StandardUserManager;
import me.lucko.luckperms.common.messaging.InternalMessagingService;
import me.lucko.luckperms.common.messaging.MessagingFactory;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.plugin.SchedulerAdapter;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.storage.StorageFactory;
import me.lucko.luckperms.common.storage.StorageType;
import me.lucko.luckperms.common.storage.dao.file.FileWatcher;
import me.lucko.luckperms.common.plugin.AbstractLuckPermsPlugin;
import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
import me.lucko.luckperms.common.tasks.UpdateTask;
import me.lucko.luckperms.common.treeview.PermissionVault;
import me.lucko.luckperms.common.verbose.VerboseHandler;
import net.md_5.bungee.api.connection.ProxiedPlayer;
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.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
/**
* LuckPerms implementation for the BungeeCord API.
*/
public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
public class LPBungeePlugin extends AbstractLuckPermsPlugin {
private final LPBungeeBootstrap bootstrap;
private long startTime;
private SchedulerAdapter scheduler;
private BungeeSenderFactory senderFactory;
private BungeeConnectionListener connectionListener;
private CommandManager commandManager;
private LuckPermsConfiguration configuration;
private StandardUserManager userManager;
private StandardGroupManager groupManager;
private StandardTrackManager trackManager;
private Storage storage;
private FileWatcher fileWatcher = null;
private InternalMessagingService messagingService = null;
private LuckPermsApiProvider apiProvider;
private EventFactory eventFactory;
private Logger log;
private LocaleManager localeManager;
private PluginClassLoader pluginClassLoader;
private DependencyManager dependencyManager;
private InheritanceHandler inheritanceHandler;
private CachedStateManager cachedStateManager;
private ContextManager<ProxiedPlayer> contextManager;
private CalculatorFactory calculatorFactory;
private BufferedRequest<Void> updateTaskBuffer;
private VerboseHandler verboseHandler;
private BungeeSenderFactory senderFactory;
private PermissionVault permissionVault;
private LogDispatcher logDispatcher;
private Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
public LPBungeePlugin(LPBungeeBootstrap bootstrap) {
this.bootstrap = bootstrap;
}
@Override
public void onLoad() {
// setup minimal functionality in order to load initial dependencies
this.scheduler = new BungeeSchedulerAdapter(this);
this.localeManager = new NoopLocaleManager();
public LPBungeeBootstrap getBootstrap() {
return this.bootstrap;
}
@Override
protected void setupSenderFactory() {
this.senderFactory = new BungeeSenderFactory(this);
this.log = new SenderLogger(this, getConsoleSender());
this.pluginClassLoader = new ReflectionClassLoader(this);
this.dependencyManager = new DependencyManager(this);
this.dependencyManager.loadDependencies(DependencyRegistry.GLOBAL_DEPENDENCIES);
}
@Override
public void onEnable() {
this.startTime = System.currentTimeMillis();
sendStartupBanner(getConsoleSender());
this.verboseHandler = new VerboseHandler(this.scheduler.async());
this.permissionVault = new PermissionVault(this.scheduler.async());
this.logDispatcher = new LogDispatcher(this);
getLog().info("Loading configuration...");
this.configuration = new AbstractConfiguration(this, new BungeeConfigAdapter(this, resolveConfig("config.yml")));
this.configuration.loadAll();
StorageFactory storageFactory = new StorageFactory(this);
Set<StorageType> storageTypes = storageFactory.getRequiredTypes(StorageType.H2);
this.dependencyManager.loadStorageDependencies(storageTypes);
// register events
getProxy().getPluginManager().registerListener(this, new BungeeConnectionListener(this));
getProxy().getPluginManager().registerListener(this, new BungeePermissionCheckListener(this));
if (getConfiguration().get(ConfigKeys.WATCH_FILES)) {
this.fileWatcher = new FileWatcher(this);
getScheduler().asyncRepeating(this.fileWatcher, 30L);
protected ConfigurationAdapter provideConfigurationAdapter() {
return new BungeeConfigAdapter(this, resolveConfig());
}
// initialise datastore
this.storage = storageFactory.getInstance(StorageType.H2);
@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));
}
// initialise messaging
this.messagingService = new BungeeMessagingFactory(this).getInstance();
@Override
protected MessagingFactory<?> provideMessagingFactory() {
return new BungeeMessagingFactory(this);
}
// setup the update task buffer
this.updateTaskBuffer = new UpdateTaskBuffer(this);
// load locale
this.localeManager = new SimpleLocaleManager();
this.localeManager.tryLoad(this, new File(getDataFolder(), "lang.yml"));
// register commands
@Override
protected void registerCommands() {
this.commandManager = new CommandManager(this);
getProxy().getPluginManager().registerCommand(this, new BungeeCommandExecutor(this, this.commandManager));
this.bootstrap.getProxy().getPluginManager().registerCommand(this.bootstrap, new BungeeCommandExecutor(this, this.commandManager));
// disable the default Bungee /perms command so it gets handled by the Bukkit plugin
getProxy().getDisabledCommands().add("perms");
this.bootstrap.getProxy().getDisabledCommands().add("perms");
}
// load internal managers
getLog().info("Loading internal permission managers...");
this.inheritanceHandler = new InheritanceHandler(this);
@Override
protected void setupManagers() {
this.userManager = new StandardUserManager(this);
this.groupManager = new StandardGroupManager(this);
this.trackManager = new StandardTrackManager(this);
this.calculatorFactory = new BungeeCalculatorFactory(this);
this.cachedStateManager = new CachedStateManager();
// setup context manager
this.contextManager = new BungeeContextManager(this);
this.contextManager.registerCalculator(new BackendServerCalculator(this));
this.contextManager.registerStaticCalculator(new LuckPermsCalculator(getConfiguration()));
if (getProxy().getPluginManager().getPlugin("RedisBungee") != null) {
this.contextManager.registerStaticCalculator(new RedisBungeeCalculator());
}
// register with the LP API
this.apiProvider = new LuckPermsApiProvider(this);
// setup event factory
this.eventFactory = new EventFactory(this, this.apiProvider);
ApiRegistrationUtil.registerProvider(this.apiProvider);
// schedule update tasks
int mins = getConfiguration().get(ConfigKeys.SYNC_TIME);
if (mins > 0) {
long ticks = mins * 60 * 20;
this.scheduler.asyncRepeating(() -> this.updateTaskBuffer.request(), ticks);
}
this.scheduler.asyncLater(() -> this.updateTaskBuffer.request(), 40L);
// run an update instantly.
getLog().info("Performing initial data load...");
try {
new UpdateTask(this, true).run();
} catch (Exception e) {
e.printStackTrace();
}
// register tasks
this.scheduler.asyncRepeating(new ExpireTemporaryTask(this), 60L);
this.scheduler.asyncRepeating(new CacheHousekeepingTask(this), 2400L);
getLog().info("Successfully enabled. (took " + (System.currentTimeMillis() - this.startTime) + "ms)");
}
@Override
public void onDisable() {
this.permissionVault.shutdown();
this.verboseHandler.shutdown();
getLog().info("Closing storage...");
this.storage.shutdown();
if (this.fileWatcher != null) {
this.fileWatcher.close();
protected CalculatorFactory provideCalculatorFactory() {
return new BungeeCalculatorFactory(this);
}
if (this.messagingService != null) {
getLog().info("Closing messaging service...");
this.messagingService.close();
@Override
protected void setupContextManager() {
this.contextManager = new BungeeContextManager(this);
this.contextManager.registerCalculator(new BackendServerCalculator(this));
if (this.bootstrap.getProxy().getPluginManager().getPlugin("RedisBungee") != null) {
this.contextManager.registerStaticCalculator(new RedisBungeeCalculator());
}
}
ApiRegistrationUtil.unregisterProvider();
@Override
protected void setupPlatformHooks() {
getLog().info("Shutting down internal scheduler...");
this.scheduler.shutdown();
getProxy().getScheduler().cancel(this);
getProxy().getPluginManager().unregisterListeners(this);
getLog().info("Goodbye!");
}
private File resolveConfig(String file) {
File configFile = new File(getDataFolder(), file);
@Override
protected void registerApiOnPlatform(LuckPermsApi api) {
// BungeeCord doesn't have a services manager
}
@Override
protected void registerHousekeepingTasks() {
this.bootstrap.getScheduler().asyncRepeating(new ExpireTemporaryTask(this), 60L);
this.bootstrap.getScheduler().asyncRepeating(new CacheHousekeepingTask(this), 2400L);
}
@Override
protected void performFinalSetup() {
}
private File resolveConfig() {
File configFile = new File(this.bootstrap.getDataFolder(), "config.yml");
if (!configFile.exists()) {
getDataFolder().mkdirs();
try (InputStream is = getResourceAsStream(file)) {
this.bootstrap.getDataFolder().mkdirs();
try (InputStream is = this.bootstrap.getResourceAsStream("config.yml")) {
Files.copy(is, configFile.toPath());
} catch (IOException e) {
throw new RuntimeException(e);
@ -272,122 +170,35 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
return configFile;
}
@Override
public Optional<InternalMessagingService> getMessagingService() {
return Optional.ofNullable(this.messagingService);
}
@Override
public void setMessagingService(InternalMessagingService messagingService) {
if (this.messagingService == null) {
this.messagingService = messagingService;
}
}
@Override
public Optional<FileWatcher> getFileWatcher() {
return Optional.ofNullable(this.fileWatcher);
}
@Override
public String getVersion() {
return getDescription().getVersion();
}
@Override
public PlatformType getServerType() {
return PlatformType.BUNGEE;
}
@Override
public String getServerBrand() {
return getProxy().getName();
}
@Override
public String getServerVersion() {
return getProxy().getVersion();
}
@Override
public File getDataDirectory() {
return super.getDataFolder();
}
@Override
public InputStream getResourceStream(String path) {
return getResourceAsStream(path);
}
@Override
public ProxiedPlayer getPlayer(User user) {
return getProxy().getPlayer(user.getUuid());
}
@Override
public Optional<UUID> lookupUuid(String username) {
if (getProxy().getPluginManager().getPlugin("RedisBungee") != null) {
try {
return RedisBungeeUtil.lookupUuid(username);
} catch (Throwable t) {
t.printStackTrace();
}
}
return Optional.empty();
}
@Override
public Optional<Contexts> getContextForUser(User user) {
ProxiedPlayer player = getPlayer(user);
ProxiedPlayer player = this.bootstrap.getPlayer(user.getUuid());
if (player == null) {
return Optional.empty();
}
return Optional.of(this.contextManager.getApplicableContexts(player));
}
@Override
public int getPlayerCount() {
return getProxy().getOnlineCount();
}
@Override
public Stream<String> getPlayerList() {
return getProxy().getPlayers().stream().map(ProxiedPlayer::getName);
}
@Override
public Stream<UUID> getOnlinePlayers() {
return getProxy().getPlayers().stream().map(ProxiedPlayer::getUniqueId);
}
@Override
public boolean isPlayerOnline(UUID external) {
ProxiedPlayer player = getProxy().getPlayer(external);
return player != null && player.isConnected();
}
@Override
public Stream<Sender> getOnlineSenders() {
return Stream.concat(
Stream.of(getConsoleSender()),
getProxy().getPlayers().stream().map(p -> getSenderFactory().wrap(p))
this.bootstrap.getProxy().getPlayers().stream().map(p -> this.senderFactory.wrap(p))
);
}
@Override
public Sender getConsoleSender() {
return getSenderFactory().wrap(getProxy().getConsole());
return this.senderFactory.wrap(this.bootstrap.getProxy().getConsole());
}
public BungeeSenderFactory getSenderFactory() {
return this.senderFactory;
}
@Override
public long getStartTime() {
return this.startTime;
}
@Override
public SchedulerAdapter getScheduler() {
return this.scheduler;
public ConnectionListener getConnectionListener() {
return this.connectionListener;
}
@Override
@ -395,11 +206,6 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
return this.commandManager;
}
@Override
public LuckPermsConfiguration getConfiguration() {
return this.configuration;
}
@Override
public StandardUserManager getUserManager() {
return this.userManager;
@ -415,87 +221,9 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
return this.trackManager;
}
@Override
public Storage getStorage() {
return this.storage;
}
@Override
public LuckPermsApiProvider getApiProvider() {
return this.apiProvider;
}
@Override
public EventFactory getEventFactory() {
return this.eventFactory;
}
@Override
public Logger getLog() {
return this.log;
}
@Override
public LocaleManager getLocaleManager() {
return this.localeManager;
}
@Override
public PluginClassLoader getPluginClassLoader() {
return this.pluginClassLoader;
}
@Override
public DependencyManager getDependencyManager() {
return this.dependencyManager;
}
@Override
public CachedStateManager getCachedStateManager() {
return this.cachedStateManager;
}
@Override
public ContextManager<ProxiedPlayer> getContextManager() {
return this.contextManager;
}
@Override
public InheritanceHandler getInheritanceHandler() {
return this.inheritanceHandler;
}
@Override
public CalculatorFactory getCalculatorFactory() {
return this.calculatorFactory;
}
@Override
public BufferedRequest<Void> getUpdateTaskBuffer() {
return this.updateTaskBuffer;
}
@Override
public VerboseHandler getVerboseHandler() {
return this.verboseHandler;
}
public BungeeSenderFactory getSenderFactory() {
return this.senderFactory;
}
@Override
public PermissionVault getPermissionVault() {
return this.permissionVault;
}
@Override
public LogDispatcher getLogDispatcher() {
return this.logDispatcher;
}
@Override
public Set<UUID> getUniqueConnections() {
return this.uniqueConnections;
}
}

View File

@ -27,9 +27,9 @@ package me.lucko.luckperms.bungee.listeners;
import me.lucko.luckperms.bungee.LPBungeePlugin;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.listener.AbstractConnectionListener;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.utils.AbstractLoginListener;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.PendingConnection;
@ -43,7 +43,7 @@ import net.md_5.bungee.event.EventPriority;
import java.util.concurrent.TimeUnit;
public class BungeeConnectionListener extends AbstractLoginListener implements Listener {
public class BungeeConnectionListener extends AbstractConnectionListener implements Listener {
private final LPBungeePlugin plugin;
public BungeeConnectionListener(LPBungeePlugin plugin) {
@ -62,16 +62,16 @@ public class BungeeConnectionListener extends AbstractLoginListener implements L
/* 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);
e.registerIntent(this.plugin.getBootstrap());
final PendingConnection c = e.getConnection();
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
this.plugin.getLog().info("Processing pre-login for " + c.getUniqueId() + " - " + c.getName());
this.plugin.getLogger().info("Processing pre-login for " + c.getUniqueId() + " - " + c.getName());
}
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getUniqueConnections().add(c.getUniqueId());
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
recordConnection(c.getUniqueId());
/* Actually process the login for the connection.
We do this here to delay the login until the data is ready.
@ -86,7 +86,7 @@ public class BungeeConnectionListener extends AbstractLoginListener implements L
User user = loadUser(c.getUniqueId(), c.getName());
this.plugin.getEventFactory().handleUserLoginProcess(c.getUniqueId(), c.getName(), user);
} catch (Exception ex) {
this.plugin.getLog().severe("Exception occurred whilst loading data for " + c.getUniqueId() + " - " + c.getName());
this.plugin.getLogger().severe("Exception occurred whilst loading data for " + c.getUniqueId() + " - " + c.getName());
ex.printStackTrace();
// there was some error loading
@ -98,7 +98,7 @@ public class BungeeConnectionListener extends AbstractLoginListener implements L
}
// finally, complete our intent to modify state, so the proxy can continue handling the connection.
e.completeIntent(this.plugin);
e.completeIntent(this.plugin.getBootstrap());
});
}
@ -108,17 +108,17 @@ public class BungeeConnectionListener extends AbstractLoginListener implements L
final User user = this.plugin.getUserManager().getIfLoaded(e.getPlayer().getUniqueId());
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
this.plugin.getLog().info("Processing post-login for " + player.getUniqueId() + " - " + player.getName());
this.plugin.getLogger().info("Processing post-login for " + player.getUniqueId() + " - " + player.getName());
}
if (user == null) {
if (this.plugin.getConfiguration().get(ConfigKeys.CANCEL_FAILED_LOGINS)) {
// disconnect the user
this.plugin.getLog().warn("User " + player.getUniqueId() + " - " + player.getName() + " doesn't have data pre-loaded - cancelling login.");
this.plugin.getLogger().warn("User " + player.getUniqueId() + " - " + player.getName() + " doesn't have data pre-loaded - cancelling login.");
e.getPlayer().disconnect(TextComponent.fromLegacyText(Message.LOADING_ERROR.asString(this.plugin.getLocaleManager())));
} else {
// just send a message
this.plugin.getProxy().getScheduler().schedule(this.plugin, () -> {
this.plugin.getBootstrap().getProxy().getScheduler().schedule(this.plugin.getBootstrap(), () -> {
if (!player.isConnected()) {
return;
}
@ -139,7 +139,7 @@ public class BungeeConnectionListener extends AbstractLoginListener implements L
this.plugin.getUserManager().getHouseKeeper().registerUsage(player.getUniqueId());
// force a clear of transient nodes
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId());
if (user != null) {
user.clearTransientNodes();

View File

@ -49,8 +49,8 @@ public class BungeeMessagingFactory extends MessagingFactory<LPBungeePlugin> {
e.printStackTrace();
}
} else if (messagingType.equals("redisbungee")) {
if (getPlugin().getProxy().getPluginManager().getPlugin("RedisBungee") == null) {
getPlugin().getLog().warn("RedisBungee plugin not present.");
if (getPlugin().getBootstrap().getProxy().getPluginManager().getPlugin("RedisBungee") == null) {
getPlugin().getLogger().warn("RedisBungee plugin not present.");
} else {
try {
return new LuckPermsMessagingService(getPlugin(), new RedisBungeeMessengerProvider());

View File

@ -57,13 +57,13 @@ public class BungeeMessenger implements Messenger, Listener {
}
public void init() {
this.plugin.getProxy().getPluginManager().registerListener(this.plugin, this);
this.plugin.getProxy().registerChannel(CHANNEL);
this.plugin.getBootstrap().getProxy().getPluginManager().registerListener(this.plugin.getBootstrap(), this);
this.plugin.getBootstrap().getProxy().registerChannel(CHANNEL);
}
@Override
public void close() {
this.plugin.getProxy().unregisterChannel(CHANNEL);
this.plugin.getBootstrap().getProxy().unregisterChannel(CHANNEL);
}
@Override
@ -73,7 +73,7 @@ public class BungeeMessenger implements Messenger, Listener {
byte[] data = out.toByteArray();
for (ServerInfo server : this.plugin.getProxy().getServers().values()) {
for (ServerInfo server : this.plugin.getBootstrap().getProxy().getServers().values()) {
server.sendData(CHANNEL, data, true);
}
}
@ -97,8 +97,8 @@ public class BungeeMessenger implements Messenger, Listener {
if (this.consumer.consumeIncomingMessageAsString(msg)) {
// Forward to other servers
this.plugin.getScheduler().doAsync(() -> {
for (ServerInfo server : this.plugin.getProxy().getServers().values()) {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
for (ServerInfo server : this.plugin.getBootstrap().getProxy().getServers().values()) {
server.sendData(CHANNEL, data, true);
}
});

View File

@ -58,7 +58,7 @@ public class RedisBungeeMessenger implements Messenger, Listener {
this.redisBungee = RedisBungee.getApi();
this.redisBungee.registerPubSubChannels(CHANNEL);
this.plugin.getProxy().getPluginManager().registerListener(this.plugin, this);
this.plugin.getBootstrap().getProxy().getPluginManager().registerListener(this.plugin.getBootstrap(), this);
}
@Override
@ -66,7 +66,7 @@ public class RedisBungeeMessenger implements Messenger, Listener {
this.redisBungee.unregisterPubSubChannels(CHANNEL);
this.redisBungee = null;
this.plugin.getProxy().getPluginManager().unregisterListener(this);
this.plugin.getBootstrap().getProxy().getPluginManager().unregisterListener(this);
}
@Override

View File

@ -2,5 +2,5 @@ name: LuckPerms
version: ${full.version}
description: A permissions plugin
author: Luck
main: me.lucko.luckperms.bungee.LPBungeePlugin
main: me.lucko.luckperms.bungee.LPBungeeBootstrap
softDepends: ["RedisBungee"]

View File

@ -58,7 +58,7 @@ public class ApiActionLogger implements ActionLogger {
@Nonnull
@Override
public CompletableFuture<Void> submit(@Nonnull LogEntry entry) {
return CompletableFuture.runAsync(() -> this.plugin.getLogDispatcher().dispatchFromApi((ExtendedLogEntry) entry), this.plugin.getScheduler().async());
return CompletableFuture.runAsync(() -> this.plugin.getLogDispatcher().dispatchFromApi((ExtendedLogEntry) entry), this.plugin.getBootstrap().getScheduler().async());
}
@Nonnull
@ -70,6 +70,6 @@ public class ApiActionLogger implements ActionLogger {
@Nonnull
@Override
public CompletableFuture<Void> broadcastAction(@Nonnull LogEntry entry) {
return CompletableFuture.runAsync(() -> this.plugin.getLogDispatcher().broadcastFromApi((ExtendedLogEntry) entry), this.plugin.getScheduler().async());
return CompletableFuture.runAsync(() -> this.plugin.getLogDispatcher().broadcastFromApi((ExtendedLogEntry) entry), this.plugin.getBootstrap().getScheduler().async());
}
}

View File

@ -45,7 +45,7 @@ public class ApiPlatformInfo implements PlatformInfo {
@Nonnull
@Override
public String getVersion() {
return this.plugin.getVersion();
return this.plugin.getBootstrap().getVersion();
}
@Override
@ -56,17 +56,17 @@ public class ApiPlatformInfo implements PlatformInfo {
@Nonnull
@Override
public PlatformType getType() {
return this.plugin.getServerType();
return this.plugin.getBootstrap().getType();
}
@Nonnull
@Override
public Set<UUID> getUniqueConnections() {
return Collections.unmodifiableSet(this.plugin.getUniqueConnections());
return Collections.unmodifiableSet(this.plugin.getConnectionListener().getUniqueConnections());
}
@Override
public long getStartTime() {
return this.plugin.getStartTime();
return this.plugin.getBootstrap().getStartupTime();
}
}

View File

@ -90,13 +90,13 @@ public class ApiStorage implements me.lucko.luckperms.api.Storage {
@Nonnull
@Override
public Executor getSyncExecutor() {
return this.plugin.getScheduler().sync();
return this.plugin.getBootstrap().getScheduler().sync();
}
@Nonnull
@Override
public Executor getAsyncExecutor() {
return this.plugin.getScheduler().async();
return this.plugin.getBootstrap().getScheduler().async();
}
@Nonnull

View File

@ -250,7 +250,7 @@ public class Exporter implements Runnable {
e.printStackTrace();
}
}
}, this.plugin.getScheduler().async()));
}, this.plugin.getBootstrap().getScheduler().async()));
}
// all of the threads have been scheduled now and are running. we just need to wait for them all to complete

View File

@ -124,7 +124,7 @@ public class Importer implements Runnable {
cmd.process();
processedCount.incrementAndGet();
}
}, this.commandManager.getPlugin().getScheduler().async()));
}, this.commandManager.getPlugin().getBootstrap().getScheduler().async()));
}
// all of the threads have been scheduled now and are running. we just need to wait for them all to complete

View File

@ -32,7 +32,7 @@ public class UpdateTaskBuffer extends BufferedRequest<Void> {
private final LuckPermsPlugin plugin;
public UpdateTaskBuffer(LuckPermsPlugin plugin) {
super(250L, 50L, plugin.getScheduler().async());
super(250L, 50L, plugin.getBootstrap().getScheduler().async());
this.plugin = plugin;
}

View File

@ -145,7 +145,7 @@ public class CommandManager {
try {
return execute(sender, label, args);
} catch (Throwable e) {
this.plugin.getLog().severe("Exception whilst executing command: " + args.toString());
this.plugin.getLogger().severe("Exception whilst executing command: " + args.toString());
e.printStackTrace();
return null;
}
@ -159,7 +159,7 @@ public class CommandManager {
// Handle no arguments
if (arguments.isEmpty() || (arguments.size() == 1 && arguments.get(0).trim().isEmpty())) {
CommandUtils.sendPluginMessage(sender, "&2Running &bLuckPerms v" + this.plugin.getVersion() + "&2.");
CommandUtils.sendPluginMessage(sender, "&2Running &bLuckPerms v" + this.plugin.getBootstrap().getVersion() + "&2.");
if (this.mainCommands.stream().anyMatch(c -> c.shouldDisplay() && c.isAuthorized(sender))) {
Message.VIEW_AVAILABLE_COMMANDS_PROMPT.send(sender, label);
} else {
@ -257,7 +257,7 @@ public class CommandManager {
}
private void sendCommandUsage(Sender sender, String label) {
CommandUtils.sendPluginMessage(sender, "&2Running &bLuckPerms v" + this.plugin.getVersion() + "&2.");
CommandUtils.sendPluginMessage(sender, "&2Running &bLuckPerms v" + this.plugin.getBootstrap().getVersion() + "&2.");
this.mainCommands.stream()
.filter(Command::shouldDisplay)
.filter(c -> c.isAuthorized(sender))

View File

@ -93,7 +93,7 @@ public class LogRecent extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
uuid = plugin.lookupUuid(target).orElse(null);
uuid = plugin.getBootstrap().lookupUuid(target).orElse(null);
if (uuid == null) {
Message.USER_NOT_FOUND.send(sender, target);
return CommandResult.INVALID_ARGS;

View File

@ -88,7 +88,7 @@ public class LogUserHistory extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
uuid = plugin.lookupUuid(target).orElse(null);
uuid = plugin.getBootstrap().lookupUuid(target).orElse(null);
if (uuid == null) {
Message.USER_NOT_FOUND.send(sender, target);
return CommandResult.INVALID_ARGS;

View File

@ -81,7 +81,7 @@ public class BulkUpdateCommand extends SingleCommand {
ex.printStackTrace();
Message.BULK_UPDATE_FAILURE.send(sender);
}
}, plugin.getScheduler().async());
}, plugin.getBootstrap().getScheduler().async());
return CommandResult.SUCCESS;
}

View File

@ -76,11 +76,11 @@ public class CheckCommand extends SingleCommand {
@Override
public List<String> tabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
if (args.isEmpty()) {
return plugin.getPlayerList().collect(Collectors.toList());
return plugin.getBootstrap().getPlayerList().collect(Collectors.toList());
}
if (args.size() == 1) {
return plugin.getPlayerList().filter(s -> s.toLowerCase().startsWith(args.get(0).toLowerCase())).collect(Collectors.toList());
return plugin.getBootstrap().getPlayerList().filter(s -> s.toLowerCase().startsWith(args.get(0).toLowerCase())).collect(Collectors.toList());
}
args.remove(0);

View File

@ -109,14 +109,14 @@ public class DebugCommand extends SingleCommand {
private static JObject getPlatformData(LuckPermsPlugin plugin) {
return new JObject()
.add("type", plugin.getServerType().name())
.add("type", plugin.getBootstrap().getType().name())
.add("version", new JObject()
.add("api", String.valueOf(plugin.getApiProvider().getPlatformInfo().getApiVersion()))
.add("plugin", plugin.getVersion())
.add("plugin", plugin.getBootstrap().getVersion())
)
.add("server", new JObject()
.add("brand", plugin.getServerBrand())
.add("version", plugin.getServerVersion())
.add("brand", plugin.getBootstrap().getServerBrand())
.add("version", plugin.getBootstrap().getServerVersion())
);
}
@ -172,7 +172,7 @@ public class DebugCommand extends SingleCommand {
private static JObject getPlayersData(LuckPermsPlugin plugin) {
JObject ret = new JObject();
Set<UUID> onlinePlayers = plugin.getOnlinePlayers().collect(Collectors.toSet());
Set<UUID> onlinePlayers = plugin.getBootstrap().getOnlinePlayers().collect(Collectors.toSet());
ret.add("count", onlinePlayers.size());
JArray playerArray = new JArray();

View File

@ -57,7 +57,7 @@ public class ExportCommand extends SingleCommand {
return CommandResult.STATE_ERROR;
}
File f = new File(plugin.getDataDirectory(), args.get(0));
File f = new File(plugin.getBootstrap().getDataDirectory(), args.get(0));
if (f.exists()) {
Message.LOG_EXPORT_ALREADY_EXISTS.send(sender, f.getAbsolutePath());
return CommandResult.INVALID_ARGS;
@ -86,7 +86,7 @@ public class ExportCommand extends SingleCommand {
Exporter exporter = new Exporter(plugin, sender, path);
// Run the exporter in its own thread.
plugin.getScheduler().doAsync(() -> {
plugin.getBootstrap().getScheduler().doAsync(() -> {
try {
exporter.run();
} finally {

View File

@ -58,7 +58,7 @@ public class ImportCommand extends SingleCommand {
return CommandResult.STATE_ERROR;
}
File f = new File(plugin.getDataDirectory(), args.get(0));
File f = new File(plugin.getBootstrap().getDataDirectory(), args.get(0));
if (!f.exists()) {
Message.IMPORT_LOG_DOESNT_EXIST.send(sender, f.getAbsolutePath());
return CommandResult.INVALID_ARGS;
@ -89,7 +89,7 @@ public class ImportCommand extends SingleCommand {
Importer importer = new Importer(plugin.getCommandManager(), sender, commands);
// Run the importer in its own thread.
plugin.getScheduler().doAsync(() -> {
plugin.getBootstrap().getScheduler().doAsync(() -> {
try {
importer.run();
} finally {

View File

@ -49,10 +49,10 @@ public class InfoCommand extends SingleCommand {
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
Message.INFO_TOP.send(sender,
plugin.getVersion(),
plugin.getServerType().getFriendlyName(),
plugin.getServerBrand(),
plugin.getServerVersion()
plugin.getBootstrap().getVersion(),
plugin.getBootstrap().getType().getFriendlyName(),
plugin.getBootstrap().getServerBrand(),
plugin.getBootstrap().getServerVersion()
);
Message.EMPTY.send(sender, "&f- &bStorage:");
@ -64,9 +64,9 @@ public class InfoCommand extends SingleCommand {
Message.INFO_MIDDLE.send(sender,
plugin.getMessagingService().map(InternalMessagingService::getName).orElse("None"),
plugin.getContextManager().getStaticContextString().orElse("None"),
plugin.getPlayerCount(),
plugin.getUniqueConnections().size(),
DateUtil.formatTimeBrief((System.currentTimeMillis() - plugin.getStartTime()) / 1000L),
plugin.getBootstrap().getPlayerCount(),
plugin.getConnectionListener().getUniqueConnections().size(),
DateUtil.formatTimeBrief((System.currentTimeMillis() - plugin.getBootstrap().getStartupTime()) / 1000L),
plugin.getUserManager().getAll().size(),
plugin.getGroupManager().getAll().size(),
plugin.getTrackManager().getAll().size()

View File

@ -79,7 +79,7 @@ public class UserClone extends SubCommand<User> {
return CommandResult.INVALID_ARGS;
}
uuid = plugin.lookupUuid(target).orElse(null);
uuid = plugin.getBootstrap().lookupUuid(target).orElse(null);
if (uuid == null) {
Message.USER_NOT_FOUND.send(sender, target);
return CommandResult.INVALID_ARGS;

View File

@ -62,7 +62,7 @@ public class UserInfo extends SubCommand<User> {
return CommandResult.NO_PERMISSION;
}
Message status = plugin.isPlayerOnline(user.getUuid()) ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE;
Message status = plugin.getBootstrap().isPlayerOnline(user.getUuid()) ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE;
Message.USER_INFO_GENERAL.send(sender,
user.getName().orElse("Unknown"),

View File

@ -103,7 +103,7 @@ public class UserMainCommand extends MainCommand<User, UserIdentifier> {
return null;
}
uuid = plugin.lookupUuid(target).orElse(null);
uuid = plugin.getBootstrap().lookupUuid(target).orElse(null);
if (uuid == null) {
Message.USER_NOT_FOUND.send(sender, target);
return null;
@ -134,6 +134,6 @@ public class UserMainCommand extends MainCommand<User, UserIdentifier> {
@Override
protected List<String> getTargets(LuckPermsPlugin plugin) {
return plugin.getPlayerList().collect(Collectors.toList());
return plugin.getBootstrap().getPlayerList().collect(Collectors.toList());
}
}

View File

@ -69,7 +69,7 @@ public class ConfigKeys {
*/
public static final ConfigKey<String> SERVER = AbstractKey.of(c -> {
if (c.getBoolean("use-server-properties-name", false)) {
String serverName = c.getPlugin().getServerName();
String serverName = c.getPlugin().getBootstrap().getServerName();
if (serverName != null && !serverName.equals("Unknown Server")) {
return serverName.toLowerCase();
}

View File

@ -53,8 +53,8 @@ public class ContextsFile {
}
public void load() {
File file = new File(this.configuration.getPlugin().getConfigDirectory(), "contexts.json");
File oldFile = new File(this.configuration.getPlugin().getConfigDirectory(), "static-contexts.json");
File file = new File(this.configuration.getPlugin().getBootstrap().getDataDirectory(), "contexts.json");
File oldFile = new File(this.configuration.getPlugin().getBootstrap().getDataDirectory(), "static-contexts.json");
if (oldFile.exists()) {
oldFile.renameTo(file);
}
@ -91,7 +91,7 @@ public class ContextsFile {
}
public void save() {
File file = new File(this.configuration.getPlugin().getConfigDirectory(), "contexts.json");
File file = new File(this.configuration.getPlugin().getBootstrap().getDataDirectory(), "contexts.json");
try (BufferedWriter writer = Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8)) {

View File

@ -202,7 +202,7 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
}
accumulator = ret;
} catch (Exception e) {
AbstractContextManager.this.plugin.getLog().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating the context of subject " + subject);
AbstractContextManager.this.plugin.getLogger().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating the context of subject " + subject);
e.printStackTrace();
}
}
@ -225,7 +225,7 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
}
accumulator = ret;
} catch (Exception e) {
AbstractContextManager.this.plugin.getLog().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating static contexts");
AbstractContextManager.this.plugin.getLogger().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating static contexts");
e.printStackTrace();
}
}

View File

@ -79,7 +79,7 @@ public class DependencyManager {
}
private File getSaveDirectory() {
File saveDirectory = new File(this.plugin.getDataDirectory(), "lib");
File saveDirectory = new File(this.plugin.getBootstrap().getDataDirectory(), "lib");
if (!(saveDirectory.exists() || saveDirectory.mkdirs())) {
throw new RuntimeException("Unable to create lib dir - " + saveDirectory.getPath());
}
@ -139,7 +139,7 @@ public class DependencyManager {
File file = downloadDependency(saveDirectory, dependency);
sources.add(new Source(dependency, file));
} catch (Throwable e) {
this.plugin.getLog().severe("Exception whilst downloading dependency " + dependency.name());
this.plugin.getLogger().severe("Exception whilst downloading dependency " + dependency.name());
e.printStackTrace();
}
}
@ -169,12 +169,12 @@ public class DependencyManager {
RelocationHandler relocationHandler = getRelocationHandler();
// attempt to remap the jar.
this.plugin.getLog().info("Attempting to apply relocations to " + input.getName() + "...");
this.plugin.getLogger().info("Attempting to apply relocations to " + input.getName() + "...");
relocationHandler.remap(input, output, relocations);
remappedJars.add(new Source(source.dependency, output));
} catch (Throwable e) {
this.plugin.getLog().severe("Unable to remap the source file '" + source.dependency.name() + "'.");
this.plugin.getLogger().severe("Unable to remap the source file '" + source.dependency.name() + "'.");
e.printStackTrace();
}
}
@ -187,10 +187,10 @@ public class DependencyManager {
}
try {
this.plugin.getPluginClassLoader().loadJar(source.file);
this.plugin.getBootstrap().getPluginClassLoader().loadJar(source.file);
this.loaded.put(source.dependency, source.file);
} catch (Throwable e) {
this.plugin.getLog().severe("Failed to load dependency jar '" + source.file.getName() + "'.");
this.plugin.getLogger().severe("Failed to load dependency jar '" + source.file.getName() + "'.");
e.printStackTrace();
}
}
@ -218,7 +218,7 @@ public class DependencyManager {
// compute a hash for the downloaded file
byte[] hash = this.digest.digest(bytes);
this.plugin.getLog().info("Successfully downloaded '" + fileName + "' with checksum: " + Base64.getEncoder().encodeToString(hash));
this.plugin.getLogger().info("Successfully downloaded '" + fileName + "' with checksum: " + Base64.getEncoder().encodeToString(hash));
// ensure the hash matches the expected checksum
if (!Arrays.equals(hash, dependency.getChecksum())) {

View File

@ -83,7 +83,7 @@ public class DependencyRegistry {
}
// don't load configurate dependencies on sponge
if (this.plugin.getServerType() == PlatformType.SPONGE) {
if (this.plugin.getBootstrap().getType() == PlatformType.SPONGE) {
dependencies.remove(Dependency.CONFIGURATE_CORE);
dependencies.remove(Dependency.CONFIGURATE_GSON);
dependencies.remove(Dependency.CONFIGURATE_YAML);

View File

@ -118,7 +118,7 @@ public class LuckPermsEventBus implements EventBus {
if (event instanceof Cancellable) {
throw new IllegalArgumentException("cannot call Cancellable event async");
}
this.plugin.getScheduler().doAsync(() -> fireEvent(event));
this.plugin.getBootstrap().getScheduler().doAsync(() -> fireEvent(event));
}
public LuckPermsPlugin getPlugin() {

View File

@ -78,7 +78,7 @@ public class LuckPermsEventHandler<T extends LuckPermsEvent> implements EventHan
this.consumer.accept(t);
this.callCount.incrementAndGet();
} catch (Throwable t) {
this.eventBus.getPlugin().getLog().warn("Unable to pass event " + event.getClass().getSimpleName() + " to handler " + this.consumer.getClass().getName());
this.eventBus.getPlugin().getLogger().warn("Unable to pass event " + event.getClass().getSimpleName() + " to handler " + this.consumer.getClass().getName());
t.printStackTrace();
}
}

View File

@ -23,25 +23,37 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.utils;
package me.lucko.luckperms.common.listener;
import me.lucko.luckperms.common.assignments.AssignmentRule;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
* Abstract listener utility for handling new player connections
*/
public abstract class AbstractLoginListener {
public abstract class AbstractConnectionListener implements ConnectionListener {
private final LuckPermsPlugin plugin;
private final Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
protected AbstractLoginListener(LuckPermsPlugin plugin) {
protected AbstractConnectionListener(LuckPermsPlugin plugin) {
this.plugin = plugin;
}
@Override
public Set<UUID> getUniqueConnections() {
return this.uniqueConnections;
}
protected void recordConnection(UUID uuid) {
this.uniqueConnections.add(uuid);
}
public User loadUser(UUID u, String username) {
final long startTime = System.currentTimeMillis();
@ -78,7 +90,7 @@ public abstract class AbstractLoginListener {
final long time = System.currentTimeMillis() - startTime;
if (time >= 1000) {
this.plugin.getLog().warn("Processing login for " + username + " took " + time + "ms.");
this.plugin.getLogger().warn("Processing login for " + username + " took " + time + "ms.");
}
return user;

View File

@ -23,37 +23,21 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.locale;
package me.lucko.luckperms.common.listener;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.Set;
import java.util.UUID;
import java.io.File;
/**
* Handles incoming connections on the platform
*/
public interface ConnectionListener {
public class NoopLocaleManager implements LocaleManager {
@Override
public void tryLoad(LuckPermsPlugin plugin, File file) {
}
@Override
public void loadFromFile(File file) {
}
@Override
public int getSize() {
return 0;
}
@Override
public String getTranslation(Message key) {
return null;
}
@Override
public CommandSpecData getTranslation(CommandSpec key) {
return null;
}
/**
* Gets the unique players which have connected to the server since it started.
*
* @return the unique connections
*/
Set<UUID> getUniqueConnections();
}

View File

@ -45,7 +45,7 @@ public class SimpleLocaleManager implements LocaleManager {
@Override
public void tryLoad(LuckPermsPlugin plugin, File file) {
if (file.exists()) {
plugin.getLog().info("Found lang.yml - loading messages...");
plugin.getLogger().info("Found lang.yml - loading messages...");
try {
loadFromFile(file);
} catch (Exception e) {

View File

@ -46,7 +46,7 @@ public abstract class AbstractUserManager<T extends User> extends AbstractManage
public AbstractUserManager(LuckPermsPlugin plugin, UserHousekeeper.TimeoutSettings timeoutSettings) {
this.plugin = plugin;
this.housekeeper = new UserHousekeeper(plugin, this, timeoutSettings);
this.plugin.getScheduler().asyncRepeating(this.housekeeper, 200L); // every 10 seconds
this.plugin.getBootstrap().getScheduler().asyncRepeating(this.housekeeper, 200L); // every 10 seconds
}
@Override
@ -147,8 +147,8 @@ public abstract class AbstractUserManager<T extends User> extends AbstractManage
@Override
public CompletableFuture<Void> updateAllUsers() {
return CompletableFuture.runAsync(
() -> this.plugin.getOnlinePlayers().forEach(u -> this.plugin.getStorage().loadUser(u, null).join()),
this.plugin.getScheduler().async()
() -> this.plugin.getBootstrap().getOnlinePlayers().forEach(u -> this.plugin.getStorage().loadUser(u, null).join()),
this.plugin.getBootstrap().getScheduler().async()
);
}

View File

@ -76,7 +76,7 @@ public class UserHousekeeper implements Runnable {
UUID uuid = identifier.getUuid();
// unload users which aren't online and who haven't been online (or tried to login) recently
if (this.recentlyUsed.contains(uuid) || this.recentlyUsedApi.contains(uuid) || this.plugin.isPlayerOnline(uuid)) {
if (this.recentlyUsed.contains(uuid) || this.recentlyUsedApi.contains(uuid) || this.plugin.getBootstrap().isPlayerOnline(uuid)) {
return;
}

View File

@ -102,32 +102,32 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
@Override
public void pushUpdate() {
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
UUID requestId = generatePingId();
this.plugin.getLog().info("[" + getName() + " Messaging] Sending ping with id: " + requestId);
this.plugin.getLogger().info("[" + getName() + " Messaging] Sending ping with id: " + requestId);
this.messenger.sendOutgoingMessage(new UpdateMessageImpl(requestId));
});
}
@Override
public void pushUserUpdate(User user) {
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
UUID requestId = generatePingId();
this.plugin.getLog().info("[" + getName() + " Messaging] Sending user ping for '" + user.getFriendlyName() + "' with id: " + requestId);
this.plugin.getLogger().info("[" + getName() + " Messaging] Sending user ping for '" + user.getFriendlyName() + "' with id: " + requestId);
this.messenger.sendOutgoingMessage(new UserUpdateMessageImpl(requestId, user.getUuid()));
});
}
@Override
public void pushLog(LogEntry logEntry) {
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
UUID requestId = generatePingId();
if (this.plugin.getEventFactory().handleLogNetworkPublish(!this.plugin.getConfiguration().get(ConfigKeys.PUSH_LOG_ENTRIES), requestId, logEntry)) {
return;
}
this.plugin.getLog().info("[" + getName() + " Messaging] Sending log with id: " + requestId);
this.plugin.getLogger().info("[" + getName() + " Messaging] Sending log with id: " + requestId);
this.messenger.sendOutgoingMessage(new LogMessageImpl(requestId, logEntry));
});
}
@ -142,7 +142,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
return false;
}
this.plugin.getLog().info("[" + getName() + " Messaging] Received update ping with id: " + msg.getId());
this.plugin.getLogger().info("[" + getName() + " Messaging] Received update ping with id: " + msg.getId());
if (this.plugin.getEventFactory().handleNetworkPreSync(false, msg.getId())) {
return true;
@ -162,7 +162,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
return true;
}
this.plugin.getLog().info("[" + getName() + " Messaging] Received user update ping for '" + user.getFriendlyName() + "' with id: " + msg.getId());
this.plugin.getLogger().info("[" + getName() + " Messaging] Received user update ping for '" + user.getFriendlyName() + "' with id: " + msg.getId());
if (this.plugin.getEventFactory().handleNetworkPreSync(false, msg.getId())) {
return true;
@ -182,7 +182,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
return true;
} else {
this.plugin.getLog().warn("Unable to decode incoming message: " + message + " (" + message.getClass().getName() + ")");
this.plugin.getLogger().warn("Unable to decode incoming message: " + message + " (" + message.getClass().getName() + ")");
return false;
}
}
@ -207,7 +207,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
private final class PushUpdateBuffer extends BufferedRequest<Void> {
public PushUpdateBuffer(LuckPermsPlugin plugin) {
super(2000L, 200L, plugin.getScheduler().async());
super(2000L, 200L, plugin.getBootstrap().getScheduler().async());
}
@Override

View File

@ -55,14 +55,14 @@ public class MessagingFactory<P extends LuckPermsPlugin> {
return null;
}
this.plugin.getLog().info("Loading messaging service... [" + messagingType.toUpperCase() + "]");
this.plugin.getLogger().info("Loading messaging service... [" + messagingType.toUpperCase() + "]");
InternalMessagingService service = getServiceFor(messagingType);
if (service != null) {
return service;
}
this.plugin.getLog().warn("Messaging service '" + messagingType + "' not recognised.");
this.plugin.getLogger().warn("Messaging service '" + messagingType + "' not recognised.");
return null;
}
@ -75,7 +75,7 @@ public class MessagingFactory<P extends LuckPermsPlugin> {
e.printStackTrace();
}
} else {
this.plugin.getLog().warn("Messaging Service was set to redis, but redis is not enabled!");
this.plugin.getLogger().warn("Messaging Service was set to redis, but redis is not enabled!");
}
}

View File

@ -65,7 +65,7 @@ public class RedisMessenger implements Messenger {
this.jedisPool = new JedisPool(new JedisPoolConfig(), host, port, 0, password);
}
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
this.sub = new LPSub(this);
try (Jedis jedis = this.jedisPool.getResource()) {
jedis.subscribe(this.sub, CHANNEL);

View File

@ -154,7 +154,7 @@ public class Group extends PermissionHolder implements Identifiable<String> {
private final Group group;
private GroupRefreshBuffer(LuckPermsPlugin plugin, Group group) {
super(50L, 5L, plugin.getScheduler().async());
super(50L, 5L, plugin.getBootstrap().getScheduler().async());
this.group = group;
}

View File

@ -235,7 +235,7 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
private final User user;
private UserRefreshBuffer(LuckPermsPlugin plugin, User user) {
super(50L, 5L, plugin.getScheduler().async());
super(50L, 5L, plugin.getBootstrap().getScheduler().async());
this.user = user;
}

View File

@ -0,0 +1,340 @@
/*
* 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.common.plugin;
import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiRegistrationUtil;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.buffers.UpdateTaskBuffer;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.CommandUtils;
import me.lucko.luckperms.common.config.AbstractConfiguration;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.contexts.LuckPermsCalculator;
import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.dependencies.DependencyRegistry;
import me.lucko.luckperms.common.event.EventFactory;
import me.lucko.luckperms.common.inheritance.InheritanceHandler;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.SimpleLocaleManager;
import me.lucko.luckperms.common.logging.Logger;
import me.lucko.luckperms.common.logging.SenderLogger;
import me.lucko.luckperms.common.messaging.InternalMessagingService;
import me.lucko.luckperms.common.messaging.MessagingFactory;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.storage.StorageFactory;
import me.lucko.luckperms.common.storage.StorageType;
import me.lucko.luckperms.common.storage.dao.file.FileWatcher;
import me.lucko.luckperms.common.tasks.UpdateTask;
import me.lucko.luckperms.common.treeview.PermissionVault;
import me.lucko.luckperms.common.verbose.VerboseHandler;
import java.io.File;
import java.util.Optional;
import java.util.Set;
public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin {
// init during load
private Logger logger;
private DependencyManager dependencyManager;
// init during enable
private VerboseHandler verboseHandler;
private PermissionVault permissionVault;
private LogDispatcher logDispatcher;
private LuckPermsConfiguration configuration;
private LocaleManager localeManager;
private FileWatcher fileWatcher = null;
private Storage storage;
private InternalMessagingService messagingService = null;
private BufferedRequest<Void> updateTaskBuffer;
private InheritanceHandler inheritanceHandler;
private CachedStateManager cachedStateManager;
private CalculatorFactory calculatorFactory;
private LuckPermsApiProvider apiProvider;
private EventFactory eventFactory;
/**
* Performs the initial actions to load the plugin
*/
public final void load() {
// load the sender factory instance and create a new logger for the plugin
setupSenderFactory();
this.logger = new SenderLogger(this, getConsoleSender());
// load dependencies
this.dependencyManager = new DependencyManager(this);
this.dependencyManager.loadDependencies(DependencyRegistry.GLOBAL_DEPENDENCIES);
}
public final void enable() {
// send the startup banner
displayBanner(getConsoleSender());
// load some utilities early
this.verboseHandler = new VerboseHandler(getBootstrap().getScheduler().platformAsync());
this.permissionVault = new PermissionVault(getBootstrap().getScheduler().platformAsync());
this.logDispatcher = new LogDispatcher(this);
// load configuration
getLogger().info("Loading configuration...");
this.configuration = new AbstractConfiguration(this, provideConfigurationAdapter());
this.configuration.loadAll();
// load locale
this.localeManager = new SimpleLocaleManager();
this.localeManager.tryLoad(this, new File(getBootstrap().getConfigDirectory(), "lang.yml"));
// now the configuration is loaded, we can create a storage factory and load initial dependencies
StorageFactory storageFactory = new StorageFactory(this);
Set<StorageType> storageTypes = storageFactory.getRequiredTypes(StorageType.H2);
this.dependencyManager.loadStorageDependencies(storageTypes);
// register listeners
registerPlatformListeners();
// initialise the storage
// first, setup the file watcher, if enabled
if (getConfiguration().get(ConfigKeys.WATCH_FILES)) {
this.fileWatcher = new FileWatcher(this);
getBootstrap().getScheduler().asyncRepeating(this.fileWatcher, 30L);
}
// initialise storage
this.storage = storageFactory.getInstance(StorageType.H2);
this.messagingService = provideMessagingFactory().getInstance();
// setup the update task buffer
this.updateTaskBuffer = new UpdateTaskBuffer(this);
// register commands
registerCommands();
// load internal managers
getLogger().info("Loading internal permission managers...");
this.inheritanceHandler = new InheritanceHandler(this);
this.cachedStateManager = new CachedStateManager();
// setup user/group/track manager
setupManagers();
// init calculator factory
this.calculatorFactory = provideCalculatorFactory();
// setup contextmanager & register common calculators
setupContextManager();
getContextManager().registerStaticCalculator(new LuckPermsCalculator(getConfiguration()));
// setup platform hooks
setupPlatformHooks();
// register with the LP API
this.apiProvider = new LuckPermsApiProvider(this);
this.eventFactory = new EventFactory(this, this.apiProvider);
ApiRegistrationUtil.registerProvider(this.apiProvider);
registerApiOnPlatform(this.apiProvider);
// schedule update tasks
int mins = getConfiguration().get(ConfigKeys.SYNC_TIME);
if (mins > 0) {
long ticks = mins * 60 * 20;
getBootstrap().getScheduler().asyncRepeating(() -> this.updateTaskBuffer.request(), ticks);
}
getBootstrap().getScheduler().asyncLater(() -> this.updateTaskBuffer.request(), 40L);
// run an update instantly.
getLogger().info("Performing initial data load...");
try {
new UpdateTask(this, true).run();
} catch (Exception e) {
e.printStackTrace();
}
// init housekeeping tasks
registerHousekeepingTasks();
// perform any platform-specific final setup tasks
performFinalSetup();
getLogger().info("Successfully enabled. (took " + (System.currentTimeMillis() - getBootstrap().getStartupTime()) + "ms)");
}
public final void disable() {
// perform initial disable tasks
performEarlyDisableTasks();
// shutdown permission vault and verbose handler tasks
this.permissionVault.shutdown();
this.verboseHandler.shutdown();
// remove any hooks into the platform
removePlatformHooks();
// close storage
getLogger().info("Closing storage...");
this.storage.shutdown();
// close file watcher
if (this.fileWatcher != null) {
this.fileWatcher.close();
}
// close messaging service
if (this.messagingService != null) {
getLogger().info("Closing messaging service...");
this.messagingService.close();
}
// unregister api
ApiRegistrationUtil.unregisterProvider();
// shutdown scheduler
getLogger().info("Shutting down internal scheduler...");
getBootstrap().getScheduler().shutdown();
getLogger().info("Goodbye!");
}
protected abstract void setupSenderFactory();
protected abstract ConfigurationAdapter provideConfigurationAdapter();
protected abstract void registerPlatformListeners();
protected abstract MessagingFactory<?> provideMessagingFactory();
protected abstract void registerCommands();
protected abstract void setupManagers();
protected abstract CalculatorFactory provideCalculatorFactory();
protected abstract void setupContextManager();
protected abstract void setupPlatformHooks();
protected abstract void registerApiOnPlatform(LuckPermsApi api);
protected abstract void registerHousekeepingTasks();
protected abstract void performFinalSetup();
protected void performEarlyDisableTasks() {}
protected void removePlatformHooks() {}
@Override
public void setMessagingService(InternalMessagingService messagingService) {
if (this.messagingService == null) {
this.messagingService = messagingService;
}
}
@Override
public Logger getLogger() {
return this.logger;
}
@Override
public DependencyManager getDependencyManager() {
return this.dependencyManager;
}
@Override
public VerboseHandler getVerboseHandler() {
return this.verboseHandler;
}
@Override
public PermissionVault getPermissionVault() {
return this.permissionVault;
}
@Override
public LogDispatcher getLogDispatcher() {
return this.logDispatcher;
}
@Override
public LuckPermsConfiguration getConfiguration() {
return this.configuration;
}
@Override
public LocaleManager getLocaleManager() {
return this.localeManager;
}
@Override
public Optional<FileWatcher> getFileWatcher() {
return Optional.ofNullable(this.fileWatcher);
}
@Override
public Storage getStorage() {
return this.storage;
}
@Override
public Optional<InternalMessagingService> getMessagingService() {
return Optional.ofNullable(this.messagingService);
}
@Override
public BufferedRequest<Void> getUpdateTaskBuffer() {
return this.updateTaskBuffer;
}
@Override
public InheritanceHandler getInheritanceHandler() {
return this.inheritanceHandler;
}
@Override
public CachedStateManager getCachedStateManager() {
return this.cachedStateManager;
}
@Override
public CalculatorFactory getCalculatorFactory() {
return this.calculatorFactory;
}
@Override
public LuckPermsApiProvider getApiProvider() {
return this.apiProvider;
}
@Override
public EventFactory getEventFactory() {
return this.eventFactory;
}
private void displayBanner(Sender sender) {
sender.sendMessage(CommandUtils.color("&b __ &3 __ ___ __ __ "));
sender.sendMessage(CommandUtils.color("&b | | | / ` |__/ &3|__) |__ |__) |\\/| /__` "));
sender.sendMessage(CommandUtils.color("&b |___ \\__/ \\__, | \\ &3| |___ | \\ | | .__/ "));
sender.sendMessage(CommandUtils.color(" "));
sender.sendMessage(CommandUtils.color("&2 Loading version &bv" + getBootstrap().getVersion() + "&2 on " + getBootstrap().getType().getFriendlyName() + " - " + getBootstrap().getServerBrand()));
sender.sendMessage(CommandUtils.color("&8 Running on server version " + getBootstrap().getServerVersion()));
sender.sendMessage(CommandUtils.color(" "));
}
}

View File

@ -26,7 +26,6 @@
package me.lucko.luckperms.common.plugin;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest;
@ -35,13 +34,12 @@ import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.abstraction.Command;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.CommandUtils;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader;
import me.lucko.luckperms.common.event.EventFactory;
import me.lucko.luckperms.common.inheritance.InheritanceHandler;
import me.lucko.luckperms.common.listener.ConnectionListener;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.logging.Logger;
import me.lucko.luckperms.common.managers.group.GroupManager;
@ -49,18 +47,15 @@ import me.lucko.luckperms.common.managers.track.TrackManager;
import me.lucko.luckperms.common.managers.user.UserManager;
import me.lucko.luckperms.common.messaging.InternalMessagingService;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.storage.dao.file.FileWatcher;
import me.lucko.luckperms.common.treeview.PermissionVault;
import me.lucko.luckperms.common.verbose.VerboseHandler;
import java.io.File;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Stream;
/**
@ -71,6 +66,13 @@ import java.util.stream.Stream;
*/
public interface LuckPermsPlugin {
/**
* Gets the bootstrap plugin instance
*
* @return the bootstrap plugin
*/
LuckPermsBootstrap getBootstrap();
/**
* Gets the user manager instance for the platform
*
@ -125,7 +127,7 @@ public interface LuckPermsPlugin {
*
* @return the plugin's logger
*/
Logger getLog();
Logger getLogger();
/**
* Gets the event factory
@ -148,6 +150,13 @@ public interface LuckPermsPlugin {
*/
CommandManager getCommandManager();
/**
* Gets the connection listener.
*
* @return the connection listener
*/
ConnectionListener getConnectionListener();
/**
* Gets the instance providing locale translations for the plugin
*
@ -155,13 +164,6 @@ public interface LuckPermsPlugin {
*/
LocaleManager getLocaleManager();
/**
* Gets the classloader wrapper for adding dependencies to the classpath
*
* @return the plugin classloader
*/
PluginClassLoader getPluginClassLoader();
/**
* Gets the dependency manager for the plugin
*
@ -219,13 +221,6 @@ public interface LuckPermsPlugin {
*/
LogDispatcher getLogDispatcher();
/**
* Gets the LuckPerms Scheduler instance
*
* @return the scheduler
*/
SchedulerAdapter getScheduler();
/**
* Gets the file watcher running on the platform
*
@ -233,97 +228,6 @@ public interface LuckPermsPlugin {
*/
Optional<FileWatcher> getFileWatcher();
/**
* Gets a string of the plugin's version
*
* @return the version of the plugin
*/
String getVersion();
/**
* Gets the platform type this instance of LuckPerms is running on.
*
* @return the platform type
*/
PlatformType getServerType();
/**
* Gets the name or "brand" of the running platform
*
* @return the server brand
*/
String getServerBrand();
/**
* Gets the version of the running platform
*
* @return the server version
*/
String getServerVersion();
/**
* Gets the name associated with this server
*
* @return the server name
*/
default String getServerName() {
return null;
}
/**
* Gets the time when the plugin first started in millis.
*
* @return the enable time
*/
long getStartTime();
/**
* Gets the plugins main data storage directory
*
* <p>Bukkit: /root/plugins/LuckPerms</p>
* <p>Bungee: /root/plugins/LuckPerms</p>
* <p>Sponge: /root/luckperms/</p>
*
* @return the platforms data folder
*/
File getDataDirectory();
/**
* Gets the plugins config directory.
*
* <p>This is the same as {@link #getDataDirectory()} on Bukkit/Bungee, but different on Sponge.</p>
*
* @return the platforms config folder
*/
default File getConfigDirectory() {
return getDataDirectory();
}
/**
* Gets a bundled resource file from the jar
*
* @param path the path of the file
* @return the file as an input stream
*/
InputStream getResourceStream(String path);
/**
* Gets a player object linked to this User. The returned object must be the same type
* as the instance used in the platforms {@link ContextManager}
*
* @param user the user instance
* @return a player object, or null, if one couldn't be found.
*/
Object getPlayer(User user);
/**
* Lookup a uuid from a username, using the servers internal uuid cache.
*
* @param username the username to lookup
* @return an optional uuid, if found
*/
Optional<UUID> lookupUuid(String username);
/**
* Gets a calculated context instance for the user using the rules of the platform.
*
@ -332,35 +236,6 @@ public interface LuckPermsPlugin {
*/
Optional<Contexts> getContextForUser(User user);
/**
* Gets the number of users online on the platform
*
* @return the number of users
*/
int getPlayerCount();
/**
* Gets the usernames of the users online on the platform
*
* @return a {@link List} of usernames
*/
Stream<String> getPlayerList();
/**
* Gets the UUIDs of the users online on the platform
*
* @return a {@link Set} of UUIDs
*/
Stream<UUID> getOnlinePlayers();
/**
* Checks if a user is online
*
* @param external the users external uuid
* @return true if the user is online
*/
boolean isPlayerOnline(UUID external);
/**
* Gets a list of online Senders on the platform
*
@ -375,13 +250,6 @@ public interface LuckPermsPlugin {
*/
Sender getConsoleSender();
/**
* Gets the unique players which have connected to the server since it started.
*
* @return the unique connections
*/
Set<UUID> getUniqueConnections();
default List<Command> getExtraCommands() {
return Collections.emptyList();
}
@ -400,14 +268,4 @@ public interface LuckPermsPlugin {
}
default void sendStartupBanner(Sender sender) {
sender.sendMessage(CommandUtils.color("&b __ &3 __ ___ __ __ "));
sender.sendMessage(CommandUtils.color("&b | | | / ` |__/ &3|__) |__ |__) |\\/| /__` "));
sender.sendMessage(CommandUtils.color("&b |___ \\__/ \\__, | \\ &3| |___ | \\ | | .__/ "));
sender.sendMessage(CommandUtils.color(" "));
sender.sendMessage(CommandUtils.color("&2 Loading version &bv" + getVersion() + "&2 on " + getServerType().getFriendlyName() + " - " + getServerBrand()));
sender.sendMessage(CommandUtils.color("&8 Running on server version " + getServerVersion()));
sender.sendMessage(CommandUtils.color(" "));
}
}

View File

@ -39,6 +39,10 @@ public interface SchedulerAdapter {
*/
Executor async();
default Executor platformAsync() {
return async();
}
/**
* Gets a sync executor instance
*

View File

@ -0,0 +1,201 @@
/*
* 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.common.plugin.bootstrap;
import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader;
import me.lucko.luckperms.common.plugin.SchedulerAdapter;
import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Stream;
import javax.annotation.Nullable;
/**
* Bootstrap plugin interface
*
* <p>Instances of this interface are responsible for loading the
* "LuckPerms plugin" on their respective platforms.</p>
*/
public interface LuckPermsBootstrap {
/**
* Gets an adapter for the platforms scheduler
*
* @return the scheduler
*/
SchedulerAdapter getScheduler();
/**
* Gets a {@link PluginClassLoader} for this instance
*
* @return a classloader
*/
PluginClassLoader getPluginClassLoader();
/**
* Returns a countdown latch which {@link CountDownLatch#countDown() counts down}
* after the plugin has loaded.
*
* @return a loading latch
*/
CountDownLatch getLoadLatch();
/**
* Returns a countdown latch which {@link CountDownLatch#countDown() counts down}
* after the plugin has enabled.
*
* @return an enable latch
*/
CountDownLatch getEnableLatch();
/**
* Gets a string of the plugin's version
*
* @return the version of the plugin
*/
String getVersion();
/**
* Gets the time when the plugin first started in millis.
*
* @return the enable time
*/
long getStartupTime();
/**
* Gets the platform type this instance of LuckPerms is running on.
*
* @return the platform type
*/
PlatformType getType();
/**
* Gets the name or "brand" of the running platform
*
* @return the server brand
*/
String getServerBrand();
/**
* Gets the version of the running platform
*
* @return the server version
*/
String getServerVersion();
/**
* Gets the name associated with this server
*
* @return the server name
*/
@Nullable
default String getServerName() {
return null;
}
/**
* Gets the plugins main data storage directory
*
* <p>Bukkit: /root/plugins/LuckPerms</p>
* <p>Bungee: /root/plugins/LuckPerms</p>
* <p>Sponge: /root/luckperms/</p>
*
* @return the platforms data folder
*/
File getDataDirectory();
/**
* Gets the plugins configuration directory
*
* @return the config directory
*/
default File getConfigDirectory() {
return getDataDirectory();
}
/**
* Gets a bundled resource file from the jar
*
* @param path the path of the file
* @return the file as an input stream
*/
InputStream getResourceStream(String path);
/**
* Gets a player object linked to this User. The returned object must be the same type
* as the instance used in the platforms ContextManager
*
* @param uuid the users unique id
* @return a player object, or null, if one couldn't be found.
*/
@Nullable
Object getPlayer(UUID uuid);
/**
* Lookup a uuid from a username, using the servers internal uuid cache.
*
* @param username the username to lookup
* @return an optional uuid, if found
*/
Optional<UUID> lookupUuid(String username);
/**
* Gets the number of users online on the platform
*
* @return the number of users
*/
int getPlayerCount();
/**
* Gets the usernames of the users online on the platform
*
* @return a {@link List} of usernames
*/
Stream<String> getPlayerList();
/**
* Gets the UUIDs of the users online on the platform
*
* @return a {@link Set} of UUIDs
*/
Stream<UUID> getOnlinePlayers();
/**
* Checks if a user is online
*
* @param uuid the users external uuid
* @return true if the user is online
*/
boolean isPlayerOnline(UUID uuid);
}

View File

@ -60,7 +60,7 @@ public class AbstractStorage implements Storage {
Storage base = new AbstractStorage(plugin, backing);
Storage phased = PhasedStorage.wrap(base);
BufferedOutputStorage buffered = BufferedOutputStorage.wrap(phased, 250L);
plugin.getScheduler().asyncRepeating(buffered, 2L);
plugin.getBootstrap().getScheduler().asyncRepeating(buffered, 2L);
return buffered;
}
@ -88,7 +88,7 @@ public class AbstractStorage implements Storage {
Throwables.propagateIfPossible(e);
throw new CompletionException(e);
}
}, this.dao.getPlugin().getScheduler().async());
}, this.dao.getPlugin().getBootstrap().getScheduler().async());
}
private CompletableFuture<Void> makeFuture(ThrowingRunnable runnable) {
@ -99,7 +99,7 @@ public class AbstractStorage implements Storage {
Throwables.propagateIfPossible(e);
throw new CompletionException(e);
}
}, this.dao.getPlugin().getScheduler().async());
}, this.dao.getPlugin().getBootstrap().getScheduler().async());
}
@Override
@ -126,7 +126,7 @@ public class AbstractStorage implements Storage {
try {
this.dao.init();
} catch (Exception e) {
this.plugin.getLog().severe("Failed to init storage dao");
this.plugin.getLogger().severe("Failed to init storage dao");
e.printStackTrace();
}
}
@ -136,7 +136,7 @@ public class AbstractStorage implements Storage {
try {
this.dao.shutdown();
} catch (Exception e) {
this.plugin.getLog().severe("Failed to shutdown storage dao");
this.plugin.getLogger().severe("Failed to shutdown storage dao");
e.printStackTrace();
}
}

View File

@ -62,7 +62,7 @@ public class StorageFactory {
.map(e -> {
StorageType type = StorageType.parse(e.getValue());
if (type == null) {
this.plugin.getLog().severe("Storage method for " + e.getKey() + " - " + e.getValue() + " not recognised. " +
this.plugin.getLogger().severe("Storage method for " + e.getKey() + " - " + e.getValue() + " not recognised. " +
"Using the default instead.");
type = defaultMethod;
}
@ -73,7 +73,7 @@ public class StorageFactory {
String method = this.plugin.getConfiguration().get(ConfigKeys.STORAGE_METHOD);
StorageType type = StorageType.parse(method);
if (type == null) {
this.plugin.getLog().severe("Storage method '" + method + "' not recognised. Using the default instead.");
this.plugin.getLogger().severe("Storage method '" + method + "' not recognised. Using the default instead.");
type = defaultMethod;
}
return ImmutableSet.of(type);
@ -83,7 +83,7 @@ public class StorageFactory {
public Storage getInstance(StorageType defaultMethod) {
Storage storage;
if (this.plugin.getConfiguration().get(ConfigKeys.SPLIT_STORAGE)) {
this.plugin.getLog().info("Loading storage provider... [SPLIT STORAGE]");
this.plugin.getLogger().info("Loading storage provider... [SPLIT STORAGE]");
Map<SplitStorageType, StorageType> mappedTypes = this.plugin.getConfiguration().get(ConfigKeys.SPLIT_STORAGE_OPTIONS).entrySet().stream()
.map(e -> {
@ -108,7 +108,7 @@ public class StorageFactory {
type = defaultMethod;
}
this.plugin.getLog().info("Loading storage provider... [" + type.name() + "]");
this.plugin.getLogger().info("Loading storage provider... [" + type.name() + "]");
storage = makeInstance(type);
}
@ -139,13 +139,13 @@ public class StorageFactory {
case SQLITE:
return new SqlDao(
this.plugin,
new SQLiteConnectionFactory(this.plugin, new File(this.plugin.getDataDirectory(), "luckperms-sqlite.db")),
new SQLiteConnectionFactory(this.plugin, new File(this.plugin.getBootstrap().getDataDirectory(), "luckperms-sqlite.db")),
this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX)
);
case H2:
return new SqlDao(
this.plugin,
new H2ConnectionFactory(this.plugin, new File(this.plugin.getDataDirectory(), "luckperms-h2")),
new H2ConnectionFactory(this.plugin, new File(this.plugin.getBootstrap().getDataDirectory(), "luckperms-h2")),
this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX)
);
case POSTGRESQL:

View File

@ -150,7 +150,7 @@ public abstract class ConfigurateDao extends AbstractDao {
}
private Exception reportException(String file, Exception ex) throws Exception {
this.plugin.getLog().warn("Exception thrown whilst performing i/o: " + file);
this.plugin.getLogger().warn("Exception thrown whilst performing i/o: " + file);
ex.printStackTrace();
throw ex;
}
@ -162,7 +162,7 @@ public abstract class ConfigurateDao extends AbstractDao {
@Override
public void init() {
try {
File data = FileUtils.mkdirs(new File(this.plugin.getDataDirectory(), this.dataFolderName));
File data = FileUtils.mkdirs(new File(this.plugin.getBootstrap().getDataDirectory(), this.dataFolderName));
this.usersDirectory = FileUtils.mkdir(new File(data, "users"));
this.groupsDirectory = FileUtils.mkdir(new File(data, "groups"));
@ -185,7 +185,7 @@ public abstract class ConfigurateDao extends AbstractDao {
User u = this.plugin.getUserManager().getIfLoaded(uuid);
if (u != null) {
this.plugin.getLog().info("[FileWatcher] Refreshing user " + u.getFriendlyName());
this.plugin.getLogger().info("[FileWatcher] Refreshing user " + u.getFriendlyName());
this.plugin.getStorage().loadUser(uuid, null);
}
});
@ -195,7 +195,7 @@ public abstract class ConfigurateDao extends AbstractDao {
}
String groupName = s.substring(0, s.length() - this.fileExtension.length());
this.plugin.getLog().info("[FileWatcher] Refreshing group " + groupName);
this.plugin.getLogger().info("[FileWatcher] Refreshing group " + groupName);
this.plugin.getUpdateTaskBuffer().request();
});
watcher.subscribe("track", this.tracksDirectory.toPath(), s -> {
@ -204,7 +204,7 @@ public abstract class ConfigurateDao extends AbstractDao {
}
String trackName = s.substring(0, s.length() - this.fileExtension.length());
this.plugin.getLog().info("[FileWatcher] Refreshing track " + trackName);
this.plugin.getLogger().info("[FileWatcher] Refreshing track " + trackName);
this.plugin.getStorage().loadAllTracks();
});
});

View File

@ -59,7 +59,7 @@ public class FileWatcher implements Runnable {
this.keyMap = Collections.synchronizedMap(new HashMap<>());
this.internalChanges = Collections.synchronizedMap(new HashMap<>());
try {
this.watchService = plugin.getDataDirectory().toPath().getFileSystem().newWatchService();
this.watchService = plugin.getBootstrap().getDataDirectory().toPath().getFileSystem().newWatchService();
} catch (IOException e) {
e.printStackTrace();
}
@ -71,7 +71,7 @@ public class FileWatcher implements Runnable {
}
// Register with a delay to ignore changes made at startup
this.plugin.getScheduler().asyncLater(() -> {
this.plugin.getBootstrap().getScheduler().asyncLater(() -> {
this.keyMap.computeIfAbsent(id, s -> {
WatchKey key;
try {
@ -137,7 +137,7 @@ public class FileWatcher implements Runnable {
this.internalChanges.put(id + "/" + fileName, System.currentTimeMillis());
this.plugin.getLog().info("[FileWatcher] Detected change in file: " + file.toString());
this.plugin.getLogger().info("[FileWatcher] Detected change in file: " + file.toString());
// Process the change
ent.getValue().getFileConsumer().accept(fileName);

View File

@ -154,7 +154,7 @@ public class SqlDao extends AbstractDao {
// Init tables
if (!tableExists(this.prefix.apply("{prefix}user_permissions"))) {
String schemaFileName = "schema/" + this.provider.getName().toLowerCase() + ".sql";
try (InputStream is = this.plugin.getResourceStream(schemaFileName)) {
try (InputStream is = this.plugin.getBootstrap().getResourceStream(schemaFileName)) {
if (is == null) {
throw new Exception("Couldn't locate schema file for " + this.provider.getName());
}
@ -203,7 +203,7 @@ public class SqlDao extends AbstractDao {
} catch (Exception e) {
this.plugin.getLog().severe("Error occurred whilst initialising the database.");
this.plugin.getLogger().severe("Error occurred whilst initialising the database.");
e.printStackTrace();
}
}

View File

@ -0,0 +1,203 @@
/*
* 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.nukkit;
import me.lucko.luckperms.api.platform.PlatformType;
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 cn.nukkit.Player;
import cn.nukkit.plugin.PluginBase;
import java.io.File;
import java.io.InputStream;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Stream;
import javax.annotation.Nullable;
/**
* Bootstrap plugin for LuckPerms running on Nukkit.
*/
public class LPNukkitBootstrap extends PluginBase implements LuckPermsBootstrap {
/**
* A scheduler adapter for the platform
*/
private final NukkitSchedulerAdapter schedulerAdapter;
/**
* The plugin classloader
*/
private final PluginClassLoader classLoader;
/**
* The plugin instance
*/
private final LPNukkitPlugin plugin;
/**
* The time when the plugin was enabled
*/
private long startTime;
// load/enable latches
private final CountDownLatch loadLatch = new CountDownLatch(1);
private final CountDownLatch enableLatch = new CountDownLatch(1);
public LPNukkitBootstrap() {
this.schedulerAdapter = new NukkitSchedulerAdapter(this);
this.classLoader = new ReflectionClassLoader(this);
this.plugin = new LPNukkitPlugin(this);
}
// provide adapters
@Override
public NukkitSchedulerAdapter getScheduler() {
return this.schedulerAdapter;
}
@Override
public PluginClassLoader getPluginClassLoader() {
return this.classLoader;
}
// lifecycle
@Override
public void onLoad() {
try {
this.plugin.load();
} finally {
this.loadLatch.countDown();
}
}
@Override
public void onEnable() {
this.startTime = System.currentTimeMillis();
try {
this.plugin.enable();
} finally {
this.enableLatch.countDown();
}
}
@Override
public void onDisable() {
this.plugin.disable();
}
@Override
public CountDownLatch getEnableLatch() {
return this.enableLatch;
}
@Override
public CountDownLatch getLoadLatch() {
return this.loadLatch;
}
// provide information about the plugin
@Override
public String getVersion() {
return getDescription().getVersion();
}
@Override
public long getStartupTime() {
return this.startTime;
}
// provide information about the platform
@Override
public PlatformType getType() {
return PlatformType.NUKKIT;
}
@Override
public String getServerBrand() {
return getServer().getName();
}
@Override
public String getServerVersion() {
return getServer().getVersion() + " - " + getServer().getNukkitVersion();
}
@Override
public String getServerName() {
return getServer().getServerUniqueId().toString();
}
@Override
public File getDataDirectory() {
return getDataFolder();
}
@Override
public InputStream getResourceStream(String path) {
return getResource(path);
}
@Nullable
@Override
public Player getPlayer(UUID uuid) {
return getServer().getOnlinePlayers().get(uuid);
}
@Override
public Optional<UUID> lookupUuid(String username) {
return Optional.empty();
}
@Override
public int getPlayerCount() {
return getServer().getOnlinePlayers().size();
}
@Override
public Stream<String> getPlayerList() {
return getServer().getOnlinePlayers().values().stream().map(Player::getName);
}
@Override
public Stream<UUID> getOnlinePlayers() {
return getServer().getOnlinePlayers().values().stream().map(Player::getUniqueId);
}
@Override
public boolean isPlayerOnline(UUID uuid) {
Player player = getServer().getOnlinePlayers().get(uuid);
return player != null && player.isOnline();
}
}

View File

@ -27,48 +27,21 @@ package me.lucko.luckperms.nukkit;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiRegistrationUtil;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.buffers.UpdateTaskBuffer;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.CommandPermission;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.AbstractConfiguration;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.contexts.LuckPermsCalculator;
import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.dependencies.DependencyRegistry;
import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader;
import me.lucko.luckperms.common.dependencies.classloader.ReflectionClassLoader;
import me.lucko.luckperms.common.event.EventFactory;
import me.lucko.luckperms.common.inheritance.InheritanceHandler;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.NoopLocaleManager;
import me.lucko.luckperms.common.locale.SimpleLocaleManager;
import me.lucko.luckperms.common.logging.Logger;
import me.lucko.luckperms.common.logging.SenderLogger;
import me.lucko.luckperms.common.listener.ConnectionListener;
import me.lucko.luckperms.common.managers.group.StandardGroupManager;
import me.lucko.luckperms.common.managers.track.StandardTrackManager;
import me.lucko.luckperms.common.managers.user.StandardUserManager;
import me.lucko.luckperms.common.messaging.InternalMessagingService;
import me.lucko.luckperms.common.messaging.MessagingFactory;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.storage.StorageFactory;
import me.lucko.luckperms.common.storage.StorageType;
import me.lucko.luckperms.common.storage.dao.file.FileWatcher;
import me.lucko.luckperms.common.plugin.AbstractLuckPermsPlugin;
import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
import me.lucko.luckperms.common.tasks.UpdateTask;
import me.lucko.luckperms.common.treeview.PermissionVault;
import me.lucko.luckperms.common.verbose.VerboseHandler;
import me.lucko.luckperms.nukkit.calculators.NukkitCalculatorFactory;
import me.lucko.luckperms.nukkit.contexts.NukkitContextManager;
import me.lucko.luckperms.nukkit.contexts.WorldCalculator;
@ -87,133 +60,97 @@ import me.lucko.luckperms.nukkit.model.server.LPSubscriptionMap;
import cn.nukkit.Player;
import cn.nukkit.command.PluginCommand;
import cn.nukkit.event.HandlerList;
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.io.InputStream;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
/**
* LuckPerms implementation for the Nukkit API.
*/
public class LPNukkitPlugin extends PluginBase implements LuckPermsPlugin {
public class LPNukkitPlugin extends AbstractLuckPermsPlugin {
private final LPNukkitBootstrap bootstrap;
private long startTime;
private NukkitSchedulerAdapter scheduler;
private NukkitSenderFactory senderFactory;
private NukkitConnectionListener connectionListener;
private NukkitCommandExecutor commandManager;
private LuckPermsConfiguration configuration;
private StandardUserManager userManager;
private StandardGroupManager groupManager;
private StandardTrackManager trackManager;
private Storage storage;
private FileWatcher fileWatcher = null;
private InternalMessagingService messagingService = null;
private LuckPermsApiProvider apiProvider;
private EventFactory eventFactory;
private Logger log;
private ContextManager<Player> contextManager;
private LPSubscriptionMap subscriptionMap;
private LPPermissionMap permissionMap;
private LPDefaultsMap defaultPermissionMap;
private LocaleManager localeManager;
private PluginClassLoader pluginClassLoader;
private DependencyManager dependencyManager;
private InheritanceHandler inheritanceHandler;
private CachedStateManager cachedStateManager;
private ContextManager<Player> contextManager;
private CalculatorFactory calculatorFactory;
private BufferedRequest<Void> updateTaskBuffer;
private VerboseHandler verboseHandler;
private NukkitSenderFactory senderFactory;
private PermissionVault permissionVault;
private LogDispatcher logDispatcher;
private Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
public LPNukkitPlugin(LPNukkitBootstrap bootstrap) {
this.bootstrap = bootstrap;
}
@Override
public void onLoad() {
// setup minimal functionality in order to load initial dependencies
this.scheduler = new NukkitSchedulerAdapter(this);
this.localeManager = new NoopLocaleManager();
public LPNukkitBootstrap getBootstrap() {
return this.bootstrap;
}
@Override
protected void setupSenderFactory() {
this.senderFactory = new NukkitSenderFactory(this);
this.log = new SenderLogger(this, getConsoleSender());
this.pluginClassLoader = new ReflectionClassLoader(this);
this.dependencyManager = new DependencyManager(this);
this.dependencyManager.loadDependencies(DependencyRegistry.GLOBAL_DEPENDENCIES);
}
@Override
public void onEnable() {
this.startTime = System.currentTimeMillis();
sendStartupBanner(getConsoleSender());
this.verboseHandler = new VerboseHandler(this.scheduler.asyncNukkit());
this.permissionVault = new PermissionVault(this.scheduler.asyncNukkit());
this.logDispatcher = new LogDispatcher(this);
getLog().info("Loading configuration...");
this.configuration = new AbstractConfiguration(this, new NukkitConfigAdapter(this, resolveConfig("config.yml")));
this.configuration.loadAll();
StorageFactory storageFactory = new StorageFactory(this);
Set<StorageType> storageTypes = storageFactory.getRequiredTypes(StorageType.H2);
this.dependencyManager.loadStorageDependencies(storageTypes);
// register events
NukkitConnectionListener connectionListener = new NukkitConnectionListener(this);
getServer().getPluginManager().registerEvents(connectionListener, this);
getServer().getPluginManager().registerEvents(new NukkitPlatformListener(this), this);
if (getConfiguration().get(ConfigKeys.WATCH_FILES)) {
this.fileWatcher = new FileWatcher(this);
getScheduler().asyncRepeating(this.fileWatcher, 30L);
protected ConfigurationAdapter provideConfigurationAdapter() {
return new NukkitConfigAdapter(this, resolveConfig());
}
// initialise datastore
this.storage = storageFactory.getInstance(StorageType.H2);
@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);
}
// initialise messaging
this.messagingService = new MessagingFactory<>(this).getInstance();
@Override
protected MessagingFactory<?> provideMessagingFactory() {
return new MessagingFactory<>(this);
}
// setup the update task buffer
this.updateTaskBuffer = new UpdateTaskBuffer(this);
// load locale
this.localeManager = new SimpleLocaleManager();
this.localeManager.tryLoad(this, new File(getDataFolder(), "lang.yml"));
// register commands
@Override
protected void registerCommands() {
this.commandManager = new NukkitCommandExecutor(this);
PluginCommand main = (PluginCommand) getServer().getPluginCommand("luckperms");
PluginCommand main = (PluginCommand) this.bootstrap.getServer().getPluginCommand("luckperms");
main.setExecutor(this.commandManager);
}
// load internal managers
getLog().info("Loading internal permission managers...");
this.inheritanceHandler = new InheritanceHandler(this);
@Override
protected void setupManagers() {
this.userManager = new StandardUserManager(this);
this.groupManager = new StandardGroupManager(this);
this.trackManager = new StandardTrackManager(this);
this.calculatorFactory = new NukkitCalculatorFactory(this);
this.cachedStateManager = new CachedStateManager();
}
// setup context manager
@Override
protected CalculatorFactory provideCalculatorFactory() {
return new NukkitCalculatorFactory(this);
}
@Override
protected void setupContextManager() {
this.contextManager = new NukkitContextManager(this);
this.contextManager.registerCalculator(new WorldCalculator(this));
this.contextManager.registerStaticCalculator(new LuckPermsCalculator(getConfiguration()));
}
@Override
protected void setupPlatformHooks() {
// inject our own custom permission maps
Runnable[] injectors = new Runnable[]{
new InjectorSubscriptionMap(this),
new InjectorPermissionMap(this),
new InjectorDefaultsMap(this)
new InjectorDefaultsMap(this),
new PermissibleMonitoringInjector(this)
};
for (Runnable injector : injectors) {
@ -221,46 +158,26 @@ public class LPNukkitPlugin extends PluginBase implements LuckPermsPlugin {
// schedule another injection after all plugins have loaded
// the entire pluginmanager instance is replaced by some plugins :(
this.scheduler.asyncLater(injector, 1L);
this.bootstrap.getScheduler().asyncLater(injector, 1L);
}
}
// inject verbose handlers into internal nukkit objects
new PermissibleMonitoringInjector(this).run();
// register with the LP API
this.apiProvider = new LuckPermsApiProvider(this);
// setup event factory
this.eventFactory = new EventFactory(this, this.apiProvider);
ApiRegistrationUtil.registerProvider(this.apiProvider);
getServer().getServiceManager().register(LuckPermsApi.class, this.apiProvider, this, ServicePriority.NORMAL);
// schedule update tasks
int mins = getConfiguration().get(ConfigKeys.SYNC_TIME);
if (mins > 0) {
long ticks = mins * 60 * 20;
this.scheduler.asyncRepeating(() -> this.updateTaskBuffer.request(), ticks);
}
this.scheduler.asyncLater(() -> this.updateTaskBuffer.request(), 40L);
// run an update instantly.
getLog().info("Performing initial data load...");
try {
new UpdateTask(this, true).run();
} catch (Exception e) {
e.printStackTrace();
@Override
protected void registerApiOnPlatform(LuckPermsApi api) {
this.bootstrap.getServer().getServiceManager().register(LuckPermsApi.class, api, this.bootstrap, ServicePriority.NORMAL);
}
@Override
protected void registerHousekeepingTasks() {
this.bootstrap.getScheduler().asyncRepeating(new ExpireTemporaryTask(this), 60L);
this.bootstrap.getScheduler().asyncRepeating(new CacheHousekeepingTask(this), 2400L);
}
// register tasks
this.scheduler.asyncRepeating(new ExpireTemporaryTask(this), 60L);
this.scheduler.asyncRepeating(new CacheHousekeepingTask(this), 2400L);
@Override
protected void performFinalSetup() {
// register permissions
try {
PluginManager pm = getServer().getPluginManager();
PluginManager pm = this.bootstrap.getServer().getPluginManager();
PermissionDefault permDefault = getConfiguration().get(ConfigKeys.COMMANDS_ALLOW_OP) ? PermissionDefault.OP : PermissionDefault.FALSE;
for (CommandPermission p : CommandPermission.values()) {
@ -271,20 +188,20 @@ public class LPNukkitPlugin extends PluginBase implements LuckPermsPlugin {
}
if (!getConfiguration().get(ConfigKeys.OPS_ENABLED)) {
Config ops = getServer().getOps();
Config ops = this.bootstrap.getServer().getOps();
ops.getKeys(false).forEach(ops::remove);
}
// replace the temporary executor when the Nukkit one starts
getServer().getScheduler().scheduleTask(this, () -> this.scheduler.setUseFallback(false), true);
this.bootstrap.getServer().getScheduler().scheduleTask(this.bootstrap, () -> this.bootstrap.getScheduler().setUseFallback(false), true);
// Load any online users (in the case of a reload)
for (Player player : getServer().getOnlinePlayers().values()) {
this.scheduler.doAsync(() -> {
for (Player player : this.bootstrap.getServer().getOnlinePlayers().values()) {
this.bootstrap.getScheduler().doAsync(() -> {
try {
User user = connectionListener.loadUser(player.getUniqueId(), player.getName());
User user = this.connectionListener.loadUser(player.getUniqueId(), player.getName());
if (user != null) {
this.scheduler.doSync(() -> {
this.bootstrap.getScheduler().doSync(() -> {
try {
LPPermissible lpPermissible = new LPPermissible(player, user, this);
PermissibleInjector.inject(player, lpPermissible);
@ -298,20 +215,18 @@ public class LPNukkitPlugin extends PluginBase implements LuckPermsPlugin {
}
});
}
getLog().info("Successfully enabled. (took " + (System.currentTimeMillis() - this.startTime) + "ms)");
}
@Override
public void onDisable() {
protected void performEarlyDisableTasks() {
// Switch back to the fallback executor, the nukkit one won't allow new tasks
this.scheduler.setUseFallback(true);
this.permissionVault.shutdown();
this.verboseHandler.shutdown();
this.bootstrap.getScheduler().setUseFallback(true);
}
@Override
protected void removePlatformHooks() {
// uninject from players
for (Player player : getServer().getOnlinePlayers().values()) {
for (Player player : this.bootstrap.getServer().getOnlinePlayers().values()) {
try {
PermissibleInjector.unInject(player, false);
} catch (Exception e) {
@ -333,29 +248,6 @@ public class LPNukkitPlugin extends PluginBase implements LuckPermsPlugin {
InjectorSubscriptionMap.uninject();
InjectorPermissionMap.uninject();
InjectorDefaultsMap.uninject();
getLog().info("Closing storage...");
this.storage.shutdown();
if (this.fileWatcher != null) {
this.fileWatcher.close();
}
if (this.messagingService != null) {
getLog().info("Closing messaging service...");
this.messagingService.close();
}
ApiRegistrationUtil.unregisterProvider();
getServer().getServiceManager().cancel(this);
getLog().info("Shutting down internal scheduler...");
this.scheduler.shutdown();
// Nukkit will do this again when #onDisable completes, but we do it early to prevent NPEs elsewhere.
getServer().getScheduler().cancelTask(this);
HandlerList.unregisterAll(this);
getLog().info("Goodbye!");
}
public void refreshAutoOp(User user, Player player) {
@ -370,15 +262,69 @@ public class LPNukkitPlugin extends PluginBase implements LuckPermsPlugin {
}
}
private File resolveConfig(String file) {
File configFile = new File(getDataFolder(), file);
private File resolveConfig() {
File configFile = new File(this.bootstrap.getDataFolder(), "config.yml");
if (!configFile.exists()) {
getDataFolder().mkdirs();
saveResource("config.yml", false);
this.bootstrap.getDataFolder().mkdirs();
this.bootstrap.saveResource("config.yml", false);
}
return configFile;
}
return configFile;
@Override
public Optional<Contexts> getContextForUser(User user) {
Player player = this.bootstrap.getPlayer(user.getUuid());
if (player == null) {
return Optional.empty();
}
return Optional.of(this.contextManager.getApplicableContexts(player));
}
@Override
public Stream<Sender> getOnlineSenders() {
return Stream.concat(
Stream.of(getConsoleSender()),
this.bootstrap.getServer().getOnlinePlayers().values().stream().map(p -> getSenderFactory().wrap(p))
);
}
@Override
public Sender getConsoleSender() {
return getSenderFactory().wrap(this.bootstrap.getServer().getConsoleSender());
}
public NukkitSenderFactory getSenderFactory() {
return this.senderFactory;
}
@Override
public ConnectionListener getConnectionListener() {
return this.connectionListener;
}
@Override
public NukkitCommandExecutor getCommandManager() {
return this.commandManager;
}
@Override
public StandardUserManager getUserManager() {
return this.userManager;
}
@Override
public StandardGroupManager getGroupManager() {
return this.groupManager;
}
@Override
public StandardTrackManager getTrackManager() {
return this.trackManager;
}
@Override
public ContextManager<Player> getContextManager() {
return this.contextManager;
}
public LPSubscriptionMap getSubscriptionMap() {
@ -405,227 +351,4 @@ public class LPNukkitPlugin extends PluginBase implements LuckPermsPlugin {
this.defaultPermissionMap = defaultPermissionMap;
}
@Override
public Optional<InternalMessagingService> getMessagingService() {
return Optional.ofNullable(this.messagingService);
}
@Override
public void setMessagingService(InternalMessagingService messagingService) {
if (this.messagingService == null) {
this.messagingService = messagingService;
}
}
@Override
public Optional<FileWatcher> getFileWatcher() {
return Optional.ofNullable(this.fileWatcher);
}
@Override
public String getVersion() {
return getDescription().getVersion();
}
@Override
public PlatformType getServerType() {
return PlatformType.NUKKIT;
}
@Override
public String getServerBrand() {
return getServer().getName();
}
@Override
public String getServerVersion() {
return getServer().getVersion() + " - " + getServer().getNukkitVersion();
}
@Override
public String getServerName() {
return getServer().getServerUniqueId().toString();
}
@Override
public File getDataDirectory() {
return super.getDataFolder();
}
@Override
public InputStream getResourceStream(String path) {
return getResource(path);
}
@Override
public Player getPlayer(User user) {
return getServer().getOnlinePlayers().get(user.getUuid());
}
@Override
public Optional<UUID> lookupUuid(String username) {
return Optional.empty();
}
@Override
public Optional<Contexts> getContextForUser(User user) {
Player player = getPlayer(user);
if (player == null) {
return Optional.empty();
}
return Optional.of(this.contextManager.getApplicableContexts(player));
}
@Override
public int getPlayerCount() {
return getServer().getOnlinePlayers().size();
}
@Override
public Stream<String> getPlayerList() {
return getServer().getOnlinePlayers().values().stream().map(Player::getName);
}
@Override
public Stream<UUID> getOnlinePlayers() {
return getServer().getOnlinePlayers().values().stream().map(Player::getUniqueId);
}
@Override
public boolean isPlayerOnline(UUID external) {
Player player = getServer().getOnlinePlayers().get(external);
return player != null && player.isOnline();
}
@Override
public Stream<Sender> getOnlineSenders() {
return Stream.concat(
Stream.of(getConsoleSender()),
getServer().getOnlinePlayers().values().stream().map(p -> getSenderFactory().wrap(p))
);
}
@Override
public Sender getConsoleSender() {
return getSenderFactory().wrap(getServer().getConsoleSender());
}
@Override
public long getStartTime() {
return this.startTime;
}
@Override
public NukkitSchedulerAdapter getScheduler() {
return this.scheduler;
}
@Override
public NukkitCommandExecutor getCommandManager() {
return this.commandManager;
}
@Override
public LuckPermsConfiguration getConfiguration() {
return this.configuration;
}
@Override
public StandardUserManager getUserManager() {
return this.userManager;
}
@Override
public StandardGroupManager getGroupManager() {
return this.groupManager;
}
@Override
public StandardTrackManager getTrackManager() {
return this.trackManager;
}
@Override
public Storage getStorage() {
return this.storage;
}
@Override
public LuckPermsApiProvider getApiProvider() {
return this.apiProvider;
}
@Override
public EventFactory getEventFactory() {
return this.eventFactory;
}
@Override
public Logger getLog() {
return this.log;
}
@Override
public LocaleManager getLocaleManager() {
return this.localeManager;
}
@Override
public PluginClassLoader getPluginClassLoader() {
return this.pluginClassLoader;
}
@Override
public DependencyManager getDependencyManager() {
return this.dependencyManager;
}
@Override
public CachedStateManager getCachedStateManager() {
return this.cachedStateManager;
}
@Override
public ContextManager<Player> getContextManager() {
return this.contextManager;
}
@Override
public InheritanceHandler getInheritanceHandler() {
return this.inheritanceHandler;
}
@Override
public CalculatorFactory getCalculatorFactory() {
return this.calculatorFactory;
}
@Override
public BufferedRequest<Void> getUpdateTaskBuffer() {
return this.updateTaskBuffer;
}
@Override
public VerboseHandler getVerboseHandler() {
return this.verboseHandler;
}
public NukkitSenderFactory getSenderFactory() {
return this.senderFactory;
}
@Override
public PermissionVault getPermissionVault() {
return this.permissionVault;
}
@Override
public LogDispatcher getLogDispatcher() {
return this.logDispatcher;
}
@Override
public Set<UUID> getUniqueConnections() {
return this.uniqueConnections;
}
}

View File

@ -45,7 +45,7 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
public class NukkitSchedulerAdapter implements SchedulerAdapter {
private final LPNukkitPlugin plugin;
private final LPNukkitBootstrap bootstrap;
private final ExecutorService asyncFallback;
private final Executor asyncNukkit;
@ -56,8 +56,8 @@ public class NukkitSchedulerAdapter implements SchedulerAdapter {
private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet();
public NukkitSchedulerAdapter(LPNukkitPlugin plugin) {
this.plugin = plugin;
public NukkitSchedulerAdapter(LPNukkitBootstrap bootstrap) {
this.bootstrap = bootstrap;
this.sync = new SyncExecutor();
this.asyncFallback = new FallbackAsyncExecutor();
@ -66,7 +66,7 @@ public class NukkitSchedulerAdapter implements SchedulerAdapter {
}
private ServerScheduler scheduler() {
return this.plugin.getServer().getScheduler();
return this.bootstrap.getServer().getScheduler();
}
@Override
@ -81,26 +81,26 @@ public class NukkitSchedulerAdapter implements SchedulerAdapter {
@Override
public SchedulerTask asyncRepeating(Runnable runnable, long intervalTicks) {
SchedulerTask task = new NukkitSchedulerTask(scheduler().scheduleDelayedRepeatingTask(this.plugin, runnable, (int) intervalTicks, (int) intervalTicks, true));
SchedulerTask task = new NukkitSchedulerTask(scheduler().scheduleDelayedRepeatingTask(this.bootstrap, runnable, (int) intervalTicks, (int) intervalTicks, true));
this.tasks.add(task);
return task;
}
@Override
public SchedulerTask syncRepeating(Runnable runnable, long intervalTicks) {
SchedulerTask task = new NukkitSchedulerTask(scheduler().scheduleDelayedRepeatingTask(this.plugin, runnable, (int) intervalTicks, (int) intervalTicks, false));
SchedulerTask task = new NukkitSchedulerTask(scheduler().scheduleDelayedRepeatingTask(this.bootstrap, runnable, (int) intervalTicks, (int) intervalTicks, false));
this.tasks.add(task);
return task;
}
@Override
public SchedulerTask asyncLater(Runnable runnable, long delayTicks) {
return new NukkitSchedulerTask(scheduler().scheduleDelayedTask(this.plugin, runnable, (int) delayTicks, true));
return new NukkitSchedulerTask(scheduler().scheduleDelayedTask(this.bootstrap, runnable, (int) delayTicks, true));
}
@Override
public SchedulerTask syncLater(Runnable runnable, long delayTicks) {
return new NukkitSchedulerTask(scheduler().scheduleDelayedTask(this.plugin, runnable, (int) delayTicks, false));
return new NukkitSchedulerTask(scheduler().scheduleDelayedTask(this.bootstrap, runnable, (int) delayTicks, false));
}
@Override
@ -142,14 +142,14 @@ public class NukkitSchedulerAdapter implements SchedulerAdapter {
private final class SyncExecutor implements Executor {
@Override
public void execute(@Nonnull Runnable runnable) {
NukkitSchedulerAdapter.this.plugin.getServer().getScheduler().scheduleTask(NukkitSchedulerAdapter.this.plugin, runnable, false);
NukkitSchedulerAdapter.this.bootstrap.getServer().getScheduler().scheduleTask(NukkitSchedulerAdapter.this.bootstrap, runnable, false);
}
}
private final class AsyncExecutor implements Executor {
@Override
public void execute(@Nonnull Runnable runnable) {
if (NukkitSchedulerAdapter.this.useFallback || !NukkitSchedulerAdapter.this.plugin.isEnabled()) {
if (NukkitSchedulerAdapter.this.useFallback || !NukkitSchedulerAdapter.this.bootstrap.isEnabled()) {
NukkitSchedulerAdapter.this.asyncFallback.execute(runnable);
} else {
NukkitSchedulerAdapter.this.asyncNukkit.execute(runnable);
@ -160,7 +160,7 @@ public class NukkitSchedulerAdapter implements SchedulerAdapter {
private final class NukkitAsyncExecutor implements Executor {
@Override
public void execute(@Nonnull Runnable runnable) {
NukkitSchedulerAdapter.this.plugin.getServer().getScheduler().scheduleTask(NukkitSchedulerAdapter.this.plugin, runnable, true);
NukkitSchedulerAdapter.this.bootstrap.getServer().getScheduler().scheduleTask(NukkitSchedulerAdapter.this.bootstrap, runnable, true);
}
}

View File

@ -69,7 +69,7 @@ public class NukkitSenderFactory extends SenderFactory<CommandSender> {
}
// otherwise, send the message sync
getPlugin().getScheduler().doSync(new SyncMessengerAgent(sender, s));
getPlugin().getBootstrap().getScheduler().doSync(new SyncMessengerAgent(sender, s));
}
@Override

View File

@ -26,9 +26,9 @@
package me.lucko.luckperms.nukkit.listeners;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.listener.AbstractConnectionListener;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.utils.AbstractLoginListener;
import me.lucko.luckperms.nukkit.LPNukkitPlugin;
import me.lucko.luckperms.nukkit.model.permissible.LPPermissible;
import me.lucko.luckperms.nukkit.model.permissible.PermissibleInjector;
@ -46,7 +46,7 @@ import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public class NukkitConnectionListener extends AbstractLoginListener implements Listener {
public class NukkitConnectionListener extends AbstractConnectionListener implements Listener {
private final LPNukkitPlugin plugin;
private final Set<UUID> deniedAsyncLogin = Collections.synchronizedSet(new HashSet<>());
@ -63,10 +63,10 @@ public class NukkitConnectionListener extends AbstractLoginListener implements L
Listening on LOW priority to allow plugins to modify username / UUID data here. (auth plugins) */
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
this.plugin.getLog().info("Processing pre-login for " + e.getUuid() + " - " + e.getName());
this.plugin.getLogger().info("Processing pre-login for " + e.getUuid() + " - " + e.getName());
}
this.plugin.getUniqueConnections().add(e.getUuid());
recordConnection(e.getUuid());
/* Actually process the login for the connection.
We do this here to delay the login until the data is ready.
@ -81,7 +81,7 @@ public class NukkitConnectionListener extends AbstractLoginListener implements L
User user = loadUser(e.getUuid(), e.getName());
this.plugin.getEventFactory().handleUserLoginProcess(e.getUuid(), e.getName(), user);
} catch (Exception ex) {
this.plugin.getLog().severe("Exception occurred whilst loading data for " + e.getUuid() + " - " + e.getName());
this.plugin.getLogger().severe("Exception occurred whilst loading data for " + e.getUuid() + " - " + e.getName());
ex.printStackTrace();
// deny the connection
@ -101,7 +101,7 @@ public class NukkitConnectionListener extends AbstractLoginListener implements L
// This is a problem, as they were denied at low priority, but are now being allowed.
if (e.getLoginResult() == PlayerAsyncPreLoginEvent.LoginResult.SUCCESS) {
this.plugin.getLog().severe("Player connection was re-allowed for " + e.getUuid());
this.plugin.getLogger().severe("Player connection was re-allowed for " + e.getUuid());
e.disAllow("");
}
}
@ -115,7 +115,7 @@ public class NukkitConnectionListener extends AbstractLoginListener implements L
final Player player = e.getPlayer();
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
this.plugin.getLog().info("Processing login for " + player.getUniqueId() + " - " + player.getName());
this.plugin.getLogger().info("Processing login for " + player.getUniqueId() + " - " + player.getName());
}
final User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId());
@ -124,7 +124,7 @@ public class NukkitConnectionListener extends AbstractLoginListener implements L
if (user == null) {
this.deniedLogin.add(e.getPlayer().getUniqueId());
this.plugin.getLog().warn("User " + player.getUniqueId() + " - " + player.getName() + " doesn't have data pre-loaded. - denying login.");
this.plugin.getLogger().warn("User " + player.getUniqueId() + " - " + player.getName() + " doesn't have data pre-loaded. - denying login.");
e.setCancelled();
e.setKickMessage(Message.LOADING_ERROR.asString(this.plugin.getLocaleManager()));
return;
@ -158,7 +158,7 @@ public class NukkitConnectionListener extends AbstractLoginListener implements L
// This is a problem, as they were denied at low priority, but are now being allowed.
if (!e.isCancelled()) {
this.plugin.getLog().severe("Player connection was re-allowed for " + e.getPlayer().getUniqueId());
this.plugin.getLogger().severe("Player connection was re-allowed for " + e.getPlayer().getUniqueId());
e.setCancelled();
}
}
@ -194,7 +194,7 @@ public class NukkitConnectionListener extends AbstractLoginListener implements L
this.plugin.getUserManager().getHouseKeeper().registerUsage(player.getUniqueId());
// force a clear of transient nodes
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId());
if (user != null) {
user.clearTransientNodes();

View File

@ -306,7 +306,7 @@ public class LPPermissionAttachment extends PermissionAttachment {
@Override
public Plugin getPlugin() {
return this.owner != null ? this.owner : this.permissible.getPlugin();
return this.owner != null ? this.owner : this.permissible.getPlugin().getBootstrap();
}
@Override

View File

@ -66,7 +66,7 @@ public class PermissibleMonitoringInjector implements Runnable {
}
private void injectConsole() throws Exception {
ConsoleCommandSender consoleSender = this.plugin.getServer().getConsoleSender();
ConsoleCommandSender consoleSender = this.plugin.getBootstrap().getServer().getConsoleSender();
// get the perm field
Field permField = ConsoleCommandSender.class.getDeclaredField("perm");

View File

@ -79,7 +79,7 @@ public class InjectorDefaultsMap implements Runnable {
this.plugin.setDefaultPermissionMap(ret);
}
} catch (Exception e) {
this.plugin.getLog().severe("Exception occurred whilst injecting LuckPerms Default Permission map.");
this.plugin.getLogger().severe("Exception occurred whilst injecting LuckPerms Default Permission map.");
e.printStackTrace();
}
}
@ -88,7 +88,7 @@ public class InjectorDefaultsMap implements Runnable {
Objects.requireNonNull(OP_DEFAULT_PERMISSIONS_FIELD, "OP_DEFAULT_PERMISSIONS_FIELD");
Objects.requireNonNull(NON_OP_DEFAULT_PERMISSIONS_FIELD, "NON_OP_DEFAULT_PERMISSIONS_FIELD");
PluginManager pluginManager = this.plugin.getServer().getPluginManager();
PluginManager pluginManager = this.plugin.getBootstrap().getServer().getPluginManager();
Object opMap = OP_DEFAULT_PERMISSIONS_FIELD.get(pluginManager);
Object nonOpMap = NON_OP_DEFAULT_PERMISSIONS_FIELD.get(pluginManager);

View File

@ -67,14 +67,14 @@ public class InjectorPermissionMap implements Runnable {
this.plugin.setPermissionMap(ret);
}
} catch (Exception e) {
this.plugin.getLog().severe("Exception occurred whilst injecting LuckPerms Permission map.");
this.plugin.getLogger().severe("Exception occurred whilst injecting LuckPerms Permission map.");
e.printStackTrace();
}
}
private LPPermissionMap inject() throws Exception {
Objects.requireNonNull(PERMISSIONS_FIELD, "PERMISSIONS_FIELD");
PluginManager pluginManager = this.plugin.getServer().getPluginManager();
PluginManager pluginManager = this.plugin.getBootstrap().getServer().getPluginManager();
Object map = PERMISSIONS_FIELD.get(pluginManager);
if (map instanceof LPPermissionMap && ((LPPermissionMap) map).plugin == this.plugin) {

View File

@ -67,14 +67,14 @@ public class InjectorSubscriptionMap implements Runnable {
this.plugin.setSubscriptionMap(ret);
}
} catch (Exception e) {
this.plugin.getLog().severe("Exception occurred whilst injecting LuckPerms Permission Subscription map.");
this.plugin.getLogger().severe("Exception occurred whilst injecting LuckPerms Permission Subscription map.");
e.printStackTrace();
}
}
private LPSubscriptionMap inject() throws Exception {
Objects.requireNonNull(PERM_SUBS_FIELD, "PERM_SUBS_FIELD");
PluginManager pluginManager = this.plugin.getServer().getPluginManager();
PluginManager pluginManager = this.plugin.getBootstrap().getServer().getPluginManager();
Object map = PERM_SUBS_FIELD.get(pluginManager);
if (map instanceof LPSubscriptionMap) {

View File

@ -169,7 +169,7 @@ public final class LPSubscriptionMap extends HashMap<String, Set<Permissible>> {
private Sets.SetView<Permissible> getContentView() {
// gather players (LPPermissibles)
Set<Permissible> players = LPSubscriptionMap.this.plugin.getServer().getOnlinePlayers().values().stream()
Set<Permissible> players = LPSubscriptionMap.this.plugin.getBootstrap().getServer().getOnlinePlayers().values().stream()
.filter(player -> player.isPermissionSet(this.permission))
.collect(Collectors.toSet());

View File

@ -5,7 +5,7 @@ description: A permissions plugin
author: Luck
website: https://github.com/lucko/LuckPerms
main: me.lucko.luckperms.nukkit.LPNukkitPlugin
main: me.lucko.luckperms.nukkit.LPNukkitBootstrap
load: STARTUP
commands:

View File

@ -158,7 +158,7 @@ public final class SubjectProxy implements Subject, ProxiedSubject {
@Nonnull
@Override
public Set<Context> getActiveContexts() {
return CompatibilityUtil.convertContexts(this.service.getPlugin().getContextManager().getApplicableContext(this));
return CompatibilityUtil.convertContexts(this.service.getContextManager().getApplicableContext(this));
}
@Override

View File

@ -159,7 +159,7 @@ public final class SubjectProxy implements Subject, ProxiedSubject {
@Nonnull
@Override
public Set<Context> getActiveContexts() {
return CompatibilityUtil.convertContexts(this.service.getPlugin().getContextManager().getApplicableContext(this));
return CompatibilityUtil.convertContexts(this.service.getContextManager().getApplicableContext(this));
}
@Override

View File

@ -29,6 +29,8 @@ import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
@ -47,7 +49,9 @@ import java.util.function.Predicate;
*/
public interface LPPermissionService {
LuckPermsSpongePlugin getPlugin();
LuckPermsPlugin getPlugin();
ContextManager<Subject> getContextManager();
SubjectReferenceFactory getReferenceFactory();

View File

@ -0,0 +1,298 @@
/*
* 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.sponge;
import com.google.inject.Inject;
import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader;
import me.lucko.luckperms.common.dependencies.classloader.ReflectionClassLoader;
import me.lucko.luckperms.common.plugin.SchedulerAdapter;
import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap;
import me.lucko.luckperms.sponge.utils.VersionData;
import org.slf4j.Logger;
import org.spongepowered.api.Game;
import org.spongepowered.api.Platform;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.config.ConfigDir;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order;
import org.spongepowered.api.event.game.state.GamePreInitializationEvent;
import org.spongepowered.api.event.game.state.GameStoppingServerEvent;
import org.spongepowered.api.plugin.Plugin;
import org.spongepowered.api.plugin.PluginContainer;
import org.spongepowered.api.scheduler.AsynchronousExecutor;
import org.spongepowered.api.scheduler.Scheduler;
import org.spongepowered.api.scheduler.SpongeExecutorService;
import org.spongepowered.api.scheduler.SynchronousExecutor;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Stream;
import javax.annotation.Nullable;
/**
* Bootstrap plugin for LuckPerms running on Sponge.
*/
@Plugin(
id = "luckperms",
name = "LuckPerms",
version = VersionData.VERSION,
authors = "Luck",
description = "A permissions plugin",
url = "https://github.com/lucko/LuckPerms"
)
public class LPSpongeBootstrap implements LuckPermsBootstrap {
/**
* A scheduler adapter for the platform
*/
private final SchedulerAdapter schedulerAdapter;
/**
* The plugin classloader
*/
private final PluginClassLoader classLoader;
/**
* The plugin instance
*/
private final LPSpongePlugin plugin;
/**
* The time when the plugin was enabled
*/
private long startTime;
// load/enable latches
private final CountDownLatch loadLatch = new CountDownLatch(1);
private final CountDownLatch enableLatch = new CountDownLatch(1);
/**
* Injected plugin logger
*/
@Inject
private Logger logger;
/**
* Reference to the central {@link Game} instance in the API
*/
@Inject
private Game game;
/**
* Reference to the sponge scheduler
*/
private final Scheduler spongeScheduler;
/**
* Injected configuration directory for the plugin
*/
@Inject
@ConfigDir(sharedRoot = false)
private Path configDirectory;
/**
* Injected plugin container for the plugin
*/
@Inject
private PluginContainer pluginContainer;
@Inject
public LPSpongeBootstrap(@SynchronousExecutor SpongeExecutorService syncExecutor, @AsynchronousExecutor SpongeExecutorService asyncExecutor) {
this.spongeScheduler = Sponge.getScheduler();
this.schedulerAdapter = new SpongeSchedulerAdapter(this, this.spongeScheduler, syncExecutor, asyncExecutor);
this.classLoader = new ReflectionClassLoader(this);
this.plugin = new LPSpongePlugin(this);
}
// provide adapters
@Override
public SchedulerAdapter getScheduler() {
return this.schedulerAdapter;
}
@Override
public PluginClassLoader getPluginClassLoader() {
return this.classLoader;
}
// lifecycle
@Listener(order = Order.FIRST)
public void onEnable(GamePreInitializationEvent event) {
this.startTime = System.currentTimeMillis();
try {
this.plugin.load();
} finally {
this.loadLatch.countDown();
}
try {
this.plugin.enable();
} finally {
this.enableLatch.countDown();
}
}
@Listener(order = Order.LATE)
public void onLateEnable(GamePreInitializationEvent event) {
this.plugin.lateEnable();
}
@Listener
public void onDisable(GameStoppingServerEvent event) {
this.plugin.disable();
}
@Override
public CountDownLatch getEnableLatch() {
return this.enableLatch;
}
@Override
public CountDownLatch getLoadLatch() {
return this.loadLatch;
}
// getters for the injected sponge instances
public Logger getLogger() {
return this.logger;
}
public Game getGame() {
return this.game;
}
public Scheduler getSpongeScheduler() {
return this.spongeScheduler;
}
public Path getConfigPath() {
return this.configDirectory;
}
public PluginContainer getPluginContainer() {
return this.pluginContainer;
}
// provide information about the plugin
@Override
public String getVersion() {
return VersionData.VERSION;
}
@Override
public long getStartupTime() {
return this.startTime;
}
// provide information about the platform
@Override
public PlatformType getType() {
return PlatformType.SPONGE;
}
@Override
public String getServerBrand() {
return getGame().getPlatform().getContainer(Platform.Component.IMPLEMENTATION).getName();
}
@Override
public String getServerVersion() {
return getGame().getPlatform().getContainer(Platform.Component.API).getName() + ": " +
getGame().getPlatform().getContainer(Platform.Component.API).getVersion().orElse("null") + " - " +
getGame().getPlatform().getContainer(Platform.Component.IMPLEMENTATION).getName() + ": " +
getGame().getPlatform().getContainer(Platform.Component.IMPLEMENTATION).getVersion().orElse("null");
}
@Override
public File getDataDirectory() {
File serverRoot = getConfigPath().toFile().getParentFile().getParentFile();
File dataDirectory = new File(serverRoot, "luckperms");
dataDirectory.mkdirs();
return dataDirectory;
}
@Override
public InputStream getResourceStream(String path) {
return getClass().getClassLoader().getResourceAsStream(path);
}
@Nullable
@Override
public Player getPlayer(UUID uuid) {
if (!getGame().isServerAvailable()) {
return null;
}
return getGame().getServer().getPlayer(uuid).orElse(null);
}
@Override
public Optional<UUID> lookupUuid(String username) {
if (!getGame().isServerAvailable()) {
return Optional.empty();
}
return getGame().getServer().getGameProfileManager().get(username)
.thenApply(p -> Optional.of(p.getUniqueId()))
.exceptionally(x -> Optional.empty())
.join();
}
@Override
public int getPlayerCount() {
return getGame().isServerAvailable() ? getGame().getServer().getOnlinePlayers().size() : 0;
}
@Override
public Stream<String> getPlayerList() {
return getGame().isServerAvailable() ? getGame().getServer().getOnlinePlayers().stream().map(Player::getName) : Stream.empty();
}
@Override
public Stream<UUID> getOnlinePlayers() {
return getGame().isServerAvailable() ? getGame().getServer().getOnlinePlayers().stream().map(Player::getUniqueId) : Stream.empty();
}
@Override
public boolean isPlayerOnline(UUID uuid) {
return getGame().isServerAvailable() ? getGame().getServer().getPlayer(uuid).map(Player::isOnline).orElse(false) : false;
}
}

View File

@ -25,50 +25,22 @@
package me.lucko.luckperms.sponge;
import com.google.inject.Inject;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiRegistrationUtil;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.buffers.UpdateTaskBuffer;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.CommandPermission;
import me.lucko.luckperms.common.commands.abstraction.Command;
import me.lucko.luckperms.common.commands.sender.DummySender;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.AbstractConfiguration;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.contexts.LuckPermsCalculator;
import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.dependencies.DependencyRegistry;
import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader;
import me.lucko.luckperms.common.dependencies.classloader.ReflectionClassLoader;
import me.lucko.luckperms.common.event.EventFactory;
import me.lucko.luckperms.common.inheritance.InheritanceHandler;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.NoopLocaleManager;
import me.lucko.luckperms.common.locale.SimpleLocaleManager;
import me.lucko.luckperms.common.logging.SenderLogger;
import me.lucko.luckperms.common.managers.track.StandardTrackManager;
import me.lucko.luckperms.common.messaging.InternalMessagingService;
import me.lucko.luckperms.common.messaging.MessagingFactory;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.SchedulerAdapter;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.storage.StorageFactory;
import me.lucko.luckperms.common.storage.StorageType;
import me.lucko.luckperms.common.storage.dao.file.FileWatcher;
import me.lucko.luckperms.common.plugin.AbstractLuckPermsPlugin;
import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
import me.lucko.luckperms.common.tasks.UpdateTask;
import me.lucko.luckperms.common.treeview.PermissionVault;
import me.lucko.luckperms.common.verbose.VerboseHandler;
import me.lucko.luckperms.sponge.calculators.SpongeCalculatorFactory;
import me.lucko.luckperms.sponge.commands.SpongeMainCommand;
import me.lucko.luckperms.sponge.contexts.SpongeContextManager;
@ -83,33 +55,13 @@ import me.lucko.luckperms.sponge.service.event.UpdateEventHandler;
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
import me.lucko.luckperms.sponge.service.model.LPSubject;
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
import me.lucko.luckperms.sponge.service.model.LuckPermsSpongePlugin;
import me.lucko.luckperms.sponge.service.persisted.PersistedCollection;
import me.lucko.luckperms.sponge.tasks.ServiceCacheHousekeepingTask;
import me.lucko.luckperms.sponge.utils.VersionData;
import org.slf4j.Logger;
import org.spongepowered.api.Game;
import org.spongepowered.api.Platform;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandManager;
import org.spongepowered.api.config.ConfigDir;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order;
import org.spongepowered.api.event.game.state.GamePreInitializationEvent;
import org.spongepowered.api.event.game.state.GameStoppingServerEvent;
import org.spongepowered.api.plugin.Plugin;
import org.spongepowered.api.plugin.PluginContainer;
import org.spongepowered.api.profile.GameProfile;
import org.spongepowered.api.scheduler.AsynchronousExecutor;
import org.spongepowered.api.scheduler.Scheduler;
import org.spongepowered.api.scheduler.SpongeExecutorService;
import org.spongepowered.api.scheduler.SynchronousExecutor;
import org.spongepowered.api.service.permission.PermissionService;
import org.spongepowered.api.service.permission.Subject;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
@ -117,233 +69,127 @@ import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.stream.Stream;
/**
* LuckPerms implementation for the Sponge API.
*/
@Plugin(
id = "luckperms",
name = "LuckPerms",
version = VersionData.VERSION,
authors = "Luck",
description = "A permissions plugin",
url = "https://github.com/lucko/LuckPerms"
)
public class LPSpongePlugin implements LuckPermsSpongePlugin {
public class LPSpongePlugin extends AbstractLuckPermsPlugin {
private final LPSpongeBootstrap bootstrap;
@Inject
private Logger logger;
@Inject
private Game game;
@Inject
@ConfigDir(sharedRoot = false)
private Path configDirectory;
private Scheduler spongeScheduler = Sponge.getScheduler();
@Inject
@SynchronousExecutor
private SpongeExecutorService syncExecutorService;
@Inject
@AsynchronousExecutor
private SpongeExecutorService asyncExecutorService;
@Inject
private PluginContainer pluginContainer;
private boolean lateLoad = false;
private long startTime;
private SchedulerAdapter scheduler;
private SpongeSenderFactory senderFactory;
private SpongeConnectionListener connectionListener;
private SpongeCommandExecutor commandManager;
private LuckPermsConfiguration configuration;
private SpongeUserManager userManager;
private SpongeGroupManager groupManager;
private StandardTrackManager trackManager;
private Storage storage;
private FileWatcher fileWatcher = null;
private InternalMessagingService messagingService = null;
private LuckPermsApiProvider apiProvider;
private EventFactory eventFactory;
private UpdateEventHandler updateEventHandler;
private me.lucko.luckperms.common.logging.Logger log;
private LuckPermsService service;
private LocaleManager localeManager;
private PluginClassLoader pluginClassLoader;
private DependencyManager dependencyManager;
private InheritanceHandler inheritanceHandler;
private CachedStateManager cachedStateManager;
private ContextManager<Subject> contextManager;
private CalculatorFactory calculatorFactory;
private BufferedRequest<Void> updateTaskBuffer;
private VerboseHandler verboseHandler;
private SpongeSenderFactory senderFactory;
private PermissionVault permissionVault;
private LogDispatcher logDispatcher;
private Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
private LuckPermsService service;
private UpdateEventHandler updateEventHandler;
@Listener(order = Order.FIRST)
public void onEnable(GamePreInitializationEvent event) {
this.startTime = System.currentTimeMillis();
this.scheduler = new SpongeSchedulerAdapter(this);
this.localeManager = new NoopLocaleManager();
this.senderFactory = new SpongeSenderFactory(this);
this.log = new SenderLogger(this, getConsoleSender());
this.pluginClassLoader = new ReflectionClassLoader(this);
this.dependencyManager = new DependencyManager(this);
this.dependencyManager.loadDependencies(DependencyRegistry.GLOBAL_DEPENDENCIES);
private boolean lateLoad = false;
sendStartupBanner(getConsoleSender());
this.verboseHandler = new VerboseHandler(this.scheduler.async());
this.permissionVault = new PermissionVault(this.scheduler.async());
this.logDispatcher = new LogDispatcher(this);
getLog().info("Loading configuration...");
this.configuration = new AbstractConfiguration(this, new SpongeConfigAdapter(this, resolveConfig("luckperms.conf")));
this.configuration.loadAll();
StorageFactory storageFactory = new StorageFactory(this);
Set<StorageType> storageTypes = storageFactory.getRequiredTypes(StorageType.H2);
this.dependencyManager.loadStorageDependencies(storageTypes);
// register events
this.game.getEventManager().registerListeners(this, new SpongeConnectionListener(this));
this.game.getEventManager().registerListeners(this, new SpongePlatformListener(this));
if (getConfiguration().get(ConfigKeys.WATCH_FILES)) {
this.fileWatcher = new FileWatcher(this);
getScheduler().asyncRepeating(this.fileWatcher, 30L);
public LPSpongePlugin(LPSpongeBootstrap bootstrap) {
this.bootstrap = bootstrap;
}
// initialise datastore
this.storage = storageFactory.getInstance(StorageType.H2);
@Override
public LPSpongeBootstrap getBootstrap() {
return this.bootstrap;
}
// initialise messaging
this.messagingService = new SpongeMessagingFactory(this).getInstance();
@Override
protected void setupSenderFactory() {
this.senderFactory = new SpongeSenderFactory(this);
}
// setup the update task buffer
this.updateTaskBuffer = new UpdateTaskBuffer(this);
@Override
protected ConfigurationAdapter provideConfigurationAdapter() {
return new SpongeConfigAdapter(this, resolveConfig());
}
// load locale
this.localeManager = new SimpleLocaleManager();
this.localeManager.tryLoad(this, new File(getDataDirectory(), "lang.yml"));
@Override
protected void registerPlatformListeners() {
this.connectionListener = new SpongeConnectionListener(this);
this.bootstrap.getGame().getEventManager().registerListeners(this, this.connectionListener);
this.bootstrap.getGame().getEventManager().registerListeners(this, new SpongePlatformListener(this));
}
// register commands
CommandManager cmdService = this.game.getCommandManager();
@Override
protected MessagingFactory<?> provideMessagingFactory() {
return new SpongeMessagingFactory(this);
}
@Override
protected void registerCommands() {
this.commandManager = new SpongeCommandExecutor(this);
cmdService.register(this, this.commandManager, "luckperms", "lp", "perm", "perms", "permission", "permissions");
this.bootstrap.getGame().getCommandManager().register(this, this.commandManager, "luckperms", "lp", "perm", "perms", "permission", "permissions");
}
// load internal managers
getLog().info("Loading internal permission managers...");
this.inheritanceHandler = new InheritanceHandler(this);
@Override
protected void setupManagers() {
this.userManager = new SpongeUserManager(this);
this.groupManager = new SpongeGroupManager(this);
this.trackManager = new StandardTrackManager(this);
this.calculatorFactory = new SpongeCalculatorFactory(this);
this.cachedStateManager = new CachedStateManager();
}
// setup context manager
@Override
protected CalculatorFactory provideCalculatorFactory() {
return new SpongeCalculatorFactory(this);
}
@Override
protected void setupContextManager() {
this.contextManager = new SpongeContextManager(this);
this.contextManager.registerCalculator(new WorldCalculator(this));
this.contextManager.registerStaticCalculator(new LuckPermsCalculator(getConfiguration()));
}
// register the PermissionService with Sponge
getLog().info("Registering PermissionService...");
@Override
protected void setupPlatformHooks() {
getLogger().info("Registering PermissionService...");
this.updateEventHandler = UpdateEventHandler.obtain(this);
this.service = new LuckPermsService(this);
if (this.game.getPluginManager().getPlugin("permissionsex").isPresent()) {
getLog().warn("Detected PermissionsEx - assuming it's loaded for migration.");
getLog().warn("Delaying LuckPerms PermissionService registration.");
if (this.bootstrap.getGame().getPluginManager().getPlugin("permissionsex").isPresent()) {
getLogger().warn("Detected PermissionsEx - assuming it's loaded for migration.");
getLogger().warn("Delaying LuckPerms PermissionService registration.");
this.lateLoad = true;
} else {
this.game.getServiceManager().setProvider(this, LPPermissionService.class, this.service);
this.game.getServiceManager().setProvider(this, PermissionService.class, this.service.sponge());
this.game.getServiceManager().setProvider(this, LuckPermsService.class, this.service);
this.bootstrap.getGame().getServiceManager().setProvider(this, LPPermissionService.class, this.service);
this.bootstrap.getGame().getServiceManager().setProvider(this, PermissionService.class, this.service.sponge());
this.bootstrap.getGame().getServiceManager().setProvider(this, LuckPermsService.class, this.service);
}
}
// register with the LP API
this.apiProvider = new LuckPermsApiProvider(this);
// setup event factory
this.eventFactory = new EventFactory(this, this.apiProvider);
ApiRegistrationUtil.registerProvider(this.apiProvider);
this.game.getServiceManager().setProvider(this, LuckPermsApi.class, this.apiProvider);
// schedule update tasks
int mins = getConfiguration().get(ConfigKeys.SYNC_TIME);
if (mins > 0) {
long ticks = mins * 60 * 20;
this.scheduler.asyncRepeating(() -> this.updateTaskBuffer.request(), ticks);
}
this.scheduler.asyncLater(() -> this.updateTaskBuffer.request(), 40L);
// run an update instantly.
getLog().info("Performing initial data load...");
try {
new UpdateTask(this, true).run();
} catch (Exception e) {
e.printStackTrace();
@Override
protected void registerApiOnPlatform(LuckPermsApi api) {
this.bootstrap.getGame().getServiceManager().setProvider(this, LuckPermsApi.class, api);
}
// register tasks
this.scheduler.asyncRepeating(new ExpireTemporaryTask(this), 60L);
this.scheduler.asyncRepeating(new CacheHousekeepingTask(this), 2400L);
this.scheduler.asyncRepeating(new ServiceCacheHousekeepingTask(this.service), 2400L);
@Override
protected void registerHousekeepingTasks() {
this.bootstrap.getScheduler().asyncRepeating(new ExpireTemporaryTask(this), 60L);
this.bootstrap.getScheduler().asyncRepeating(new CacheHousekeepingTask(this), 2400L);
this.bootstrap.getScheduler().asyncRepeating(new ServiceCacheHousekeepingTask(this.service), 2400L);
}
@Override
protected void performFinalSetup() {
// register permissions
for (CommandPermission perm : CommandPermission.values()) {
this.service.registerPermissionDescription(perm.getPermission(), null, this.pluginContainer);
this.service.registerPermissionDescription(perm.getPermission(), null, this.bootstrap.getPluginContainer());
}
}
getLog().info("Successfully enabled. (took " + (System.currentTimeMillis() - this.startTime) + "ms)");
}
@Listener(order = Order.LATE)
public void onLateEnable(GamePreInitializationEvent event) {
public void lateEnable() {
if (this.lateLoad) {
getLog().info("Providing late registration of PermissionService...");
this.game.getServiceManager().setProvider(this, LPPermissionService.class, this.service);
this.game.getServiceManager().setProvider(this, PermissionService.class, this.service.sponge());
this.game.getServiceManager().setProvider(this, LuckPermsService.class, this.service);
getLogger().info("Providing late registration of PermissionService...");
this.bootstrap.getGame().getServiceManager().setProvider(this, LPPermissionService.class, this.service);
this.bootstrap.getGame().getServiceManager().setProvider(this, PermissionService.class, this.service.sponge());
this.bootstrap.getGame().getServiceManager().setProvider(this, LuckPermsService.class, this.service);
}
}
@Listener
public void onDisable(GameStoppingServerEvent event) {
this.permissionVault.shutdown();
this.verboseHandler.shutdown();
getLog().info("Closing storage...");
this.storage.shutdown();
if (this.fileWatcher != null) {
this.fileWatcher.close();
}
if (this.messagingService != null) {
getLog().info("Closing messaging service...");
this.messagingService.close();
}
ApiRegistrationUtil.unregisterProvider();
getLog().info("Shutting down internal scheduler...");
this.scheduler.shutdown();
getLog().info("Goodbye!");
}
@Override
public void onPostUpdate() {
for (LPSubjectCollection collection : this.service.getLoadedCollections().values()) {
@ -354,13 +200,12 @@ public class LPSpongePlugin implements LuckPermsSpongePlugin {
this.service.invalidateAllCaches(LPSubject.CacheLevel.PARENT);
}
private Path resolveConfig(String file) {
Path path = this.configDirectory.resolve(file);
private Path resolveConfig() {
Path path = this.bootstrap.getConfigPath().resolve("luckperms.conf");
if (!Files.exists(path)) {
try {
Files.createDirectories(this.configDirectory);
try (InputStream is = getClass().getClassLoader().getResourceAsStream(file)) {
Files.createDirectories(this.bootstrap.getConfigPath());
try (InputStream is = getClass().getClassLoader().getResourceAsStream("luckperms.conf")) {
Files.copy(is, path);
}
} catch (IOException e) {
@ -371,140 +216,38 @@ public class LPSpongePlugin implements LuckPermsSpongePlugin {
return path;
}
@Override
public Optional<InternalMessagingService> getMessagingService() {
return Optional.ofNullable(this.messagingService);
}
@Override
public void setMessagingService(InternalMessagingService messagingService) {
if (this.messagingService == null) {
this.messagingService = messagingService;
}
}
@Override
public Optional<FileWatcher> getFileWatcher() {
return Optional.ofNullable(this.fileWatcher);
}
@Override
public File getDataDirectory() {
File serverRoot = this.configDirectory.toFile().getParentFile().getParentFile();
File dataDirectory = new File(serverRoot, "luckperms");
dataDirectory.mkdirs();
return dataDirectory;
}
@Override
public File getConfigDirectory() {
return this.configDirectory.toFile();
}
@Override
public InputStream getResourceStream(String path) {
return getClass().getClassLoader().getResourceAsStream(path);
}
@Override
public Player getPlayer(User user) {
if (!this.game.isServerAvailable()) {
return null;
}
return this.game.getServer().getPlayer(user.getUuid()).orElse(null);
}
@Override
public Optional<UUID> lookupUuid(String username) {
if (!this.game.isServerAvailable()) {
return Optional.empty();
}
CompletableFuture<GameProfile> fut = this.game.getServer().getGameProfileManager().get(username);
try {
return Optional.of(fut.get().getUniqueId());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
return Optional.empty();
}
}
@Override
public Optional<Contexts> getContextForUser(User user) {
Player player = getPlayer(user);
Player player = this.bootstrap.getPlayer(user.getUuid());
if (player == null) {
return Optional.empty();
}
return Optional.of(this.contextManager.getApplicableContexts(player));
}
@Override
public String getVersion() {
return VersionData.VERSION;
}
@Override
public PlatformType getServerType() {
return PlatformType.SPONGE;
}
@Override
public String getServerBrand() {
return getGame().getPlatform().getContainer(Platform.Component.IMPLEMENTATION).getName();
}
@Override
public String getServerVersion() {
return getGame().getPlatform().getContainer(Platform.Component.API).getName() + ": " +
getGame().getPlatform().getContainer(Platform.Component.API).getVersion().orElse("null") + " - " +
getGame().getPlatform().getContainer(Platform.Component.IMPLEMENTATION).getName() + ": " +
getGame().getPlatform().getContainer(Platform.Component.IMPLEMENTATION).getVersion().orElse("null");
}
@Override
public int getPlayerCount() {
return this.game.isServerAvailable() ? this.game.getServer().getOnlinePlayers().size() : 0;
}
@Override
public Stream<String> getPlayerList() {
return this.game.isServerAvailable() ? this.game.getServer().getOnlinePlayers().stream().map(Player::getName) : Stream.empty();
}
@Override
public Stream<UUID> getOnlinePlayers() {
return this.game.isServerAvailable() ? this.game.getServer().getOnlinePlayers().stream().map(Player::getUniqueId) : Stream.empty();
}
@Override
public boolean isPlayerOnline(UUID external) {
return this.game.isServerAvailable() ? this.game.getServer().getPlayer(external).map(Player::isOnline).orElse(false) : false;
}
@Override
public Stream<Sender> getOnlineSenders() {
if (!this.game.isServerAvailable()) {
if (!this.bootstrap.getGame().isServerAvailable()) {
return Stream.empty();
}
return Stream.concat(
Stream.of(getConsoleSender()),
this.game.getServer().getOnlinePlayers().stream().map(s -> getSenderFactory().wrap(s))
this.bootstrap.getGame().getServer().getOnlinePlayers().stream().map(s -> this.senderFactory.wrap(s))
);
}
@Override
public Sender getConsoleSender() {
if (!this.game.isServerAvailable()) {
return new DummySender(this, me.lucko.luckperms.common.commands.CommandManager.CONSOLE_UUID, me.lucko.luckperms.common.commands.CommandManager.CONSOLE_NAME) {
if (!this.bootstrap.getGame().isServerAvailable()) {
return new DummySender(this, CommandManager.CONSOLE_UUID, CommandManager.CONSOLE_NAME) {
@Override
protected void consumeMessage(String s) {
LPSpongePlugin.this.logger.info(s);
LPSpongePlugin.this.bootstrap.getLogger().info(s);
}
};
}
return getSenderFactory().wrap(this.game.getServer().getConsole());
return this.senderFactory.wrap(this.bootstrap.getGame().getServer().getConsole());
}
@Override
@ -512,38 +255,13 @@ public class LPSpongePlugin implements LuckPermsSpongePlugin {
return Collections.singletonList(new SpongeMainCommand(this));
}
public Game getGame() {
return this.game;
}
public PluginContainer getPluginContainer() {
return this.pluginContainer;
}
public Scheduler getSpongeScheduler() {
return this.spongeScheduler;
}
public UpdateEventHandler getUpdateEventHandler() {
return this.updateEventHandler;
}
public SpongeExecutorService getSyncExecutorService() {
return this.syncExecutorService;
}
public SpongeExecutorService getAsyncExecutorService() {
return this.asyncExecutorService;
public SpongeSenderFactory getSenderFactory() {
return this.senderFactory;
}
@Override
public long getStartTime() {
return this.startTime;
}
@Override
public SchedulerAdapter getScheduler() {
return this.scheduler;
public SpongeConnectionListener getConnectionListener() {
return this.connectionListener;
}
@Override
@ -551,11 +269,6 @@ public class LPSpongePlugin implements LuckPermsSpongePlugin {
return this.commandManager;
}
@Override
public LuckPermsConfiguration getConfiguration() {
return this.configuration;
}
@Override
public SpongeUserManager getUserManager() {
return this.userManager;
@ -572,90 +285,16 @@ public class LPSpongePlugin implements LuckPermsSpongePlugin {
}
@Override
public Storage getStorage() {
return this.storage;
}
@Override
public LuckPermsApiProvider getApiProvider() {
return this.apiProvider;
}
@Override
public EventFactory getEventFactory() {
return this.eventFactory;
}
@Override
public me.lucko.luckperms.common.logging.Logger getLog() {
return this.log;
public ContextManager<Subject> getContextManager() {
return this.contextManager;
}
public LuckPermsService getService() {
return this.service;
}
@Override
public LocaleManager getLocaleManager() {
return this.localeManager;
public UpdateEventHandler getUpdateEventHandler() {
return this.updateEventHandler;
}
@Override
public PluginClassLoader getPluginClassLoader() {
return this.pluginClassLoader;
}
@Override
public DependencyManager getDependencyManager() {
return this.dependencyManager;
}
@Override
public CachedStateManager getCachedStateManager() {
return this.cachedStateManager;
}
@Override
public ContextManager<Subject> getContextManager() {
return this.contextManager;
}
@Override
public InheritanceHandler getInheritanceHandler() {
return this.inheritanceHandler;
}
@Override
public CalculatorFactory getCalculatorFactory() {
return this.calculatorFactory;
}
@Override
public BufferedRequest<Void> getUpdateTaskBuffer() {
return this.updateTaskBuffer;
}
@Override
public VerboseHandler getVerboseHandler() {
return this.verboseHandler;
}
public SpongeSenderFactory getSenderFactory() {
return this.senderFactory;
}
@Override
public PermissionVault getPermissionVault() {
return this.permissionVault;
}
@Override
public LogDispatcher getLogDispatcher() {
return this.logDispatcher;
}
@Override
public Set<UUID> getUniqueConnections() {
return this.uniqueConnections;
}
}

View File

@ -30,6 +30,7 @@ import me.lucko.luckperms.common.plugin.SchedulerTask;
import me.lucko.luckperms.common.utils.SafeIteration;
import org.spongepowered.api.scheduler.Scheduler;
import org.spongepowered.api.scheduler.SpongeExecutorService;
import org.spongepowered.api.scheduler.Task;
import java.util.Set;
@ -37,45 +38,49 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
public class SpongeSchedulerAdapter implements SchedulerAdapter {
private final LPSpongePlugin plugin;
private final LPSpongeBootstrap bootstrap;
private final Scheduler scheduler;
private final SpongeExecutorService sync;
private final SpongeExecutorService async;
private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet();
public SpongeSchedulerAdapter(LPSpongePlugin plugin) {
this.plugin = plugin;
}
private Scheduler scheduler() {
return this.plugin.getSpongeScheduler();
public SpongeSchedulerAdapter(LPSpongeBootstrap bootstrap, Scheduler scheduler, SpongeExecutorService sync, SpongeExecutorService async) {
this.bootstrap = bootstrap;
this.scheduler = scheduler;
this.sync = sync;
this.async = async;
}
@Override
public Executor async() {
return this.plugin.getAsyncExecutorService();
return this.async;
}
@Override
public Executor sync() {
return this.plugin.getSyncExecutorService();
return this.sync;
}
@Override
public void doAsync(Runnable runnable) {
this.plugin.getSpongeScheduler().createTaskBuilder().async().execute(runnable).submit(this.plugin);
this.scheduler.createTaskBuilder().async().execute(runnable).submit(this.bootstrap);
}
@Override
public void doSync(Runnable runnable) {
this.plugin.getSpongeScheduler().createTaskBuilder().execute(runnable).submit(this.plugin);
this.scheduler.createTaskBuilder().execute(runnable).submit(this.bootstrap);
}
@Override
public SchedulerTask asyncRepeating(Runnable runnable, long intervalTicks) {
Task task = scheduler().createTaskBuilder()
Task task = this.scheduler.createTaskBuilder()
.async()
.intervalTicks(intervalTicks)
.delayTicks(intervalTicks)
.execute(runnable)
.submit(this.plugin);
.submit(this.bootstrap);
SchedulerTask wrapped = new SpongeSchedulerTask(task);
this.tasks.add(wrapped);
@ -84,11 +89,11 @@ public class SpongeSchedulerAdapter implements SchedulerAdapter {
@Override
public SchedulerTask syncRepeating(Runnable runnable, long intervalTicks) {
Task task = scheduler().createTaskBuilder()
Task task = this.scheduler.createTaskBuilder()
.intervalTicks(intervalTicks)
.delayTicks(intervalTicks)
.execute(runnable)
.submit(this.plugin);
.submit(this.bootstrap);
SchedulerTask wrapped = new SpongeSchedulerTask(task);
this.tasks.add(wrapped);
@ -97,11 +102,11 @@ public class SpongeSchedulerAdapter implements SchedulerAdapter {
@Override
public SchedulerTask asyncLater(Runnable runnable, long delayTicks) {
Task task = scheduler().createTaskBuilder()
Task task = this.scheduler.createTaskBuilder()
.async()
.delayTicks(delayTicks)
.execute(runnable)
.submit(this.plugin);
.submit(this.bootstrap);
SchedulerTask wrapped = new SpongeSchedulerTask(task);
this.tasks.add(wrapped);
@ -110,10 +115,10 @@ public class SpongeSchedulerAdapter implements SchedulerAdapter {
@Override
public SchedulerTask syncLater(Runnable runnable, long delayTicks) {
Task task = scheduler().createTaskBuilder()
Task task = this.scheduler.createTaskBuilder()
.delayTicks(delayTicks)
.execute(runnable)
.submit(this.plugin);
.submit(this.bootstrap);
SchedulerTask wrapped = new SpongeSchedulerTask(task);
this.tasks.add(wrapped);

View File

@ -26,9 +26,9 @@
package me.lucko.luckperms.sponge.listeners;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.listener.AbstractConnectionListener;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.utils.AbstractLoginListener;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import org.spongepowered.api.entity.living.player.Player;
@ -45,7 +45,7 @@ import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public class SpongeConnectionListener extends AbstractLoginListener {
public class SpongeConnectionListener extends AbstractConnectionListener {
private final LPSpongePlugin plugin;
private final Set<UUID> deniedAsyncLogin = Collections.synchronizedSet(new HashSet<>());
@ -66,10 +66,10 @@ public class SpongeConnectionListener extends AbstractLoginListener {
final String username = profile.getName().orElseThrow(() -> new RuntimeException("No username present for user " + profile.getUniqueId()));
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
this.plugin.getLog().info("Processing auth event for " + profile.getUniqueId() + " - " + profile.getName());
this.plugin.getLogger().info("Processing auth event for " + profile.getUniqueId() + " - " + profile.getName());
}
this.plugin.getUniqueConnections().add(profile.getUniqueId());
recordConnection(profile.getUniqueId());
/* Actually process the login for the connection.
We do this here to delay the login until the data is ready.
@ -84,7 +84,7 @@ public class SpongeConnectionListener extends AbstractLoginListener {
User user = loadUser(profile.getUniqueId(), username);
this.plugin.getEventFactory().handleUserLoginProcess(profile.getUniqueId(), username, user);
} catch (Exception ex) {
this.plugin.getLog().severe("Exception occurred whilst loading data for " + profile.getUniqueId() + " - " + profile.getName());
this.plugin.getLogger().severe("Exception occurred whilst loading data for " + profile.getUniqueId() + " - " + profile.getName());
ex.printStackTrace();
this.deniedAsyncLogin.add(profile.getUniqueId());
@ -107,7 +107,7 @@ public class SpongeConnectionListener extends AbstractLoginListener {
// This is a problem, as they were denied at low priority, but are now being allowed.
if (e.isCancelled()) {
this.plugin.getLog().severe("Player connection was re-allowed for " + e.getProfile().getUniqueId());
this.plugin.getLogger().severe("Player connection was re-allowed for " + e.getProfile().getUniqueId());
e.setCancelled(true);
}
}
@ -123,7 +123,7 @@ public class SpongeConnectionListener extends AbstractLoginListener {
final GameProfile profile = e.getProfile();
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
this.plugin.getLog().info("Processing login event for " + profile.getUniqueId() + " - " + profile.getName());
this.plugin.getLogger().info("Processing login event for " + profile.getUniqueId() + " - " + profile.getName());
}
final User user = this.plugin.getUserManager().getIfLoaded(profile.getUniqueId());
@ -132,7 +132,7 @@ public class SpongeConnectionListener extends AbstractLoginListener {
if (user == null) {
this.deniedLogin.add(profile.getUniqueId());
this.plugin.getLog().warn("User " + profile.getUniqueId() + " - " + profile.getName() + " doesn't have data pre-loaded. - denying login.");
this.plugin.getLogger().warn("User " + profile.getUniqueId() + " - " + profile.getName() + " doesn't have data pre-loaded. - denying login.");
e.setCancelled(true);
e.setMessageCancelled(false);
//noinspection deprecation
@ -150,7 +150,7 @@ public class SpongeConnectionListener extends AbstractLoginListener {
if (this.deniedLogin.remove(e.getProfile().getUniqueId())) {
// This is a problem, as they were denied at low priority, but are now being allowed.
if (!e.isCancelled()) {
this.plugin.getLog().severe("Player connection was re-allowed for " + e.getProfile().getUniqueId());
this.plugin.getLogger().severe("Player connection was re-allowed for " + e.getProfile().getUniqueId());
e.setCancelled(true);
}
}
@ -165,7 +165,7 @@ public class SpongeConnectionListener extends AbstractLoginListener {
this.plugin.getUserManager().getHouseKeeper().registerUsage(player.getUniqueId());
// force a clear of transient nodes
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId());
if (user != null) {
user.clearTransientNodes();

View File

@ -82,7 +82,7 @@ public class SpongeGroupManager extends AbstractGroupManager<SpongeGroup> implem
group = getIfLoaded(s);
if (group == null) {
getPlugin().getLog().severe("Error whilst loading group '" + s + "'.");
getPlugin().getLogger().severe("Error whilst loading group '" + s + "'.");
throw new RuntimeException();
}
@ -137,7 +137,7 @@ public class SpongeGroupManager extends AbstractGroupManager<SpongeGroup> implem
return CompletableFuture.completedFuture(present);
}
return CompletableFuture.supplyAsync(() -> this.subjectLoadingCache.get(identifier.toLowerCase()), this.plugin.getScheduler().async());
return CompletableFuture.supplyAsync(() -> this.subjectLoadingCache.get(identifier.toLowerCase()), this.plugin.getBootstrap().getScheduler().async());
}
@Override
@ -170,7 +170,7 @@ public class SpongeGroupManager extends AbstractGroupManager<SpongeGroup> implem
}
return ret.build();
}, this.plugin.getScheduler().async());
}, this.plugin.getBootstrap().getScheduler().async());
}
@Override
@ -196,7 +196,7 @@ public class SpongeGroupManager extends AbstractGroupManager<SpongeGroup> implem
}
return ret.build();
}, this.plugin.getScheduler().async());
}, this.plugin.getBootstrap().getScheduler().async());
}
@Override
@ -212,7 +212,7 @@ public class SpongeGroupManager extends AbstractGroupManager<SpongeGroup> implem
}
return ret.build();
}, this.plugin.getScheduler().async());
}, this.plugin.getBootstrap().getScheduler().async());
}
@Override

View File

@ -89,7 +89,7 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
getPlugin().getStorage().loadUser(u, null).join();
user = getIfLoaded(u);
if (user == null) {
getPlugin().getLog().severe("Error whilst loading user '" + u + "'.");
getPlugin().getLogger().severe("Error whilst loading user '" + u + "'.");
throw new RuntimeException();
}
@ -149,7 +149,7 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
return CompletableFuture.completedFuture(present);
}
return CompletableFuture.supplyAsync(() -> this.subjectLoadingCache.get(uuid), this.plugin.getScheduler().async());
return CompletableFuture.supplyAsync(() -> this.subjectLoadingCache.get(uuid), this.plugin.getBootstrap().getScheduler().async());
}
@Override
@ -188,7 +188,7 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
}
return ret.build();
}, this.plugin.getScheduler().async());
}, this.plugin.getBootstrap().getScheduler().async());
}
@Override
@ -205,7 +205,7 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
this.plugin.getStorage().getUniqueUsers().join().forEach(uuid -> ids.add(uuid.toString()));
return ids.build();
}, this.plugin.getScheduler().async());
}, this.plugin.getBootstrap().getScheduler().async());
}
@Override
@ -221,7 +221,7 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
}
return ret.build();
}, this.plugin.getScheduler().async());
}, this.plugin.getBootstrap().getScheduler().async());
}
@Override
@ -237,7 +237,7 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
}
return ret.build();
}, this.plugin.getScheduler().async());
}, this.plugin.getBootstrap().getScheduler().async());
}
@Override

View File

@ -61,25 +61,25 @@ public class BungeeMessenger implements Messenger, RawDataListener {
}
public void init() {
this.channel = this.plugin.getGame().getChannelRegistrar().createRawChannel(this.plugin, CHANNEL);
this.channel = this.plugin.getBootstrap().getGame().getChannelRegistrar().createRawChannel(this.plugin, CHANNEL);
this.channel.addListener(Platform.Type.SERVER, this);
}
@Override
public void close() {
if (this.channel != null) {
this.plugin.getGame().getChannelRegistrar().unbindChannel(this.channel);
this.plugin.getBootstrap().getGame().getChannelRegistrar().unbindChannel(this.channel);
}
}
@Override
public void sendOutgoingMessage(@Nonnull OutgoingMessage outgoingMessage) {
this.plugin.getSpongeScheduler().createTaskBuilder().interval(10, TimeUnit.SECONDS).execute(task -> {
if (!this.plugin.getGame().isServerAvailable()) {
this.plugin.getBootstrap().getSpongeScheduler().createTaskBuilder().interval(10, TimeUnit.SECONDS).execute(task -> {
if (!this.plugin.getBootstrap().getGame().isServerAvailable()) {
return;
}
Collection<Player> players = this.plugin.getGame().getServer().getOnlinePlayers();
Collection<Player> players = this.plugin.getBootstrap().getGame().getServer().getOnlinePlayers();
Player p = Iterables.getFirst(players, null);
if (p == null) {
return;

View File

@ -31,6 +31,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.utils.Predicates;
import me.lucko.luckperms.sponge.LPSpongePlugin;
@ -88,7 +89,7 @@ public class LuckPermsService implements LPPermissionService {
this.referenceFactory = new SubjectReferenceFactory(this);
this.spongeProxy = ProxyFactory.toSponge(this);
this.storage = new SubjectStorage(this, new File(plugin.getDataDirectory(), "sponge-data"));
this.storage = new SubjectStorage(this, new File(plugin.getBootstrap().getDataDirectory(), "sponge-data"));
this.userSubjects = plugin.getUserManager();
this.groupSubjects = plugin.getGroupManager();
@ -122,6 +123,11 @@ public class LuckPermsService implements LPPermissionService {
return this.plugin;
}
@Override
public ContextManager<Subject> getContextManager() {
return this.plugin.getContextManager();
}
@Override
public SubjectReferenceFactory getReferenceFactory() {
return this.referenceFactory;

View File

@ -59,7 +59,7 @@ public class LPSubjectDataUpdateEvent extends AbstractEvent implements SubjectDa
@Override
public Cause getCause() {
EventContext eventContext = EventContext.builder()
.add(EventContextKeys.PLUGIN, this.plugin.getPluginContainer())
.add(EventContextKeys.PLUGIN, this.plugin.getBootstrap().getPluginContainer())
.build();
return Cause.builder().build(eventContext);

View File

@ -40,6 +40,6 @@ public class UpdateEventHandlerImpl implements UpdateEventHandler {
@Override
public void fireUpdateEvent(LPSubjectData subjectData) {
SubjectDataUpdateEvent event = new LPSubjectDataUpdateEvent(this.plugin, subjectData);
this.plugin.getGame().getEventManager().post(event);
this.plugin.getBootstrap().getGame().getEventManager().post(event);
}
}

View File

@ -465,7 +465,7 @@ public class HolderSubjectData implements LPSubjectData {
}
user.getRefreshBuffer().request().thenAccept(fut::complete);
}, this.service.getPlugin().getScheduler().async());
}, this.service.getPlugin().getBootstrap().getScheduler().async());
return fut;
} else {
Group group = ((Group) t);
@ -476,7 +476,7 @@ public class HolderSubjectData implements LPSubjectData {
}
this.service.getPlugin().getUpdateTaskBuffer().request().thenAccept(fut::complete);
}, this.service.getPlugin().getScheduler().async());
}, this.service.getPlugin().getBootstrap().getScheduler().async());
return fut;
}
}

View File

@ -77,7 +77,7 @@ public class PersistedSubject implements LPSubject {
.expireAfterAccess(20, TimeUnit.MINUTES)
.build(lookup -> lookupOptionValue(lookup.contexts, lookup.key));
private final BufferedRequest<Void> saveBuffer = new BufferedRequest<Void>(1000L, 500L, r -> PersistedSubject.this.service.getPlugin().getScheduler().doAsync(r)) {
private final BufferedRequest<Void> saveBuffer = new BufferedRequest<Void>(1000L, 500L, r -> PersistedSubject.this.service.getPlugin().getBootstrap().getScheduler().doAsync(r)) {
@Override
protected Void perform() {
try {