Command Argument Serializer

This commit is contained in:
Adrian Bergqvist 2023-02-08 17:54:37 +01:00
parent 6a541ff8ce
commit 3172c5f672
No known key found for this signature in database
GPG Key ID: FAE7D8EDE225E686
9 changed files with 164 additions and 10 deletions

View File

@ -5,7 +5,7 @@ plugins {
}
group = "org.adde0109"
version = "1.1.7-alpha"
version = "1.2.0-beta"
repositories {
mavenCentral()
@ -24,6 +24,7 @@ dependencies {
implementation("org.apache.commons:commons-collections4:4.4")
compileOnly("io.netty:netty-buffer:4.1.86.Final")
compileOnly("io.netty:netty-transport:4.1.86.Final")
compileOnly("io.netty:netty-codec:4.1.86.Final")
}
tasks {

View File

@ -4,28 +4,37 @@ import com.google.inject.Inject;
import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.network.BackendChannelInitializer;
import com.velocitypowered.proxy.network.ConnectionManager;
import com.velocitypowered.proxy.network.ServerChannelInitializer;
import com.velocitypowered.proxy.protocol.packet.brigadier.ArgumentIdentifier;
import com.velocitypowered.proxy.protocol.packet.brigadier.ArgumentPropertyRegistry;
import com.velocitypowered.proxy.protocol.packet.brigadier.ArgumentPropertySerializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelInitializer;
import org.adde0109.ambassador.velocity.VelocityBackendChannelInitializer;
import org.adde0109.ambassador.velocity.VelocityServerChannelInitializer;
import org.adde0109.ambassador.velocity.VelocityEventHandler;
import org.adde0109.ambassador.velocity.protocol.EnumArgumentProperty;
import org.adde0109.ambassador.velocity.protocol.EnumArgumentPropertySerializer;
import org.adde0109.ambassador.velocity.protocol.ModIdArgumentProperty;
import org.bstats.charts.SingleLineChart;
import org.bstats.velocity.Metrics;
import org.slf4j.Logger;
import java.nio.file.Path;
@Plugin(id = "ambassador", name = "Ambassador", version = "1.1.7-alpha", authors = {"adde0109"})
@Plugin(id = "ambassador", name = "Ambassador", version = "1.2.0-beta", authors = {"adde0109"})
public class Ambassador {
public ProxyServer server;
@ -66,6 +75,23 @@ public class Ambassador {
ChannelInitializer<?> originalBackend = ((ConnectionManager) cmField.get(server)).backendChannelInitializer.get();
((ConnectionManager) cmField.get(server)).backendChannelInitializer.set(new VelocityBackendChannelInitializer(originalBackend,(VelocityServer) server));
Method argumentRegistry = ArgumentPropertyRegistry.class.getDeclaredMethod("register", ArgumentIdentifier.class, Class.class, ArgumentPropertySerializer.class);
argumentRegistry.setAccessible(true);
argumentRegistry.invoke(null,ArgumentIdentifier.id("forge:enum"), EnumArgumentProperty.class, EnumArgumentPropertySerializer.ENUM);
argumentRegistry.invoke(null,ArgumentIdentifier.id("forge:modid"), ModIdArgumentProperty.class,
new ArgumentPropertySerializer<>() {
@Override
public ModIdArgumentProperty deserialize(ByteBuf buf, ProtocolVersion protocolVersion) {
return new ModIdArgumentProperty();
}
@Override
public void serialize(Object object, ByteBuf buf, ProtocolVersion protocolVersion) {
}
});
}
private void initMetrics() {

View File

@ -4,6 +4,7 @@ import com.velocitypowered.proxy.connection.ConnectionType;
public class ForgeConstants {
public static final String HANDLER = "Modern Forge handler";
public static final String MARKER_ADDER = "FML2/3 Marker Adder";
public static final String OUTBOUND_CATCHER_NAME = "ambassador-catcher";
public static final String RESET_LISTENER = "ambassador-reset-listener";

View File

@ -5,6 +5,7 @@ import com.velocitypowered.proxy.network.BackendChannelInitializer;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import org.adde0109.ambassador.forge.ForgeConstants;
import org.adde0109.ambassador.velocity.backend.FMLMarkerAdder;
import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendHandshakeHandler;
@ -39,6 +40,7 @@ public class VelocityBackendChannelInitializer extends BackendChannelInitializer
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
ch.pipeline().addLast(ForgeConstants.MARKER_ADDER, new FMLMarkerAdder());
ch.pipeline().addLast(ForgeConstants.HANDLER, new VelocityForgeBackendHandshakeHandler(server));
}
}

View File

@ -0,0 +1,32 @@
package org.adde0109.ambassador.velocity.backend;
import com.velocitypowered.proxy.connection.MinecraftConnection;
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
import com.velocitypowered.proxy.network.Connections;
import com.velocitypowered.proxy.protocol.packet.Handshake;
import io.netty.channel.*;
import io.netty.handler.codec.MessageToMessageEncoder;
import org.adde0109.ambassador.forge.ForgeConstants;
import org.adde0109.ambassador.forge.ForgeFMLConnectionType;
import java.util.ArrayList;
import java.util.List;
public class FMLMarkerAdder extends MessageToMessageEncoder<Handshake> {
public FMLMarkerAdder() {
super(Handshake.class);
}
@Override
protected void encode(ChannelHandlerContext ctx, Handshake msg, List<Object> out) {
MinecraftConnection connection = (MinecraftConnection) ctx.pipeline().get(Connections.HANDLER);
VelocityServerConnection serverConnection = (VelocityServerConnection) connection.getAssociation();
if (serverConnection.getPlayer().getConnection().getType() instanceof ForgeFMLConnectionType) {
msg.setServerAddress(msg.getServerAddress() + ForgeConstants.FML2Marker);
}
out.add(msg);
ctx.pipeline().remove(this);
}
}

View File

@ -1,19 +1,12 @@
package org.adde0109.ambassador.velocity.backend;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.config.PlayerInfoForwarding;
import com.velocitypowered.proxy.connection.MinecraftConnection;
import com.velocitypowered.proxy.connection.backend.LoginSessionHandler;
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
import com.velocitypowered.proxy.network.Connections;
import com.velocitypowered.proxy.protocol.packet.Handshake;
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
import io.netty.channel.*;
import io.netty.util.ReferenceCountUtil;
import org.adde0109.ambassador.forge.ForgeConstants;
import org.adde0109.ambassador.forge.ForgeFMLConnectionType;
import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase;
import org.jetbrains.annotations.NotNull;
public class VelocityForgeBackendHandshakeHandler extends ChannelInboundHandlerAdapter {
@ -29,11 +22,12 @@ public class VelocityForgeBackendHandshakeHandler extends ChannelInboundHandlerA
MinecraftConnection connection = (MinecraftConnection) ctx.pipeline().get(Connections.HANDLER);
VelocityServerConnection serverConnection = (VelocityServerConnection) connection.getAssociation();
ctx.pipeline().remove(this);
if (serverConnection.getPlayer().getConnection().getType() instanceof ForgeFMLConnectionType) {
connection.setSessionHandler(new ForgeHandshakeSessionHandler((LoginSessionHandler) connection.getSessionHandler(),serverConnection,server));
}
ctx.pipeline().remove(this);
ctx.pipeline().fireChannelActive();
}
}

View File

@ -0,0 +1,23 @@
package org.adde0109.ambassador.velocity.protocol;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
public class EnumArgumentProperty implements ArgumentType<String> {
private final String className;
public EnumArgumentProperty(String className) {
this.className = className;
}
public String getClassName() {
return this.className;
}
@Override
public String parse(StringReader reader) throws CommandSyntaxException {
return reader.readUnquotedString();
}
}

View File

@ -0,0 +1,28 @@
package org.adde0109.ambassador.velocity.protocol;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.packet.brigadier.ArgumentPropertySerializer;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* An argument property serializer that will serialize and deserialize nothing.
*/
public class EnumArgumentPropertySerializer implements ArgumentPropertySerializer<EnumArgumentProperty> {
public static final EnumArgumentPropertySerializer ENUM = new EnumArgumentPropertySerializer();
private EnumArgumentPropertySerializer() {
}
@Override
public @Nullable EnumArgumentProperty deserialize(ByteBuf buf, ProtocolVersion protocolVersion) {
return new EnumArgumentProperty(ProtocolUtils.readString(buf));
}
@Override
public void serialize(EnumArgumentProperty object, ByteBuf buf, ProtocolVersion protocolVersion) {
ProtocolUtils.writeString(buf, object.getClassName());
}
}

View File

@ -0,0 +1,47 @@
package org.adde0109.ambassador.velocity.protocol;
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 com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.util.ModInfo;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
public class ModIdArgumentProperty implements ArgumentType<String> {
public ModIdArgumentProperty() {}
@Override
public String parse(StringReader reader) throws CommandSyntaxException {
return reader.readUnquotedString();
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context,
SuggestionsBuilder builder) {
S source = context.getSource();
if (source instanceof Player) {
ModInfo modInfo = ((Player) source).getModInfo().orElse(null);
if (modInfo != null) {
for (ModInfo.Mod mod : modInfo.getMods()) {
builder.suggest(mod.getId());
}
return builder.buildFuture();
}
}
return Suggestions.empty();
}
@Override
public Collection<String> getExamples() {
throw new UnsupportedOperationException();
}
}