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; import javax.annotation.Nonnull;
public class BukkitSchedulerAdapter implements SchedulerAdapter { public class BukkitSchedulerAdapter implements SchedulerAdapter {
private final LPBukkitPlugin plugin; private final LPBukkitBootstrap bootstrap;
private final ExecutorService asyncFallback; private final ExecutorService asyncFallback;
private final Executor asyncBukkit; private final Executor asyncBukkit;
@ -56,8 +56,8 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet(); private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet();
public BukkitSchedulerAdapter(LPBukkitPlugin plugin) { public BukkitSchedulerAdapter(LPBukkitBootstrap bootstrap) {
this.plugin = plugin; this.bootstrap = bootstrap;
this.sync = new SyncExecutor(); this.sync = new SyncExecutor();
this.asyncFallback = new FallbackAsyncExecutor(); this.asyncFallback = new FallbackAsyncExecutor();
@ -66,7 +66,7 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
} }
private BukkitScheduler scheduler() { private BukkitScheduler scheduler() {
return this.plugin.getServer().getScheduler(); return this.bootstrap.getServer().getScheduler();
} }
@Override @Override
@ -81,26 +81,26 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
@Override @Override
public SchedulerTask asyncRepeating(Runnable runnable, long intervalTicks) { 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); this.tasks.add(task);
return task; return task;
} }
@Override @Override
public SchedulerTask syncRepeating(Runnable runnable, long intervalTicks) { 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); this.tasks.add(task);
return task; return task;
} }
@Override @Override
public SchedulerTask asyncLater(Runnable runnable, long delayTicks) { 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 @Override
public SchedulerTask syncLater(Runnable runnable, long delayTicks) { 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 @Override
@ -142,14 +142,14 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
private final class SyncExecutor implements Executor { private final class SyncExecutor implements Executor {
@Override @Override
public void execute(@Nonnull Runnable runnable) { 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 { private final class AsyncExecutor implements Executor {
@Override @Override
public void execute(@Nonnull Runnable runnable) { 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); BukkitSchedulerAdapter.this.asyncFallback.execute(runnable);
} else { } else {
BukkitSchedulerAdapter.this.asyncBukkit.execute(runnable); BukkitSchedulerAdapter.this.asyncBukkit.execute(runnable);
@ -160,7 +160,7 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
private final class BukkitAsyncExecutor implements Executor { private final class BukkitAsyncExecutor implements Executor {
@Override @Override
public void execute(@Nonnull Runnable runnable) { 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 // otherwise, send the message sync
getPlugin().getScheduler().doSync(new SyncMessengerAgent(sender, s)); getPlugin().getBootstrap().getScheduler().doSync(new SyncMessengerAgent(sender, s));
} }
@Override @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.Contexts;
import me.lucko.luckperms.api.LuckPermsApi; 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.calculators.BukkitCalculatorFactory;
import me.lucko.luckperms.bukkit.compat.NullSafeConsoleCommandSender;
import me.lucko.luckperms.bukkit.contexts.BukkitContextManager; import me.lucko.luckperms.bukkit.contexts.BukkitContextManager;
import me.lucko.luckperms.bukkit.contexts.WorldCalculator; import me.lucko.luckperms.bukkit.contexts.WorldCalculator;
import me.lucko.luckperms.bukkit.listeners.BukkitConnectionListener; 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.LPPermissionMap;
import me.lucko.luckperms.bukkit.model.server.LPSubscriptionMap; import me.lucko.luckperms.bukkit.model.server.LPSubscriptionMap;
import me.lucko.luckperms.bukkit.vault.VaultHookManager; 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.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.CommandPermission; import me.lucko.luckperms.common.commands.CommandPermission;
import me.lucko.luckperms.common.commands.sender.Sender; 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.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.ContextManager;
import me.lucko.luckperms.common.contexts.LuckPermsCalculator; import me.lucko.luckperms.common.listener.ConnectionListener;
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.managers.group.StandardGroupManager; import me.lucko.luckperms.common.managers.group.StandardGroupManager;
import me.lucko.luckperms.common.managers.track.StandardTrackManager; import me.lucko.luckperms.common.managers.track.StandardTrackManager;
import me.lucko.luckperms.common.managers.user.StandardUserManager; 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.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.AbstractLuckPermsPlugin;
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.CacheHousekeepingTask; import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask; 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.command.PluginCommand;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.permissions.Permission; import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault; import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.ServicePriority; import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File; import java.io.File;
import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.Optional; 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; import java.util.stream.Stream;
/** /**
* LuckPerms implementation for the Bukkit API. * 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 BukkitSenderFactory senderFactory;
private BukkitSchedulerAdapter scheduler; private BukkitConnectionListener connectionListener;
private BukkitCommandExecutor commandManager; private BukkitCommandExecutor commandManager;
private VaultHookManager vaultHookManager = null;
private LuckPermsConfiguration configuration;
private StandardUserManager userManager; private StandardUserManager userManager;
private StandardGroupManager groupManager; private StandardGroupManager groupManager;
private StandardTrackManager trackManager; private StandardTrackManager trackManager;
private Storage storage; private ContextManager<Player> contextManager;
private FileWatcher fileWatcher = null;
private InternalMessagingService messagingService = null;
private LuckPermsApiProvider apiProvider;
private EventFactory eventFactory;
private Logger log;
private ConsoleCommandSender console;
private LPSubscriptionMap subscriptionMap; private LPSubscriptionMap subscriptionMap;
private LPPermissionMap permissionMap; private LPPermissionMap permissionMap;
private LPDefaultsMap defaultPermissionMap; private LPDefaultsMap defaultPermissionMap;
private LocaleManager localeManager; private VaultHookManager vaultHookManager = null;
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 boolean invalidVersion = false; public LPBukkitPlugin(LPBukkitBootstrap bootstrap) {
this.bootstrap = bootstrap;
@Override
public void onLoad() {
if (checkInvalidVersion()) {
this.invalidVersion = true;
return;
} }
// setup minimal functionality in order to load initial dependencies @Override
this.console = new NullSafeConsoleCommandSender(getServer()); public LPBukkitBootstrap getBootstrap() {
this.scheduler = new BukkitSchedulerAdapter(this); return this.bootstrap;
this.localeManager = new NoopLocaleManager(); }
@Override
protected void setupSenderFactory() {
this.senderFactory = new BukkitSenderFactory(this); 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 @Override
public void onEnable() { protected ConfigurationAdapter provideConfigurationAdapter() {
if (this.invalidVersion) { return new BukkitConfigAdapter(this, resolveConfig());
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;
} }
try { @Override
enable(); protected void registerPlatformListeners() {
} finally { this.connectionListener = new BukkitConnectionListener(this);
// count down the latch when onEnable has been called this.bootstrap.getServer().getPluginManager().registerEvents(this.connectionListener, this.bootstrap);
// we don't care about the result here this.bootstrap.getServer().getPluginManager().registerEvents(new BukkitPlatformListener(this), this.bootstrap);
this.enableLatch.countDown();
}
} }
private void enable() { @Override
this.startTime = System.currentTimeMillis(); protected MessagingFactory<?> provideMessagingFactory() {
sendStartupBanner(getConsoleSender()); return new BukkitMessagingFactory(this);
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);
} }
// initialise datastore @Override
this.storage = storageFactory.getInstance(StorageType.H2); protected void registerCommands() {
// 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
this.commandManager = new BukkitCommandExecutor(this); this.commandManager = new BukkitCommandExecutor(this);
PluginCommand main = getServer().getPluginCommand("luckperms"); PluginCommand main = this.bootstrap.getServer().getPluginCommand("luckperms");
main.setExecutor(this.commandManager); main.setExecutor(this.commandManager);
main.setTabCompleter(this.commandManager); main.setTabCompleter(this.commandManager);
main.setDescription("Manage permissions"); main.setDescription("Manage permissions");
main.setAliases(Arrays.asList("lp", "perm", "perms", "permission", "permissions")); main.setAliases(Arrays.asList("lp", "perm", "perms", "permission", "permissions"));
}
// load internal managers @Override
getLog().info("Loading internal permission managers..."); protected void setupManagers() {
this.inheritanceHandler = new InheritanceHandler(this);
this.userManager = new StandardUserManager(this); this.userManager = new StandardUserManager(this);
this.groupManager = new StandardGroupManager(this); this.groupManager = new StandardGroupManager(this);
this.trackManager = new StandardTrackManager(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 = new BukkitContextManager(this);
this.contextManager.registerCalculator(new WorldCalculator(this)); this.contextManager.registerCalculator(new WorldCalculator(this));
this.contextManager.registerStaticCalculator(new LuckPermsCalculator(getConfiguration())); }
@Override
protected void setupPlatformHooks() {
// inject our own custom permission maps // inject our own custom permission maps
Runnable[] injectors = new Runnable[]{ Runnable[] injectors = new Runnable[]{
new InjectorSubscriptionMap(this), new InjectorSubscriptionMap(this),
@ -262,46 +164,47 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
// schedule another injection after all plugins have loaded // schedule another injection after all plugins have loaded
// the entire pluginmanager instance is replaced by some plugins :( // the entire pluginmanager instance is replaced by some plugins :(
this.scheduler.asyncLater(injector, 1L); this.bootstrap.getScheduler().asyncLater(injector, 1L);
} }
// Provide vault support // Provide vault support
tryVaultHook(false); 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. public void tryVaultHook(boolean force) {
getLog().info("Performing initial data load..."); if (this.vaultHookManager != null) {
return; // already hooked
}
try { 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) { } catch (Exception e) {
this.vaultHookManager = null;
getLogger().severe("Error occurred whilst hooking into Vault.");
e.printStackTrace(); e.printStackTrace();
} }
}
@Override
protected void registerApiOnPlatform(LuckPermsApi api) {
this.bootstrap.getServer().getServicesManager().register(LuckPermsApi.class, api, this.bootstrap, ServicePriority.Normal);
}
// register tasks @Override
this.scheduler.asyncRepeating(new ExpireTemporaryTask(this), 60L); protected void registerHousekeepingTasks() {
this.scheduler.asyncRepeating(new CacheHousekeepingTask(this), 2400L); this.bootstrap.getScheduler().asyncRepeating(new ExpireTemporaryTask(this), 60L);
this.bootstrap.getScheduler().asyncRepeating(new CacheHousekeepingTask(this), 2400L);
}
@Override
protected void performFinalSetup() {
// register permissions // register permissions
try { try {
PluginManager pm = getServer().getPluginManager(); PluginManager pm = this.bootstrap.getServer().getPluginManager();
PermissionDefault permDefault = getConfiguration().get(ConfigKeys.COMMANDS_ALLOW_OP) ? PermissionDefault.OP : PermissionDefault.FALSE; PermissionDefault permDefault = getConfiguration().get(ConfigKeys.COMMANDS_ALLOW_OP) ? PermissionDefault.OP : PermissionDefault.FALSE;
for (CommandPermission p : CommandPermission.values()) { for (CommandPermission p : CommandPermission.values()) {
@ -312,19 +215,19 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
} }
if (!getConfiguration().get(ConfigKeys.OPS_ENABLED)) { 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 // 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) // Load any online users (in the case of a reload)
for (Player player : getServer().getOnlinePlayers()) { for (Player player : this.bootstrap.getServer().getOnlinePlayers()) {
this.scheduler.doAsync(() -> { this.bootstrap.getScheduler().doAsync(() -> {
try { try {
User user = connectionListener.loadUser(player.getUniqueId(), player.getName()); User user = this.connectionListener.loadUser(player.getUniqueId(), player.getName());
if (user != null) { if (user != null) {
this.scheduler.doSync(() -> { this.bootstrap.getScheduler().doSync(() -> {
try { try {
LPPermissible lpPermissible = new LPPermissible(player, user, this); LPPermissible lpPermissible = new LPPermissible(player, user, this);
PermissibleInjector.inject(player, lpPermissible); 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 @Override
public void onDisable() { protected void performEarlyDisableTasks() {
if (this.invalidVersion) { // Switch back to the fallback executor, the bukkit one won't allow new tasks
return; this.bootstrap.getScheduler().setUseFallback(true);
} }
// Switch back to the fallback executor, the bukkit one won't allow new tasks @Override
this.scheduler.setUseFallback(true); protected void removePlatformHooks() {
this.permissionVault.shutdown();
this.verboseHandler.shutdown();
// uninject from players // uninject from players
for (Player player : getServer().getOnlinePlayers()) { for (Player player : this.bootstrap.getServer().getOnlinePlayers()) {
try { try {
PermissibleInjector.unInject(player, false); PermissibleInjector.unInject(player, false);
} catch (Exception e) { } catch (Exception e) {
@ -378,50 +275,10 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
InjectorPermissionMap.uninject(); InjectorPermissionMap.uninject();
InjectorDefaultsMap.uninject(); InjectorDefaultsMap.uninject();
getLog().info("Closing storage..."); // unhook vault
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);
if (this.vaultHookManager != null) { if (this.vaultHookManager != null) {
this.vaultHookManager.unhook(this); 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) { public void refreshAutoOp(User user, Player player) {
@ -436,15 +293,69 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
} }
} }
private File resolveConfig(String file) { private File resolveConfig() {
File configFile = new File(getDataFolder(), file); File configFile = new File(this.bootstrap.getDataFolder(), "config.yml");
if (!configFile.exists()) { if (!configFile.exists()) {
getDataFolder().mkdirs(); this.bootstrap.getDataFolder().mkdirs();
saveResource("config.yml", false); 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() { public LPSubscriptionMap getSubscriptionMap() {
@ -471,250 +382,4 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
this.defaultPermissionMap = defaultPermissionMap; 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.LPPermissible;
import me.lucko.luckperms.bukkit.model.permissible.PermissibleInjector; import me.lucko.luckperms.bukkit.model.permissible.PermissibleInjector;
import me.lucko.luckperms.common.config.ConfigKeys; 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.locale.Message;
import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.utils.AbstractLoginListener;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -47,7 +47,7 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; 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 LPBukkitPlugin plugin;
private final Set<UUID> deniedAsyncLogin = Collections.synchronizedSet(new HashSet<>()); 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 /* wait for the plugin to enable. because these events are fired async, they can be called before
the plugin has enabled. */ the plugin has enabled. */
try { try {
this.plugin.getEnableLatch().await(60, TimeUnit.SECONDS); this.plugin.getBootstrap().getEnableLatch().await(60, TimeUnit.SECONDS);
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) { 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. /* Actually process the login for the connection.
We do this here to delay the login until the data is ready. 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()); User user = loadUser(e.getUniqueId(), e.getName());
this.plugin.getEventFactory().handleUserLoginProcess(e.getUniqueId(), e.getName(), user); this.plugin.getEventFactory().handleUserLoginProcess(e.getUniqueId(), e.getName(), user);
} catch (Exception ex) { } 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(); ex.printStackTrace();
// deny the connection // 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. // This is a problem, as they were denied at low priority, but are now being allowed.
if (e.getLoginResult() == AsyncPlayerPreLoginEvent.Result.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, ""); e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, "");
} }
} }
@ -124,7 +124,7 @@ public class BukkitConnectionListener extends AbstractLoginListener implements L
final Player player = e.getPlayer(); final Player player = e.getPlayer();
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) { 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()); final User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId());
@ -133,7 +133,7 @@ public class BukkitConnectionListener extends AbstractLoginListener implements L
if (user == null) { if (user == null) {
this.deniedLogin.add(e.getPlayer().getUniqueId()); 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())); e.disallow(PlayerLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.asString(this.plugin.getLocaleManager()));
return; 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. // This is a problem, as they were denied at low priority, but are now being allowed.
if (e.getResult() == PlayerLoginEvent.Result.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, ""); e.disallow(PlayerLoginEvent.Result.KICK_OTHER, "");
} }
} }
@ -202,7 +202,7 @@ public class BukkitConnectionListener extends AbstractLoginListener implements L
this.plugin.getUserManager().getHouseKeeper().registerUsage(player.getUniqueId()); this.plugin.getUserManager().getHouseKeeper().registerUsage(player.getUniqueId());
// force a clear of transient nodes // force a clear of transient nodes
this.plugin.getScheduler().doAsync(() -> { this.plugin.getBootstrap().getScheduler().doAsync(() -> {
User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId()); User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId());
if (user != null) { if (user != null) {
user.clearTransientNodes(); user.clearTransientNodes();

View File

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

View File

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

View File

@ -58,7 +58,7 @@ public class LilyPadMessenger implements Messenger {
} }
public void init() { 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); this.connect.registerEvents(this);
} }
@ -87,7 +87,7 @@ public class LilyPadMessenger implements Messenger {
@EventListener @EventListener
public void onMessage(MessageEvent event) { public void onMessage(MessageEvent event) {
this.plugin.getScheduler().doAsync(() -> { this.plugin.getBootstrap().getScheduler().doAsync(() -> {
try { try {
String channel = event.getChannel(); String channel = event.getChannel();

View File

@ -219,7 +219,7 @@ public class LPPermissible extends PermissibleBase {
} }
LPPermissionAttachment ret = addAttachment(plugin); 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(); ret.remove();
throw new RuntimeException("Could not add PermissionAttachment to " + this.player + " for plugin " + plugin.getDescription().getFullName() + ": Scheduler returned -1"); 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 @Override
public Plugin getPlugin() { public Plugin getPlugin() {
return this.owner != null ? this.owner : this.permissible.getPlugin(); return this.owner != null ? this.owner : this.permissible.getPlugin().getBootstrap();
} }
@Override @Override

View File

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

View File

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

View File

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

View File

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

View File

@ -207,7 +207,7 @@ public final class LPSubscriptionMap extends HashMap<String, Map<Permissible, Bo
@Override @Override
public Set<Permissible> keySet() { public Set<Permissible> keySet() {
// gather players (LPPermissibles) // 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)) .filter(player -> player.isPermissionSet(this.permission))
.collect(Collectors.toSet()); .collect(Collectors.toSet());

View File

@ -270,7 +270,7 @@ public class VaultChatHook extends AbstractVaultChat {
return this.plugin.getConfiguration().get(ConfigKeys.VAULT_DEBUG); return this.plugin.getConfiguration().get(ConfigKeys.VAULT_DEBUG);
} }
private void logMsg(String format, Object... args) { 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.SECTION_CHAR, '$')
.replace(CommandManager.AMPERSAND_CHAR, '$') .replace(CommandManager.AMPERSAND_CHAR, '$')
); );

View File

@ -56,9 +56,9 @@ public class VaultHookManager {
this.chatHook = new VaultChatHook(plugin, this.permissionHook); this.chatHook = new VaultChatHook(plugin, this.permissionHook);
} }
final ServicesManager sm = plugin.getServer().getServicesManager(); final ServicesManager sm = plugin.getBootstrap().getServer().getServicesManager();
sm.register(Permission.class, this.permissionHook, plugin, ServicePriority.High); sm.register(Permission.class, this.permissionHook, plugin.getBootstrap(), ServicePriority.High);
sm.register(Chat.class, this.chatHook, plugin, ServicePriority.High); sm.register(Chat.class, this.chatHook, plugin.getBootstrap(), ServicePriority.High);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -71,7 +71,7 @@ public class VaultHookManager {
* @param plugin the plugin * @param plugin the plugin
*/ */
public void unhook(LPBukkitPlugin plugin) { public void unhook(LPBukkitPlugin plugin) {
final ServicesManager sm = plugin.getServer().getServicesManager(); final ServicesManager sm = plugin.getBootstrap().getServer().getServicesManager();
if (this.permissionHook != null) { if (this.permissionHook != null) {
sm.unregister(Permission.class, this.permissionHook); 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); return this.plugin.getConfiguration().get(ConfigKeys.VAULT_DEBUG);
} }
private void logMsg(String format, Object... args) { 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.SECTION_CHAR, '$')
.replace(CommandManager.AMPERSAND_CHAR, '$') .replace(CommandManager.AMPERSAND_CHAR, '$')
); );
@ -337,7 +337,7 @@ public class VaultPermissionHook extends AbstractVaultPermission {
Contexts contextForLookup(User user, String world) { Contexts contextForLookup(User user, String world) {
MutableContextSet context; 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) { if (player != null) {
context = this.plugin.getContextManager().getApplicableContext(player).mutableCopy(); context = this.plugin.getContextManager().getApplicableContext(player).mutableCopy();
} else { } else {
@ -402,11 +402,11 @@ public class VaultPermissionHook extends AbstractVaultPermission {
void holderSave(PermissionHolder holder) { void holderSave(PermissionHolder holder) {
if (holder.getType().isUser()) { if (holder.getType().isUser()) {
User u = (User) holder; 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()) { if (holder.getType().isGroup()) {
Group g = (Group) holder; 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 author: Luck
website: https://github.com/lucko/LuckPerms website: https://github.com/lucko/LuckPerms
main: me.lucko.luckperms.bukkit.LPBukkitPlugin main: me.lucko.luckperms.bukkit.LPBukkitBootstrap
load: STARTUP load: STARTUP
# This means that all plugins that (soft-)depend on Vault, depend on LuckPerms too. # 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; return ticks * MILLISECONDS_PER_TICK;
} }
private final LPBungeePlugin plugin; private final LPBungeeBootstrap bootstrap;
private final Executor asyncExecutor; private final Executor asyncExecutor;
private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet(); private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet();
public BungeeSchedulerAdapter(LPBungeePlugin plugin) { public BungeeSchedulerAdapter(LPBungeeBootstrap bootstrap) {
this.plugin = plugin; this.bootstrap = bootstrap;
this.asyncExecutor = r -> plugin.getProxy().getScheduler().runAsync(plugin, r); this.asyncExecutor = r -> bootstrap.getProxy().getScheduler().runAsync(bootstrap, r);
} }
private TaskScheduler scheduler() { private TaskScheduler scheduler() {
return this.plugin.getProxy().getScheduler(); return this.bootstrap.getProxy().getScheduler();
} }
@Override @Override
@ -87,7 +87,7 @@ public class BungeeSchedulerAdapter implements SchedulerAdapter {
@Override @Override
public SchedulerTask asyncRepeating(Runnable runnable, long intervalTicks) { public SchedulerTask asyncRepeating(Runnable runnable, long intervalTicks) {
long millis = ticksToMillis(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); this.tasks.add(task);
return task; return task;
} }
@ -99,7 +99,7 @@ public class BungeeSchedulerAdapter implements SchedulerAdapter {
@Override @Override
public SchedulerTask asyncLater(Runnable runnable, long delayTicks) { 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 @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; package me.lucko.luckperms.bungee;
import me.lucko.luckperms.api.Contexts; 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.calculators.BungeeCalculatorFactory;
import me.lucko.luckperms.bungee.contexts.BackendServerCalculator; import me.lucko.luckperms.bungee.contexts.BackendServerCalculator;
import me.lucko.luckperms.bungee.contexts.BungeeContextManager; 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.BungeeConnectionListener;
import me.lucko.luckperms.bungee.listeners.BungeePermissionCheckListener; import me.lucko.luckperms.bungee.listeners.BungeePermissionCheckListener;
import me.lucko.luckperms.bungee.messaging.BungeeMessagingFactory; 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.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.CommandManager; import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.AbstractConfiguration; import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.contexts.ContextManager; import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.contexts.LuckPermsCalculator; import me.lucko.luckperms.common.listener.ConnectionListener;
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.managers.group.StandardGroupManager; import me.lucko.luckperms.common.managers.group.StandardGroupManager;
import me.lucko.luckperms.common.managers.track.StandardTrackManager; import me.lucko.luckperms.common.managers.track.StandardTrackManager;
import me.lucko.luckperms.common.managers.user.StandardUserManager; 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.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.AbstractLuckPermsPlugin;
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.tasks.CacheHousekeepingTask; import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask; 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.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Plugin;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
* LuckPerms implementation for the BungeeCord API. * 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 BungeeSenderFactory senderFactory;
private SchedulerAdapter scheduler; private BungeeConnectionListener connectionListener;
private CommandManager commandManager; private CommandManager commandManager;
private LuckPermsConfiguration configuration;
private StandardUserManager userManager; private StandardUserManager userManager;
private StandardGroupManager groupManager; private StandardGroupManager groupManager;
private StandardTrackManager trackManager; 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 ContextManager<ProxiedPlayer> contextManager;
private CalculatorFactory calculatorFactory;
private BufferedRequest<Void> updateTaskBuffer; public LPBungeePlugin(LPBungeeBootstrap bootstrap) {
private VerboseHandler verboseHandler; this.bootstrap = bootstrap;
private BungeeSenderFactory senderFactory; }
private PermissionVault permissionVault;
private LogDispatcher logDispatcher;
private Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
@Override @Override
public void onLoad() { public LPBungeeBootstrap getBootstrap() {
// setup minimal functionality in order to load initial dependencies return this.bootstrap;
this.scheduler = new BungeeSchedulerAdapter(this); }
this.localeManager = new NoopLocaleManager();
@Override
protected void setupSenderFactory() {
this.senderFactory = new BungeeSenderFactory(this); 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 @Override
public void onEnable() { protected ConfigurationAdapter provideConfigurationAdapter() {
this.startTime = System.currentTimeMillis(); return new BungeeConfigAdapter(this, resolveConfig());
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);
} }
// initialise datastore @Override
this.storage = storageFactory.getInstance(StorageType.H2); 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 @Override
this.messagingService = new BungeeMessagingFactory(this).getInstance(); protected MessagingFactory<?> provideMessagingFactory() {
return new BungeeMessagingFactory(this);
}
// setup the update task buffer @Override
this.updateTaskBuffer = new UpdateTaskBuffer(this); protected void registerCommands() {
// load locale
this.localeManager = new SimpleLocaleManager();
this.localeManager.tryLoad(this, new File(getDataFolder(), "lang.yml"));
// register commands
this.commandManager = new CommandManager(this); 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 // 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 @Override
getLog().info("Loading internal permission managers..."); protected void setupManagers() {
this.inheritanceHandler = new InheritanceHandler(this);
this.userManager = new StandardUserManager(this); this.userManager = new StandardUserManager(this);
this.groupManager = new StandardGroupManager(this); this.groupManager = new StandardGroupManager(this);
this.trackManager = new StandardTrackManager(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 @Override
public void onDisable() { protected CalculatorFactory provideCalculatorFactory() {
this.permissionVault.shutdown(); return new BungeeCalculatorFactory(this);
this.verboseHandler.shutdown();
getLog().info("Closing storage...");
this.storage.shutdown();
if (this.fileWatcher != null) {
this.fileWatcher.close();
} }
if (this.messagingService != null) { @Override
getLog().info("Closing messaging service..."); protected void setupContextManager() {
this.messagingService.close(); 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) { @Override
File configFile = new File(getDataFolder(), file); 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()) { if (!configFile.exists()) {
getDataFolder().mkdirs(); this.bootstrap.getDataFolder().mkdirs();
try (InputStream is = getResourceAsStream(file)) { try (InputStream is = this.bootstrap.getResourceAsStream("config.yml")) {
Files.copy(is, configFile.toPath()); Files.copy(is, configFile.toPath());
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -272,122 +170,35 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
return configFile; 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 @Override
public Optional<Contexts> getContextForUser(User user) { public Optional<Contexts> getContextForUser(User user) {
ProxiedPlayer player = getPlayer(user); ProxiedPlayer player = this.bootstrap.getPlayer(user.getUuid());
if (player == null) { if (player == null) {
return Optional.empty(); return Optional.empty();
} }
return Optional.of(this.contextManager.getApplicableContexts(player)); 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 @Override
public Stream<Sender> getOnlineSenders() { public Stream<Sender> getOnlineSenders() {
return Stream.concat( return Stream.concat(
Stream.of(getConsoleSender()), Stream.of(getConsoleSender()),
getProxy().getPlayers().stream().map(p -> getSenderFactory().wrap(p)) this.bootstrap.getProxy().getPlayers().stream().map(p -> this.senderFactory.wrap(p))
); );
} }
@Override @Override
public Sender getConsoleSender() { public Sender getConsoleSender() {
return getSenderFactory().wrap(getProxy().getConsole()); return this.senderFactory.wrap(this.bootstrap.getProxy().getConsole());
}
public BungeeSenderFactory getSenderFactory() {
return this.senderFactory;
} }
@Override @Override
public long getStartTime() { public ConnectionListener getConnectionListener() {
return this.startTime; return this.connectionListener;
}
@Override
public SchedulerAdapter getScheduler() {
return this.scheduler;
} }
@Override @Override
@ -395,11 +206,6 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
return this.commandManager; return this.commandManager;
} }
@Override
public LuckPermsConfiguration getConfiguration() {
return this.configuration;
}
@Override @Override
public StandardUserManager getUserManager() { public StandardUserManager getUserManager() {
return this.userManager; return this.userManager;
@ -415,87 +221,9 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
return this.trackManager; 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 @Override
public ContextManager<ProxiedPlayer> getContextManager() { public ContextManager<ProxiedPlayer> getContextManager() {
return this.contextManager; 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.bungee.LPBungeePlugin;
import me.lucko.luckperms.common.config.ConfigKeys; 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.locale.Message;
import me.lucko.luckperms.common.model.User; 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.chat.TextComponent;
import net.md_5.bungee.api.connection.PendingConnection; import net.md_5.bungee.api.connection.PendingConnection;
@ -43,7 +43,7 @@ import net.md_5.bungee.event.EventPriority;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class BungeeConnectionListener extends AbstractLoginListener implements Listener { public class BungeeConnectionListener extends AbstractConnectionListener implements Listener {
private final LPBungeePlugin plugin; private final LPBungeePlugin plugin;
public BungeeConnectionListener(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. /* registers the plugins intent to modify this events state going forward.
this will prevent the event from completing until we're finished handling. */ 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(); final PendingConnection c = e.getConnection();
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) { 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.getBootstrap().getScheduler().doAsync(() -> {
this.plugin.getUniqueConnections().add(c.getUniqueId()); recordConnection(c.getUniqueId());
/* Actually process the login for the connection. /* Actually process the login for the connection.
We do this here to delay the login until the data is ready. 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()); User user = loadUser(c.getUniqueId(), c.getName());
this.plugin.getEventFactory().handleUserLoginProcess(c.getUniqueId(), c.getName(), user); this.plugin.getEventFactory().handleUserLoginProcess(c.getUniqueId(), c.getName(), user);
} catch (Exception ex) { } 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(); ex.printStackTrace();
// there was some error loading // 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. // 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()); final User user = this.plugin.getUserManager().getIfLoaded(e.getPlayer().getUniqueId());
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) { 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 (user == null) {
if (this.plugin.getConfiguration().get(ConfigKeys.CANCEL_FAILED_LOGINS)) { if (this.plugin.getConfiguration().get(ConfigKeys.CANCEL_FAILED_LOGINS)) {
// disconnect the user // 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()))); e.getPlayer().disconnect(TextComponent.fromLegacyText(Message.LOADING_ERROR.asString(this.plugin.getLocaleManager())));
} else { } else {
// just send a message // just send a message
this.plugin.getProxy().getScheduler().schedule(this.plugin, () -> { this.plugin.getBootstrap().getProxy().getScheduler().schedule(this.plugin.getBootstrap(), () -> {
if (!player.isConnected()) { if (!player.isConnected()) {
return; return;
} }
@ -139,7 +139,7 @@ public class BungeeConnectionListener extends AbstractLoginListener implements L
this.plugin.getUserManager().getHouseKeeper().registerUsage(player.getUniqueId()); this.plugin.getUserManager().getHouseKeeper().registerUsage(player.getUniqueId());
// force a clear of transient nodes // force a clear of transient nodes
this.plugin.getScheduler().doAsync(() -> { this.plugin.getBootstrap().getScheduler().doAsync(() -> {
User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId()); User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId());
if (user != null) { if (user != null) {
user.clearTransientNodes(); user.clearTransientNodes();

View File

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

View File

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

View File

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

View File

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

View File

@ -58,7 +58,7 @@ public class ApiActionLogger implements ActionLogger {
@Nonnull @Nonnull
@Override @Override
public CompletableFuture<Void> submit(@Nonnull LogEntry entry) { 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 @Nonnull
@ -70,6 +70,6 @@ public class ApiActionLogger implements ActionLogger {
@Nonnull @Nonnull
@Override @Override
public CompletableFuture<Void> broadcastAction(@Nonnull LogEntry entry) { 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 @Nonnull
@Override @Override
public String getVersion() { public String getVersion() {
return this.plugin.getVersion(); return this.plugin.getBootstrap().getVersion();
} }
@Override @Override
@ -56,17 +56,17 @@ public class ApiPlatformInfo implements PlatformInfo {
@Nonnull @Nonnull
@Override @Override
public PlatformType getType() { public PlatformType getType() {
return this.plugin.getServerType(); return this.plugin.getBootstrap().getType();
} }
@Nonnull @Nonnull
@Override @Override
public Set<UUID> getUniqueConnections() { public Set<UUID> getUniqueConnections() {
return Collections.unmodifiableSet(this.plugin.getUniqueConnections()); return Collections.unmodifiableSet(this.plugin.getConnectionListener().getUniqueConnections());
} }
@Override @Override
public long getStartTime() { 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 @Nonnull
@Override @Override
public Executor getSyncExecutor() { public Executor getSyncExecutor() {
return this.plugin.getScheduler().sync(); return this.plugin.getBootstrap().getScheduler().sync();
} }
@Nonnull @Nonnull
@Override @Override
public Executor getAsyncExecutor() { public Executor getAsyncExecutor() {
return this.plugin.getScheduler().async(); return this.plugin.getBootstrap().getScheduler().async();
} }
@Nonnull @Nonnull

View File

@ -250,7 +250,7 @@ public class Exporter implements Runnable {
e.printStackTrace(); 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 // 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(); cmd.process();
processedCount.incrementAndGet(); 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 // 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; private final LuckPermsPlugin plugin;
public UpdateTaskBuffer(LuckPermsPlugin plugin) { public UpdateTaskBuffer(LuckPermsPlugin plugin) {
super(250L, 50L, plugin.getScheduler().async()); super(250L, 50L, plugin.getBootstrap().getScheduler().async());
this.plugin = plugin; this.plugin = plugin;
} }

View File

@ -145,7 +145,7 @@ public class CommandManager {
try { try {
return execute(sender, label, args); return execute(sender, label, args);
} catch (Throwable e) { } 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(); e.printStackTrace();
return null; return null;
} }
@ -159,7 +159,7 @@ public class CommandManager {
// Handle no arguments // Handle no arguments
if (arguments.isEmpty() || (arguments.size() == 1 && arguments.get(0).trim().isEmpty())) { 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))) { if (this.mainCommands.stream().anyMatch(c -> c.shouldDisplay() && c.isAuthorized(sender))) {
Message.VIEW_AVAILABLE_COMMANDS_PROMPT.send(sender, label); Message.VIEW_AVAILABLE_COMMANDS_PROMPT.send(sender, label);
} else { } else {
@ -257,7 +257,7 @@ public class CommandManager {
} }
private void sendCommandUsage(Sender sender, String label) { 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() this.mainCommands.stream()
.filter(Command::shouldDisplay) .filter(Command::shouldDisplay)
.filter(c -> c.isAuthorized(sender)) .filter(c -> c.isAuthorized(sender))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -62,7 +62,7 @@ public class UserInfo extends SubCommand<User> {
return CommandResult.NO_PERMISSION; 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, Message.USER_INFO_GENERAL.send(sender,
user.getName().orElse("Unknown"), user.getName().orElse("Unknown"),

View File

@ -103,7 +103,7 @@ public class UserMainCommand extends MainCommand<User, UserIdentifier> {
return null; return null;
} }
uuid = plugin.lookupUuid(target).orElse(null); uuid = plugin.getBootstrap().lookupUuid(target).orElse(null);
if (uuid == null) { if (uuid == null) {
Message.USER_NOT_FOUND.send(sender, target); Message.USER_NOT_FOUND.send(sender, target);
return null; return null;
@ -134,6 +134,6 @@ public class UserMainCommand extends MainCommand<User, UserIdentifier> {
@Override @Override
protected List<String> getTargets(LuckPermsPlugin plugin) { 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 -> { public static final ConfigKey<String> SERVER = AbstractKey.of(c -> {
if (c.getBoolean("use-server-properties-name", false)) { 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")) { if (serverName != null && !serverName.equals("Unknown Server")) {
return serverName.toLowerCase(); return serverName.toLowerCase();
} }

View File

@ -53,8 +53,8 @@ public class ContextsFile {
} }
public void load() { public void load() {
File file = new File(this.configuration.getPlugin().getConfigDirectory(), "contexts.json"); File file = new File(this.configuration.getPlugin().getBootstrap().getDataDirectory(), "contexts.json");
File oldFile = new File(this.configuration.getPlugin().getConfigDirectory(), "static-contexts.json"); File oldFile = new File(this.configuration.getPlugin().getBootstrap().getDataDirectory(), "static-contexts.json");
if (oldFile.exists()) { if (oldFile.exists()) {
oldFile.renameTo(file); oldFile.renameTo(file);
} }
@ -91,7 +91,7 @@ public class ContextsFile {
} }
public void save() { 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)) { 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; accumulator = ret;
} catch (Exception e) { } 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(); e.printStackTrace();
} }
} }
@ -225,7 +225,7 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
} }
accumulator = ret; accumulator = ret;
} catch (Exception e) { } 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(); e.printStackTrace();
} }
} }

View File

@ -79,7 +79,7 @@ public class DependencyManager {
} }
private File getSaveDirectory() { 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())) { if (!(saveDirectory.exists() || saveDirectory.mkdirs())) {
throw new RuntimeException("Unable to create lib dir - " + saveDirectory.getPath()); throw new RuntimeException("Unable to create lib dir - " + saveDirectory.getPath());
} }
@ -139,7 +139,7 @@ public class DependencyManager {
File file = downloadDependency(saveDirectory, dependency); File file = downloadDependency(saveDirectory, dependency);
sources.add(new Source(dependency, file)); sources.add(new Source(dependency, file));
} catch (Throwable e) { } 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(); e.printStackTrace();
} }
} }
@ -169,12 +169,12 @@ public class DependencyManager {
RelocationHandler relocationHandler = getRelocationHandler(); RelocationHandler relocationHandler = getRelocationHandler();
// attempt to remap the jar. // 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); relocationHandler.remap(input, output, relocations);
remappedJars.add(new Source(source.dependency, output)); remappedJars.add(new Source(source.dependency, output));
} catch (Throwable e) { } 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(); e.printStackTrace();
} }
} }
@ -187,10 +187,10 @@ public class DependencyManager {
} }
try { try {
this.plugin.getPluginClassLoader().loadJar(source.file); this.plugin.getBootstrap().getPluginClassLoader().loadJar(source.file);
this.loaded.put(source.dependency, source.file); this.loaded.put(source.dependency, source.file);
} catch (Throwable e) { } 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(); e.printStackTrace();
} }
} }
@ -218,7 +218,7 @@ public class DependencyManager {
// compute a hash for the downloaded file // compute a hash for the downloaded file
byte[] hash = this.digest.digest(bytes); 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 // ensure the hash matches the expected checksum
if (!Arrays.equals(hash, dependency.getChecksum())) { if (!Arrays.equals(hash, dependency.getChecksum())) {

View File

@ -83,7 +83,7 @@ public class DependencyRegistry {
} }
// don't load configurate dependencies on sponge // 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_CORE);
dependencies.remove(Dependency.CONFIGURATE_GSON); dependencies.remove(Dependency.CONFIGURATE_GSON);
dependencies.remove(Dependency.CONFIGURATE_YAML); dependencies.remove(Dependency.CONFIGURATE_YAML);

View File

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

View File

@ -78,7 +78,7 @@ public class LuckPermsEventHandler<T extends LuckPermsEvent> implements EventHan
this.consumer.accept(t); this.consumer.accept(t);
this.callCount.incrementAndGet(); this.callCount.incrementAndGet();
} catch (Throwable t) { } 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(); t.printStackTrace();
} }
} }

View File

@ -23,25 +23,37 @@
* SOFTWARE. * 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.assignments.AssignmentRule;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* Abstract listener utility for handling new player connections * Abstract listener utility for handling new player connections
*/ */
public abstract class AbstractLoginListener { public abstract class AbstractConnectionListener implements ConnectionListener {
private final LuckPermsPlugin plugin; private final LuckPermsPlugin plugin;
private final Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
protected AbstractLoginListener(LuckPermsPlugin plugin) { protected AbstractConnectionListener(LuckPermsPlugin plugin) {
this.plugin = 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) { public User loadUser(UUID u, String username) {
final long startTime = System.currentTimeMillis(); final long startTime = System.currentTimeMillis();
@ -78,7 +90,7 @@ public abstract class AbstractLoginListener {
final long time = System.currentTimeMillis() - startTime; final long time = System.currentTimeMillis() - startTime;
if (time >= 1000) { 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; return user;

View File

@ -23,37 +23,21 @@
* SOFTWARE. * 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 { /**
* Gets the unique players which have connected to the server since it started.
@Override *
public void tryLoad(LuckPermsPlugin plugin, File file) { * @return the unique connections
*/
} Set<UUID> getUniqueConnections();
@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;
}
} }

View File

@ -45,7 +45,7 @@ public class SimpleLocaleManager implements LocaleManager {
@Override @Override
public void tryLoad(LuckPermsPlugin plugin, File file) { public void tryLoad(LuckPermsPlugin plugin, File file) {
if (file.exists()) { if (file.exists()) {
plugin.getLog().info("Found lang.yml - loading messages..."); plugin.getLogger().info("Found lang.yml - loading messages...");
try { try {
loadFromFile(file); loadFromFile(file);
} catch (Exception e) { } 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) { public AbstractUserManager(LuckPermsPlugin plugin, UserHousekeeper.TimeoutSettings timeoutSettings) {
this.plugin = plugin; this.plugin = plugin;
this.housekeeper = new UserHousekeeper(plugin, this, timeoutSettings); 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 @Override
@ -147,8 +147,8 @@ public abstract class AbstractUserManager<T extends User> extends AbstractManage
@Override @Override
public CompletableFuture<Void> updateAllUsers() { public CompletableFuture<Void> updateAllUsers() {
return CompletableFuture.runAsync( return CompletableFuture.runAsync(
() -> this.plugin.getOnlinePlayers().forEach(u -> this.plugin.getStorage().loadUser(u, null).join()), () -> this.plugin.getBootstrap().getOnlinePlayers().forEach(u -> this.plugin.getStorage().loadUser(u, null).join()),
this.plugin.getScheduler().async() this.plugin.getBootstrap().getScheduler().async()
); );
} }

View File

@ -76,7 +76,7 @@ public class UserHousekeeper implements Runnable {
UUID uuid = identifier.getUuid(); UUID uuid = identifier.getUuid();
// unload users which aren't online and who haven't been online (or tried to login) recently // 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; return;
} }

View File

@ -102,32 +102,32 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
@Override @Override
public void pushUpdate() { public void pushUpdate() {
this.plugin.getScheduler().doAsync(() -> { this.plugin.getBootstrap().getScheduler().doAsync(() -> {
UUID requestId = generatePingId(); 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)); this.messenger.sendOutgoingMessage(new UpdateMessageImpl(requestId));
}); });
} }
@Override @Override
public void pushUserUpdate(User user) { public void pushUserUpdate(User user) {
this.plugin.getScheduler().doAsync(() -> { this.plugin.getBootstrap().getScheduler().doAsync(() -> {
UUID requestId = generatePingId(); 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())); this.messenger.sendOutgoingMessage(new UserUpdateMessageImpl(requestId, user.getUuid()));
}); });
} }
@Override @Override
public void pushLog(LogEntry logEntry) { public void pushLog(LogEntry logEntry) {
this.plugin.getScheduler().doAsync(() -> { this.plugin.getBootstrap().getScheduler().doAsync(() -> {
UUID requestId = generatePingId(); UUID requestId = generatePingId();
if (this.plugin.getEventFactory().handleLogNetworkPublish(!this.plugin.getConfiguration().get(ConfigKeys.PUSH_LOG_ENTRIES), requestId, logEntry)) { if (this.plugin.getEventFactory().handleLogNetworkPublish(!this.plugin.getConfiguration().get(ConfigKeys.PUSH_LOG_ENTRIES), requestId, logEntry)) {
return; 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)); this.messenger.sendOutgoingMessage(new LogMessageImpl(requestId, logEntry));
}); });
} }
@ -142,7 +142,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
return false; 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())) { if (this.plugin.getEventFactory().handleNetworkPreSync(false, msg.getId())) {
return true; return true;
@ -162,7 +162,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
return true; 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())) { if (this.plugin.getEventFactory().handleNetworkPreSync(false, msg.getId())) {
return true; return true;
@ -182,7 +182,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
return true; return true;
} else { } 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; return false;
} }
} }
@ -207,7 +207,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
private final class PushUpdateBuffer extends BufferedRequest<Void> { private final class PushUpdateBuffer extends BufferedRequest<Void> {
public PushUpdateBuffer(LuckPermsPlugin plugin) { public PushUpdateBuffer(LuckPermsPlugin plugin) {
super(2000L, 200L, plugin.getScheduler().async()); super(2000L, 200L, plugin.getBootstrap().getScheduler().async());
} }
@Override @Override

View File

@ -55,14 +55,14 @@ public class MessagingFactory<P extends LuckPermsPlugin> {
return null; return null;
} }
this.plugin.getLog().info("Loading messaging service... [" + messagingType.toUpperCase() + "]"); this.plugin.getLogger().info("Loading messaging service... [" + messagingType.toUpperCase() + "]");
InternalMessagingService service = getServiceFor(messagingType); InternalMessagingService service = getServiceFor(messagingType);
if (service != null) { if (service != null) {
return service; return service;
} }
this.plugin.getLog().warn("Messaging service '" + messagingType + "' not recognised."); this.plugin.getLogger().warn("Messaging service '" + messagingType + "' not recognised.");
return null; return null;
} }
@ -75,7 +75,7 @@ public class MessagingFactory<P extends LuckPermsPlugin> {
e.printStackTrace(); e.printStackTrace();
} }
} else { } 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.jedisPool = new JedisPool(new JedisPoolConfig(), host, port, 0, password);
} }
this.plugin.getScheduler().doAsync(() -> { this.plugin.getBootstrap().getScheduler().doAsync(() -> {
this.sub = new LPSub(this); this.sub = new LPSub(this);
try (Jedis jedis = this.jedisPool.getResource()) { try (Jedis jedis = this.jedisPool.getResource()) {
jedis.subscribe(this.sub, CHANNEL); jedis.subscribe(this.sub, CHANNEL);

View File

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

View File

@ -235,7 +235,7 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
private final User user; private final User user;
private UserRefreshBuffer(LuckPermsPlugin plugin, User user) { private UserRefreshBuffer(LuckPermsPlugin plugin, User user) {
super(50L, 5L, plugin.getScheduler().async()); super(50L, 5L, plugin.getBootstrap().getScheduler().async());
this.user = user; 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; package me.lucko.luckperms.common.plugin;
import me.lucko.luckperms.api.Contexts; 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.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.LuckPermsApiProvider; import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest; 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.CommandManager;
import me.lucko.luckperms.common.commands.abstraction.Command; import me.lucko.luckperms.common.commands.abstraction.Command;
import me.lucko.luckperms.common.commands.sender.Sender; 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.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.contexts.ContextManager; import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.dependencies.DependencyManager; 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.event.EventFactory;
import me.lucko.luckperms.common.inheritance.InheritanceHandler; 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.locale.LocaleManager;
import me.lucko.luckperms.common.logging.Logger; import me.lucko.luckperms.common.logging.Logger;
import me.lucko.luckperms.common.managers.group.GroupManager; 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.managers.user.UserManager;
import me.lucko.luckperms.common.messaging.InternalMessagingService; import me.lucko.luckperms.common.messaging.InternalMessagingService;
import me.lucko.luckperms.common.model.User; 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.Storage;
import me.lucko.luckperms.common.storage.dao.file.FileWatcher; import me.lucko.luckperms.common.storage.dao.file.FileWatcher;
import me.lucko.luckperms.common.treeview.PermissionVault; import me.lucko.luckperms.common.treeview.PermissionVault;
import me.lucko.luckperms.common.verbose.VerboseHandler; import me.lucko.luckperms.common.verbose.VerboseHandler;
import java.io.File;
import java.io.InputStream;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -71,6 +66,13 @@ import java.util.stream.Stream;
*/ */
public interface LuckPermsPlugin { public interface LuckPermsPlugin {
/**
* Gets the bootstrap plugin instance
*
* @return the bootstrap plugin
*/
LuckPermsBootstrap getBootstrap();
/** /**
* Gets the user manager instance for the platform * Gets the user manager instance for the platform
* *
@ -125,7 +127,7 @@ public interface LuckPermsPlugin {
* *
* @return the plugin's logger * @return the plugin's logger
*/ */
Logger getLog(); Logger getLogger();
/** /**
* Gets the event factory * Gets the event factory
@ -148,6 +150,13 @@ public interface LuckPermsPlugin {
*/ */
CommandManager getCommandManager(); CommandManager getCommandManager();
/**
* Gets the connection listener.
*
* @return the connection listener
*/
ConnectionListener getConnectionListener();
/** /**
* Gets the instance providing locale translations for the plugin * Gets the instance providing locale translations for the plugin
* *
@ -155,13 +164,6 @@ public interface LuckPermsPlugin {
*/ */
LocaleManager getLocaleManager(); 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 * Gets the dependency manager for the plugin
* *
@ -219,13 +221,6 @@ public interface LuckPermsPlugin {
*/ */
LogDispatcher getLogDispatcher(); LogDispatcher getLogDispatcher();
/**
* Gets the LuckPerms Scheduler instance
*
* @return the scheduler
*/
SchedulerAdapter getScheduler();
/** /**
* Gets the file watcher running on the platform * Gets the file watcher running on the platform
* *
@ -233,97 +228,6 @@ public interface LuckPermsPlugin {
*/ */
Optional<FileWatcher> getFileWatcher(); 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. * 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); 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 * Gets a list of online Senders on the platform
* *
@ -375,13 +250,6 @@ public interface LuckPermsPlugin {
*/ */
Sender getConsoleSender(); 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() { default List<Command> getExtraCommands() {
return Collections.emptyList(); 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(); Executor async();
default Executor platformAsync() {
return async();
}
/** /**
* Gets a sync executor instance * 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 base = new AbstractStorage(plugin, backing);
Storage phased = PhasedStorage.wrap(base); Storage phased = PhasedStorage.wrap(base);
BufferedOutputStorage buffered = BufferedOutputStorage.wrap(phased, 250L); BufferedOutputStorage buffered = BufferedOutputStorage.wrap(phased, 250L);
plugin.getScheduler().asyncRepeating(buffered, 2L); plugin.getBootstrap().getScheduler().asyncRepeating(buffered, 2L);
return buffered; return buffered;
} }
@ -88,7 +88,7 @@ public class AbstractStorage implements Storage {
Throwables.propagateIfPossible(e); Throwables.propagateIfPossible(e);
throw new CompletionException(e); throw new CompletionException(e);
} }
}, this.dao.getPlugin().getScheduler().async()); }, this.dao.getPlugin().getBootstrap().getScheduler().async());
} }
private CompletableFuture<Void> makeFuture(ThrowingRunnable runnable) { private CompletableFuture<Void> makeFuture(ThrowingRunnable runnable) {
@ -99,7 +99,7 @@ public class AbstractStorage implements Storage {
Throwables.propagateIfPossible(e); Throwables.propagateIfPossible(e);
throw new CompletionException(e); throw new CompletionException(e);
} }
}, this.dao.getPlugin().getScheduler().async()); }, this.dao.getPlugin().getBootstrap().getScheduler().async());
} }
@Override @Override
@ -126,7 +126,7 @@ public class AbstractStorage implements Storage {
try { try {
this.dao.init(); this.dao.init();
} catch (Exception e) { } catch (Exception e) {
this.plugin.getLog().severe("Failed to init storage dao"); this.plugin.getLogger().severe("Failed to init storage dao");
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -136,7 +136,7 @@ public class AbstractStorage implements Storage {
try { try {
this.dao.shutdown(); this.dao.shutdown();
} catch (Exception e) { } catch (Exception e) {
this.plugin.getLog().severe("Failed to shutdown storage dao"); this.plugin.getLogger().severe("Failed to shutdown storage dao");
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@ -62,7 +62,7 @@ public class StorageFactory {
.map(e -> { .map(e -> {
StorageType type = StorageType.parse(e.getValue()); StorageType type = StorageType.parse(e.getValue());
if (type == null) { 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."); "Using the default instead.");
type = defaultMethod; type = defaultMethod;
} }
@ -73,7 +73,7 @@ public class StorageFactory {
String method = this.plugin.getConfiguration().get(ConfigKeys.STORAGE_METHOD); String method = this.plugin.getConfiguration().get(ConfigKeys.STORAGE_METHOD);
StorageType type = StorageType.parse(method); StorageType type = StorageType.parse(method);
if (type == null) { 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; type = defaultMethod;
} }
return ImmutableSet.of(type); return ImmutableSet.of(type);
@ -83,7 +83,7 @@ public class StorageFactory {
public Storage getInstance(StorageType defaultMethod) { public Storage getInstance(StorageType defaultMethod) {
Storage storage; Storage storage;
if (this.plugin.getConfiguration().get(ConfigKeys.SPLIT_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<SplitStorageType, StorageType> mappedTypes = this.plugin.getConfiguration().get(ConfigKeys.SPLIT_STORAGE_OPTIONS).entrySet().stream()
.map(e -> { .map(e -> {
@ -108,7 +108,7 @@ public class StorageFactory {
type = defaultMethod; type = defaultMethod;
} }
this.plugin.getLog().info("Loading storage provider... [" + type.name() + "]"); this.plugin.getLogger().info("Loading storage provider... [" + type.name() + "]");
storage = makeInstance(type); storage = makeInstance(type);
} }
@ -139,13 +139,13 @@ public class StorageFactory {
case SQLITE: case SQLITE:
return new SqlDao( return new SqlDao(
this.plugin, 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) this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX)
); );
case H2: case H2:
return new SqlDao( return new SqlDao(
this.plugin, 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) this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX)
); );
case POSTGRESQL: case POSTGRESQL:

View File

@ -150,7 +150,7 @@ public abstract class ConfigurateDao extends AbstractDao {
} }
private Exception reportException(String file, Exception ex) throws Exception { 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(); ex.printStackTrace();
throw ex; throw ex;
} }
@ -162,7 +162,7 @@ public abstract class ConfigurateDao extends AbstractDao {
@Override @Override
public void init() { public void init() {
try { 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.usersDirectory = FileUtils.mkdir(new File(data, "users"));
this.groupsDirectory = FileUtils.mkdir(new File(data, "groups")); 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); User u = this.plugin.getUserManager().getIfLoaded(uuid);
if (u != null) { 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); 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()); 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(); this.plugin.getUpdateTaskBuffer().request();
}); });
watcher.subscribe("track", this.tracksDirectory.toPath(), s -> { 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()); 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(); this.plugin.getStorage().loadAllTracks();
}); });
}); });

View File

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

View File

@ -154,7 +154,7 @@ public class SqlDao extends AbstractDao {
// Init tables // Init tables
if (!tableExists(this.prefix.apply("{prefix}user_permissions"))) { if (!tableExists(this.prefix.apply("{prefix}user_permissions"))) {
String schemaFileName = "schema/" + this.provider.getName().toLowerCase() + ".sql"; 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) { if (is == null) {
throw new Exception("Couldn't locate schema file for " + this.provider.getName()); throw new Exception("Couldn't locate schema file for " + this.provider.getName());
} }
@ -203,7 +203,7 @@ public class SqlDao extends AbstractDao {
} catch (Exception e) { } 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(); 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.Contexts;
import me.lucko.luckperms.api.LuckPermsApi; 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.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.CommandPermission; import me.lucko.luckperms.common.commands.CommandPermission;
import me.lucko.luckperms.common.commands.sender.Sender; 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.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.ContextManager;
import me.lucko.luckperms.common.contexts.LuckPermsCalculator; import me.lucko.luckperms.common.listener.ConnectionListener;
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.managers.group.StandardGroupManager; import me.lucko.luckperms.common.managers.group.StandardGroupManager;
import me.lucko.luckperms.common.managers.track.StandardTrackManager; import me.lucko.luckperms.common.managers.track.StandardTrackManager;
import me.lucko.luckperms.common.managers.user.StandardUserManager; 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.messaging.MessagingFactory;
import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.AbstractLuckPermsPlugin;
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.CacheHousekeepingTask; import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask; 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.calculators.NukkitCalculatorFactory;
import me.lucko.luckperms.nukkit.contexts.NukkitContextManager; import me.lucko.luckperms.nukkit.contexts.NukkitContextManager;
import me.lucko.luckperms.nukkit.contexts.WorldCalculator; 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.Player;
import cn.nukkit.command.PluginCommand; import cn.nukkit.command.PluginCommand;
import cn.nukkit.event.HandlerList;
import cn.nukkit.permission.Permission; import cn.nukkit.permission.Permission;
import cn.nukkit.plugin.PluginBase;
import cn.nukkit.plugin.PluginManager; import cn.nukkit.plugin.PluginManager;
import cn.nukkit.plugin.service.ServicePriority; import cn.nukkit.plugin.service.ServicePriority;
import cn.nukkit.utils.Config; import cn.nukkit.utils.Config;
import java.io.File; import java.io.File;
import java.io.InputStream;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
* LuckPerms implementation for the Nukkit API. * 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 NukkitSenderFactory senderFactory;
private NukkitSchedulerAdapter scheduler; private NukkitConnectionListener connectionListener;
private NukkitCommandExecutor commandManager; private NukkitCommandExecutor commandManager;
private LuckPermsConfiguration configuration;
private StandardUserManager userManager; private StandardUserManager userManager;
private StandardGroupManager groupManager; private StandardGroupManager groupManager;
private StandardTrackManager trackManager; private StandardTrackManager trackManager;
private Storage storage; private ContextManager<Player> contextManager;
private FileWatcher fileWatcher = null;
private InternalMessagingService messagingService = null;
private LuckPermsApiProvider apiProvider;
private EventFactory eventFactory;
private Logger log;
private LPSubscriptionMap subscriptionMap; private LPSubscriptionMap subscriptionMap;
private LPPermissionMap permissionMap; private LPPermissionMap permissionMap;
private LPDefaultsMap defaultPermissionMap; private LPDefaultsMap defaultPermissionMap;
private LocaleManager localeManager;
private PluginClassLoader pluginClassLoader; public LPNukkitPlugin(LPNukkitBootstrap bootstrap) {
private DependencyManager dependencyManager; this.bootstrap = bootstrap;
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();
@Override @Override
public void onLoad() { public LPNukkitBootstrap getBootstrap() {
// setup minimal functionality in order to load initial dependencies return this.bootstrap;
this.scheduler = new NukkitSchedulerAdapter(this); }
this.localeManager = new NoopLocaleManager();
@Override
protected void setupSenderFactory() {
this.senderFactory = new NukkitSenderFactory(this); 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 @Override
public void onEnable() { protected ConfigurationAdapter provideConfigurationAdapter() {
this.startTime = System.currentTimeMillis(); return new NukkitConfigAdapter(this, resolveConfig());
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);
} }
// initialise datastore @Override
this.storage = storageFactory.getInstance(StorageType.H2); 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 @Override
this.messagingService = new MessagingFactory<>(this).getInstance(); protected MessagingFactory<?> provideMessagingFactory() {
return new MessagingFactory<>(this);
}
// setup the update task buffer @Override
this.updateTaskBuffer = new UpdateTaskBuffer(this); protected void registerCommands() {
// load locale
this.localeManager = new SimpleLocaleManager();
this.localeManager.tryLoad(this, new File(getDataFolder(), "lang.yml"));
// register commands
this.commandManager = new NukkitCommandExecutor(this); this.commandManager = new NukkitCommandExecutor(this);
PluginCommand main = (PluginCommand) getServer().getPluginCommand("luckperms"); PluginCommand main = (PluginCommand) this.bootstrap.getServer().getPluginCommand("luckperms");
main.setExecutor(this.commandManager); main.setExecutor(this.commandManager);
}
// load internal managers @Override
getLog().info("Loading internal permission managers..."); protected void setupManagers() {
this.inheritanceHandler = new InheritanceHandler(this);
this.userManager = new StandardUserManager(this); this.userManager = new StandardUserManager(this);
this.groupManager = new StandardGroupManager(this); this.groupManager = new StandardGroupManager(this);
this.trackManager = new StandardTrackManager(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 = new NukkitContextManager(this);
this.contextManager.registerCalculator(new WorldCalculator(this)); this.contextManager.registerCalculator(new WorldCalculator(this));
this.contextManager.registerStaticCalculator(new LuckPermsCalculator(getConfiguration())); }
@Override
protected void setupPlatformHooks() {
// inject our own custom permission maps // inject our own custom permission maps
Runnable[] injectors = new Runnable[]{ Runnable[] injectors = new Runnable[]{
new InjectorSubscriptionMap(this), new InjectorSubscriptionMap(this),
new InjectorPermissionMap(this), new InjectorPermissionMap(this),
new InjectorDefaultsMap(this) new InjectorDefaultsMap(this),
new PermissibleMonitoringInjector(this)
}; };
for (Runnable injector : injectors) { for (Runnable injector : injectors) {
@ -221,46 +158,26 @@ public class LPNukkitPlugin extends PluginBase implements LuckPermsPlugin {
// schedule another injection after all plugins have loaded // schedule another injection after all plugins have loaded
// the entire pluginmanager instance is replaced by some plugins :( // 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 @Override
new PermissibleMonitoringInjector(this).run(); protected void registerApiOnPlatform(LuckPermsApi api) {
this.bootstrap.getServer().getServiceManager().register(LuckPermsApi.class, api, this.bootstrap, ServicePriority.NORMAL);
// 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 registerHousekeepingTasks() {
this.bootstrap.getScheduler().asyncRepeating(new ExpireTemporaryTask(this), 60L);
this.bootstrap.getScheduler().asyncRepeating(new CacheHousekeepingTask(this), 2400L);
}
// register tasks @Override
this.scheduler.asyncRepeating(new ExpireTemporaryTask(this), 60L); protected void performFinalSetup() {
this.scheduler.asyncRepeating(new CacheHousekeepingTask(this), 2400L);
// register permissions // register permissions
try { try {
PluginManager pm = getServer().getPluginManager(); PluginManager pm = this.bootstrap.getServer().getPluginManager();
PermissionDefault permDefault = getConfiguration().get(ConfigKeys.COMMANDS_ALLOW_OP) ? PermissionDefault.OP : PermissionDefault.FALSE; PermissionDefault permDefault = getConfiguration().get(ConfigKeys.COMMANDS_ALLOW_OP) ? PermissionDefault.OP : PermissionDefault.FALSE;
for (CommandPermission p : CommandPermission.values()) { for (CommandPermission p : CommandPermission.values()) {
@ -271,20 +188,20 @@ public class LPNukkitPlugin extends PluginBase implements LuckPermsPlugin {
} }
if (!getConfiguration().get(ConfigKeys.OPS_ENABLED)) { if (!getConfiguration().get(ConfigKeys.OPS_ENABLED)) {
Config ops = getServer().getOps(); Config ops = this.bootstrap.getServer().getOps();
ops.getKeys(false).forEach(ops::remove); ops.getKeys(false).forEach(ops::remove);
} }
// replace the temporary executor when the Nukkit one starts // 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) // Load any online users (in the case of a reload)
for (Player player : getServer().getOnlinePlayers().values()) { for (Player player : this.bootstrap.getServer().getOnlinePlayers().values()) {
this.scheduler.doAsync(() -> { this.bootstrap.getScheduler().doAsync(() -> {
try { try {
User user = connectionListener.loadUser(player.getUniqueId(), player.getName()); User user = this.connectionListener.loadUser(player.getUniqueId(), player.getName());
if (user != null) { if (user != null) {
this.scheduler.doSync(() -> { this.bootstrap.getScheduler().doSync(() -> {
try { try {
LPPermissible lpPermissible = new LPPermissible(player, user, this); LPPermissible lpPermissible = new LPPermissible(player, user, this);
PermissibleInjector.inject(player, lpPermissible); 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 @Override
public void onDisable() { protected void performEarlyDisableTasks() {
// Switch back to the fallback executor, the nukkit one won't allow new tasks // Switch back to the fallback executor, the nukkit one won't allow new tasks
this.scheduler.setUseFallback(true); this.bootstrap.getScheduler().setUseFallback(true);
}
this.permissionVault.shutdown();
this.verboseHandler.shutdown();
@Override
protected void removePlatformHooks() {
// uninject from players // uninject from players
for (Player player : getServer().getOnlinePlayers().values()) { for (Player player : this.bootstrap.getServer().getOnlinePlayers().values()) {
try { try {
PermissibleInjector.unInject(player, false); PermissibleInjector.unInject(player, false);
} catch (Exception e) { } catch (Exception e) {
@ -333,29 +248,6 @@ public class LPNukkitPlugin extends PluginBase implements LuckPermsPlugin {
InjectorSubscriptionMap.uninject(); InjectorSubscriptionMap.uninject();
InjectorPermissionMap.uninject(); InjectorPermissionMap.uninject();
InjectorDefaultsMap.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) { public void refreshAutoOp(User user, Player player) {
@ -370,15 +262,69 @@ public class LPNukkitPlugin extends PluginBase implements LuckPermsPlugin {
} }
} }
private File resolveConfig(String file) { private File resolveConfig() {
File configFile = new File(getDataFolder(), file); File configFile = new File(this.bootstrap.getDataFolder(), "config.yml");
if (!configFile.exists()) { if (!configFile.exists()) {
getDataFolder().mkdirs(); this.bootstrap.getDataFolder().mkdirs();
saveResource("config.yml", false); 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() { public LPSubscriptionMap getSubscriptionMap() {
@ -405,227 +351,4 @@ public class LPNukkitPlugin extends PluginBase implements LuckPermsPlugin {
this.defaultPermissionMap = defaultPermissionMap; 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; import javax.annotation.Nonnull;
public class NukkitSchedulerAdapter implements SchedulerAdapter { public class NukkitSchedulerAdapter implements SchedulerAdapter {
private final LPNukkitPlugin plugin; private final LPNukkitBootstrap bootstrap;
private final ExecutorService asyncFallback; private final ExecutorService asyncFallback;
private final Executor asyncNukkit; private final Executor asyncNukkit;
@ -56,8 +56,8 @@ public class NukkitSchedulerAdapter implements SchedulerAdapter {
private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet(); private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet();
public NukkitSchedulerAdapter(LPNukkitPlugin plugin) { public NukkitSchedulerAdapter(LPNukkitBootstrap bootstrap) {
this.plugin = plugin; this.bootstrap = bootstrap;
this.sync = new SyncExecutor(); this.sync = new SyncExecutor();
this.asyncFallback = new FallbackAsyncExecutor(); this.asyncFallback = new FallbackAsyncExecutor();
@ -66,7 +66,7 @@ public class NukkitSchedulerAdapter implements SchedulerAdapter {
} }
private ServerScheduler scheduler() { private ServerScheduler scheduler() {
return this.plugin.getServer().getScheduler(); return this.bootstrap.getServer().getScheduler();
} }
@Override @Override
@ -81,26 +81,26 @@ public class NukkitSchedulerAdapter implements SchedulerAdapter {
@Override @Override
public SchedulerTask asyncRepeating(Runnable runnable, long intervalTicks) { 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); this.tasks.add(task);
return task; return task;
} }
@Override @Override
public SchedulerTask syncRepeating(Runnable runnable, long intervalTicks) { 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); this.tasks.add(task);
return task; return task;
} }
@Override @Override
public SchedulerTask asyncLater(Runnable runnable, long delayTicks) { 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 @Override
public SchedulerTask syncLater(Runnable runnable, long delayTicks) { 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 @Override
@ -142,14 +142,14 @@ public class NukkitSchedulerAdapter implements SchedulerAdapter {
private final class SyncExecutor implements Executor { private final class SyncExecutor implements Executor {
@Override @Override
public void execute(@Nonnull Runnable runnable) { 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 { private final class AsyncExecutor implements Executor {
@Override @Override
public void execute(@Nonnull Runnable runnable) { 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); NukkitSchedulerAdapter.this.asyncFallback.execute(runnable);
} else { } else {
NukkitSchedulerAdapter.this.asyncNukkit.execute(runnable); NukkitSchedulerAdapter.this.asyncNukkit.execute(runnable);
@ -160,7 +160,7 @@ public class NukkitSchedulerAdapter implements SchedulerAdapter {
private final class NukkitAsyncExecutor implements Executor { private final class NukkitAsyncExecutor implements Executor {
@Override @Override
public void execute(@Nonnull Runnable runnable) { 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 // otherwise, send the message sync
getPlugin().getScheduler().doSync(new SyncMessengerAgent(sender, s)); getPlugin().getBootstrap().getScheduler().doSync(new SyncMessengerAgent(sender, s));
} }
@Override @Override

View File

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

View File

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

View File

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

View File

@ -79,7 +79,7 @@ public class InjectorDefaultsMap implements Runnable {
this.plugin.setDefaultPermissionMap(ret); this.plugin.setDefaultPermissionMap(ret);
} }
} catch (Exception e) { } 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(); e.printStackTrace();
} }
} }
@ -88,7 +88,7 @@ public class InjectorDefaultsMap implements Runnable {
Objects.requireNonNull(OP_DEFAULT_PERMISSIONS_FIELD, "OP_DEFAULT_PERMISSIONS_FIELD"); Objects.requireNonNull(OP_DEFAULT_PERMISSIONS_FIELD, "OP_DEFAULT_PERMISSIONS_FIELD");
Objects.requireNonNull(NON_OP_DEFAULT_PERMISSIONS_FIELD, "NON_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 opMap = OP_DEFAULT_PERMISSIONS_FIELD.get(pluginManager);
Object nonOpMap = NON_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); this.plugin.setPermissionMap(ret);
} }
} catch (Exception e) { } 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(); e.printStackTrace();
} }
} }
private LPPermissionMap inject() throws Exception { private LPPermissionMap inject() throws Exception {
Objects.requireNonNull(PERMISSIONS_FIELD, "PERMISSIONS_FIELD"); 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); Object map = PERMISSIONS_FIELD.get(pluginManager);
if (map instanceof LPPermissionMap && ((LPPermissionMap) map).plugin == this.plugin) { if (map instanceof LPPermissionMap && ((LPPermissionMap) map).plugin == this.plugin) {

View File

@ -67,14 +67,14 @@ public class InjectorSubscriptionMap implements Runnable {
this.plugin.setSubscriptionMap(ret); this.plugin.setSubscriptionMap(ret);
} }
} catch (Exception e) { } 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(); e.printStackTrace();
} }
} }
private LPSubscriptionMap inject() throws Exception { private LPSubscriptionMap inject() throws Exception {
Objects.requireNonNull(PERM_SUBS_FIELD, "PERM_SUBS_FIELD"); 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); Object map = PERM_SUBS_FIELD.get(pluginManager);
if (map instanceof LPSubscriptionMap) { if (map instanceof LPSubscriptionMap) {

View File

@ -169,7 +169,7 @@ public final class LPSubscriptionMap extends HashMap<String, Set<Permissible>> {
private Sets.SetView<Permissible> getContentView() { private Sets.SetView<Permissible> getContentView() {
// gather players (LPPermissibles) // 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)) .filter(player -> player.isPermissionSet(this.permission))
.collect(Collectors.toSet()); .collect(Collectors.toSet());

View File

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

View File

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

View File

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

View File

@ -29,6 +29,8 @@ import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; 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.LPSubjectReference;
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory; import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
@ -47,7 +49,9 @@ import java.util.function.Predicate;
*/ */
public interface LPPermissionService { public interface LPPermissionService {
LuckPermsSpongePlugin getPlugin(); LuckPermsPlugin getPlugin();
ContextManager<Subject> getContextManager();
SubjectReferenceFactory getReferenceFactory(); 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; package me.lucko.luckperms.sponge;
import com.google.inject.Inject;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.LuckPermsApi; 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.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.CommandPermission; import me.lucko.luckperms.common.commands.CommandPermission;
import me.lucko.luckperms.common.commands.abstraction.Command; import me.lucko.luckperms.common.commands.abstraction.Command;
import me.lucko.luckperms.common.commands.sender.DummySender; import me.lucko.luckperms.common.commands.sender.DummySender;
import me.lucko.luckperms.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.AbstractConfiguration; import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.contexts.ContextManager; 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.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.model.User;
import me.lucko.luckperms.common.plugin.SchedulerAdapter; import me.lucko.luckperms.common.plugin.AbstractLuckPermsPlugin;
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.CacheHousekeepingTask; import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask; 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.calculators.SpongeCalculatorFactory;
import me.lucko.luckperms.sponge.commands.SpongeMainCommand; import me.lucko.luckperms.sponge.commands.SpongeMainCommand;
import me.lucko.luckperms.sponge.contexts.SpongeContextManager; 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.LPPermissionService;
import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubject;
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; 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.service.persisted.PersistedCollection;
import me.lucko.luckperms.sponge.tasks.ServiceCacheHousekeepingTask; 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.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.PermissionService;
import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.Subject;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
@ -117,233 +69,127 @@ import java.nio.file.Path;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; 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; import java.util.stream.Stream;
/** /**
* LuckPerms implementation for the Sponge API. * LuckPerms implementation for the Sponge API.
*/ */
@Plugin( public class LPSpongePlugin extends AbstractLuckPermsPlugin {
id = "luckperms", private final LPSpongeBootstrap bootstrap;
name = "LuckPerms",
version = VersionData.VERSION,
authors = "Luck",
description = "A permissions plugin",
url = "https://github.com/lucko/LuckPerms"
)
public class LPSpongePlugin implements LuckPermsSpongePlugin {
@Inject private SpongeSenderFactory senderFactory;
private Logger logger; private SpongeConnectionListener connectionListener;
@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 SpongeCommandExecutor commandManager; private SpongeCommandExecutor commandManager;
private LuckPermsConfiguration configuration;
private SpongeUserManager userManager; private SpongeUserManager userManager;
private SpongeGroupManager groupManager; private SpongeGroupManager groupManager;
private StandardTrackManager trackManager; 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 ContextManager<Subject> contextManager;
private CalculatorFactory calculatorFactory; private LuckPermsService service;
private BufferedRequest<Void> updateTaskBuffer; private UpdateEventHandler updateEventHandler;
private VerboseHandler verboseHandler;
private SpongeSenderFactory senderFactory;
private PermissionVault permissionVault;
private LogDispatcher logDispatcher;
private Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
@Listener(order = Order.FIRST) private boolean lateLoad = false;
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);
sendStartupBanner(getConsoleSender()); public LPSpongePlugin(LPSpongeBootstrap bootstrap) {
this.verboseHandler = new VerboseHandler(this.scheduler.async()); this.bootstrap = bootstrap;
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);
} }
// initialise datastore @Override
this.storage = storageFactory.getInstance(StorageType.H2); public LPSpongeBootstrap getBootstrap() {
return this.bootstrap;
}
// initialise messaging @Override
this.messagingService = new SpongeMessagingFactory(this).getInstance(); protected void setupSenderFactory() {
this.senderFactory = new SpongeSenderFactory(this);
}
// setup the update task buffer @Override
this.updateTaskBuffer = new UpdateTaskBuffer(this); protected ConfigurationAdapter provideConfigurationAdapter() {
return new SpongeConfigAdapter(this, resolveConfig());
}
// load locale @Override
this.localeManager = new SimpleLocaleManager(); protected void registerPlatformListeners() {
this.localeManager.tryLoad(this, new File(getDataDirectory(), "lang.yml")); this.connectionListener = new SpongeConnectionListener(this);
this.bootstrap.getGame().getEventManager().registerListeners(this, this.connectionListener);
this.bootstrap.getGame().getEventManager().registerListeners(this, new SpongePlatformListener(this));
}
// register commands @Override
CommandManager cmdService = this.game.getCommandManager(); protected MessagingFactory<?> provideMessagingFactory() {
return new SpongeMessagingFactory(this);
}
@Override
protected void registerCommands() {
this.commandManager = new SpongeCommandExecutor(this); 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 @Override
getLog().info("Loading internal permission managers..."); protected void setupManagers() {
this.inheritanceHandler = new InheritanceHandler(this);
this.userManager = new SpongeUserManager(this); this.userManager = new SpongeUserManager(this);
this.groupManager = new SpongeGroupManager(this); this.groupManager = new SpongeGroupManager(this);
this.trackManager = new StandardTrackManager(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 = new SpongeContextManager(this);
this.contextManager.registerCalculator(new WorldCalculator(this)); this.contextManager.registerCalculator(new WorldCalculator(this));
this.contextManager.registerStaticCalculator(new LuckPermsCalculator(getConfiguration())); }
// register the PermissionService with Sponge @Override
getLog().info("Registering PermissionService..."); protected void setupPlatformHooks() {
getLogger().info("Registering PermissionService...");
this.updateEventHandler = UpdateEventHandler.obtain(this); this.updateEventHandler = UpdateEventHandler.obtain(this);
this.service = new LuckPermsService(this); this.service = new LuckPermsService(this);
if (this.game.getPluginManager().getPlugin("permissionsex").isPresent()) { if (this.bootstrap.getGame().getPluginManager().getPlugin("permissionsex").isPresent()) {
getLog().warn("Detected PermissionsEx - assuming it's loaded for migration."); getLogger().warn("Detected PermissionsEx - assuming it's loaded for migration.");
getLog().warn("Delaying LuckPerms PermissionService registration."); getLogger().warn("Delaying LuckPerms PermissionService registration.");
this.lateLoad = true; this.lateLoad = true;
} else { } else {
this.game.getServiceManager().setProvider(this, LPPermissionService.class, this.service); this.bootstrap.getGame().getServiceManager().setProvider(this, LPPermissionService.class, this.service);
this.game.getServiceManager().setProvider(this, PermissionService.class, this.service.sponge()); this.bootstrap.getGame().getServiceManager().setProvider(this, PermissionService.class, this.service.sponge());
this.game.getServiceManager().setProvider(this, LuckPermsService.class, this.service); this.bootstrap.getGame().getServiceManager().setProvider(this, LuckPermsService.class, this.service);
}
} }
// register with the LP API @Override
this.apiProvider = new LuckPermsApiProvider(this); protected void registerApiOnPlatform(LuckPermsApi api) {
this.bootstrap.getGame().getServiceManager().setProvider(this, LuckPermsApi.class, api);
// 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();
} }
// register tasks @Override
this.scheduler.asyncRepeating(new ExpireTemporaryTask(this), 60L); protected void registerHousekeepingTasks() {
this.scheduler.asyncRepeating(new CacheHousekeepingTask(this), 2400L); this.bootstrap.getScheduler().asyncRepeating(new ExpireTemporaryTask(this), 60L);
this.scheduler.asyncRepeating(new ServiceCacheHousekeepingTask(this.service), 2400L); this.bootstrap.getScheduler().asyncRepeating(new CacheHousekeepingTask(this), 2400L);
this.bootstrap.getScheduler().asyncRepeating(new ServiceCacheHousekeepingTask(this.service), 2400L);
}
@Override
protected void performFinalSetup() {
// register permissions // register permissions
for (CommandPermission perm : CommandPermission.values()) { 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)"); public void lateEnable() {
}
@Listener(order = Order.LATE)
public void onLateEnable(GamePreInitializationEvent event) {
if (this.lateLoad) { if (this.lateLoad) {
getLog().info("Providing late registration of PermissionService..."); getLogger().info("Providing late registration of PermissionService...");
this.game.getServiceManager().setProvider(this, LPPermissionService.class, this.service); this.bootstrap.getGame().getServiceManager().setProvider(this, LPPermissionService.class, this.service);
this.game.getServiceManager().setProvider(this, PermissionService.class, this.service.sponge()); this.bootstrap.getGame().getServiceManager().setProvider(this, PermissionService.class, this.service.sponge());
this.game.getServiceManager().setProvider(this, LuckPermsService.class, this.service); 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 @Override
public void onPostUpdate() { public void onPostUpdate() {
for (LPSubjectCollection collection : this.service.getLoadedCollections().values()) { for (LPSubjectCollection collection : this.service.getLoadedCollections().values()) {
@ -354,13 +200,12 @@ public class LPSpongePlugin implements LuckPermsSpongePlugin {
this.service.invalidateAllCaches(LPSubject.CacheLevel.PARENT); this.service.invalidateAllCaches(LPSubject.CacheLevel.PARENT);
} }
private Path resolveConfig(String file) { private Path resolveConfig() {
Path path = this.configDirectory.resolve(file); Path path = this.bootstrap.getConfigPath().resolve("luckperms.conf");
if (!Files.exists(path)) { if (!Files.exists(path)) {
try { try {
Files.createDirectories(this.configDirectory); Files.createDirectories(this.bootstrap.getConfigPath());
try (InputStream is = getClass().getClassLoader().getResourceAsStream(file)) { try (InputStream is = getClass().getClassLoader().getResourceAsStream("luckperms.conf")) {
Files.copy(is, path); Files.copy(is, path);
} }
} catch (IOException e) { } catch (IOException e) {
@ -371,140 +216,38 @@ public class LPSpongePlugin implements LuckPermsSpongePlugin {
return path; 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 @Override
public Optional<Contexts> getContextForUser(User user) { public Optional<Contexts> getContextForUser(User user) {
Player player = getPlayer(user); Player player = this.bootstrap.getPlayer(user.getUuid());
if (player == null) { if (player == null) {
return Optional.empty(); return Optional.empty();
} }
return Optional.of(this.contextManager.getApplicableContexts(player)); 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 @Override
public Stream<Sender> getOnlineSenders() { public Stream<Sender> getOnlineSenders() {
if (!this.game.isServerAvailable()) { if (!this.bootstrap.getGame().isServerAvailable()) {
return Stream.empty(); return Stream.empty();
} }
return Stream.concat( return Stream.concat(
Stream.of(getConsoleSender()), 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 @Override
public Sender getConsoleSender() { public Sender getConsoleSender() {
if (!this.game.isServerAvailable()) { if (!this.bootstrap.getGame().isServerAvailable()) {
return new DummySender(this, me.lucko.luckperms.common.commands.CommandManager.CONSOLE_UUID, me.lucko.luckperms.common.commands.CommandManager.CONSOLE_NAME) { return new DummySender(this, CommandManager.CONSOLE_UUID, CommandManager.CONSOLE_NAME) {
@Override @Override
protected void consumeMessage(String s) { 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 @Override
@ -512,38 +255,13 @@ public class LPSpongePlugin implements LuckPermsSpongePlugin {
return Collections.singletonList(new SpongeMainCommand(this)); return Collections.singletonList(new SpongeMainCommand(this));
} }
public Game getGame() { public SpongeSenderFactory getSenderFactory() {
return this.game; return this.senderFactory;
}
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;
} }
@Override @Override
public long getStartTime() { public SpongeConnectionListener getConnectionListener() {
return this.startTime; return this.connectionListener;
}
@Override
public SchedulerAdapter getScheduler() {
return this.scheduler;
} }
@Override @Override
@ -551,11 +269,6 @@ public class LPSpongePlugin implements LuckPermsSpongePlugin {
return this.commandManager; return this.commandManager;
} }
@Override
public LuckPermsConfiguration getConfiguration() {
return this.configuration;
}
@Override @Override
public SpongeUserManager getUserManager() { public SpongeUserManager getUserManager() {
return this.userManager; return this.userManager;
@ -572,90 +285,16 @@ public class LPSpongePlugin implements LuckPermsSpongePlugin {
} }
@Override @Override
public Storage getStorage() { public ContextManager<Subject> getContextManager() {
return this.storage; return this.contextManager;
}
@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 LuckPermsService getService() { public LuckPermsService getService() {
return this.service; return this.service;
} }
@Override public UpdateEventHandler getUpdateEventHandler() {
public LocaleManager getLocaleManager() { return this.updateEventHandler;
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<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 me.lucko.luckperms.common.utils.SafeIteration;
import org.spongepowered.api.scheduler.Scheduler; import org.spongepowered.api.scheduler.Scheduler;
import org.spongepowered.api.scheduler.SpongeExecutorService;
import org.spongepowered.api.scheduler.Task; import org.spongepowered.api.scheduler.Task;
import java.util.Set; import java.util.Set;
@ -37,45 +38,49 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
public class SpongeSchedulerAdapter implements SchedulerAdapter { 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(); private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet();
public SpongeSchedulerAdapter(LPSpongePlugin plugin) { public SpongeSchedulerAdapter(LPSpongeBootstrap bootstrap, Scheduler scheduler, SpongeExecutorService sync, SpongeExecutorService async) {
this.plugin = plugin; this.bootstrap = bootstrap;
} this.scheduler = scheduler;
this.sync = sync;
private Scheduler scheduler() { this.async = async;
return this.plugin.getSpongeScheduler();
} }
@Override @Override
public Executor async() { public Executor async() {
return this.plugin.getAsyncExecutorService(); return this.async;
} }
@Override @Override
public Executor sync() { public Executor sync() {
return this.plugin.getSyncExecutorService(); return this.sync;
} }
@Override @Override
public void doAsync(Runnable runnable) { 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 @Override
public void doSync(Runnable runnable) { public void doSync(Runnable runnable) {
this.plugin.getSpongeScheduler().createTaskBuilder().execute(runnable).submit(this.plugin); this.scheduler.createTaskBuilder().execute(runnable).submit(this.bootstrap);
} }
@Override @Override
public SchedulerTask asyncRepeating(Runnable runnable, long intervalTicks) { public SchedulerTask asyncRepeating(Runnable runnable, long intervalTicks) {
Task task = scheduler().createTaskBuilder() Task task = this.scheduler.createTaskBuilder()
.async() .async()
.intervalTicks(intervalTicks) .intervalTicks(intervalTicks)
.delayTicks(intervalTicks) .delayTicks(intervalTicks)
.execute(runnable) .execute(runnable)
.submit(this.plugin); .submit(this.bootstrap);
SchedulerTask wrapped = new SpongeSchedulerTask(task); SchedulerTask wrapped = new SpongeSchedulerTask(task);
this.tasks.add(wrapped); this.tasks.add(wrapped);
@ -84,11 +89,11 @@ public class SpongeSchedulerAdapter implements SchedulerAdapter {
@Override @Override
public SchedulerTask syncRepeating(Runnable runnable, long intervalTicks) { public SchedulerTask syncRepeating(Runnable runnable, long intervalTicks) {
Task task = scheduler().createTaskBuilder() Task task = this.scheduler.createTaskBuilder()
.intervalTicks(intervalTicks) .intervalTicks(intervalTicks)
.delayTicks(intervalTicks) .delayTicks(intervalTicks)
.execute(runnable) .execute(runnable)
.submit(this.plugin); .submit(this.bootstrap);
SchedulerTask wrapped = new SpongeSchedulerTask(task); SchedulerTask wrapped = new SpongeSchedulerTask(task);
this.tasks.add(wrapped); this.tasks.add(wrapped);
@ -97,11 +102,11 @@ public class SpongeSchedulerAdapter implements SchedulerAdapter {
@Override @Override
public SchedulerTask asyncLater(Runnable runnable, long delayTicks) { public SchedulerTask asyncLater(Runnable runnable, long delayTicks) {
Task task = scheduler().createTaskBuilder() Task task = this.scheduler.createTaskBuilder()
.async() .async()
.delayTicks(delayTicks) .delayTicks(delayTicks)
.execute(runnable) .execute(runnable)
.submit(this.plugin); .submit(this.bootstrap);
SchedulerTask wrapped = new SpongeSchedulerTask(task); SchedulerTask wrapped = new SpongeSchedulerTask(task);
this.tasks.add(wrapped); this.tasks.add(wrapped);
@ -110,10 +115,10 @@ public class SpongeSchedulerAdapter implements SchedulerAdapter {
@Override @Override
public SchedulerTask syncLater(Runnable runnable, long delayTicks) { public SchedulerTask syncLater(Runnable runnable, long delayTicks) {
Task task = scheduler().createTaskBuilder() Task task = this.scheduler.createTaskBuilder()
.delayTicks(delayTicks) .delayTicks(delayTicks)
.execute(runnable) .execute(runnable)
.submit(this.plugin); .submit(this.bootstrap);
SchedulerTask wrapped = new SpongeSchedulerTask(task); SchedulerTask wrapped = new SpongeSchedulerTask(task);
this.tasks.add(wrapped); this.tasks.add(wrapped);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -40,6 +40,6 @@ public class UpdateEventHandlerImpl implements UpdateEventHandler {
@Override @Override
public void fireUpdateEvent(LPSubjectData subjectData) { public void fireUpdateEvent(LPSubjectData subjectData) {
SubjectDataUpdateEvent event = new LPSubjectDataUpdateEvent(this.plugin, 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); user.getRefreshBuffer().request().thenAccept(fut::complete);
}, this.service.getPlugin().getScheduler().async()); }, this.service.getPlugin().getBootstrap().getScheduler().async());
return fut; return fut;
} else { } else {
Group group = ((Group) t); Group group = ((Group) t);
@ -476,7 +476,7 @@ public class HolderSubjectData implements LPSubjectData {
} }
this.service.getPlugin().getUpdateTaskBuffer().request().thenAccept(fut::complete); this.service.getPlugin().getUpdateTaskBuffer().request().thenAccept(fut::complete);
}, this.service.getPlugin().getScheduler().async()); }, this.service.getPlugin().getBootstrap().getScheduler().async());
return fut; return fut;
} }
} }

View File

@ -77,7 +77,7 @@ public class PersistedSubject implements LPSubject {
.expireAfterAccess(20, TimeUnit.MINUTES) .expireAfterAccess(20, TimeUnit.MINUTES)
.build(lookup -> lookupOptionValue(lookup.contexts, lookup.key)); .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 @Override
protected Void perform() { protected Void perform() {
try { try {