fabric: work
This commit is contained in:
parent
6eae149089
commit
3f67a1ae04
11 changed files with 303 additions and 3 deletions
|
|
@ -27,7 +27,11 @@ package cloud.commandframework.fabric;
|
||||||
import cloud.commandframework.CommandTree;
|
import cloud.commandframework.CommandTree;
|
||||||
import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
|
import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
|
||||||
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
||||||
|
import cloud.commandframework.fabric.argument.FabricArgumentParsers;
|
||||||
|
import cloud.commandframework.fabric.argument.server.MessageArgument;
|
||||||
|
import cloud.commandframework.fabric.data.Message;
|
||||||
import cloud.commandframework.meta.CommandMeta;
|
import cloud.commandframework.meta.CommandMeta;
|
||||||
|
import io.leangen.geantyref.TypeToken;
|
||||||
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
|
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
|
||||||
import net.minecraft.server.command.CommandManager;
|
import net.minecraft.server.command.CommandManager;
|
||||||
import net.minecraft.server.command.CommandOutput;
|
import net.minecraft.server.command.CommandOutput;
|
||||||
|
|
@ -110,6 +114,12 @@ public final class FabricServerCommandManager<C> extends FabricCommandManager<C,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.registerParsers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerParsers() {
|
||||||
|
this.getParserRegistry().registerParserSupplier(TypeToken.get(Message.class), params -> FabricArgumentParsers.message());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,24 @@ import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
import cloud.commandframework.brigadier.argument.WrappedBrigadierParser;
|
import cloud.commandframework.brigadier.argument.WrappedBrigadierParser;
|
||||||
import cloud.commandframework.fabric.FabricCommandContextKeys;
|
import cloud.commandframework.fabric.FabricCommandContextKeys;
|
||||||
|
import cloud.commandframework.fabric.argument.server.MessageArgument;
|
||||||
|
import cloud.commandframework.fabric.data.Message;
|
||||||
import cloud.commandframework.fabric.data.MinecraftTime;
|
import cloud.commandframework.fabric.data.MinecraftTime;
|
||||||
|
import cloud.commandframework.fabric.mixin.MessageArgumentTypeMessageFormatAccess;
|
||||||
|
import cloud.commandframework.fabric.mixin.MessageArgumentTypeMessageSelectorAccess;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import net.minecraft.command.CommandSource;
|
import net.minecraft.command.CommandSource;
|
||||||
import net.minecraft.command.argument.FunctionArgumentType;
|
import net.minecraft.command.argument.FunctionArgumentType;
|
||||||
|
import net.minecraft.command.argument.MessageArgumentType;
|
||||||
import net.minecraft.command.argument.TimeArgumentType;
|
import net.minecraft.command.argument.TimeArgumentType;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
import net.minecraft.server.function.CommandFunction;
|
import net.minecraft.server.function.CommandFunction;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parsers for Vanilla command argument types.
|
* Parsers for Vanilla command argument types.
|
||||||
|
|
@ -64,4 +77,65 @@ public final class FabricArgumentParsers {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <C> ArgumentParser<C, Message> message() {
|
||||||
|
return new WrappedBrigadierParser<C, MessageArgumentType.MessageFormat>(MessageArgumentType.message())
|
||||||
|
.map((ctx, format) -> {
|
||||||
|
final CommandSource either = ctx.get(FabricCommandContextKeys.NATIVE_COMMAND_SOURCE);
|
||||||
|
if (!(either instanceof ServerCommandSource)) {
|
||||||
|
return ArgumentParseResult.failure(new IllegalStateException("This argument is server-only"));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return ArgumentParseResult.success(MessageImpl.from(
|
||||||
|
(ServerCommandSource) either,
|
||||||
|
format,
|
||||||
|
true
|
||||||
|
));
|
||||||
|
} catch (final CommandSyntaxException ex) {
|
||||||
|
return ArgumentParseResult.failure(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class MessageImpl implements Message {
|
||||||
|
private final Collection<Entity> mentionedEntities;
|
||||||
|
private final Text contents;
|
||||||
|
|
||||||
|
static MessageImpl from(
|
||||||
|
final ServerCommandSource source,
|
||||||
|
final MessageArgumentType.MessageFormat message,
|
||||||
|
final boolean useSelectors
|
||||||
|
) throws CommandSyntaxException {
|
||||||
|
final Text contents = message.format(source, useSelectors);
|
||||||
|
final MessageArgumentType.MessageSelector[] selectors =
|
||||||
|
((MessageArgumentTypeMessageFormatAccess) message).accessor$selectors();
|
||||||
|
final Collection<Entity> entities;
|
||||||
|
if (!useSelectors || selectors.length == 0) {
|
||||||
|
entities = Collections.emptySet();
|
||||||
|
} else {
|
||||||
|
entities = new HashSet<>();
|
||||||
|
for (final MessageArgumentType.MessageSelector selector : selectors) {
|
||||||
|
entities.addAll(((MessageArgumentTypeMessageSelectorAccess) selector).accessor$selector().getEntities(source));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MessageImpl(entities, contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageImpl(final Collection<Entity> mentionedEntities, final Text contents) {
|
||||||
|
this.mentionedEntities = mentionedEntities;
|
||||||
|
this.contents = contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Entity> getMentionedEntities() {
|
||||||
|
return this.mentionedEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Text getContents() {
|
||||||
|
return this.contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
//
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2020 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.argument.server;
|
||||||
|
|
||||||
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
|
import cloud.commandframework.brigadier.argument.WrappedBrigadierParser;
|
||||||
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import cloud.commandframework.fabric.FabricCommandContextKeys;
|
||||||
|
import cloud.commandframework.fabric.argument.FabricArgumentParsers;
|
||||||
|
import cloud.commandframework.fabric.data.Message;
|
||||||
|
import cloud.commandframework.fabric.mixin.MessageArgumentTypeMessageFormatAccess;
|
||||||
|
import cloud.commandframework.fabric.mixin.MessageArgumentTypeMessageSelectorAccess;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
import net.minecraft.command.CommandSource;
|
||||||
|
import net.minecraft.command.argument.MessageArgumentType;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An argument similar to a greedy string, but one that resolves selectors.
|
||||||
|
*
|
||||||
|
* @param <C> the sender type
|
||||||
|
* @since 1.4.0
|
||||||
|
*/
|
||||||
|
public final class MessageArgument<C> extends CommandArgument<C, Message> {
|
||||||
|
|
||||||
|
MessageArgument(
|
||||||
|
final boolean required,
|
||||||
|
final @NonNull String name,
|
||||||
|
final @NonNull String defaultValue,
|
||||||
|
final @Nullable BiFunction<CommandContext<C>, String, List<String>> suggestionsProvider
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
required,
|
||||||
|
name,
|
||||||
|
FabricArgumentParsers.message(),
|
||||||
|
defaultValue,
|
||||||
|
Message.class,
|
||||||
|
suggestionsProvider
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new builder.
|
||||||
|
*
|
||||||
|
* @param name Name of the argument
|
||||||
|
* @param <C> Command sender type
|
||||||
|
* @return Created builder
|
||||||
|
*/
|
||||||
|
public static <C> MessageArgument.@NonNull Builder<C> newBuilder(final @NonNull String name) {
|
||||||
|
return new MessageArgument.Builder<>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new required command argument.
|
||||||
|
*
|
||||||
|
* @param name Component name
|
||||||
|
* @param <C> Command sender type
|
||||||
|
* @return Created argument
|
||||||
|
*/
|
||||||
|
public static <C> @NonNull MessageArgument<C> of(final @NonNull String name) {
|
||||||
|
return MessageArgument.<C>newBuilder(name).asRequired().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new optional command argument
|
||||||
|
*
|
||||||
|
* @param name Component name
|
||||||
|
* @param <C> Command sender type
|
||||||
|
* @return Created argument
|
||||||
|
*/
|
||||||
|
public static <C> @NonNull MessageArgument<C> optional(final @NonNull String name) {
|
||||||
|
return MessageArgument.<C>newBuilder(name).asOptional().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new optional command argument with a default value
|
||||||
|
*
|
||||||
|
* @param name Argument name
|
||||||
|
* @param defaultValue Default value
|
||||||
|
* @param <C> Command sender type
|
||||||
|
* @return Created argument
|
||||||
|
*/
|
||||||
|
public static <C> @NonNull MessageArgument<C> optional(
|
||||||
|
final @NonNull String name,
|
||||||
|
final String defaultValue
|
||||||
|
) {
|
||||||
|
return MessageArgument.<C>newBuilder(name).asOptionalWithDefault(defaultValue).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static final class Builder<C> extends TypedBuilder<C, Message, Builder<C>> {
|
||||||
|
|
||||||
|
Builder(final @NonNull String name) {
|
||||||
|
super(Message.class, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a new criterion argument
|
||||||
|
*
|
||||||
|
* @return Constructed argument
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public @NonNull MessageArgument<C> build() {
|
||||||
|
return new MessageArgument<>(this.isRequired(), this.getName(), this.getDefaultValue(), this.getSuggestionsProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package cloud.commandframework.fabric.data;
|
||||||
|
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A parsed message.
|
||||||
|
*/
|
||||||
|
public interface Message {
|
||||||
|
|
||||||
|
Collection<Entity> getMentionedEntities();
|
||||||
|
|
||||||
|
Text getContents();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package cloud.commandframework.fabric.data;
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import net.minecraft.command.EntitySelector;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class MultipleGameProfileSelector implements Selector<GameProfile> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInput() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable EntitySelector getSelector() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<GameProfile> get() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import net.minecraft.command.EntitySelector;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A selector string to query multiple entity-like values
|
* A selector string to query multiple entity-like values
|
||||||
|
|
@ -42,6 +43,11 @@ public interface Selector<V> {
|
||||||
*/
|
*/
|
||||||
interface Single<V> extends Selector<V> {
|
interface Single<V> extends Selector<V> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Collection<V> get() {
|
||||||
|
return Collections.singletonList(this.getSingle());
|
||||||
|
}
|
||||||
|
|
||||||
V getSingle();
|
V getSingle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package cloud.commandframework.fabric.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.command.argument.MessageArgumentType;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
@Mixin(MessageArgumentType.MessageFormat.class)
|
||||||
|
public interface MessageArgumentTypeMessageFormatAccess {
|
||||||
|
|
||||||
|
@Accessor("selectors") MessageArgumentType.MessageSelector[] accessor$selectors();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package cloud.commandframework.fabric.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.command.EntitySelector;
|
||||||
|
import net.minecraft.command.argument.MessageArgumentType;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
@Mixin(MessageArgumentType.MessageSelector.class)
|
||||||
|
public interface MessageArgumentTypeMessageSelectorAccess {
|
||||||
|
@Accessor("selector") EntitySelector accessor$selector();
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,9 @@
|
||||||
"required": true,
|
"required": true,
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"CloudStringReaderMixin",
|
"CloudStringReaderMixin",
|
||||||
"CommandManagerMixin"
|
"CommandManagerMixin",
|
||||||
|
"MessageArgumentTypeMessageFormatAccess",
|
||||||
|
"MessageArgumentTypeMessageSelectorAccess"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"schemaVersion": 1,
|
"schemaVersion": 1,
|
||||||
"id": "cloud",
|
"id": "cloud-v1",
|
||||||
"version": "${version}",
|
"version": "${version}",
|
||||||
|
|
||||||
"name": "Cloud",
|
"name": "Cloud",
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,6 @@
|
||||||
"fabricloader": ">=0.7.4",
|
"fabricloader": ">=0.7.4",
|
||||||
"fabric-command-api-v1": "*",
|
"fabric-command-api-v1": "*",
|
||||||
"minecraft": ">=1.14",
|
"minecraft": ">=1.14",
|
||||||
"cloud": "*"
|
"cloud-v1": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue