Compare commits

...
Author SHA1 Message Date
Owen1212055 400eaa17db Fix tests 2025-10-27 13:43:47 -04:00
Owen1212055 cce675a86e Add some experiemental 2025-10-17 21:22:34 -04:00
Owen1212055 c88039b3da Permission registration hook API
Allows for getting player permissions before a player is accessible. Useful for moving away from the main Player instance.
2025-10-17 21:15:14 -04:00
21 changed files with 405 additions and 169 deletions

No files matched your search

@@ -1,10 +1,15 @@
package io.papermc.paper.plugin;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.ServerOperator;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
@@ -163,4 +168,13 @@ public interface PermissionManager {
*/
void clearPermissions();
@ApiStatus.Experimental
Permissible createPermissible(@NotNull ServerOperator operator);
@ApiStatus.Experimental
Permissible createCommandBlockPermissible();
// This is very special, and also this is expected to hold no state to PermissionManager.
@ApiStatus.Experimental
CompletableFuture<Optional<Permissible>> loadPlayerPermissible(@NotNull UUID playerUuid);
}
@@ -0,0 +1,12 @@
package io.papermc.paper.plugin;
import io.papermc.paper.plugin.lifecycle.event.registrar.Registrar;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@ApiStatus.Experimental
public interface PermissionManagerRegistrar extends Registrar {
void register(@NotNull PermissionManager permissionManager);
}
@@ -2,6 +2,7 @@ package io.papermc.paper.plugin.lifecycle.event.types;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.datapack.DatapackRegistrar;
import io.papermc.paper.plugin.PermissionManagerRegistrar;
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
@@ -41,6 +42,14 @@ public final class LifecycleEvents {
@ApiStatus.Experimental
public static final LifecycleEventType.Prioritizable<BootstrapContext, RegistrarEvent<DatapackRegistrar>> DATAPACK_DISCOVERY = bootstrapPrioritized("datapack_discovery");
/**
* This event is for informing the server about any available datapacks from other sources such as inside a plugin's jar. You
* can register a handler for this event only in {@link io.papermc.paper.plugin.bootstrap.PluginBootstrap#bootstrap(BootstrapContext)}.
* @see DatapackRegistrar an example of a datapack being discovered
*/
@ApiStatus.Experimental
public static final LifecycleEventType.Prioritizable<BootstrapContext, RegistrarEvent<PermissionManagerRegistrar>> PERMISSION_MANAGER_REGISTER = bootstrapPrioritized("permission_manager_register");
//<editor-fold desc="helper methods" defaultstate="collapsed">
@ApiStatus.Internal
static <E extends LifecycleEvent> LifecycleEventType.Monitorable<Plugin, E> plugin(final String name) {
@@ -156,4 +156,8 @@ public interface Permissible extends ServerOperator {
}
}
// Paper end
default void clearPermissions() {
}
}
@@ -179,6 +179,7 @@ public class PermissibleBase implements Permissible {
}
}
@Override
public synchronized void clearPermissions() {
Set<String> perms = permissions.keySet();
@@ -320,13 +320,5 @@ public interface PluginManager extends io.papermc.paper.plugin.PermissionManager
*/
@org.jetbrains.annotations.ApiStatus.Internal
boolean isTransitiveDependency(io.papermc.paper.plugin.configuration.PluginMeta pluginMeta, io.papermc.paper.plugin.configuration.PluginMeta dependencyConfig);
/**
* Sets the permission manager to be used for this server.
*
* @param permissionManager permission manager
*/
@org.jetbrains.annotations.ApiStatus.Experimental
void overridePermissionManager(@NotNull Plugin plugin, @Nullable io.papermc.paper.plugin.PermissionManager permissionManager);
// Paper end
}
@@ -20,8 +20,11 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -37,6 +40,7 @@ import org.bukkit.event.Listener;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.permissions.ServerOperator;
import org.bukkit.util.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -978,13 +982,23 @@ public final class SimplePluginManager implements PluginManager {
}
@Override
public boolean isTransitiveDependency(io.papermc.paper.plugin.configuration.PluginMeta pluginMeta, io.papermc.paper.plugin.configuration.PluginMeta dependencyConfig) {
return this.paperPluginManager.isTransitiveDependency(pluginMeta, dependencyConfig);
public Permissible createPermissible(@NotNull ServerOperator operator) {
return this.paperPluginManager.createPermissible(operator);
}
@Override
public void overridePermissionManager(@NotNull Plugin plugin, @Nullable io.papermc.paper.plugin.PermissionManager permissionManager) {
this.paperPluginManager.overridePermissionManager(plugin, permissionManager);
public Permissible createCommandBlockPermissible() {
return this.paperPluginManager.createCommandBlockPermissible();
}
@Override
public CompletableFuture<Optional<Permissible>> loadPlayerPermissible(@NotNull UUID playerUuid) {
return this.paperPluginManager.loadPlayerPermissible(playerUuid);
}
@Override
public boolean isTransitiveDependency(io.papermc.paper.plugin.configuration.PluginMeta pluginMeta, io.papermc.paper.plugin.configuration.PluginMeta dependencyConfig) {
return this.paperPluginManager.isTransitiveDependency(pluginMeta, dependencyConfig);
}
@Override
@@ -1,5 +1,10 @@
package io.papermc.paper.plugin.entrypoint;
import io.papermc.paper.plugin.PermissionManagerRegistrar;
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner;
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
import io.papermc.paper.plugin.manager.PermissionRegistrar;
import io.papermc.paper.plugin.provider.PluginProvider;
import io.papermc.paper.plugin.storage.BootstrapProviderStorage;
import io.papermc.paper.plugin.storage.ProviderStorage;
@@ -27,6 +32,11 @@ public class LaunchEntryPointHandler implements EntrypointHandler {
// Utility
public static void enterBootstrappers() {
LaunchEntryPointHandler.INSTANCE.enter(Entrypoint.BOOTSTRAPPER);
// Register permission manager
LifecycleEventRunner.INSTANCE.callStaticRegistrarEvent(LifecycleEvents.PERMISSION_MANAGER_REGISTER,
PermissionRegistrar.INSTANCE,
BootstrapContext.class
);
}
@Override
@@ -1,13 +1,20 @@
package io.papermc.paper.plugin.manager;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.PermissibleBase;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.ServerOperator;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
class NormalPaperPermissionManager extends PaperPermissionManager {
@@ -15,6 +22,7 @@ class NormalPaperPermissionManager extends PaperPermissionManager {
private final Map<Boolean, Set<Permission>> defaultPerms = new LinkedHashMap<>();
private final Map<String, Map<Permissible, Boolean>> permSubs = new HashMap<>();
private final Map<Boolean, Map<Permissible, Boolean>> defSubs = new HashMap<>();
private Permissible sharedEntityPermissible;
public NormalPaperPermissionManager() {
this.defaultPerms().put(true, new LinkedHashSet<>());
@@ -40,4 +48,50 @@ class NormalPaperPermissionManager extends PaperPermissionManager {
public Map<Boolean, Map<Permissible, Boolean>> defSubs() {
return this.defSubs;
}
@Override
public Permissible createPermissible(final ServerOperator operator) {
if (operator instanceof Player player) {
return new PermissibleBase(player);
} else {
// Has to be lazy since it recalculated default permissions in the constructor
if (this.sharedEntityPermissible == null) {
this.sharedEntityPermissible = new PermissibleBase(new ServerOperator() {
@Override
public boolean isOp() {
return false;
}
@Override
public void setOp(final boolean value) {
}
});
}
return this.sharedEntityPermissible;
}
}
@Override
public Permissible createCommandBlockPermissible() {
return new PermissibleBase(new ServerOperator() {
@Override
public boolean isOp() {
return true;
}
@Override
public void setOp(boolean value) {
throw new UnsupportedOperationException("Cannot change operator status of a block");
}
});
}
@Override
public CompletableFuture<Optional<Permissible>> loadPlayerPermissible(@NotNull UUID playerUuid) {
return CompletableFuture.completedFuture(Optional.empty());
}
}
@@ -1,6 +1,7 @@
package io.papermc.paper.plugin.manager;
import com.google.common.graph.MutableGraph;
import com.mojang.logging.LogUtils;
import io.papermc.paper.plugin.PermissionManager;
import io.papermc.paper.plugin.configuration.PluginMeta;
import io.papermc.paper.plugin.provider.entrypoint.DependencyContext;
@@ -13,6 +14,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.ServerOperator;
import org.bukkit.plugin.EventExecutor;
import org.bukkit.plugin.InvalidDescriptionException;
import org.bukkit.plugin.InvalidPluginException;
@@ -23,25 +25,32 @@ import org.bukkit.plugin.SimplePluginManager;
import org.bukkit.plugin.UnknownDependencyException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import java.io.File;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class PaperPluginManagerImpl implements PluginManager, DependencyContext {
private static final Logger LOGGER = LogUtils.getClassLogger();
final PaperPluginInstanceManager instanceManager;
final PaperEventManager paperEventManager;
PermissionManager permissionManager;
public PaperPluginManagerImpl(Server server, CommandMap commandMap, @Nullable SimplePluginManager permissionManager) {
public PaperPluginManagerImpl(Server server, CommandMap commandMap) {
this.instanceManager = new PaperPluginInstanceManager(this, commandMap, server);
this.paperEventManager = new PaperEventManager(server);
if (permissionManager == null) {
this.permissionManager = new NormalPaperPermissionManager();
PermissionManager possibleCustomImpl = PermissionRegistrar.INSTANCE.getRegistered();
if (possibleCustomImpl != null) {
this.permissionManager = possibleCustomImpl;
LOGGER.info("Custom Permission Manager Implementation from plugin {}", PermissionRegistrar.INSTANCE.getRegisteredOwner());
} else {
this.permissionManager = new StupidSPMPermissionManagerWrapper(permissionManager); // TODO: See comment when SimplePermissionManager is removed
this.permissionManager = new NormalPaperPermissionManager();
}
}
@@ -224,10 +233,19 @@ public class PaperPluginManagerImpl implements PluginManager, DependencyContext
}
@Override
public void overridePermissionManager(@NotNull Plugin plugin, @Nullable PermissionManager permissionManager) {
this.permissionManager = permissionManager;
public Permissible createPermissible(@NotNull ServerOperator operator) {
return this.permissionManager.createPermissible(operator);
}
@Override
public Permissible createCommandBlockPermissible() {
return this.permissionManager.createCommandBlockPermissible();
}
@Override
public CompletableFuture<Optional<Permissible>> loadPlayerPermissible(@NotNull UUID playerUuid) {
return this.permissionManager.loadPlayerPermissible(playerUuid);
}
// Etc
@Override
@@ -0,0 +1,45 @@
package io.papermc.paper.plugin.manager;
import com.mojang.logging.LogUtils;
import io.papermc.paper.plugin.PermissionManager;
import io.papermc.paper.plugin.PermissionManagerRegistrar;
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import io.papermc.paper.plugin.lifecycle.event.registrar.PaperRegistrar;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.NullMarked;
import org.slf4j.Logger;
@NullMarked
public enum PermissionRegistrar implements PermissionManagerRegistrar, PaperRegistrar<BootstrapContext> {
INSTANCE;
private static final Logger LOGGER = LogUtils.getClassLogger();
private BootstrapContext owner;
private @Nullable PermissionManager registered;
private String registeredOwner;
@Override
public void register(PermissionManager permissionManager) {
if (this.registered != null) {
LOGGER.warn("Permission manager registration overridden! (Was {}, now is {})", this.registeredOwner, this.owner.getPluginMeta().getDisplayName());
}
this.registered = permissionManager;
this.registeredOwner = this.owner.getPluginMeta().getDisplayName();
}
@Override
public void setCurrentContext(@Nullable BootstrapContext owner) {
this.owner = owner;
}
public @Nullable PermissionManager getRegistered() {
return this.registered;
}
public String getRegisteredOwner() {
return registeredOwner;
}
}
@@ -1,42 +0,0 @@
package io.papermc.paper.plugin.manager;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.Permission;
import org.bukkit.plugin.SimplePluginManager;
import java.util.Map;
import java.util.Set;
/*
This is actually so cursed I hate it.
We need to wrap these in fields as people override the fields, so we need to access them lazily at all times.
// TODO: When SimplePluginManager is GONE remove this and cleanup the PaperPermissionManager to use actual fields.
*/
class StupidSPMPermissionManagerWrapper extends PaperPermissionManager {
private final SimplePluginManager simplePluginManager;
public StupidSPMPermissionManagerWrapper(SimplePluginManager simplePluginManager) {
this.simplePluginManager = simplePluginManager;
}
@Override
public Map<String, Permission> permissions() {
return this.simplePluginManager.permissions;
}
@Override
public Map<Boolean, Set<Permission>> defaultPerms() {
return this.simplePluginManager.defaultPerms;
}
@Override
public Map<String, Map<Permissible, Boolean>> permSubs() {
return this.simplePluginManager.permSubs;
}
@Override
public Map<Boolean, Map<Permissible, Boolean>> defSubs() {
return this.simplePluginManager.defSubs;
}
}
@@ -414,7 +414,7 @@ public final class CraftServer implements Server {
// Paper start
this.commandMap = new CraftCommandMap(this);
this.pluginManager = new SimplePluginManager(this, commandMap);
this.paperPluginManager = new io.papermc.paper.plugin.manager.PaperPluginManagerImpl(this, this.commandMap, pluginManager);
this.paperPluginManager = new io.papermc.paper.plugin.manager.PaperPluginManagerImpl(this, this.commandMap);
this.pluginManager.paperPluginManager = this.paperPluginManager;
// Paper end
@@ -3,10 +3,12 @@ package org.bukkit.craftbukkit.command;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.entity.BlockEntity;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.craftbukkit.util.CraftChatMessage;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.PermissibleBase;
import org.bukkit.permissions.ServerOperator;
@@ -16,18 +18,7 @@ import org.bukkit.permissions.ServerOperator;
public class CraftBlockCommandSender extends ServerCommandSender implements BlockCommandSender {
// For performance reasons, use one PermissibleBase for all command blocks.
private static final PermissibleBase SHARED_PERM = new PermissibleBase(new ServerOperator() {
@Override
public boolean isOp() {
return true;
}
@Override
public void setOp(boolean value) {
throw new UnsupportedOperationException("Cannot change operator status of a block");
}
});
private static final Permissible SHARED_PERM = Bukkit.getServer().getPluginManager().createCommandBlockPermissible();
private final CommandSourceStack block;
private final BlockEntity blockEntity;
@@ -6,6 +6,7 @@ import net.kyori.adventure.pointer.PointersSupplier;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.PermissibleBase;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
@@ -18,13 +19,13 @@ public abstract class ServerCommandSender implements CommandSender {
.resolving(net.kyori.adventure.permission.PermissionChecker.POINTER, serverCommandSender -> serverCommandSender::permissionValue)
.build();
public final PermissibleBase perm;
public final Permissible perm;
protected ServerCommandSender() {
this.perm = new PermissibleBase(this);
this.perm = Bukkit.getServer().getPluginManager().createPermissible(this);
}
protected ServerCommandSender(PermissibleBase perm) {
protected ServerCommandSender(Permissible perm) {
this.perm = perm;
}
@@ -66,6 +66,7 @@ import org.bukkit.event.entity.EntityRemoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.PermissibleBase;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
@@ -83,7 +84,6 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
private static final Logger LOGGER = LogUtils.getLogger();
private static PermissibleBase perm;
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
static final PointersSupplier<org.bukkit.entity.Entity> POINTERS_SUPPLIER = PointersSupplier.<org.bukkit.entity.Entity>builder()
.resolving(net.kyori.adventure.identity.Identity.DISPLAY_NAME, org.bukkit.entity.Entity::name)
@@ -93,6 +93,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
protected final CraftServer server;
protected Entity entity;
protected final Permissible perm;
private final EntityType entityType;
private EntityDamageEvent lastDamageEvent;
private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(CraftEntity.DATA_TYPE_REGISTRY);
@@ -110,6 +111,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
this.server = server;
this.entity = entity;
this.entityType = CraftEntityType.minecraftToBukkit(entity.getType());
this.perm = server.getPluginManager().createPermissible(this);
}
public static <T extends Entity> CraftEntity getEntity(CraftServer server, T entity) {
@@ -798,67 +800,67 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@Override
public boolean isPermissionSet(String name) {
return CraftEntity.getPermissibleBase().isPermissionSet(name);
return this.perm.isPermissionSet(name);
}
@Override
public boolean isPermissionSet(Permission perm) {
return CraftEntity.getPermissibleBase().isPermissionSet(perm);
return this.perm.isPermissionSet(perm);
}
@Override
public boolean hasPermission(String name) {
return CraftEntity.getPermissibleBase().hasPermission(name);
return this.perm.hasPermission(name);
}
@Override
public boolean hasPermission(Permission perm) {
return CraftEntity.getPermissibleBase().hasPermission(perm);
return this.perm.hasPermission(perm);
}
@Override
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) {
return CraftEntity.getPermissibleBase().addAttachment(plugin, name, value);
return this.perm.addAttachment(plugin, name, value);
}
@Override
public PermissionAttachment addAttachment(Plugin plugin) {
return CraftEntity.getPermissibleBase().addAttachment(plugin);
return this.perm.addAttachment(plugin);
}
@Override
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) {
return CraftEntity.getPermissibleBase().addAttachment(plugin, name, value, ticks);
return this.perm.addAttachment(plugin, name, value, ticks);
}
@Override
public PermissionAttachment addAttachment(Plugin plugin, int ticks) {
return CraftEntity.getPermissibleBase().addAttachment(plugin, ticks);
return this.perm.addAttachment(plugin, ticks);
}
@Override
public void removeAttachment(PermissionAttachment attachment) {
CraftEntity.getPermissibleBase().removeAttachment(attachment);
this.perm.removeAttachment(attachment);
}
@Override
public void recalculatePermissions() {
CraftEntity.getPermissibleBase().recalculatePermissions();
this.perm.recalculatePermissions();
}
@Override
public Set<PermissionAttachmentInfo> getEffectivePermissions() {
return CraftEntity.getPermissibleBase().getEffectivePermissions();
return this.perm.getEffectivePermissions();
}
@Override
public boolean isOp() {
return CraftEntity.getPermissibleBase().isOp();
return this.perm.isOp();
}
@Override
public void setOp(boolean value) {
CraftEntity.getPermissibleBase().setOp(value);
this.perm.setOp(value);
}
@Override
@@ -1096,24 +1098,6 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
player.connection.send(this.getHandle().getAddEntityPacket(entityTracker.serverEntity));
}
private static PermissibleBase getPermissibleBase() {
if (CraftEntity.perm == null) {
CraftEntity.perm = new PermissibleBase(new ServerOperator() {
@Override
public boolean isOp() {
return false;
}
@Override
public void setOp(boolean value) {
}
});
}
return CraftEntity.perm;
}
// Paper start - more teleport API / async chunk API
@Override
public CompletableFuture<Boolean> teleportAsync(final Location location, final TeleportCause cause, final TeleportFlag... teleportFlags) {
@@ -77,7 +77,6 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
private CraftInventoryPlayer inventory;
private final CraftInventory enderChest;
protected final PermissibleBase perm = new PermissibleBase(this);
private boolean op;
private GameMode mode;
@@ -241,67 +240,12 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
return this.op;
}
@Override
public boolean isPermissionSet(String name) {
return this.perm.isPermissionSet(name);
}
@Override
public boolean isPermissionSet(Permission perm) {
return this.perm.isPermissionSet(perm);
}
@Override
public boolean hasPermission(String name) {
return this.perm.hasPermission(name);
}
@Override
public boolean hasPermission(Permission perm) {
return this.perm.hasPermission(perm);
}
@Override
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) {
return this.perm.addAttachment(plugin, name, value);
}
@Override
public PermissionAttachment addAttachment(Plugin plugin) {
return this.perm.addAttachment(plugin);
}
@Override
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) {
return this.perm.addAttachment(plugin, name, value, ticks);
}
@Override
public PermissionAttachment addAttachment(Plugin plugin, int ticks) {
return this.perm.addAttachment(plugin, ticks);
}
@Override
public void removeAttachment(PermissionAttachment attachment) {
this.perm.removeAttachment(attachment);
}
@Override
public void recalculatePermissions() {
this.perm.recalculatePermissions();
}
@Override
public void setOp(boolean value) {
this.op = value;
this.perm.recalculatePermissions();
}
@Override
public Set<PermissionAttachmentInfo> getEffectivePermissions() {
return this.perm.getEffectivePermissions();
}
@Override
public GameMode getGameMode() {
return this.mode;
@@ -7,6 +7,7 @@ import org.bukkit.Server;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.util.CraftChatMessage;
import org.bukkit.entity.minecart.CommandMinecart;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.PermissibleBase;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
@@ -15,7 +16,7 @@ import org.bukkit.plugin.Plugin;
public class CraftMinecartCommand extends CraftMinecart implements CommandMinecart, io.papermc.paper.commands.PaperCommandBlockHolder {
private final PermissibleBase perm = new PermissibleBase(this);
private final Permissible perm = Bukkit.getPluginManager().createPermissible(this);
public CraftMinecartCommand(CraftServer server, MinecartCommandBlock entity) {
super(server, entity);
@@ -15,7 +15,7 @@ public class SyntheticEventTest {
@Test
public void test() {
PaperTestPlugin paperTestPlugin = new PaperTestPlugin("synthetictest");
PaperPluginManagerImpl paperPluginManager = new PaperPluginManagerImpl(Bukkit.getServer(), null, null);
PaperPluginManagerImpl paperPluginManager = new PaperPluginManagerImpl(Bukkit.getServer(), null);
TestEvent event = new TestEvent(false);
Impl impl = new Impl();
@@ -95,7 +95,7 @@ public final class DummyServerHelper {
// Paper start - testing additions
final Thread currentThread = Thread.currentThread();
when(instance.isPrimaryThread()).thenAnswer(ignored -> Thread.currentThread().equals(currentThread));
final org.bukkit.plugin.PluginManager pluginManager = new io.papermc.paper.plugin.manager.PaperPluginManagerImpl(instance, new org.bukkit.command.SimpleCommandMap(instance, new java.util.HashMap<>()), null);
final org.bukkit.plugin.PluginManager pluginManager = new io.papermc.paper.plugin.manager.PaperPluginManagerImpl(instance, new org.bukkit.command.SimpleCommandMap(instance, new java.util.HashMap<>()));
when(instance.getPluginManager()).thenReturn(pluginManager);
// Paper end - testing additions
@@ -1,14 +1,198 @@
package io.papermc.testplugin;
import com.mojang.brigadier.Command;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.plugin.PermissionManager;
import io.papermc.paper.plugin.PermissionManagerRegistrar;
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import io.papermc.paper.plugin.bootstrap.PluginBootstrap;
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
import io.papermc.testplugin.brigtests.example.MaterialArgumentType;
import org.bukkit.Material;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.permissions.ServerOperator;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class TestPluginBootstrap implements PluginBootstrap {
@Override
public void bootstrap(@NotNull BootstrapContext context) {
// io.papermc.testplugin.brigtests.Registration.registerViaBootstrap(context);
context.getLifecycleManager().registerEventHandler(LifecycleEvents.PERMISSION_MANAGER_REGISTER, event -> {
final PermissionManagerRegistrar permissionManagerRegistrar = event.registrar();
PermissionManager permissionManager = new PermissionManager() {
@Override
public @org.jspecify.annotations.Nullable Permission getPermission(String name) {
return null;
}
@Override
public void addPermission(Permission perm) {
}
@Override
public void removePermission(Permission perm) {
}
@Override
public void removePermission(String name) {
}
@Override
public Set<Permission> getDefaultPermissions(boolean op) {
return Set.of();
}
@Override
public void recalculatePermissionDefaults(Permission perm) {
}
@Override
public void subscribeToPermission(String permission, Permissible permissible) {
}
@Override
public void unsubscribeFromPermission(String permission, Permissible permissible) {
}
@Override
public Set<Permissible> getPermissionSubscriptions(String permission) {
return Set.of();
}
@Override
public void subscribeToDefaultPerms(boolean op, Permissible permissible) {
}
@Override
public void unsubscribeFromDefaultPerms(boolean op, Permissible permissible) {
}
@Override
public Set<Permissible> getDefaultPermSubscriptions(boolean op) {
return Set.of();
}
@Override
public Set<Permission> getPermissions() {
return Set.of();
}
@Override
public void addPermissions(List<Permission> perm) {
}
@Override
public void clearPermissions() {
}
@Override
public Permissible createPermissible(@NotNull ServerOperator operator) {
return EmptyPermissible.INSTANCE;
}
@Override
public Permissible createCommandBlockPermissible() {
return EmptyPermissible.INSTANCE;
}
@Override
public CompletableFuture<Optional<Permissible>> loadPlayerPermissible(@NotNull UUID playerUuid) {
return CompletableFuture.completedFuture(Optional.of(EmptyPermissible.INSTANCE));
}
};
permissionManagerRegistrar.register(permissionManager);
});
}
enum EmptyPermissible implements Permissible {
INSTANCE;
@Override
public boolean isPermissionSet(@NotNull final String name) {
return true;
}
@Override
public boolean isPermissionSet(@NotNull final Permission perm) {
return true;
}
@Override
public boolean hasPermission(@NotNull final String name) {
return true;
}
@Override
public boolean hasPermission(@NotNull final Permission perm) {
return true;
}
@Override
public @NotNull PermissionAttachment addAttachment(@NotNull final Plugin plugin, @NotNull final String name, final boolean value) {
throw new UnsupportedOperationException("Expected a read only instance!");
}
@Override
public @NotNull PermissionAttachment addAttachment(@NotNull final Plugin plugin) {
throw new UnsupportedOperationException("Expected a read only instance!");
}
@Override
public @Nullable PermissionAttachment addAttachment(@NotNull final Plugin plugin, @NotNull final String name, final boolean value, final int ticks) {
throw new UnsupportedOperationException("Expected a read only instance!");
}
@Override
public @Nullable PermissionAttachment addAttachment(@NotNull final Plugin plugin, final int ticks) {
throw new UnsupportedOperationException("Expected a read only instance!");
}
@Override
public void removeAttachment(@NotNull final PermissionAttachment attachment) {
throw new UnsupportedOperationException("Expected a read only instance!");
}
@Override
public void recalculatePermissions() {
}
@Override
public @NotNull Set<PermissionAttachmentInfo> getEffectivePermissions() {
return Set.of();
}
@Override
public boolean isOp() {
return false;
}
@Override
public void setOp(final boolean value) {
throw new UnsupportedOperationException("Expected a read only instance!");
}
}
}