fabric: add some pre-built predicate permissions for the client command manager

This commit is contained in:
jmp 2021-03-13 12:24:39 -08:00 committed by Jason
parent 9e9a9d79d8
commit 1409b91db0
7 changed files with 155 additions and 30 deletions

View file

@ -59,7 +59,7 @@ public interface CommandPermission {
* @return a new {@code or} permission
* @since 1.4.0
*/
default CommandPermission or(final CommandPermission other) {
default @NonNull CommandPermission or(final @NonNull CommandPermission other) {
requireNonNull(other, "other");
final Set<CommandPermission> permission = new HashSet<>(2);
permission.add(this);
@ -74,7 +74,7 @@ public interface CommandPermission {
* @return a new {@code or} permission
* @since 1.4.0
*/
default CommandPermission or(final CommandPermission... other) {
default @NonNull CommandPermission or(final @NonNull CommandPermission @NonNull ... other) {
requireNonNull(other, "other");
final Set<CommandPermission> permission = new HashSet<>(other.length + 1);
permission.add(this);
@ -89,7 +89,7 @@ public interface CommandPermission {
* @return a new {@code and} permission
* @since 1.4.0
*/
default CommandPermission and(final CommandPermission other) {
default @NonNull CommandPermission and(final @NonNull CommandPermission other) {
requireNonNull(other, "other");
final Set<CommandPermission> permission = new HashSet<>(2);
permission.add(this);
@ -104,7 +104,7 @@ public interface CommandPermission {
* @return a new {@code and} permission
* @since 1.4.0
*/
default CommandPermission and(final CommandPermission... other) {
default @NonNull CommandPermission and(final @NonNull CommandPermission @NonNull ... other) {
requireNonNull(other, "other");
final Set<CommandPermission> permission = new HashSet<>(other.length + 1);
permission.add(this);

View file

@ -27,6 +27,7 @@ package cloud.commandframework.fabric;
import cloud.commandframework.CommandTree;
import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.permission.PredicatePermission;
import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.minecraft.client.MinecraftClient;
@ -115,4 +116,86 @@ public final class FabricClientCommandManager<C> extends FabricCommandManager<C,
return true;
}
/**
* Get a permission predicate which passes when the integrated server is running.
*
* @param <C> sender type
* @return a predicate permission
*/
public static <C> @NonNull PredicatePermission<C> integratedServerRunning() {
return sender -> MinecraftClient.getInstance().isIntegratedServerRunning();
}
/**
* Get a permission predicate which passes when the integrated server is not running.
*
* @param <C> sender type
* @return a predicate permission
*/
public static <C> @NonNull PredicatePermission<C> integratedServerNotRunning() {
return sender -> !MinecraftClient.getInstance().isIntegratedServerRunning();
}
/**
* Get a permission predicate which passes when cheats are enabled on the currently running integrated server.
*
* <p>This predicate will always pass if there is no integrated server running, i.e. when connected to a multiplayer server.</p>
*
* @param <C> sender type
* @return a predicate permission
*/
public static <C> @NonNull PredicatePermission<C> cheatsAllowed() {
return cheatsAllowed(true);
}
/**
* Get a permission predicate which passes when cheats are enabled on the currently running integrated server.
*
* <p>When there is no integrated server running, i.e. when connected to a multiplayer server, the predicate will
* fall back to the provided boolean argument.</p>
*
* @param allowOnMultiplayer whether the predicate should pass on multiplayer servers
* @param <C> sender type
* @return a predicate permission
*/
public static <C> @NonNull PredicatePermission<C> cheatsAllowed(final boolean allowOnMultiplayer) {
return sender -> {
if (!MinecraftClient.getInstance().isIntegratedServerRunning()) {
return allowOnMultiplayer;
}
return MinecraftClient.getInstance().getServer().getPlayerManager().areCheatsAllowed();
};
}
/**
* Get a permission predicate which passes when cheats are disabled on the currently running integrated server.
*
* <p>This predicate will always pass if there is no integrated server running, i.e. when connected to a multiplayer server.</p>
*
* @param <C> sender type
* @return a predicate permission
*/
public static <C> @NonNull PredicatePermission<C> cheatsDisallowed() {
return cheatsDisallowed(true);
}
/**
* Get a permission predicate which passes when cheats are disabled on the currently running integrated server.
*
* <p>When there is no integrated server running, i.e. when connected to a multiplayer server, the predicate will
* fall back to the provided boolean argument.</p>
*
* @param allowOnMultiplayer whether the predicate should pass on multiplayer servers
* @param <C> sender type
* @return a predicate permission
*/
public static <C> @NonNull PredicatePermission<C> cheatsDisallowed(final boolean allowOnMultiplayer) {
return sender -> {
if (!MinecraftClient.getInstance().isIntegratedServerRunning()) {
return allowOnMultiplayer;
}
return !MinecraftClient.getInstance().getServer().getPlayerManager().areCheatsAllowed();
};
}
}

View file

@ -39,6 +39,7 @@ import cloud.commandframework.fabric.argument.TeamArgument;
import cloud.commandframework.fabric.data.MinecraftTime;
import cloud.commandframework.meta.CommandMeta;
import cloud.commandframework.meta.SimpleCommandMeta;
import cloud.commandframework.permission.PredicatePermission;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.serialization.Codec;
@ -373,4 +374,16 @@ public abstract class FabricCommandManager<C, S extends CommandSource> extends C
this.transitionOrThrow(RegistrationState.REGISTERING, RegistrationState.AFTER_REGISTRATION);
}
/**
* Get a permission predicate which passes when the sender has the specified permission level.
*
* @param permissionLevel permission level to require
* @return a permission predicate
*/
public @NonNull PredicatePermission<C> permissionLevel(final int permissionLevel) {
return sender -> this.getBackwardsCommandSourceMapper()
.apply(sender)
.hasPermissionLevel(permissionLevel);
}
}

View file

@ -0,0 +1,51 @@
//
// MIT License
//
// Copyright (c) 2021 Alexander Söderberg & 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 cloud.commandframework.fabric;
import cloud.commandframework.arguments.parser.ParserParameter;
import io.leangen.geantyref.TypeToken;
import org.checkerframework.checker.nullness.qual.NonNull;
/**
* {@link ParserParameter} keys for cloud-fabric.
*
* @since 1.5.0
*/
public final class FabricParserParameters {
/**
* Indicates that positions should be centered on the middle of blocks, i.e. x.5.
*
* @since 1.5.0
*/
public static final ParserParameter<Boolean> CENTER_INTEGERS = create("center_integers", TypeToken.get(Boolean.class));
private static <T> @NonNull ParserParameter<T> create(
final @NonNull String key,
final @NonNull TypeToken<T> expectedType
) {
return new ParserParameter<>(key, expectedType);
}
}

View file

@ -30,7 +30,6 @@ import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.fabric.annotations.specifier.Center;
import cloud.commandframework.fabric.argument.FabricArgumentParsers;
import cloud.commandframework.fabric.argument.FabricArgumentParsers.FabricParserParameters;
import cloud.commandframework.fabric.data.Coordinates;
import cloud.commandframework.fabric.data.Message;
import cloud.commandframework.fabric.data.MultipleEntitySelector;

View file

@ -26,7 +26,6 @@ package cloud.commandframework.fabric.argument;
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.arguments.parser.ParserParameter;
import cloud.commandframework.brigadier.argument.WrappedBrigadierParser;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.fabric.FabricCommandContextKeys;
@ -41,7 +40,6 @@ import cloud.commandframework.fabric.internal.EntitySelectorAccess;
import cloud.commandframework.fabric.mixin.MessageArgumentTypeMessageFormatAccess;
import cloud.commandframework.fabric.mixin.MessageArgumentTypeMessageSelectorAccess;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import io.leangen.geantyref.TypeToken;
import net.minecraft.command.CommandSource;
import net.minecraft.command.EntitySelector;
import net.minecraft.command.argument.BlockPosArgumentType;
@ -285,29 +283,6 @@ public final class FabricArgumentParsers {
return resultFunction.apply((ServerCommandSource) nativeSource);
}
/**
* {@link ParserParameter} keys for cloud-fabric.
*
* @since 1.5.0
*/
public static final class FabricParserParameters {
/**
* Indicates that positions should be centered on the middle of blocks, i.e. x.5.
*
* @since 1.5.0
*/
public static final ParserParameter<Boolean> CENTER_INTEGERS = create("center_integers", TypeToken.get(Boolean.class));
private static <T> @NonNull ParserParameter<T> create(
final @NonNull String key,
final @NonNull TypeToken<T> expectedType
) {
return new ParserParameter<>(key, expectedType);
}
}
static final class MessageImpl implements Message {
private final Collection<Entity> mentionedEntities;

View file

@ -106,6 +106,10 @@ public final class FabricClientExample implements ClientModInitializer {
commandManager.command(base.literal("disconnect")
.handler(ctx -> disconnectClient(MinecraftClient.getInstance())));
commandManager.command(base.literal("requires_cheats")
.permission(FabricClientCommandManager.cheatsAllowed(false))
.handler(ctx -> ctx.getSender().sendFeedback(new LiteralText("Cheats are enabled!"))));
}
private static void disconnectClient(final @NonNull MinecraftClient client) {