Forward Bukkit permissions to Forge
This commit is contained in:
parent
23e365fc14
commit
aad0b1cab3
|
@ -1,5 +1,7 @@
|
|||
package io.izzel.arclight.common.mixin.bukkit;
|
||||
|
||||
import io.izzel.arclight.common.mod.server.ArclightForgePermissible;
|
||||
import io.izzel.arclight.i18n.ArclightConfig;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import org.bukkit.craftbukkit.v.CraftServer;
|
||||
|
@ -7,10 +9,14 @@ import org.bukkit.craftbukkit.v.entity.CraftEntity;
|
|||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.v.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.v.inventory.CraftInventoryPlayer;
|
||||
import org.bukkit.permissions.PermissibleBase;
|
||||
import org.bukkit.permissions.ServerOperator;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(value = CraftHumanEntity.class, remap = false)
|
||||
public abstract class CraftHumanEntityMixin extends CraftEntity {
|
||||
|
@ -24,6 +30,15 @@ public abstract class CraftHumanEntityMixin extends CraftEntity {
|
|||
super(server, entity);
|
||||
}
|
||||
|
||||
@Redirect(method = "<init>", at = @At(value = "NEW", target = "org/bukkit/permissions/PermissibleBase"))
|
||||
private PermissibleBase arclight$forwardPerm(ServerOperator opable) {
|
||||
if (ArclightConfig.spec().getCompat().isForwardPermissionReverse()) {
|
||||
return new ArclightForgePermissible(opable);
|
||||
} else {
|
||||
return new PermissibleBase(opable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHandle(Entity entity) {
|
||||
super.setHandle(entity);
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package io.izzel.arclight.common.mod.server;
|
||||
|
||||
import io.izzel.arclight.api.Unsafe;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.server.permission.PermissionAPI;
|
||||
import net.minecraftforge.server.permission.handler.IPermissionHandler;
|
||||
import net.minecraftforge.server.permission.nodes.PermissionDynamicContextKey;
|
||||
import net.minecraftforge.server.permission.nodes.PermissionNode;
|
||||
import net.minecraftforge.server.permission.nodes.PermissionType;
|
||||
import net.minecraftforge.server.permission.nodes.PermissionTypes;
|
||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||
import org.bukkit.permissions.PermissibleBase;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.ServerOperator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
public class ArclightForgePermissible extends PermissibleBase {
|
||||
|
||||
private final CraftHumanEntity player;
|
||||
|
||||
public ArclightForgePermissible(@Nullable ServerOperator opable) {
|
||||
super(opable);
|
||||
this.player = (CraftHumanEntity) opable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull String inName) {
|
||||
var node = newNode(inName, (player, playerUUID, context) -> super.hasPermission(inName));
|
||||
if (player.getHandle() instanceof ServerPlayer player) {
|
||||
return getHandler().getPermission(player, node);
|
||||
} else {
|
||||
return getHandler().getOfflinePermission(player.getUniqueId(), node);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull Permission perm) {
|
||||
var node = newNode(perm.getName(), (player, playerUUID, context) -> super.hasPermission(perm));
|
||||
if (player.getHandle() instanceof ServerPlayer player) {
|
||||
return getHandler().getPermission(player, node);
|
||||
} else {
|
||||
return getHandler().getOfflinePermission(player.getUniqueId(), node);
|
||||
}
|
||||
}
|
||||
|
||||
private static final MethodHandle H_handler, H_newNode;
|
||||
|
||||
private static IPermissionHandler getHandler() {
|
||||
try {
|
||||
return (IPermissionHandler) H_handler.invokeExact();
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> PermissionNode<T> newNode(String nodeName, PermissionNode.PermissionResolver<T> defaultResolver, PermissionDynamicContextKey... dynamics) {
|
||||
try {
|
||||
return (PermissionNode<T>) H_newNode.invokeExact(nodeName, PermissionTypes.BOOLEAN, defaultResolver, dynamics);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
try {
|
||||
H_handler = Unsafe.lookup().findStaticGetter(PermissionAPI.class, "activeHandler", IPermissionHandler.class);
|
||||
H_newNode = Unsafe.lookup().findConstructor(PermissionNode.class, MethodType.methodType(void.class, String.class, PermissionType.class, PermissionNode.PermissionResolver.class, PermissionDynamicContextKey[].class));
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
@ConfigSerializable
|
||||
|
@ -23,7 +24,7 @@ public class CompatSpec {
|
|||
private List<String> extraLogicWorlds;
|
||||
|
||||
@Setting("forward-permission")
|
||||
private boolean forwardPermission;
|
||||
private String forwardPermission;
|
||||
|
||||
public Map<String, MaterialPropertySpec> getMaterials() {
|
||||
return materials;
|
||||
|
@ -50,6 +51,10 @@ public class CompatSpec {
|
|||
}
|
||||
|
||||
public boolean isForwardPermission() {
|
||||
return forwardPermission;
|
||||
return Objects.equals(forwardPermission, "true");
|
||||
}
|
||||
|
||||
public boolean isForwardPermissionReverse() {
|
||||
return Objects.equals(forwardPermission, "reverse");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,5 +115,10 @@ comments {
|
|||
"Extra worlds running logic"
|
||||
"If any mods do not function well, try search class names in logs related to [EXT_LOGIC] and add them here"
|
||||
]
|
||||
forward-permission.comment = [
|
||||
"true - Forward Forge permission query to Bukkit"
|
||||
"false - Disable permission forward"
|
||||
"reverse - Forward Bukkit player perimission query to Forge"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,5 +115,10 @@ comments {
|
|||
"额外运行逻辑的维度类名"
|
||||
"如果有模组世界/功能运行不正常,尝试在日志中搜索和 [EXT_LOGIC] 有关的对应类名并添加"
|
||||
]
|
||||
forward-permission.comment = [
|
||||
"true - 将 Forge 权限查询请求转发至 Bukkit"
|
||||
"false - 不启用权限转发"
|
||||
"reverse - 将 Bukkit 玩家权限查询请求转发至 Forge"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user