mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-14 19:25:23 -05:00
* Fix #2237: Allow registering argument types without interacting with the class map * Add testmod :)
This commit is contained in:
parent
59c610c9f3
commit
e8d1ecd4c1
7 changed files with 240 additions and 1 deletions
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.command.v2;
|
||||
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
|
||||
import net.minecraft.command.argument.serialize.ArgumentSerializer;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import net.fabricmc.fabric.mixin.command.ArgumentTypesAccessor;
|
||||
|
||||
public class ArgumentTypeRegistry {
|
||||
/**
|
||||
* Register a new argument type.
|
||||
*
|
||||
* @param id the identifier of the argument type
|
||||
* @param clazz the class of the argument type
|
||||
* @param serializer the serializer for the argument type
|
||||
* @param <A> the argument type
|
||||
* @param <T> the argument type properties
|
||||
*/
|
||||
public static <A extends ArgumentType<?>, T extends ArgumentSerializer.ArgumentTypeProperties<A>> void registerArgumentType(
|
||||
Identifier id, Class<? extends A> clazz, ArgumentSerializer<A, T> serializer) {
|
||||
ArgumentTypesAccessor.fabric_getClassMap().put(clazz, serializer);
|
||||
Registry.register(Registry.COMMAND_ARGUMENT_TYPE, id, serializer);
|
||||
}
|
||||
|
||||
private ArgumentTypeRegistry() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.command.argument.ArgumentTypes;
|
||||
import net.minecraft.command.argument.serialize.ArgumentSerializer;
|
||||
|
||||
@Mixin(ArgumentTypes.class)
|
||||
public interface ArgumentTypesAccessor {
|
||||
@Accessor("CLASS_MAP")
|
||||
static Map<Class<?>, ArgumentSerializer<?, ?>> fabric_getClassMap() {
|
||||
throw new AssertionError("");
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
"package": "net.fabricmc.fabric.mixin.command",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
"ArgumentTypesAccessor",
|
||||
"CommandManagerMixin",
|
||||
"HelpCommandAccessor"
|
||||
],
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.command;
|
||||
|
||||
import static net.minecraft.server.command.CommandManager.argument;
|
||||
import static net.minecraft.server.command.CommandManager.literal;
|
||||
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
|
||||
import net.minecraft.command.argument.serialize.ConstantArgumentSerializer;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.command.v2.ArgumentTypeRegistry;
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
import net.fabricmc.fabric.test.command.argument.SmileyArgument;
|
||||
import net.fabricmc.fabric.test.command.argument.SmileyArgumentType;
|
||||
|
||||
public class CustomArgumentTest implements ModInitializer {
|
||||
private static final String ARG_NAME = "smiley_value";
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
ArgumentTypeRegistry.registerArgumentType(new Identifier("fabric-command-test", "smiley"), SmileyArgumentType.class, ConstantArgumentSerializer.of(SmileyArgumentType::smiley));
|
||||
|
||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||
dispatcher.register(
|
||||
literal("fabric_custom_argument_test").then(
|
||||
argument(ARG_NAME, SmileyArgumentType.smiley())
|
||||
.executes(CustomArgumentTest::executeSmileyCommand)));
|
||||
});
|
||||
}
|
||||
|
||||
private static int executeSmileyCommand(CommandContext<ServerCommandSource> context) {
|
||||
SmileyArgument smiley = context.getArgument(ARG_NAME, SmileyArgument.class);
|
||||
String feedback = switch (smiley) {
|
||||
case SAD -> "Oh no, here is a heart: <3";
|
||||
case HAPPY -> "Nice to see that you are having a good day :)";
|
||||
};
|
||||
context.getSource().sendFeedback(Text.literal(feedback), false);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.command.argument;
|
||||
|
||||
public enum SmileyArgument {
|
||||
HAPPY(":)"),
|
||||
SAD(":(");
|
||||
|
||||
public final String smiley;
|
||||
|
||||
SmileyArgument(String smiley) {
|
||||
this.smiley = smiley;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.command.argument;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public class SmileyArgumentType implements ArgumentType<SmileyArgument> {
|
||||
private static final Collection<String> SMILEY_VALUES = Arrays.stream(SmileyArgument.values()).map(s -> s.smiley).toList();
|
||||
public static final DynamicCommandExceptionType INVALID_COLOR_EXCEPTION = new DynamicCommandExceptionType(smiley -> {
|
||||
return Text.literal("Invalid smiley: " + smiley); // use Text.translatable in your mod!
|
||||
});
|
||||
|
||||
public static SmileyArgumentType smiley() {
|
||||
return new SmileyArgumentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmileyArgument parse(StringReader reader) throws CommandSyntaxException {
|
||||
// Note: normally we would use reader.readUnquotedString(), but that won't allow : that we want for our smiley!
|
||||
String string = "" + reader.read();
|
||||
|
||||
if (reader.canRead()) {
|
||||
string += reader.read();
|
||||
|
||||
for (SmileyArgument possibleSmiley : SmileyArgument.values()) {
|
||||
if (string.equals(possibleSmiley.smiley)) {
|
||||
return possibleSmiley;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw INVALID_COLOR_EXCEPTION.create(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
|
||||
return CommandSource.suggestMatching(SMILEY_VALUES, builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getExamples() {
|
||||
return SMILEY_VALUES;
|
||||
}
|
||||
}
|
|
@ -10,7 +10,8 @@
|
|||
},
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"net.fabricmc.fabric.test.command.CommandTest"
|
||||
"net.fabricmc.fabric.test.command.CommandTest",
|
||||
"net.fabricmc.fabric.test.command.CustomArgumentTest"
|
||||
],
|
||||
"client": [
|
||||
"net.fabricmc.fabric.test.command.client.ClientCommandTest"
|
||||
|
|
Loading…
Reference in a new issue