mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-04 15:43:00 +00:00
Use permission APIs for the /computercraft command
- Add a generic PermissionRegistry interface. This behaves similarly to our ShaderMod interface, searching all providers until it finds a compatible one. We could just make this part of the platform code instead, but this allows us to support multiple systems on Fabric, where things are less standardised. This interface behaves like a registry, rather than a straight `getPermission(node, player)` method, as Forge requires us to list our nodes up-front. - Add Forge (using the built-in system) and Fabric (using fabric-permissions-api) implementations of the above interface. - Register permission nodes for our commands, and use those instead. This does mean that the permissions check for the root /computercraft command now requires enumerating all child commands (and so potential does 7 permission lookups), but hopefully this isn't too bad in practice. - Remove UserLevel.OWNER - we never used this anywhere, and I can't imagine we'll want to in the future.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.shared.integration;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.shared.command.UserLevel;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.server.permission.PermissionAPI;
|
||||
import net.minecraftforge.server.permission.events.PermissionGatherEvent;
|
||||
import net.minecraftforge.server.permission.nodes.PermissionNode;
|
||||
import net.minecraftforge.server.permission.nodes.PermissionType;
|
||||
import net.minecraftforge.server.permission.nodes.PermissionTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* An implementation of {@link PermissionRegistry} using Forge's {@link PermissionAPI}.
|
||||
*/
|
||||
public final class ForgePermissionRegistry extends PermissionRegistry {
|
||||
private final List<PermissionNode<?>> nodes = new ArrayList<>();
|
||||
|
||||
private ForgePermissionRegistry() {
|
||||
}
|
||||
|
||||
private <T> PermissionNode<T> registerNode(String nodeName, PermissionType<T> type, PermissionNode.PermissionResolver<T> defaultResolver) {
|
||||
checkNotFrozen();
|
||||
var node = new PermissionNode<>(ComputerCraftAPI.MOD_ID, nodeName, type, defaultResolver);
|
||||
nodes.add(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate<CommandSourceStack> registerCommand(String command, UserLevel fallback) {
|
||||
var node = registerNode(
|
||||
"command." + command, PermissionTypes.BOOLEAN,
|
||||
(player, uuid, context) -> player != null && fallback.test(player)
|
||||
);
|
||||
|
||||
return source -> {
|
||||
var player = source.getPlayer();
|
||||
return player == null ? fallback.test(source) : PermissionAPI.getPermission(player, node);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
super.register();
|
||||
MinecraftForge.EVENT_BUS.addListener((PermissionGatherEvent.Nodes event) -> event.addNodes(nodes));
|
||||
}
|
||||
|
||||
@AutoService(PermissionRegistry.Provider.class)
|
||||
public static final class Provider implements PermissionRegistry.Provider {
|
||||
@Override
|
||||
public Optional<PermissionRegistry> get() {
|
||||
return Optional.of(new ForgePermissionRegistry());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user