diff --git a/patches/minecraft/net/minecraft/command/impl/LocateCommand.java.patch b/patches/minecraft/net/minecraft/command/impl/LocateCommand.java.patch index c5fb832c6..c827f85cb 100644 --- a/patches/minecraft/net/minecraft/command/impl/LocateCommand.java.patch +++ b/patches/minecraft/net/minecraft/command/impl/LocateCommand.java.patch @@ -1,17 +1,17 @@ --- a/net/minecraft/command/impl/LocateCommand.java +++ b/net/minecraft/command/impl/LocateCommand.java -@@ -20,6 +20,14 @@ - public static void func_198528_a(CommandDispatcher p_198528_0_) { - p_198528_0_.register(Commands.func_197057_a("locate").requires((p_198533_0_) -> { - return p_198533_0_.func_197034_c(2); -+ }).then(Commands.func_197056_a("structure_type", net.minecraftforge.common.command.StructureArgument.structure()) -+ .suggests(net.minecraftforge.common.command.StructureArgument.suggestions()) -+ .executes(ctx -> { -+ return func_198534_a(ctx.getSource(), ctx.getArgument("structure_type", net.minecraft.util.ResourceLocation.class).toString().replace("minecraft:", "")); -+ }))); -+ if (true) return; // Forge: replace this code with above extensible version -+ p_198528_0_.register(Commands.func_197057_a("locate").requires((p_198533_0_) -> { -+ return p_198533_0_.func_197034_c(2); - }).then(Commands.func_197057_a("Pillager_Outpost").executes((p_198530_0_) -> { - return func_198534_a(p_198530_0_.getSource(), "Pillager_Outpost"); - })).then(Commands.func_197057_a("Mineshaft").executes((p_198535_0_) -> { +@@ -50,7 +50,13 @@ + return func_198534_a(p_204758_0_.getSource(), "Shipwreck"); + })).then(Commands.func_197057_a("Village").executes((p_218858_0_) -> { + return func_198534_a(p_218858_0_.getSource(), "Village"); +- }))); ++ // FORGE: Support modded structures via registry name ++ })).then(Commands.func_197056_a("structure_type", net.minecraft.command.arguments.ResourceLocationArgument.func_197197_a()) ++ .suggests((ctx, sb) -> net.minecraft.command.ISuggestionProvider.func_197013_a( ++ net.minecraftforge.registries.GameData.getStructureFeatures().func_148742_b().stream() ++ .map(net.minecraft.util.ResourceLocation::toString), sb)) ++ .executes(ctx -> func_198534_a(ctx.getSource(), ctx.getArgument("structure_type", net.minecraft.util.ResourceLocation.class).toString().replace("minecraft:", "")) ++ ))); + } + + private static int func_198534_a(CommandSource p_198534_0_, String p_198534_1_) throws CommandSyntaxException { diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index d9e319d32..8804bd3ac 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -30,6 +30,7 @@ import net.minecraftforge.fml.event.server.FMLServerStoppingEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.server.command.ConfigCommand; import net.minecraftforge.server.command.EnumArgument; +import net.minecraftforge.server.command.ForgeArguments; import net.minecraftforge.server.command.ForgeCommand; import net.minecraftforge.server.command.ModIdArgument; import net.minecraftforge.versions.forge.ForgeVersion; @@ -133,8 +134,7 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook VersionChecker.startVersionCheck(); } - //ArgumentTypes.register("forge:enum", EnumArgument.class, new EnumArgument.Serialzier()); //This can't register, it breaks vanilla clients. As the packet serailzier doesn't discard unknown data - ArgumentTypes.register("forge:modid", ModIdArgument.class, new ArgumentSerializer<>(ModIdArgument::modIdArgument)); + ForgeArguments.register(); } public void serverStarting(FMLServerStartingEvent evt) diff --git a/src/main/java/net/minecraftforge/common/command/StructureArgument.java b/src/main/java/net/minecraftforge/common/command/StructureArgument.java deleted file mode 100644 index 0fd673675..000000000 --- a/src/main/java/net/minecraftforge/common/command/StructureArgument.java +++ /dev/null @@ -1,93 +0,0 @@ -package net.minecraftforge.common.command; - -import com.google.common.collect.Streams; -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.exceptions.SimpleCommandExceptionType; -import com.mojang.brigadier.suggestion.SuggestionProvider; - -import net.minecraft.command.CommandSource; -import net.minecraft.command.ISuggestionProvider; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.ResourceLocationException; -import net.minecraft.util.text.TranslationTextComponent; -import net.minecraft.world.gen.feature.structure.Structure; -import net.minecraftforge.registries.GameData; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Locale; - -public class StructureArgument implements ArgumentType -{ - private static final Collection EXAMPLES = Arrays.asList("minecraft:village", "Mansion"); - public static final DynamicCommandExceptionType STRUCTURE_UNKNOWN_TYPE = new DynamicCommandExceptionType((p_211367_0_) -> - { - return new TranslationTextComponent("structure.notFound", p_211367_0_); - }); - - public static StructureArgument structure() - { - return new StructureArgument(); - } - - public static SuggestionProvider suggestions() - { - return (ctx, sb) -> ISuggestionProvider.suggest(Streams.concat( - GameData.getStructureMap().values().stream().map(Structure::getStructureName), - GameData.getStructureFeatures().keySet().stream().map(ResourceLocation::toString)), sb); - } - - public static ResourceLocation getStructureId(CommandContext context, String name) throws CommandSyntaxException - { - return checkIfStructureExists(context.getArgument(name, ResourceLocation.class)); - } - - private static ResourceLocation checkIfStructureExists(ResourceLocation id) throws CommandSyntaxException - { - if (id.getNamespace().equals("minecraft")) - { - // Special case vanilla hardcoded names, for vanilla compat - Structure structure = GameData.getStructureMap().values().stream() - .filter(s -> s.getStructureName().equalsIgnoreCase(id.getPath())) - .findFirst() - .orElse(null); - if (structure != null) - return id; - } - GameData.getStructureFeatures().getValue(id).orElseThrow(() -> STRUCTURE_UNKNOWN_TYPE.create(id)); - return id; - } - - private static final SimpleCommandExceptionType INVALID_EXCEPTION = new SimpleCommandExceptionType(new TranslationTextComponent("argument.id.invalid")); - - public ResourceLocation parse(StringReader reader) throws CommandSyntaxException - { - // Logic taken from ResourceLocation.read, but made case-insensitive - int cursor = reader.getCursor(); - try - { - while (reader.canRead() && ResourceLocation.isValidPathCharacter(Character.toLowerCase(reader.peek()))) - { - reader.skip(); - } - - String s = reader.getString().substring(cursor, reader.getCursor()); - ResourceLocation rl = new ResourceLocation(s.toLowerCase(Locale.ROOT)); - return checkIfStructureExists(rl); - } - catch (ResourceLocationException e) - { - reader.setCursor(cursor); - throw INVALID_EXCEPTION.createWithContext(reader); - } - } - - public Collection getExamples() - { - return EXAMPLES; - } -} diff --git a/src/main/java/net/minecraftforge/server/command/ForgeArguments.java b/src/main/java/net/minecraftforge/server/command/ForgeArguments.java new file mode 100644 index 000000000..d37e58321 --- /dev/null +++ b/src/main/java/net/minecraftforge/server/command/ForgeArguments.java @@ -0,0 +1,15 @@ +package net.minecraftforge.server.command; + +public class ForgeArguments +{ + public static void register() + { + /* + * We can't actually add any of these, because vanilla clients will choke on unknown argument types + * So our custom arguments will not validate client-side, but they do still work + ArgumentTypes.register("forge:enum", EnumArgument.class, new EnumArgument.Serializer()); + ArgumentTypes.register("forge:modid", ModIdArgument.class, new ArgumentSerializer<>(ModIdArgument::modIdArgument)); + ArgumentTypes.register("forge:structure_type", StructureArgument.class, new ArgumentSerializer<>(StructureArgument::structure)); + */ + } +} diff --git a/src/main/java/net/minecraftforge/server/command/ModIdArgument.java b/src/main/java/net/minecraftforge/server/command/ModIdArgument.java index 2a69835cf..5772fe5d3 100644 --- a/src/main/java/net/minecraftforge/server/command/ModIdArgument.java +++ b/src/main/java/net/minecraftforge/server/command/ModIdArgument.java @@ -19,16 +19,14 @@ package net.minecraftforge.server.command; -import com.google.gson.JsonObject; 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.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; + import net.minecraft.command.ISuggestionProvider; -import net.minecraft.command.arguments.IArgumentSerializer; -import net.minecraft.network.PacketBuffer; import net.minecraftforge.fml.ModContainer; import net.minecraftforge.fml.ModList; @@ -58,22 +56,4 @@ public class ModIdArgument implements ArgumentType { public Collection getExamples() { return EXAMPLES; } - - public static class Serialzier implements IArgumentSerializer { - - @Override - public void write(ModIdArgument argument, PacketBuffer buffer) { - } - - @Override - public ModIdArgument read(PacketBuffer buffer) { - return null; - } - - @Override - public void write(ModIdArgument argument, JsonObject json) { - - } - - } }