Extract common plugin behaviour into an abstract class

This commit is contained in:
Luck
2018-03-03 16:26:27 +00:00
Unverified
parent cd5447de38
commit 68e4d36f40
98 changed files with 2310 additions and 2177 deletions
@@ -58,7 +58,7 @@ public class ApiActionLogger implements ActionLogger {
@Nonnull
@Override
public CompletableFuture<Void> submit(@Nonnull LogEntry entry) {
return CompletableFuture.runAsync(() -> this.plugin.getLogDispatcher().dispatchFromApi((ExtendedLogEntry) entry), this.plugin.getScheduler().async());
return CompletableFuture.runAsync(() -> this.plugin.getLogDispatcher().dispatchFromApi((ExtendedLogEntry) entry), this.plugin.getBootstrap().getScheduler().async());
}
@Nonnull
@@ -70,6 +70,6 @@ public class ApiActionLogger implements ActionLogger {
@Nonnull
@Override
public CompletableFuture<Void> broadcastAction(@Nonnull LogEntry entry) {
return CompletableFuture.runAsync(() -> this.plugin.getLogDispatcher().broadcastFromApi((ExtendedLogEntry) entry), this.plugin.getScheduler().async());
return CompletableFuture.runAsync(() -> this.plugin.getLogDispatcher().broadcastFromApi((ExtendedLogEntry) entry), this.plugin.getBootstrap().getScheduler().async());
}
}
@@ -45,7 +45,7 @@ public class ApiPlatformInfo implements PlatformInfo {
@Nonnull
@Override
public String getVersion() {
return this.plugin.getVersion();
return this.plugin.getBootstrap().getVersion();
}
@Override
@@ -56,17 +56,17 @@ public class ApiPlatformInfo implements PlatformInfo {
@Nonnull
@Override
public PlatformType getType() {
return this.plugin.getServerType();
return this.plugin.getBootstrap().getType();
}
@Nonnull
@Override
public Set<UUID> getUniqueConnections() {
return Collections.unmodifiableSet(this.plugin.getUniqueConnections());
return Collections.unmodifiableSet(this.plugin.getConnectionListener().getUniqueConnections());
}
@Override
public long getStartTime() {
return this.plugin.getStartTime();
return this.plugin.getBootstrap().getStartupTime();
}
}
@@ -90,13 +90,13 @@ public class ApiStorage implements me.lucko.luckperms.api.Storage {
@Nonnull
@Override
public Executor getSyncExecutor() {
return this.plugin.getScheduler().sync();
return this.plugin.getBootstrap().getScheduler().sync();
}
@Nonnull
@Override
public Executor getAsyncExecutor() {
return this.plugin.getScheduler().async();
return this.plugin.getBootstrap().getScheduler().async();
}
@Nonnull
@@ -250,7 +250,7 @@ public class Exporter implements Runnable {
e.printStackTrace();
}
}
}, this.plugin.getScheduler().async()));
}, this.plugin.getBootstrap().getScheduler().async()));
}
// all of the threads have been scheduled now and are running. we just need to wait for them all to complete
@@ -124,7 +124,7 @@ public class Importer implements Runnable {
cmd.process();
processedCount.incrementAndGet();
}
}, this.commandManager.getPlugin().getScheduler().async()));
}, this.commandManager.getPlugin().getBootstrap().getScheduler().async()));
}
// all of the threads have been scheduled now and are running. we just need to wait for them all to complete
@@ -32,7 +32,7 @@ public class UpdateTaskBuffer extends BufferedRequest<Void> {
private final LuckPermsPlugin plugin;
public UpdateTaskBuffer(LuckPermsPlugin plugin) {
super(250L, 50L, plugin.getScheduler().async());
super(250L, 50L, plugin.getBootstrap().getScheduler().async());
this.plugin = plugin;
}
@@ -145,7 +145,7 @@ public class CommandManager {
try {
return execute(sender, label, args);
} catch (Throwable e) {
this.plugin.getLog().severe("Exception whilst executing command: " + args.toString());
this.plugin.getLogger().severe("Exception whilst executing command: " + args.toString());
e.printStackTrace();
return null;
}
@@ -159,7 +159,7 @@ public class CommandManager {
// Handle no arguments
if (arguments.isEmpty() || (arguments.size() == 1 && arguments.get(0).trim().isEmpty())) {
CommandUtils.sendPluginMessage(sender, "&2Running &bLuckPerms v" + this.plugin.getVersion() + "&2.");
CommandUtils.sendPluginMessage(sender, "&2Running &bLuckPerms v" + this.plugin.getBootstrap().getVersion() + "&2.");
if (this.mainCommands.stream().anyMatch(c -> c.shouldDisplay() && c.isAuthorized(sender))) {
Message.VIEW_AVAILABLE_COMMANDS_PROMPT.send(sender, label);
} else {
@@ -257,7 +257,7 @@ public class CommandManager {
}
private void sendCommandUsage(Sender sender, String label) {
CommandUtils.sendPluginMessage(sender, "&2Running &bLuckPerms v" + this.plugin.getVersion() + "&2.");
CommandUtils.sendPluginMessage(sender, "&2Running &bLuckPerms v" + this.plugin.getBootstrap().getVersion() + "&2.");
this.mainCommands.stream()
.filter(Command::shouldDisplay)
.filter(c -> c.isAuthorized(sender))
@@ -93,7 +93,7 @@ public class LogRecent extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
uuid = plugin.lookupUuid(target).orElse(null);
uuid = plugin.getBootstrap().lookupUuid(target).orElse(null);
if (uuid == null) {
Message.USER_NOT_FOUND.send(sender, target);
return CommandResult.INVALID_ARGS;
@@ -88,7 +88,7 @@ public class LogUserHistory extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
uuid = plugin.lookupUuid(target).orElse(null);
uuid = plugin.getBootstrap().lookupUuid(target).orElse(null);
if (uuid == null) {
Message.USER_NOT_FOUND.send(sender, target);
return CommandResult.INVALID_ARGS;
@@ -81,7 +81,7 @@ public class BulkUpdateCommand extends SingleCommand {
ex.printStackTrace();
Message.BULK_UPDATE_FAILURE.send(sender);
}
}, plugin.getScheduler().async());
}, plugin.getBootstrap().getScheduler().async());
return CommandResult.SUCCESS;
}
@@ -76,11 +76,11 @@ public class CheckCommand extends SingleCommand {
@Override
public List<String> tabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
if (args.isEmpty()) {
return plugin.getPlayerList().collect(Collectors.toList());
return plugin.getBootstrap().getPlayerList().collect(Collectors.toList());
}
if (args.size() == 1) {
return plugin.getPlayerList().filter(s -> s.toLowerCase().startsWith(args.get(0).toLowerCase())).collect(Collectors.toList());
return plugin.getBootstrap().getPlayerList().filter(s -> s.toLowerCase().startsWith(args.get(0).toLowerCase())).collect(Collectors.toList());
}
args.remove(0);
@@ -109,14 +109,14 @@ public class DebugCommand extends SingleCommand {
private static JObject getPlatformData(LuckPermsPlugin plugin) {
return new JObject()
.add("type", plugin.getServerType().name())
.add("type", plugin.getBootstrap().getType().name())
.add("version", new JObject()
.add("api", String.valueOf(plugin.getApiProvider().getPlatformInfo().getApiVersion()))
.add("plugin", plugin.getVersion())
.add("plugin", plugin.getBootstrap().getVersion())
)
.add("server", new JObject()
.add("brand", plugin.getServerBrand())
.add("version", plugin.getServerVersion())
.add("brand", plugin.getBootstrap().getServerBrand())
.add("version", plugin.getBootstrap().getServerVersion())
);
}
@@ -172,7 +172,7 @@ public class DebugCommand extends SingleCommand {
private static JObject getPlayersData(LuckPermsPlugin plugin) {
JObject ret = new JObject();
Set<UUID> onlinePlayers = plugin.getOnlinePlayers().collect(Collectors.toSet());
Set<UUID> onlinePlayers = plugin.getBootstrap().getOnlinePlayers().collect(Collectors.toSet());
ret.add("count", onlinePlayers.size());
JArray playerArray = new JArray();
@@ -57,7 +57,7 @@ public class ExportCommand extends SingleCommand {
return CommandResult.STATE_ERROR;
}
File f = new File(plugin.getDataDirectory(), args.get(0));
File f = new File(plugin.getBootstrap().getDataDirectory(), args.get(0));
if (f.exists()) {
Message.LOG_EXPORT_ALREADY_EXISTS.send(sender, f.getAbsolutePath());
return CommandResult.INVALID_ARGS;
@@ -86,7 +86,7 @@ public class ExportCommand extends SingleCommand {
Exporter exporter = new Exporter(plugin, sender, path);
// Run the exporter in its own thread.
plugin.getScheduler().doAsync(() -> {
plugin.getBootstrap().getScheduler().doAsync(() -> {
try {
exporter.run();
} finally {
@@ -58,7 +58,7 @@ public class ImportCommand extends SingleCommand {
return CommandResult.STATE_ERROR;
}
File f = new File(plugin.getDataDirectory(), args.get(0));
File f = new File(plugin.getBootstrap().getDataDirectory(), args.get(0));
if (!f.exists()) {
Message.IMPORT_LOG_DOESNT_EXIST.send(sender, f.getAbsolutePath());
return CommandResult.INVALID_ARGS;
@@ -89,7 +89,7 @@ public class ImportCommand extends SingleCommand {
Importer importer = new Importer(plugin.getCommandManager(), sender, commands);
// Run the importer in its own thread.
plugin.getScheduler().doAsync(() -> {
plugin.getBootstrap().getScheduler().doAsync(() -> {
try {
importer.run();
} finally {
@@ -49,10 +49,10 @@ public class InfoCommand extends SingleCommand {
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
Message.INFO_TOP.send(sender,
plugin.getVersion(),
plugin.getServerType().getFriendlyName(),
plugin.getServerBrand(),
plugin.getServerVersion()
plugin.getBootstrap().getVersion(),
plugin.getBootstrap().getType().getFriendlyName(),
plugin.getBootstrap().getServerBrand(),
plugin.getBootstrap().getServerVersion()
);
Message.EMPTY.send(sender, "&f- &bStorage:");
@@ -64,9 +64,9 @@ public class InfoCommand extends SingleCommand {
Message.INFO_MIDDLE.send(sender,
plugin.getMessagingService().map(InternalMessagingService::getName).orElse("None"),
plugin.getContextManager().getStaticContextString().orElse("None"),
plugin.getPlayerCount(),
plugin.getUniqueConnections().size(),
DateUtil.formatTimeBrief((System.currentTimeMillis() - plugin.getStartTime()) / 1000L),
plugin.getBootstrap().getPlayerCount(),
plugin.getConnectionListener().getUniqueConnections().size(),
DateUtil.formatTimeBrief((System.currentTimeMillis() - plugin.getBootstrap().getStartupTime()) / 1000L),
plugin.getUserManager().getAll().size(),
plugin.getGroupManager().getAll().size(),
plugin.getTrackManager().getAll().size()
@@ -79,7 +79,7 @@ public class UserClone extends SubCommand<User> {
return CommandResult.INVALID_ARGS;
}
uuid = plugin.lookupUuid(target).orElse(null);
uuid = plugin.getBootstrap().lookupUuid(target).orElse(null);
if (uuid == null) {
Message.USER_NOT_FOUND.send(sender, target);
return CommandResult.INVALID_ARGS;
@@ -62,7 +62,7 @@ public class UserInfo extends SubCommand<User> {
return CommandResult.NO_PERMISSION;
}
Message status = plugin.isPlayerOnline(user.getUuid()) ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE;
Message status = plugin.getBootstrap().isPlayerOnline(user.getUuid()) ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE;
Message.USER_INFO_GENERAL.send(sender,
user.getName().orElse("Unknown"),
@@ -103,7 +103,7 @@ public class UserMainCommand extends MainCommand<User, UserIdentifier> {
return null;
}
uuid = plugin.lookupUuid(target).orElse(null);
uuid = plugin.getBootstrap().lookupUuid(target).orElse(null);
if (uuid == null) {
Message.USER_NOT_FOUND.send(sender, target);
return null;
@@ -134,6 +134,6 @@ public class UserMainCommand extends MainCommand<User, UserIdentifier> {
@Override
protected List<String> getTargets(LuckPermsPlugin plugin) {
return plugin.getPlayerList().collect(Collectors.toList());
return plugin.getBootstrap().getPlayerList().collect(Collectors.toList());
}
}
@@ -69,7 +69,7 @@ public class ConfigKeys {
*/
public static final ConfigKey<String> SERVER = AbstractKey.of(c -> {
if (c.getBoolean("use-server-properties-name", false)) {
String serverName = c.getPlugin().getServerName();
String serverName = c.getPlugin().getBootstrap().getServerName();
if (serverName != null && !serverName.equals("Unknown Server")) {
return serverName.toLowerCase();
}
@@ -53,8 +53,8 @@ public class ContextsFile {
}
public void load() {
File file = new File(this.configuration.getPlugin().getConfigDirectory(), "contexts.json");
File oldFile = new File(this.configuration.getPlugin().getConfigDirectory(), "static-contexts.json");
File file = new File(this.configuration.getPlugin().getBootstrap().getDataDirectory(), "contexts.json");
File oldFile = new File(this.configuration.getPlugin().getBootstrap().getDataDirectory(), "static-contexts.json");
if (oldFile.exists()) {
oldFile.renameTo(file);
}
@@ -91,7 +91,7 @@ public class ContextsFile {
}
public void save() {
File file = new File(this.configuration.getPlugin().getConfigDirectory(), "contexts.json");
File file = new File(this.configuration.getPlugin().getBootstrap().getDataDirectory(), "contexts.json");
try (BufferedWriter writer = Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8)) {
@@ -202,7 +202,7 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
}
accumulator = ret;
} catch (Exception e) {
AbstractContextManager.this.plugin.getLog().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating the context of subject " + subject);
AbstractContextManager.this.plugin.getLogger().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating the context of subject " + subject);
e.printStackTrace();
}
}
@@ -225,7 +225,7 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
}
accumulator = ret;
} catch (Exception e) {
AbstractContextManager.this.plugin.getLog().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating static contexts");
AbstractContextManager.this.plugin.getLogger().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating static contexts");
e.printStackTrace();
}
}
@@ -79,7 +79,7 @@ public class DependencyManager {
}
private File getSaveDirectory() {
File saveDirectory = new File(this.plugin.getDataDirectory(), "lib");
File saveDirectory = new File(this.plugin.getBootstrap().getDataDirectory(), "lib");
if (!(saveDirectory.exists() || saveDirectory.mkdirs())) {
throw new RuntimeException("Unable to create lib dir - " + saveDirectory.getPath());
}
@@ -139,7 +139,7 @@ public class DependencyManager {
File file = downloadDependency(saveDirectory, dependency);
sources.add(new Source(dependency, file));
} catch (Throwable e) {
this.plugin.getLog().severe("Exception whilst downloading dependency " + dependency.name());
this.plugin.getLogger().severe("Exception whilst downloading dependency " + dependency.name());
e.printStackTrace();
}
}
@@ -169,12 +169,12 @@ public class DependencyManager {
RelocationHandler relocationHandler = getRelocationHandler();
// attempt to remap the jar.
this.plugin.getLog().info("Attempting to apply relocations to " + input.getName() + "...");
this.plugin.getLogger().info("Attempting to apply relocations to " + input.getName() + "...");
relocationHandler.remap(input, output, relocations);
remappedJars.add(new Source(source.dependency, output));
} catch (Throwable e) {
this.plugin.getLog().severe("Unable to remap the source file '" + source.dependency.name() + "'.");
this.plugin.getLogger().severe("Unable to remap the source file '" + source.dependency.name() + "'.");
e.printStackTrace();
}
}
@@ -187,10 +187,10 @@ public class DependencyManager {
}
try {
this.plugin.getPluginClassLoader().loadJar(source.file);
this.plugin.getBootstrap().getPluginClassLoader().loadJar(source.file);
this.loaded.put(source.dependency, source.file);
} catch (Throwable e) {
this.plugin.getLog().severe("Failed to load dependency jar '" + source.file.getName() + "'.");
this.plugin.getLogger().severe("Failed to load dependency jar '" + source.file.getName() + "'.");
e.printStackTrace();
}
}
@@ -218,7 +218,7 @@ public class DependencyManager {
// compute a hash for the downloaded file
byte[] hash = this.digest.digest(bytes);
this.plugin.getLog().info("Successfully downloaded '" + fileName + "' with checksum: " + Base64.getEncoder().encodeToString(hash));
this.plugin.getLogger().info("Successfully downloaded '" + fileName + "' with checksum: " + Base64.getEncoder().encodeToString(hash));
// ensure the hash matches the expected checksum
if (!Arrays.equals(hash, dependency.getChecksum())) {
@@ -83,7 +83,7 @@ public class DependencyRegistry {
}
// don't load configurate dependencies on sponge
if (this.plugin.getServerType() == PlatformType.SPONGE) {
if (this.plugin.getBootstrap().getType() == PlatformType.SPONGE) {
dependencies.remove(Dependency.CONFIGURATE_CORE);
dependencies.remove(Dependency.CONFIGURATE_GSON);
dependencies.remove(Dependency.CONFIGURATE_YAML);
@@ -118,7 +118,7 @@ public class LuckPermsEventBus implements EventBus {
if (event instanceof Cancellable) {
throw new IllegalArgumentException("cannot call Cancellable event async");
}
this.plugin.getScheduler().doAsync(() -> fireEvent(event));
this.plugin.getBootstrap().getScheduler().doAsync(() -> fireEvent(event));
}
public LuckPermsPlugin getPlugin() {
@@ -78,7 +78,7 @@ public class LuckPermsEventHandler<T extends LuckPermsEvent> implements EventHan
this.consumer.accept(t);
this.callCount.incrementAndGet();
} catch (Throwable t) {
this.eventBus.getPlugin().getLog().warn("Unable to pass event " + event.getClass().getSimpleName() + " to handler " + this.consumer.getClass().getName());
this.eventBus.getPlugin().getLogger().warn("Unable to pass event " + event.getClass().getSimpleName() + " to handler " + this.consumer.getClass().getName());
t.printStackTrace();
}
}
@@ -23,25 +23,37 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.utils;
package me.lucko.luckperms.common.listener;
import me.lucko.luckperms.common.assignments.AssignmentRule;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
* Abstract listener utility for handling new player connections
*/
public abstract class AbstractLoginListener {
public abstract class AbstractConnectionListener implements ConnectionListener {
private final LuckPermsPlugin plugin;
private final Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
protected AbstractLoginListener(LuckPermsPlugin plugin) {
protected AbstractConnectionListener(LuckPermsPlugin plugin) {
this.plugin = plugin;
}
@Override
public Set<UUID> getUniqueConnections() {
return this.uniqueConnections;
}
protected void recordConnection(UUID uuid) {
this.uniqueConnections.add(uuid);
}
public User loadUser(UUID u, String username) {
final long startTime = System.currentTimeMillis();
@@ -78,7 +90,7 @@ public abstract class AbstractLoginListener {
final long time = System.currentTimeMillis() - startTime;
if (time >= 1000) {
this.plugin.getLog().warn("Processing login for " + username + " took " + time + "ms.");
this.plugin.getLogger().warn("Processing login for " + username + " took " + time + "ms.");
}
return user;
@@ -23,37 +23,21 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.locale;
package me.lucko.luckperms.common.listener;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.Set;
import java.util.UUID;
import java.io.File;
/**
* Handles incoming connections on the platform
*/
public interface ConnectionListener {
public class NoopLocaleManager implements LocaleManager {
@Override
public void tryLoad(LuckPermsPlugin plugin, File file) {
}
@Override
public void loadFromFile(File file) {
}
@Override
public int getSize() {
return 0;
}
@Override
public String getTranslation(Message key) {
return null;
}
@Override
public CommandSpecData getTranslation(CommandSpec key) {
return null;
}
/**
* Gets the unique players which have connected to the server since it started.
*
* @return the unique connections
*/
Set<UUID> getUniqueConnections();
}
@@ -45,7 +45,7 @@ public class SimpleLocaleManager implements LocaleManager {
@Override
public void tryLoad(LuckPermsPlugin plugin, File file) {
if (file.exists()) {
plugin.getLog().info("Found lang.yml - loading messages...");
plugin.getLogger().info("Found lang.yml - loading messages...");
try {
loadFromFile(file);
} catch (Exception e) {
@@ -46,7 +46,7 @@ public abstract class AbstractUserManager<T extends User> extends AbstractManage
public AbstractUserManager(LuckPermsPlugin plugin, UserHousekeeper.TimeoutSettings timeoutSettings) {
this.plugin = plugin;
this.housekeeper = new UserHousekeeper(plugin, this, timeoutSettings);
this.plugin.getScheduler().asyncRepeating(this.housekeeper, 200L); // every 10 seconds
this.plugin.getBootstrap().getScheduler().asyncRepeating(this.housekeeper, 200L); // every 10 seconds
}
@Override
@@ -147,8 +147,8 @@ public abstract class AbstractUserManager<T extends User> extends AbstractManage
@Override
public CompletableFuture<Void> updateAllUsers() {
return CompletableFuture.runAsync(
() -> this.plugin.getOnlinePlayers().forEach(u -> this.plugin.getStorage().loadUser(u, null).join()),
this.plugin.getScheduler().async()
() -> this.plugin.getBootstrap().getOnlinePlayers().forEach(u -> this.plugin.getStorage().loadUser(u, null).join()),
this.plugin.getBootstrap().getScheduler().async()
);
}
@@ -76,7 +76,7 @@ public class UserHousekeeper implements Runnable {
UUID uuid = identifier.getUuid();
// unload users which aren't online and who haven't been online (or tried to login) recently
if (this.recentlyUsed.contains(uuid) || this.recentlyUsedApi.contains(uuid) || this.plugin.isPlayerOnline(uuid)) {
if (this.recentlyUsed.contains(uuid) || this.recentlyUsedApi.contains(uuid) || this.plugin.getBootstrap().isPlayerOnline(uuid)) {
return;
}
@@ -102,32 +102,32 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
@Override
public void pushUpdate() {
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
UUID requestId = generatePingId();
this.plugin.getLog().info("[" + getName() + " Messaging] Sending ping with id: " + requestId);
this.plugin.getLogger().info("[" + getName() + " Messaging] Sending ping with id: " + requestId);
this.messenger.sendOutgoingMessage(new UpdateMessageImpl(requestId));
});
}
@Override
public void pushUserUpdate(User user) {
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
UUID requestId = generatePingId();
this.plugin.getLog().info("[" + getName() + " Messaging] Sending user ping for '" + user.getFriendlyName() + "' with id: " + requestId);
this.plugin.getLogger().info("[" + getName() + " Messaging] Sending user ping for '" + user.getFriendlyName() + "' with id: " + requestId);
this.messenger.sendOutgoingMessage(new UserUpdateMessageImpl(requestId, user.getUuid()));
});
}
@Override
public void pushLog(LogEntry logEntry) {
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
UUID requestId = generatePingId();
if (this.plugin.getEventFactory().handleLogNetworkPublish(!this.plugin.getConfiguration().get(ConfigKeys.PUSH_LOG_ENTRIES), requestId, logEntry)) {
return;
}
this.plugin.getLog().info("[" + getName() + " Messaging] Sending log with id: " + requestId);
this.plugin.getLogger().info("[" + getName() + " Messaging] Sending log with id: " + requestId);
this.messenger.sendOutgoingMessage(new LogMessageImpl(requestId, logEntry));
});
}
@@ -142,7 +142,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
return false;
}
this.plugin.getLog().info("[" + getName() + " Messaging] Received update ping with id: " + msg.getId());
this.plugin.getLogger().info("[" + getName() + " Messaging] Received update ping with id: " + msg.getId());
if (this.plugin.getEventFactory().handleNetworkPreSync(false, msg.getId())) {
return true;
@@ -162,7 +162,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
return true;
}
this.plugin.getLog().info("[" + getName() + " Messaging] Received user update ping for '" + user.getFriendlyName() + "' with id: " + msg.getId());
this.plugin.getLogger().info("[" + getName() + " Messaging] Received user update ping for '" + user.getFriendlyName() + "' with id: " + msg.getId());
if (this.plugin.getEventFactory().handleNetworkPreSync(false, msg.getId())) {
return true;
@@ -182,7 +182,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
return true;
} else {
this.plugin.getLog().warn("Unable to decode incoming message: " + message + " (" + message.getClass().getName() + ")");
this.plugin.getLogger().warn("Unable to decode incoming message: " + message + " (" + message.getClass().getName() + ")");
return false;
}
}
@@ -207,7 +207,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
private final class PushUpdateBuffer extends BufferedRequest<Void> {
public PushUpdateBuffer(LuckPermsPlugin plugin) {
super(2000L, 200L, plugin.getScheduler().async());
super(2000L, 200L, plugin.getBootstrap().getScheduler().async());
}
@Override
@@ -55,14 +55,14 @@ public class MessagingFactory<P extends LuckPermsPlugin> {
return null;
}
this.plugin.getLog().info("Loading messaging service... [" + messagingType.toUpperCase() + "]");
this.plugin.getLogger().info("Loading messaging service... [" + messagingType.toUpperCase() + "]");
InternalMessagingService service = getServiceFor(messagingType);
if (service != null) {
return service;
}
this.plugin.getLog().warn("Messaging service '" + messagingType + "' not recognised.");
this.plugin.getLogger().warn("Messaging service '" + messagingType + "' not recognised.");
return null;
}
@@ -75,7 +75,7 @@ public class MessagingFactory<P extends LuckPermsPlugin> {
e.printStackTrace();
}
} else {
this.plugin.getLog().warn("Messaging Service was set to redis, but redis is not enabled!");
this.plugin.getLogger().warn("Messaging Service was set to redis, but redis is not enabled!");
}
}
@@ -65,7 +65,7 @@ public class RedisMessenger implements Messenger {
this.jedisPool = new JedisPool(new JedisPoolConfig(), host, port, 0, password);
}
this.plugin.getScheduler().doAsync(() -> {
this.plugin.getBootstrap().getScheduler().doAsync(() -> {
this.sub = new LPSub(this);
try (Jedis jedis = this.jedisPool.getResource()) {
jedis.subscribe(this.sub, CHANNEL);
@@ -154,7 +154,7 @@ public class Group extends PermissionHolder implements Identifiable<String> {
private final Group group;
private GroupRefreshBuffer(LuckPermsPlugin plugin, Group group) {
super(50L, 5L, plugin.getScheduler().async());
super(50L, 5L, plugin.getBootstrap().getScheduler().async());
this.group = group;
}
@@ -235,7 +235,7 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
private final User user;
private UserRefreshBuffer(LuckPermsPlugin plugin, User user) {
super(50L, 5L, plugin.getScheduler().async());
super(50L, 5L, plugin.getBootstrap().getScheduler().async());
this.user = user;
}
@@ -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(" "));
}
}
@@ -26,7 +26,6 @@
package me.lucko.luckperms.common.plugin;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest;
@@ -35,13 +34,12 @@ import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.abstraction.Command;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.CommandUtils;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.dependencies.classloader.PluginClassLoader;
import me.lucko.luckperms.common.event.EventFactory;
import me.lucko.luckperms.common.inheritance.InheritanceHandler;
import me.lucko.luckperms.common.listener.ConnectionListener;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.logging.Logger;
import me.lucko.luckperms.common.managers.group.GroupManager;
@@ -49,18 +47,15 @@ import me.lucko.luckperms.common.managers.track.TrackManager;
import me.lucko.luckperms.common.managers.user.UserManager;
import me.lucko.luckperms.common.messaging.InternalMessagingService;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.storage.dao.file.FileWatcher;
import me.lucko.luckperms.common.treeview.PermissionVault;
import me.lucko.luckperms.common.verbose.VerboseHandler;
import java.io.File;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Stream;
/**
@@ -71,6 +66,13 @@ import java.util.stream.Stream;
*/
public interface LuckPermsPlugin {
/**
* Gets the bootstrap plugin instance
*
* @return the bootstrap plugin
*/
LuckPermsBootstrap getBootstrap();
/**
* Gets the user manager instance for the platform
*
@@ -125,7 +127,7 @@ public interface LuckPermsPlugin {
*
* @return the plugin's logger
*/
Logger getLog();
Logger getLogger();
/**
* Gets the event factory
@@ -148,6 +150,13 @@ public interface LuckPermsPlugin {
*/
CommandManager getCommandManager();
/**
* Gets the connection listener.
*
* @return the connection listener
*/
ConnectionListener getConnectionListener();
/**
* Gets the instance providing locale translations for the plugin
*
@@ -155,13 +164,6 @@ public interface LuckPermsPlugin {
*/
LocaleManager getLocaleManager();
/**
* Gets the classloader wrapper for adding dependencies to the classpath
*
* @return the plugin classloader
*/
PluginClassLoader getPluginClassLoader();
/**
* Gets the dependency manager for the plugin
*
@@ -219,13 +221,6 @@ public interface LuckPermsPlugin {
*/
LogDispatcher getLogDispatcher();
/**
* Gets the LuckPerms Scheduler instance
*
* @return the scheduler
*/
SchedulerAdapter getScheduler();
/**
* Gets the file watcher running on the platform
*
@@ -233,97 +228,6 @@ public interface LuckPermsPlugin {
*/
Optional<FileWatcher> getFileWatcher();
/**
* Gets a string of the plugin's version
*
* @return the version of the plugin
*/
String getVersion();
/**
* Gets the platform type this instance of LuckPerms is running on.
*
* @return the platform type
*/
PlatformType getServerType();
/**
* Gets the name or "brand" of the running platform
*
* @return the server brand
*/
String getServerBrand();
/**
* Gets the version of the running platform
*
* @return the server version
*/
String getServerVersion();
/**
* Gets the name associated with this server
*
* @return the server name
*/
default String getServerName() {
return null;
}
/**
* Gets the time when the plugin first started in millis.
*
* @return the enable time
*/
long getStartTime();
/**
* Gets the plugins main data storage directory
*
* <p>Bukkit: /root/plugins/LuckPerms</p>
* <p>Bungee: /root/plugins/LuckPerms</p>
* <p>Sponge: /root/luckperms/</p>
*
* @return the platforms data folder
*/
File getDataDirectory();
/**
* Gets the plugins config directory.
*
* <p>This is the same as {@link #getDataDirectory()} on Bukkit/Bungee, but different on Sponge.</p>
*
* @return the platforms config folder
*/
default File getConfigDirectory() {
return getDataDirectory();
}
/**
* Gets a bundled resource file from the jar
*
* @param path the path of the file
* @return the file as an input stream
*/
InputStream getResourceStream(String path);
/**
* Gets a player object linked to this User. The returned object must be the same type
* as the instance used in the platforms {@link ContextManager}
*
* @param user the user instance
* @return a player object, or null, if one couldn't be found.
*/
Object getPlayer(User user);
/**
* Lookup a uuid from a username, using the servers internal uuid cache.
*
* @param username the username to lookup
* @return an optional uuid, if found
*/
Optional<UUID> lookupUuid(String username);
/**
* Gets a calculated context instance for the user using the rules of the platform.
*
@@ -332,35 +236,6 @@ public interface LuckPermsPlugin {
*/
Optional<Contexts> getContextForUser(User user);
/**
* Gets the number of users online on the platform
*
* @return the number of users
*/
int getPlayerCount();
/**
* Gets the usernames of the users online on the platform
*
* @return a {@link List} of usernames
*/
Stream<String> getPlayerList();
/**
* Gets the UUIDs of the users online on the platform
*
* @return a {@link Set} of UUIDs
*/
Stream<UUID> getOnlinePlayers();
/**
* Checks if a user is online
*
* @param external the users external uuid
* @return true if the user is online
*/
boolean isPlayerOnline(UUID external);
/**
* Gets a list of online Senders on the platform
*
@@ -375,13 +250,6 @@ public interface LuckPermsPlugin {
*/
Sender getConsoleSender();
/**
* Gets the unique players which have connected to the server since it started.
*
* @return the unique connections
*/
Set<UUID> getUniqueConnections();
default List<Command> getExtraCommands() {
return Collections.emptyList();
}
@@ -400,14 +268,4 @@ public interface LuckPermsPlugin {
}
default void sendStartupBanner(Sender sender) {
sender.sendMessage(CommandUtils.color("&b __ &3 __ ___ __ __ "));
sender.sendMessage(CommandUtils.color("&b | | | / ` |__/ &3|__) |__ |__) |\\/| /__` "));
sender.sendMessage(CommandUtils.color("&b |___ \\__/ \\__, | \\ &3| |___ | \\ | | .__/ "));
sender.sendMessage(CommandUtils.color(" "));
sender.sendMessage(CommandUtils.color("&2 Loading version &bv" + getVersion() + "&2 on " + getServerType().getFriendlyName() + " - " + getServerBrand()));
sender.sendMessage(CommandUtils.color("&8 Running on server version " + getServerVersion()));
sender.sendMessage(CommandUtils.color(" "));
}
}
@@ -39,6 +39,10 @@ public interface SchedulerAdapter {
*/
Executor async();
default Executor platformAsync() {
return async();
}
/**
* Gets a sync executor instance
*
@@ -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);
}
@@ -60,7 +60,7 @@ public class AbstractStorage implements Storage {
Storage base = new AbstractStorage(plugin, backing);
Storage phased = PhasedStorage.wrap(base);
BufferedOutputStorage buffered = BufferedOutputStorage.wrap(phased, 250L);
plugin.getScheduler().asyncRepeating(buffered, 2L);
plugin.getBootstrap().getScheduler().asyncRepeating(buffered, 2L);
return buffered;
}
@@ -88,7 +88,7 @@ public class AbstractStorage implements Storage {
Throwables.propagateIfPossible(e);
throw new CompletionException(e);
}
}, this.dao.getPlugin().getScheduler().async());
}, this.dao.getPlugin().getBootstrap().getScheduler().async());
}
private CompletableFuture<Void> makeFuture(ThrowingRunnable runnable) {
@@ -99,7 +99,7 @@ public class AbstractStorage implements Storage {
Throwables.propagateIfPossible(e);
throw new CompletionException(e);
}
}, this.dao.getPlugin().getScheduler().async());
}, this.dao.getPlugin().getBootstrap().getScheduler().async());
}
@Override
@@ -126,7 +126,7 @@ public class AbstractStorage implements Storage {
try {
this.dao.init();
} catch (Exception e) {
this.plugin.getLog().severe("Failed to init storage dao");
this.plugin.getLogger().severe("Failed to init storage dao");
e.printStackTrace();
}
}
@@ -136,7 +136,7 @@ public class AbstractStorage implements Storage {
try {
this.dao.shutdown();
} catch (Exception e) {
this.plugin.getLog().severe("Failed to shutdown storage dao");
this.plugin.getLogger().severe("Failed to shutdown storage dao");
e.printStackTrace();
}
}
@@ -62,7 +62,7 @@ public class StorageFactory {
.map(e -> {
StorageType type = StorageType.parse(e.getValue());
if (type == null) {
this.plugin.getLog().severe("Storage method for " + e.getKey() + " - " + e.getValue() + " not recognised. " +
this.plugin.getLogger().severe("Storage method for " + e.getKey() + " - " + e.getValue() + " not recognised. " +
"Using the default instead.");
type = defaultMethod;
}
@@ -73,7 +73,7 @@ public class StorageFactory {
String method = this.plugin.getConfiguration().get(ConfigKeys.STORAGE_METHOD);
StorageType type = StorageType.parse(method);
if (type == null) {
this.plugin.getLog().severe("Storage method '" + method + "' not recognised. Using the default instead.");
this.plugin.getLogger().severe("Storage method '" + method + "' not recognised. Using the default instead.");
type = defaultMethod;
}
return ImmutableSet.of(type);
@@ -83,7 +83,7 @@ public class StorageFactory {
public Storage getInstance(StorageType defaultMethod) {
Storage storage;
if (this.plugin.getConfiguration().get(ConfigKeys.SPLIT_STORAGE)) {
this.plugin.getLog().info("Loading storage provider... [SPLIT STORAGE]");
this.plugin.getLogger().info("Loading storage provider... [SPLIT STORAGE]");
Map<SplitStorageType, StorageType> mappedTypes = this.plugin.getConfiguration().get(ConfigKeys.SPLIT_STORAGE_OPTIONS).entrySet().stream()
.map(e -> {
@@ -108,7 +108,7 @@ public class StorageFactory {
type = defaultMethod;
}
this.plugin.getLog().info("Loading storage provider... [" + type.name() + "]");
this.plugin.getLogger().info("Loading storage provider... [" + type.name() + "]");
storage = makeInstance(type);
}
@@ -139,13 +139,13 @@ public class StorageFactory {
case SQLITE:
return new SqlDao(
this.plugin,
new SQLiteConnectionFactory(this.plugin, new File(this.plugin.getDataDirectory(), "luckperms-sqlite.db")),
new SQLiteConnectionFactory(this.plugin, new File(this.plugin.getBootstrap().getDataDirectory(), "luckperms-sqlite.db")),
this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX)
);
case H2:
return new SqlDao(
this.plugin,
new H2ConnectionFactory(this.plugin, new File(this.plugin.getDataDirectory(), "luckperms-h2")),
new H2ConnectionFactory(this.plugin, new File(this.plugin.getBootstrap().getDataDirectory(), "luckperms-h2")),
this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX)
);
case POSTGRESQL:
@@ -150,7 +150,7 @@ public abstract class ConfigurateDao extends AbstractDao {
}
private Exception reportException(String file, Exception ex) throws Exception {
this.plugin.getLog().warn("Exception thrown whilst performing i/o: " + file);
this.plugin.getLogger().warn("Exception thrown whilst performing i/o: " + file);
ex.printStackTrace();
throw ex;
}
@@ -162,7 +162,7 @@ public abstract class ConfigurateDao extends AbstractDao {
@Override
public void init() {
try {
File data = FileUtils.mkdirs(new File(this.plugin.getDataDirectory(), this.dataFolderName));
File data = FileUtils.mkdirs(new File(this.plugin.getBootstrap().getDataDirectory(), this.dataFolderName));
this.usersDirectory = FileUtils.mkdir(new File(data, "users"));
this.groupsDirectory = FileUtils.mkdir(new File(data, "groups"));
@@ -185,7 +185,7 @@ public abstract class ConfigurateDao extends AbstractDao {
User u = this.plugin.getUserManager().getIfLoaded(uuid);
if (u != null) {
this.plugin.getLog().info("[FileWatcher] Refreshing user " + u.getFriendlyName());
this.plugin.getLogger().info("[FileWatcher] Refreshing user " + u.getFriendlyName());
this.plugin.getStorage().loadUser(uuid, null);
}
});
@@ -195,7 +195,7 @@ public abstract class ConfigurateDao extends AbstractDao {
}
String groupName = s.substring(0, s.length() - this.fileExtension.length());
this.plugin.getLog().info("[FileWatcher] Refreshing group " + groupName);
this.plugin.getLogger().info("[FileWatcher] Refreshing group " + groupName);
this.plugin.getUpdateTaskBuffer().request();
});
watcher.subscribe("track", this.tracksDirectory.toPath(), s -> {
@@ -204,7 +204,7 @@ public abstract class ConfigurateDao extends AbstractDao {
}
String trackName = s.substring(0, s.length() - this.fileExtension.length());
this.plugin.getLog().info("[FileWatcher] Refreshing track " + trackName);
this.plugin.getLogger().info("[FileWatcher] Refreshing track " + trackName);
this.plugin.getStorage().loadAllTracks();
});
});
@@ -59,7 +59,7 @@ public class FileWatcher implements Runnable {
this.keyMap = Collections.synchronizedMap(new HashMap<>());
this.internalChanges = Collections.synchronizedMap(new HashMap<>());
try {
this.watchService = plugin.getDataDirectory().toPath().getFileSystem().newWatchService();
this.watchService = plugin.getBootstrap().getDataDirectory().toPath().getFileSystem().newWatchService();
} catch (IOException e) {
e.printStackTrace();
}
@@ -71,7 +71,7 @@ public class FileWatcher implements Runnable {
}
// Register with a delay to ignore changes made at startup
this.plugin.getScheduler().asyncLater(() -> {
this.plugin.getBootstrap().getScheduler().asyncLater(() -> {
this.keyMap.computeIfAbsent(id, s -> {
WatchKey key;
try {
@@ -137,7 +137,7 @@ public class FileWatcher implements Runnable {
this.internalChanges.put(id + "/" + fileName, System.currentTimeMillis());
this.plugin.getLog().info("[FileWatcher] Detected change in file: " + file.toString());
this.plugin.getLogger().info("[FileWatcher] Detected change in file: " + file.toString());
// Process the change
ent.getValue().getFileConsumer().accept(fileName);
@@ -154,7 +154,7 @@ public class SqlDao extends AbstractDao {
// Init tables
if (!tableExists(this.prefix.apply("{prefix}user_permissions"))) {
String schemaFileName = "schema/" + this.provider.getName().toLowerCase() + ".sql";
try (InputStream is = this.plugin.getResourceStream(schemaFileName)) {
try (InputStream is = this.plugin.getBootstrap().getResourceStream(schemaFileName)) {
if (is == null) {
throw new Exception("Couldn't locate schema file for " + this.provider.getName());
}
@@ -203,7 +203,7 @@ public class SqlDao extends AbstractDao {
} catch (Exception e) {
this.plugin.getLog().severe("Error occurred whilst initialising the database.");
this.plugin.getLogger().severe("Error occurred whilst initialising the database.");
e.printStackTrace();
}
}