
org.incendo.cloud.brigadier.node.LiteralBrigadierNodeFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cloud-brigadier Show documentation
Show all versions of cloud-brigadier Show documentation
Integrations between Minecraft and Cloud Command Framework
//
// MIT License
//
// Copyright (c) 2024 Incendo
//
// 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 org.incendo.cloud.brigadier.node;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.leangen.geantyref.GenericTypeReflector;
import io.leangen.geantyref.TypeToken;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
import org.apiguardian.api.API;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.CommandManager;
import org.incendo.cloud.brigadier.BrigadierSetting;
import org.incendo.cloud.brigadier.CloudBrigadierManager;
import org.incendo.cloud.brigadier.argument.ArgumentTypeFactory;
import org.incendo.cloud.brigadier.argument.BrigadierMapping;
import org.incendo.cloud.brigadier.permission.BrigadierPermissionChecker;
import org.incendo.cloud.brigadier.permission.BrigadierPermissionPredicate;
import org.incendo.cloud.brigadier.suggestion.BrigadierSuggestionFactory;
import org.incendo.cloud.brigadier.suggestion.CloudDelegatingSuggestionProvider;
import org.incendo.cloud.brigadier.suggestion.SuggestionsType;
import org.incendo.cloud.brigadier.suggestion.TooltipSuggestion;
import org.incendo.cloud.component.CommandComponent;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.internal.CommandNode;
import org.incendo.cloud.parser.ArgumentParser;
import org.incendo.cloud.parser.MappedArgumentParser;
import org.incendo.cloud.parser.aggregate.AggregateParser;
import org.incendo.cloud.suggestion.SuggestionFactory;
@SuppressWarnings({"unchecked", "rawtypes"})
@API(status = API.Status.STABLE, since = "2.0.0")
public final class LiteralBrigadierNodeFactory implements BrigadierNodeFactory> {
private final CloudBrigadierManager cloudBrigadierManager;
private final CommandManager commandManager;
private final BrigadierSuggestionFactory brigadierSuggestionFactory;
/**
* Creates a new factory that produces literal command nodes.
*
* @param cloudBrigadierManager the brigadier manager
* @param commandManager the command manager
* @param dummyContextProvider creates the context provided when retrieving suggestions
* @param suggestionFactory the suggestion factory-producing tooltip suggestions
*/
public LiteralBrigadierNodeFactory(
final @NonNull CloudBrigadierManager cloudBrigadierManager,
final @NonNull CommandManager commandManager,
final @NonNull Supplier> dummyContextProvider,
final @NonNull SuggestionFactory suggestionFactory
) {
this.cloudBrigadierManager = cloudBrigadierManager;
this.commandManager = commandManager;
this.brigadierSuggestionFactory = new BrigadierSuggestionFactory<>(
cloudBrigadierManager,
commandManager,
dummyContextProvider,
suggestionFactory
);
}
@Override
public @NonNull LiteralCommandNode createNode(
final @NonNull String label,
final @NonNull CommandNode cloudCommand,
final @NonNull Command executor,
final @NonNull BrigadierPermissionChecker permissionChecker
) {
final LiteralArgumentBuilder literalArgumentBuilder = LiteralArgumentBuilder
.literal(label)
.requires(this.requirement(cloudCommand, permissionChecker));
this.updateExecutes(literalArgumentBuilder, cloudCommand, executor);
final LiteralCommandNode constructedRoot = literalArgumentBuilder.build();
for (final CommandNode child : cloudCommand.children()) {
constructedRoot.addChild(this.constructCommandNode(child, permissionChecker, executor).build());
}
return constructedRoot;
}
private @NonNull BrigadierPermissionPredicate requirement(
final @NonNull CommandNode cloudCommand,
final @NonNull BrigadierPermissionChecker permissionChecker
) {
return new BrigadierPermissionPredicate<>(this.cloudBrigadierManager.senderMapper(), permissionChecker, cloudCommand);
}
@Override
public @NonNull LiteralCommandNode createNode(
final @NonNull String label,
final org.incendo.cloud.@NonNull Command cloudCommand,
final @NonNull Command executor,
final @NonNull BrigadierPermissionChecker permissionChecker
) {
final CommandNode node =
this.commandManager.commandTree().getNamedNode(cloudCommand.rootComponent().name());
Objects.requireNonNull(node, "node");
return this.createNode(label, node, executor, permissionChecker);
}
@Override
public @NonNull LiteralCommandNode createNode(
final @NonNull String label,
final org.incendo.cloud.@NonNull Command cloudCommand,
final @NonNull Command executor
) {
return this.createNode(label, cloudCommand, executor,
(sender, permission) -> this.commandManager.testPermission(sender, permission).allowed());
}
private @NonNull ArgumentBuilder constructCommandNode(
final @NonNull CommandNode root,
final @NonNull BrigadierPermissionChecker permissionChecker,
final com.mojang.brigadier.@NonNull Command executor
) {
if (root.component().parser() instanceof AggregateParser) {
final AggregateParser aggregateParser = (AggregateParser) root.component().parser();
return this.constructAggregateNode(
aggregateParser,
root,
permissionChecker,
executor
);
}
final ArgumentBuilder argumentBuilder;
if (root.component().type() == CommandComponent.ComponentType.LITERAL) {
argumentBuilder = this.createLiteralArgumentBuilder(root.component(), root, permissionChecker);
} else {
argumentBuilder = this.createVariableArgumentBuilder(root.component(), root, permissionChecker);
}
this.updateExecutes(argumentBuilder, root, executor);
for (final CommandNode node : root.children()) {
argumentBuilder.then(this.constructCommandNode(node, permissionChecker, executor));
}
return argumentBuilder;
}
private @NonNull ArgumentBuilder createLiteralArgumentBuilder(
final @NonNull CommandComponent component,
final @NonNull CommandNode root,
final @NonNull BrigadierPermissionChecker permissionChecker
) {
return LiteralArgumentBuilder.literal(component.name())
.requires(this.requirement(root, permissionChecker));
}
private @NonNull ArgumentBuilder createVariableArgumentBuilder(
final @NonNull CommandComponent component,
final @NonNull CommandNode root,
final @NonNull BrigadierPermissionChecker permissionChecker
) {
final ArgumentMapping argumentMapping = this.getArgument(
component.valueType(),
component.parser()
);
final SuggestionProvider provider;
if (argumentMapping.suggestionsType() == SuggestionsType.CLOUD_SUGGESTIONS) {
provider = new CloudDelegatingSuggestionProvider<>(this.brigadierSuggestionFactory, root);
} else {
provider = argumentMapping.suggestionProvider();
}
return RequiredArgumentBuilder
.argument(component.name(), (ArgumentType
© 2015 - 2025 Weber Informatics LLC | Privacy Policy