@@ -0,0 +1,3107 @@
+package us.myles.ViaVersion.api.rewriters;%0A%0Aimport org.jetbrains.annotations.Nullable;%0Aimport us.myles.ViaVersion.api.PacketWrapper;%0Aimport us.myles.ViaVersion.api.protocol.ClientboundPacketType;%0Aimport us.myles.ViaVersion.api.protocol.Protocol;%0Aimport us.myles.ViaVersion.api.remapper.PacketRemapper;%0Aimport us.myles.ViaVersion.api.type.Type;%0A%0Aimport java.util.HashMap;%0Aimport java.util.Map;%0A%0A/**%0A * Abstract rewriter for the declare commands packet to handle argument type name and content changes.%0A */%0Apublic abstract class CommandRewriter %7B%0A    protected final Protocol protocol;%0A    protected final Map%3CString, CommandArgumentConsumer%3E parserHandlers = new HashMap%3C%3E();%0A%0A    protected CommandRewriter(Protocol protocol) %7B%0A        this.protocol = protocol;%0A    %7D%0A%0A    public void handleArgument(PacketWrapper wrapper, String argumentType) throws Exception %7B%0A        CommandArgumentConsumer handler = parserHandlers.get(argumentType);%0A        if (handler != null) %7B%0A            handler.accept(wrapper);%0A        %7D%0A    %7D%0A%0A    public void registerDeclareCommands(ClientboundPacketType packetType) %7B%0A        protocol.registerOutgoing(packetType, new PacketRemapper() %7B%0A            @Override%0A            public void registerMap() %7B%0A                handler(wrapper -%3E %7B%0A                    int size = wrapper.passthrough(Type.VAR_INT);%0A                    for (int i = 0; i %3C size; i++) %7B%0A                        byte flags = wrapper.passthrough(Type.BYTE);%0A                        wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE); // Children indices%0A                        if ((flags & 0x08) != 0) %7B%0A                            wrapper.passthrough(Type.VAR_INT); // Redirect node index%0A                        %7D%0A%0A                        byte nodeType = (byte) (flags & 0x03);%0A                        if (nodeType == 1 %7C%7C nodeType == 2) %7B // Literal/argument node%0A                            wrapper.passthrough(Type.STRING); // Name%0A                        %7D%0A%0A                        if (nodeType == 2) %7B // Argument node%0A                            String argumentType = handleArgumentType(wrapper.read(Type.STRING));%0A                            if (argumentType != null) %7B%0A                                wrapper.write(Type.STRING, argumentType);%0A                                handleArgument(wrapper, argumentType);%0A                            %7D%0A                        %7D%0A%0A                        if ((flags & 0x10) != 0) %7B%0A                            wrapper.passthrough(Type.STRING); // Suggestion type%0A                        %7D%0A                    %7D%0A%0A                    wrapper.passthrough(Type.VAR_INT); // Root node index%0A                %7D);%0A            %7D%0A        %7D);%0A    %7D%0A%0A    /**%0A     * Can be overridden if needed.%0A     *%0A     * @param argumentType argument type%0A     * @return new argument type, or null if it should be removed%0A     */%0A    @Nullable%0A    protected String handleArgumentType(String argumentType) %7B%0A        return argumentType;%0A    %7D%0A%0A    @FunctionalInterface%0A    public interface CommandArgumentConsumer %7B%0A%0A        void accept(PacketWrapper wrapper) throws Exception;%0A    %7D%0A%7D%0A

Add abstract declare commands handler