Folia support (#3615)

This commit is contained in:
lucko authored and GitHub committed 2026-05-21 22:16:56 +01:00
1 parent a97bdba0a0
commit fe3078e5d0
29 files changed
+257 -133

No files matched your search

+5 -1
View File
@@ -6,11 +6,15 @@ repositories {
maven { url 'https://repo.papermc.io/repository/maven-public/' }
}
java {
disableAutoTargetJvm()
}
dependencies {
implementation project(':common')
compileOnly project(':common:loader-utils')
compileOnly 'com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT'
compileOnly 'dev.folia:folia-api:26.1.2.build.8-stable'
compileOnly('net.kyori:adventure-platform-bukkit:4.4.0') {
exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
@@ -10,6 +10,7 @@ load: STARTUP
# remapping when the plugin is loaded. Note that despite what this setting might otherwise imply,
# LP is still compatible with pre-1.13 releases.
api-version: 1.13
folia-supported: true
# Load LuckPerms before Vault. This means that all plugins that (soft-)depend
# on Vault depend on LuckPerms too.
@@ -25,22 +25,32 @@
package me.lucko.luckperms.bukkit;
import me.lucko.luckperms.common.plugin.scheduler.AbstractJavaScheduler;
import me.lucko.luckperms.common.plugin.scheduler.JavaSchedulerAdapter;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
import me.lucko.luckperms.common.sender.Sender;
import org.bukkit.command.CommandSender;
import java.util.concurrent.Executor;
public class BukkitSchedulerAdapter extends AbstractJavaScheduler implements SchedulerAdapter {
private final Executor sync;
public class BukkitSchedulerAdapter extends JavaSchedulerAdapter implements SchedulerAdapter {
private final Executor syncExecutor;
public BukkitSchedulerAdapter(LPBukkitBootstrap bootstrap) {
super(bootstrap);
this.sync = r -> bootstrap.getServer().getScheduler().scheduleSyncDelayedTask(bootstrap.getLoader(), r);
this.syncExecutor = r -> bootstrap.getServer().getScheduler().scheduleSyncDelayedTask(bootstrap.getLoader(), r);
}
public void executeSync(Runnable task) {
this.syncExecutor.execute(task);
}
public void executeSync(CommandSender ctx, Runnable task) {
this.syncExecutor.execute(task);
}
@Override
public Executor sync() {
return this.sync;
public void executeSync(Sender ctx, Runnable task) {
this.syncExecutor.execute(task);
}
}
@@ -67,7 +67,7 @@ public class BukkitSenderFactory extends SenderFactory<LPBukkitPlugin, CommandSe
if (sender instanceof Player || sender instanceof ConsoleCommandSender || sender instanceof RemoteConsoleCommandSender) {
this.audiences.sender(sender).sendMessage(message);
} else {
getPlugin().getBootstrap().getScheduler().executeSync(() -> this.audiences.sender(sender).sendMessage(message));
getPlugin().getBootstrap().getScheduler().executeSync(sender, () -> this.audiences.sender(sender).sendMessage(message));
}
}
@@ -0,0 +1,86 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <[email protected]>
* 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 io.papermc.paper.threadedregions.scheduler.RegionScheduler;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
import me.lucko.luckperms.common.sender.AbstractSender;
import me.lucko.luckperms.common.sender.Sender;
import org.bukkit.Server;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.ProxiedCommandSender;
import org.bukkit.command.RemoteConsoleCommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.java.JavaPlugin;
public class FoliaSchedulerAdapter extends BukkitSchedulerAdapter implements SchedulerAdapter {
private final JavaPlugin loader;
private final Server server;
public FoliaSchedulerAdapter(LPBukkitBootstrap bootstrap) {
super(bootstrap);
this.loader = bootstrap.getLoader();
this.server = bootstrap.getServer();
}
@Override
public void executeSync(Runnable task) {
this.server.getGlobalRegionScheduler().execute(this.loader, task);
}
@Override
public void executeSync(Sender ctx, Runnable task) {
executeSync(unwrapSender(ctx), task);
}
@Override
public void executeSync(CommandSender ctx, Runnable task) {
if (ctx instanceof Entity) {
((Entity) ctx).getScheduler().execute(this.loader, task, null, 0);
} else if (ctx instanceof BlockCommandSender) {
RegionScheduler scheduler = this.server.getRegionScheduler();
scheduler.execute(this.loader, ((BlockCommandSender) ctx).getBlock().getLocation(), task);
} else if (ctx instanceof ConsoleCommandSender || ctx instanceof RemoteConsoleCommandSender) {
this.server.getGlobalRegionScheduler().execute(this.loader, task);
} else if (ctx instanceof ProxiedCommandSender) {
executeSync(((ProxiedCommandSender) ctx).getCallee(), task);
} else {
throw new IllegalArgumentException("Unknown command sender type: " + ctx.getClass().getName());
}
}
@SuppressWarnings("unchecked")
private static CommandSender unwrapSender(Sender sender) {
if (sender instanceof AbstractSender) {
return ((AbstractSender<CommandSender>) sender).getSender();
} else {
throw new IllegalArgumentException("unknown sender type: " + sender.getClass());
}
}
}
@@ -102,7 +102,9 @@ public class LPBukkitBootstrap implements LuckPermsBootstrap, LoaderBootstrap, B
this.loader = loader;
this.logger = new JavaPluginLogger(loader.getLogger());
this.schedulerAdapter = new BukkitSchedulerAdapter(this);
this.schedulerAdapter = isFolia()
? new FoliaSchedulerAdapter(this)
: new BukkitSchedulerAdapter(this);
this.classPathAppender = new JarInJarClassPathAppender(getClass().getClassLoader());
this.console = new NullSafeConsoleCommandSender(getServer());
this.plugin = new LPBukkitPlugin(this);
@@ -175,7 +177,7 @@ public class LPBukkitBootstrap implements LuckPermsBootstrap, LoaderBootstrap, B
this.plugin.enable();
// schedule a task to update the 'serverStarting' flag
getServer().getScheduler().runTask(this.loader, () -> this.serverStarting = false);
this.schedulerAdapter.executeSync(() -> this.serverStarting = false);
} finally {
this.enableLatch.countDown();
}
@@ -311,4 +313,13 @@ public class LPBukkitBootstrap implements LuckPermsBootstrap, LoaderBootstrap, B
return true;
}
}
private static boolean isFolia() {
try {
Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}
@@ -206,7 +206,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin {
// schedule another injection after all plugins have loaded
// the entire pluginmanager instance is replaced by some plugins :(
this.bootstrap.getServer().getScheduler().runTaskLaterAsynchronously(this.bootstrap.getLoader(), injector, 1);
this.bootstrap.getScheduler().executeSync(injector);
}
/*
@@ -268,7 +268,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin {
// remove all operators on startup if they're disabled
if (!getConfiguration().get(ConfigKeys.OPS_ENABLED)) {
this.bootstrap.getServer().getScheduler().runTaskAsynchronously(this.bootstrap.getLoader(), () -> {
this.bootstrap.getScheduler().executeSync(() -> {
for (OfflinePlayer player : this.bootstrap.getServer().getOperators()) {
player.setOp(false);
}
@@ -291,7 +291,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin {
try {
User user = this.connectionListener.loadUser(player.getUniqueId(), player.getName());
if (user != null) {
this.bootstrap.getScheduler().executeSync(() -> {
this.bootstrap.getScheduler().executeSync(player, () -> {
try {
LuckPermsPermissible lpPermissible = new LuckPermsPermissible(player, user, this);
PermissibleInjector.inject(player, lpPermissible, getLogger());
@@ -83,7 +83,7 @@ public class BukkitAutoOpListener implements LuckPermsEventListener {
if (callerIsSync) {
player.setOp(value);
} else {
this.plugin.getBootstrap().getScheduler().executeSync(() -> player.setOp(value));
this.plugin.getBootstrap().getScheduler().executeSync(player, () -> player.setOp(value));
}
}
@@ -26,6 +26,7 @@
package me.lucko.luckperms.bukkit.listeners;
import com.github.benmanes.caffeine.cache.LoadingCache;
import me.lucko.luckperms.bukkit.LPBukkitBootstrap;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.cache.BufferedRequest;
import me.lucko.luckperms.common.event.LuckPermsEventListener;
@@ -90,12 +91,15 @@ public class BukkitCommandListUpdater implements LuckPermsEventListener {
// Called when the buffer times out.
private void sendUpdate(UUID uniqueId) {
if (this.plugin.getBootstrap().isServerStopping()) {
LPBukkitBootstrap bootstrap = this.plugin.getBootstrap();
if (bootstrap.isServerStopping()) {
return;
}
this.plugin.getBootstrap().getScheduler().sync()
.execute(() -> this.plugin.getBootstrap().getPlayer(uniqueId).ifPresent(Player::updateCommands));
Player player = bootstrap.getPlayer(uniqueId).orElse(null);
if (player != null) {
bootstrap.getScheduler().executeSync(player, player::updateCommands);
}
}
private final class SendBuffer extends BufferedRequest<Void> {
@@ -240,7 +240,7 @@ public class BukkitConnectionListener extends AbstractConnectionListener impleme
// perform unhooking from bukkit objects 1 tick later.
// this allows plugins listening after us on MONITOR to still have intact permissions data
this.plugin.getBootstrap().getServer().getScheduler().runTaskLater(this.plugin.getLoader(), () -> {
this.plugin.getBootstrap().getScheduler().executeSync(() -> {
// Remove the custom permissible
try {
PermissibleInjector.uninject(player, true);
@@ -253,7 +253,7 @@ public class BukkitConnectionListener extends AbstractConnectionListener impleme
if (this.plugin.getConfiguration().get(ConfigKeys.AUTO_OP)) {
player.setOp(false);
}
}, 1L);
});
}
}
@@ -25,6 +25,7 @@
package me.lucko.luckperms.bukkit.util;
import net.kyori.adventure.text.Component;
import org.bukkit.ChatColor;
import org.bukkit.Server;
import org.bukkit.command.ConsoleCommandSender;
@@ -35,9 +36,12 @@ import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
/**
* The {@link Server#getConsoleSender()} method returns null during onEnable
@@ -109,12 +113,16 @@ public class NullSafeConsoleCommandSender implements ConsoleCommandSender {
// just throw UnsupportedOperationException - we never use any of these methods
@Override public @NonNull Spigot spigot() { throw new UnsupportedOperationException(); }
@Override public void sendMessage(@Nullable UUID uuid, @NotNull String s) { throw new UnsupportedOperationException(); }
@Override public void sendMessage(@Nullable UUID uuid, @NotNull String... strings) { throw new UnsupportedOperationException(); }
@Override public @NotNull Component name() { throw new UnsupportedOperationException(); }
@Override public boolean isConversing() { throw new UnsupportedOperationException(); }
@Override public void acceptConversationInput(@NonNull String s) { throw new UnsupportedOperationException(); }
@Override public boolean beginConversation(@NonNull Conversation conversation) { throw new UnsupportedOperationException(); }
@Override public void abandonConversation(@NonNull Conversation conversation) { throw new UnsupportedOperationException(); }
@Override public void abandonConversation(@NonNull Conversation conversation, @NonNull ConversationAbandonedEvent conversationAbandonedEvent) { throw new UnsupportedOperationException(); }
@Override public void sendRawMessage(@NonNull String s) { throw new UnsupportedOperationException(); }
@Override public void sendRawMessage(@Nullable UUID uuid, @NotNull String s) { throw new UnsupportedOperationException(); }
@Override public @NonNull PermissionAttachment addAttachment(@NonNull Plugin plugin, @NonNull String s, boolean b) { throw new UnsupportedOperationException(); }
@Override public @NonNull PermissionAttachment addAttachment(@NonNull Plugin plugin) { throw new UnsupportedOperationException(); }
@Override public PermissionAttachment addAttachment(@NonNull Plugin plugin, @NonNull String s, boolean b, int i) { throw new UnsupportedOperationException(); }
@@ -52,11 +52,6 @@ public class BungeeSchedulerAdapter implements SchedulerAdapter {
return this.executor;
}
@Override
public Executor sync() {
return this.executor;
}
@Override
public SchedulerTask asyncLater(Runnable task, long delay, TimeUnit unit) {
ScheduledTask t = this.bootstrap.getProxy().getScheduler().schedule(this.bootstrap.getLoader(), task, delay, unit);
@@ -26,6 +26,7 @@
package me.lucko.luckperms.common.minecraft;
import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.players.NameAndId;
@@ -42,6 +43,9 @@ public abstract class MinecraftLuckPermsBootstrap implements LuckPermsBootstrap
public abstract Optional<MinecraftServer> getServer();
@Override
public abstract MinecraftSchedulerAdapter getScheduler();
@Override
public final Optional<ServerPlayer> getPlayer(UUID uniqueId) {
return getServer().map(MinecraftServer::getPlayerList).map(playerList -> playerList.getPlayer(uniqueId));
@@ -25,20 +25,25 @@
package me.lucko.luckperms.common.minecraft;
import me.lucko.luckperms.common.plugin.scheduler.AbstractJavaScheduler;
import me.lucko.luckperms.common.plugin.scheduler.JavaSchedulerAdapter;
import me.lucko.luckperms.common.sender.Sender;
import java.util.concurrent.Executor;
public class MinecraftSchedulerAdapter extends AbstractJavaScheduler {
private final Executor sync;
public class MinecraftSchedulerAdapter extends JavaSchedulerAdapter {
private final Executor syncExecutor;
public MinecraftSchedulerAdapter(MinecraftLuckPermsBootstrap bootstrap) {
super(bootstrap);
this.sync = r -> bootstrap.getServer().orElseThrow(() -> new IllegalStateException("Server not ready")).executeBlocking(r);
this.syncExecutor = r -> bootstrap.getServer().orElseThrow(() -> new IllegalStateException("Server not ready")).executeBlocking(r);
}
public void executeSync(Runnable task) {
this.syncExecutor.execute(task);
}
@Override
public Executor sync() {
return this.sync;
public void executeSync(Sender ctx, Runnable task) {
this.syncExecutor.execute(task);
}
}
@@ -89,12 +89,13 @@ public class MinecraftCommandListUpdater implements LuckPermsEventListener {
// Called when the buffer times out.
private void sendUpdate(UUID uniqueId) {
this.plugin.getBootstrap().getScheduler().sync().execute(() ->
this.plugin.getBootstrap().getPlayer(uniqueId).ifPresent(player -> {
MinecraftServer server = player.level().getServer();
server.getPlayerList().sendPlayerPermissionLevel(player);
})
);
this.plugin.getBootstrap().getScheduler().executeSync(() -> {
ServerPlayer player = this.plugin.getBootstrap().getPlayer(uniqueId).orElse(null);
if (player != null) {
MinecraftServer server = player.level().getServer();
server.getPlayerList().sendPlayerPermissionLevel(player);
}
});
}
private final class SendBuffer extends BufferedRequest<Void> {
@@ -94,7 +94,7 @@ public class VerboseCommand extends SingleCommand {
String commandWithSlash = String.join(" ", args.subList(2, args.size()));
String command = commandWithSlash.charAt(0) == '/' ? commandWithSlash.substring(1) : commandWithSlash;
plugin.getBootstrap().getScheduler().sync().execute(() -> {
plugin.getBootstrap().getScheduler().executeSync(executor, () -> {
Message.VERBOSE_ON_COMMAND.send(sender, executor.getName(), command);
verboseHandler.registerListener(sender, VerboseFilter.acceptAll(), true);
@@ -44,7 +44,7 @@ import java.util.stream.Collectors;
/**
* Abstract implementation of {@link SchedulerAdapter} using a {@link ScheduledExecutorService}.
*/
public abstract class AbstractJavaScheduler implements SchedulerAdapter {
public class JavaSchedulerAdapter implements SchedulerAdapter {
private static final int PARALLELISM = 16;
private final LuckPermsBootstrap bootstrap;
@@ -52,7 +52,7 @@ public abstract class AbstractJavaScheduler implements SchedulerAdapter {
private final ScheduledThreadPoolExecutor scheduler;
private final ForkJoinPool worker;
public AbstractJavaScheduler(LuckPermsBootstrap bootstrap) {
public JavaSchedulerAdapter(LuckPermsBootstrap bootstrap) {
this.bootstrap = bootstrap;
this.scheduler = new ScheduledThreadPoolExecutor(1, r -> {
@@ -133,7 +133,7 @@ public abstract class AbstractJavaScheduler implements SchedulerAdapter {
private final class ExceptionHandler implements UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
AbstractJavaScheduler.this.bootstrap.getPluginLogger().warn("Thread " + t.getName() + " threw an uncaught exception", e);
JavaSchedulerAdapter.this.bootstrap.getPluginLogger().warn("Thread " + t.getName() + " threw an uncaught exception", e);
}
}
}
@@ -25,6 +25,8 @@
package me.lucko.luckperms.common.plugin.scheduler;
import me.lucko.luckperms.common.sender.Sender;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@@ -40,13 +42,6 @@ public interface SchedulerAdapter {
*/
Executor async();
/**
* Gets a sync executor instance
*
* @return a sync executor instance
*/
Executor sync();
/**
* Executes a task async
*
@@ -61,8 +56,8 @@ public interface SchedulerAdapter {
*
* @param task the task
*/
default void executeSync(Runnable task) {
sync().execute(task);
default void executeSync(Sender ctx, Runnable task) {
executeAsync(task);
}
/**
@@ -69,6 +69,10 @@ public final class AbstractSender<T> implements Sender {
return this.plugin;
}
public T getSender() {
return this.sender;
}
@Override
public UUID getUniqueId() {
return this.uniqueId;
@@ -31,7 +31,6 @@ import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap;
import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender;
import me.lucko.luckperms.common.plugin.logging.Log4jPluginLogger;
import me.lucko.luckperms.common.plugin.logging.PluginLogger;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
import net.fabricmc.api.DedicatedServerModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.loader.api.FabricLoader;
@@ -68,7 +67,7 @@ public final class LPFabricBootstrap extends MinecraftLuckPermsBootstrap impleme
/**
* A scheduler adapter for the platform
*/
private final SchedulerAdapter schedulerAdapter;
private final MinecraftSchedulerAdapter schedulerAdapter;
/**
* The plugin class path appender
@@ -111,7 +110,7 @@ public final class LPFabricBootstrap extends MinecraftLuckPermsBootstrap impleme
}
@Override
public SchedulerAdapter getScheduler() {
public MinecraftSchedulerAdapter getScheduler() {
return this.schedulerAdapter;
}
@@ -34,7 +34,6 @@ import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender;
import me.lucko.luckperms.common.plugin.classpath.JarInJarClassPathAppender;
import me.lucko.luckperms.common.plugin.logging.Log4jPluginLogger;
import me.lucko.luckperms.common.plugin.logging.PluginLogger;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
import me.lucko.luckperms.common.util.BuildInfo;
import net.luckperms.api.platform.Platform;
import net.minecraft.server.MinecraftServer;
@@ -80,7 +79,7 @@ public final class LPForgeBootstrap extends MinecraftLuckPermsBootstrap implemen
/**
* A scheduler adapter for the platform
*/
private final SchedulerAdapter schedulerAdapter;
private final MinecraftSchedulerAdapter schedulerAdapter;
/**
* The plugin class path appender
@@ -132,7 +131,7 @@ public final class LPForgeBootstrap extends MinecraftLuckPermsBootstrap implemen
}
@Override
public SchedulerAdapter getScheduler() {
public MinecraftSchedulerAdapter getScheduler() {
return this.schedulerAdapter;
}
@@ -25,20 +25,55 @@
package me.lucko.luckperms.hytale;
import me.lucko.luckperms.common.plugin.scheduler.AbstractJavaScheduler;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.command.system.CommandSender;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.receiver.IMessageReceiver;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import me.lucko.luckperms.common.plugin.scheduler.JavaSchedulerAdapter;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
import me.lucko.luckperms.common.sender.AbstractSender;
import me.lucko.luckperms.common.sender.Sender;
import java.util.concurrent.Executor;
public class HytaleSchedulerAdapter extends AbstractJavaScheduler implements SchedulerAdapter {
public class HytaleSchedulerAdapter extends JavaSchedulerAdapter implements SchedulerAdapter {
public HytaleSchedulerAdapter(LPHytaleBootstrap bootstrap) {
super(bootstrap);
}
@Override
public Executor sync() {
return this.async();
public void executeSync(Sender ctx, Runnable task) {
executeSync(unwrapSender(ctx), task);
}
public void executeSync(IMessageReceiver ctx, Runnable task) {
if (ctx instanceof PlayerRef playerRef) {
Ref<EntityStore> ref = playerRef.getReference();
if (ref != null) {
World world = ref.getStore().getExternalData().getWorld();
world.execute(task);
return;
}
} else if (ctx instanceof Player player) {
World world = player.getWorld();
if (world != null) {
world.execute(task);
return;
}
}
// fallback
executeAsync(task);
}
@SuppressWarnings("unchecked")
private static IMessageReceiver unwrapSender(Sender sender) {
if (sender instanceof AbstractSender) {
return ((AbstractSender<IMessageReceiver>) sender).getSender();
} else {
throw new IllegalArgumentException("unknown sender type: " + sender.getClass());
}
}
}
@@ -75,7 +75,7 @@ public final class LPNeoForgeBootstrap extends MinecraftLuckPermsBootstrap imple
/**
* A scheduler adapter for the platform
*/
private final SchedulerAdapter schedulerAdapter;
private final MinecraftSchedulerAdapter schedulerAdapter;
/**
* The plugin class path appender
@@ -128,7 +128,7 @@ public final class LPNeoForgeBootstrap extends MinecraftLuckPermsBootstrap imple
}
@Override
public SchedulerAdapter getScheduler() {
public MinecraftSchedulerAdapter getScheduler() {
return this.schedulerAdapter;
}
@@ -25,22 +25,27 @@
package me.lucko.luckperms.nukkit;
import me.lucko.luckperms.common.plugin.scheduler.AbstractJavaScheduler;
import me.lucko.luckperms.common.plugin.scheduler.JavaSchedulerAdapter;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
import me.lucko.luckperms.common.sender.Sender;
import java.util.concurrent.Executor;
public class NukkitSchedulerAdapter extends AbstractJavaScheduler implements SchedulerAdapter {
private final Executor sync;
public class NukkitSchedulerAdapter extends JavaSchedulerAdapter implements SchedulerAdapter {
private final Executor syncExecutor;
public NukkitSchedulerAdapter(LPNukkitBootstrap bootstrap) {
super(bootstrap);
this.sync = r -> bootstrap.getServer().getScheduler().scheduleTask(bootstrap.getLoader(), r, false);
this.syncExecutor = r -> bootstrap.getServer().getScheduler().scheduleTask(bootstrap.getLoader(), r, false);
}
public void executeSync(Runnable task) {
this.syncExecutor.execute(task);
}
@Override
public Executor sync() {
return this.sync;
public void executeSync(Sender ctx, Runnable task) {
this.syncExecutor.execute(task);
}
}
@@ -28,6 +28,7 @@ package me.lucko.luckperms.sponge;
import com.google.common.base.Suppliers;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerTask;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Iterators;
import org.spongepowered.api.Game;
import org.spongepowered.api.scheduler.ScheduledTask;
@@ -64,20 +65,24 @@ public class SpongeSchedulerAdapter implements SchedulerAdapter {
this.sync = Suppliers.memoize(() -> getSyncScheduler().executor(this.pluginContainer));
}
public Scheduler getSyncScheduler() {
return this.game.server().scheduler();
}
public void executeSync(Runnable task) {
this.sync.get().execute(task);
}
@Override
public void executeSync(Sender ctx, Runnable task) {
this.sync.get().execute(task);
}
@Override
public Executor async() {
return this.async;
}
@Override
public Executor sync() {
return this.sync.get();
}
public Scheduler getSyncScheduler() {
return this.game.server().scheduler();
}
private SchedulerTask submitAsyncTask(Runnable runnable, Consumer<Task.Builder> config) {
Task.Builder builder = Task.builder();
config.accept(builder);
@@ -79,7 +79,7 @@ public class SpongeCommandListUpdater implements LuckPermsEventListener {
// Called when the buffer times out.
private void sendUpdate(UUID uniqueId) {
this.plugin.getBootstrap().getScheduler().sync().execute(() -> {
this.plugin.getBootstrap().getScheduler().executeSync(() -> {
ServerPlayer player = this.plugin.getBootstrap().getPlayer(uniqueId).orElse(null);
if (player != null) {
CommandManager commandManager = this.plugin.getBootstrap().getGame().server().commandManager();
@@ -32,6 +32,8 @@ import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender;
import me.lucko.luckperms.common.plugin.classpath.JarInJarClassPathAppender;
import me.lucko.luckperms.common.plugin.logging.Log4jPluginLogger;
import me.lucko.luckperms.common.plugin.logging.PluginLogger;
import me.lucko.luckperms.common.plugin.scheduler.JavaSchedulerAdapter;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
import me.lucko.luckperms.common.util.BuildInfo;
import me.lucko.luckperms.standalone.app.LuckPermsApplication;
import net.luckperms.api.platform.Platform;
@@ -52,7 +54,7 @@ public class LPStandaloneBootstrap implements LuckPermsBootstrap, LoaderBootstra
private final LuckPermsApplication loader;
private final PluginLogger logger;
private final StandaloneSchedulerAdapter schedulerAdapter;
private final SchedulerAdapter schedulerAdapter;
private final ClassPathAppender classPathAppender;
private final LPStandalonePlugin plugin;
@@ -64,7 +66,7 @@ public class LPStandaloneBootstrap implements LuckPermsBootstrap, LoaderBootstra
this.loader = loader;
this.logger = new Log4jPluginLogger(LuckPermsApplication.LOGGER);
this.schedulerAdapter = new StandaloneSchedulerAdapter(this);
this.schedulerAdapter = new JavaSchedulerAdapter(this);
this.classPathAppender = new JarInJarClassPathAppender(getClass().getClassLoader());
this.plugin = new LPStandalonePlugin(this);
}
@@ -74,7 +76,7 @@ public class LPStandaloneBootstrap implements LuckPermsBootstrap, LoaderBootstra
this.loader = loader;
this.logger = new Log4jPluginLogger(LuckPermsApplication.LOGGER);
this.schedulerAdapter = new StandaloneSchedulerAdapter(this);
this.schedulerAdapter = new JavaSchedulerAdapter(this);
this.classPathAppender = classPathAppender;
this.plugin = createTestPlugin();
}
@@ -97,7 +99,7 @@ public class LPStandaloneBootstrap implements LuckPermsBootstrap, LoaderBootstra
}
@Override
public StandaloneSchedulerAdapter getScheduler() {
public SchedulerAdapter getScheduler() {
return this.schedulerAdapter;
}
@@ -1,44 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <[email protected]>
* 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.standalone;
import me.lucko.luckperms.common.plugin.scheduler.AbstractJavaScheduler;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
import java.util.concurrent.Executor;
public class StandaloneSchedulerAdapter extends AbstractJavaScheduler implements SchedulerAdapter {
public StandaloneSchedulerAdapter(LPStandaloneBootstrap bootstrap) {
super(bootstrap);
}
@Override
public Executor sync() {
return this.async();
}
}
@@ -52,11 +52,6 @@ public class VelocitySchedulerAdapter implements SchedulerAdapter {
return this.executor;
}
@Override
public Executor sync() {
return this.executor;
}
@Override
public SchedulerTask asyncLater(Runnable task, long delay, TimeUnit unit) {
ScheduledTask t = this.bootstrap.getProxy().getScheduler().buildTask(this.bootstrap, task)