From 7ead4add671edb8736e8c46a597d2783a80e0b00 Mon Sep 17 00:00:00 2001 From: Andrew Steinborn Date: Mon, 16 Nov 2020 02:58:00 -0500 Subject: [PATCH] Support custom mod argument tunneling (#390) --- .../brigadier/ArgumentPropertyRegistry.java | 8 ++++ .../packet/brigadier/ModArgumentProperty.java | 47 +++++++++++++++++++ .../ModArgumentPropertySerializer.java | 27 +++++++++++ 3 files changed, 82 insertions(+) create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ModArgumentProperty.java create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ModArgumentPropertySerializer.java diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertyRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertyRegistry.java index c175f8dc4..b98365d3a 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertyRegistry.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertyRegistry.java @@ -5,6 +5,7 @@ import static com.velocitypowered.proxy.protocol.packet.brigadier.EmptyArgumentP import static com.velocitypowered.proxy.protocol.packet.brigadier.FloatArgumentPropertySerializer.FLOAT; import static com.velocitypowered.proxy.protocol.packet.brigadier.IntegerArgumentPropertySerializer.INTEGER; import static com.velocitypowered.proxy.protocol.packet.brigadier.LongArgumentPropertySerializer.LONG; +import static com.velocitypowered.proxy.protocol.packet.brigadier.ModArgumentPropertySerializer.MOD; import static com.velocitypowered.proxy.protocol.packet.brigadier.StringArgumentPropertySerializer.STRING; import com.mojang.brigadier.arguments.ArgumentType; @@ -76,6 +77,10 @@ public class ArgumentPropertyRegistry { if (property.getResult() != null) { property.getSerializer().serialize(property.getResult(), buf); } + } else if (type instanceof ModArgumentProperty) { + ModArgumentProperty property = (ModArgumentProperty) type; + ProtocolUtils.writeString(buf, property.getIdentifier()); + buf.writeBytes(property.getData()); } else { ArgumentPropertySerializer serializer = byClass.get(type.getClass()); String id = classToId.get(type.getClass()); @@ -98,6 +103,9 @@ public class ArgumentPropertyRegistry { GenericArgumentPropertySerializer.create(BoolArgumentType::bool)); register("brigadier:long", LongArgumentType.class, LONG); + // Crossstitch support + register("crossstitch:mod_argument", ModArgumentProperty.class, MOD); + // Minecraft argument types with extra properties empty("minecraft:entity", ByteArgumentPropertySerializer.BYTE); empty("minecraft:score_holder", ByteArgumentPropertySerializer.BYTE); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ModArgumentProperty.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ModArgumentProperty.java new file mode 100644 index 000000000..f82133260 --- /dev/null +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ModArgumentProperty.java @@ -0,0 +1,47 @@ +package com.velocitypowered.proxy.protocol.packet.brigadier; + +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 io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import java.util.Collection; +import java.util.concurrent.CompletableFuture; + +public class ModArgumentProperty implements ArgumentType { + + private final String identifier; + private final ByteBuf data; + + public ModArgumentProperty(String identifier, ByteBuf data) { + this.identifier = identifier; + this.data = Unpooled.unreleasableBuffer(data.asReadOnly()); + } + + public String getIdentifier() { + return identifier; + } + + public ByteBuf getData() { + return data.slice(); + } + + @Override + public ByteBuf parse(StringReader reader) throws CommandSyntaxException { + throw new UnsupportedOperationException(); + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, + SuggestionsBuilder builder) { + throw new UnsupportedOperationException(); + } + + @Override + public Collection getExamples() { + throw new UnsupportedOperationException(); + } +} diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ModArgumentPropertySerializer.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ModArgumentPropertySerializer.java new file mode 100644 index 000000000..6c6eebbd0 --- /dev/null +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ModArgumentPropertySerializer.java @@ -0,0 +1,27 @@ +package com.velocitypowered.proxy.protocol.packet.brigadier; + +import com.velocitypowered.proxy.protocol.ProtocolUtils; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.checkerframework.checker.nullness.qual.Nullable; + +class ModArgumentPropertySerializer implements ArgumentPropertySerializer { + static final ModArgumentPropertySerializer MOD = new ModArgumentPropertySerializer(); + + private ModArgumentPropertySerializer() { + + } + + @Override + public @Nullable ModArgumentProperty deserialize(ByteBuf buf) { + String identifier = ProtocolUtils.readString(buf); + byte[] extraData = ProtocolUtils.readByteArray(buf); + return new ModArgumentProperty(identifier, Unpooled.wrappedBuffer(extraData)); + } + + @Override + public void serialize(ModArgumentProperty object, ByteBuf buf) { + // This is special-cased by ArgumentPropertyRegistry + throw new UnsupportedOperationException(); + } +}