Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-25 15:50:19 +01:00
Finishing up plugin message stuff for tonight.
Dieser Commit ist enthalten in:
Ursprung
a216d25a1a
Commit
b345d3aba3
@ -40,6 +40,8 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
connection.getProxyPlayer().getConnection().write(packet);
|
connection.getProxyPlayer().getConnection().write(packet);
|
||||||
|
} else if (packet instanceof PluginMessage) {
|
||||||
|
playerHandler.handlePluginMessage((PluginMessage) packet, true);
|
||||||
} else {
|
} else {
|
||||||
// Just forward the packet on. We don't have anything to handle at this time.
|
// Just forward the packet on. We don't have anything to handle at this time.
|
||||||
connection.getProxyPlayer().getConnection().write(packet);
|
connection.getProxyPlayer().getConnection().write(packet);
|
||||||
|
@ -4,10 +4,12 @@ import com.velocitypowered.proxy.VelocityServer;
|
|||||||
import com.velocitypowered.proxy.connection.backend.ServerConnection;
|
import com.velocitypowered.proxy.connection.backend.ServerConnection;
|
||||||
import com.velocitypowered.proxy.data.ServerInfo;
|
import com.velocitypowered.proxy.data.ServerInfo;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.packets.*;
|
import com.velocitypowered.proxy.protocol.packets.*;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
import com.velocitypowered.proxy.util.ThrowableUtils;
|
import com.velocitypowered.proxy.util.ThrowableUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.EventLoop;
|
||||||
import net.kyori.text.TextComponent;
|
import net.kyori.text.TextComponent;
|
||||||
import net.kyori.text.format.TextColor;
|
import net.kyori.text.format.TextColor;
|
||||||
@ -15,15 +17,14 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||||
private static final Logger logger = LogManager.getLogger(ClientPlaySessionHandler.class);
|
private static final Logger logger = LogManager.getLogger(ClientPlaySessionHandler.class);
|
||||||
|
private static final int MAX_PLUGIN_CHANNELS = 128;
|
||||||
|
|
||||||
private final ConnectedPlayer player;
|
private final ConnectedPlayer player;
|
||||||
private ScheduledFuture<?> pingTask;
|
private ScheduledFuture<?> pingTask;
|
||||||
@ -76,6 +77,11 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (packet instanceof PluginMessage) {
|
||||||
|
handlePluginMessage((PluginMessage) packet, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If we don't want to handle this packet, just forward it on.
|
// If we don't want to handle this packet, just forward it on.
|
||||||
player.getConnectedServer().getChannel().write(packet);
|
player.getConnectedServer().getChannel().write(packet);
|
||||||
}
|
}
|
||||||
@ -149,4 +155,64 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
public List<UUID> getServerBossBars() {
|
public List<UUID> getServerBossBars() {
|
||||||
return serverBossBars;
|
return serverBossBars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handlePluginMessage(PluginMessage packet, boolean fromBackend) {
|
||||||
|
logger.info("Got plugin message packet {}", packet);
|
||||||
|
|
||||||
|
// TODO: this certainly isn't the right approach, need a better way!
|
||||||
|
/*if (packet.getChannel().equals("REGISTER")) {
|
||||||
|
List<String> actuallyRegistered = new ArrayList<>();
|
||||||
|
List<String> channels = PluginMessageUtil.getChannels(packet);
|
||||||
|
for (String channel : channels) {
|
||||||
|
if (pluginMessageChannels.size() >= MAX_PLUGIN_CHANNELS && !pluginMessageChannels.contains(channel)) {
|
||||||
|
throw new IllegalStateException("Too many plugin message channels registered");
|
||||||
|
}
|
||||||
|
if (pluginMessageChannels.add(channel)) {
|
||||||
|
actuallyRegistered.add(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actuallyRegistered.size() > 0) {
|
||||||
|
logger.info("Rewritten register packet: {}", actuallyRegistered);
|
||||||
|
PluginMessage newRegisterPacket = PluginMessageUtil.constructChannelsPacket("REGISTER", actuallyRegistered);
|
||||||
|
if (fromBackend) {
|
||||||
|
player.getConnection().write(newRegisterPacket);
|
||||||
|
} else {
|
||||||
|
player.getConnectedServer().getChannel().write(newRegisterPacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet.getChannel().equals("UNREGISTER")) {
|
||||||
|
List<String> channels = PluginMessageUtil.getChannels(packet);
|
||||||
|
pluginMessageChannels.removeAll(channels);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (packet.getChannel().equals("MC|Brand")) {
|
||||||
|
// Rewrite this packet to indicate that Velocity is running. Hurrah!
|
||||||
|
ByteBuf currentBrandBuf = Unpooled.wrappedBuffer(packet.getData());
|
||||||
|
|
||||||
|
ByteBuf buf = Unpooled.buffer();
|
||||||
|
byte[] rewrittenBrand;
|
||||||
|
try {
|
||||||
|
String currentBrand = ProtocolUtils.readString(currentBrandBuf);
|
||||||
|
logger.info("Remote server brand: {}", currentBrand);
|
||||||
|
ProtocolUtils.writeString(buf, currentBrand + " (Velocity)");
|
||||||
|
rewrittenBrand = new byte[buf.readableBytes()];
|
||||||
|
buf.readBytes(rewrittenBrand);
|
||||||
|
} finally {
|
||||||
|
buf.release();
|
||||||
|
}
|
||||||
|
packet.setData(rewrittenBrand);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No other special handling?
|
||||||
|
if (fromBackend) {
|
||||||
|
player.getConnection().write(packet);
|
||||||
|
} else {
|
||||||
|
player.getConnectedServer().getChannel().write(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package com.velocitypowered.proxy.protocol;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public enum ProtocolConstants { ;
|
public enum ProtocolConstants { ;
|
||||||
|
public static final int MINECRAFT_1_7_2 = 4;
|
||||||
public static final int MINECRAFT_1_11 = 315;
|
public static final int MINECRAFT_1_11 = 315;
|
||||||
public static final int MINECRAFT_1_11_1 = 316;
|
public static final int MINECRAFT_1_11_1 = 316;
|
||||||
public static final int MINECRAFT_1_12 = 335;
|
public static final int MINECRAFT_1_12 = 335;
|
||||||
@ -10,6 +11,7 @@ public enum ProtocolConstants { ;
|
|||||||
public static final int MINECRAFT_1_12_2 = 340;
|
public static final int MINECRAFT_1_12_2 = 340;
|
||||||
|
|
||||||
public static final int MINIMUM_VERSION_SUPPORTED = MINECRAFT_1_11;
|
public static final int MINIMUM_VERSION_SUPPORTED = MINECRAFT_1_11;
|
||||||
|
public static final int MINIMUM_GENERIC_VERSION = MINECRAFT_1_11;
|
||||||
|
|
||||||
public static final int[] SUPPORTED_VERSIONS = new int[] {
|
public static final int[] SUPPORTED_VERSIONS = new int[] {
|
||||||
MINECRAFT_1_11,
|
MINECRAFT_1_11,
|
||||||
|
@ -13,20 +13,20 @@ public enum StateRegistry {
|
|||||||
HANDSHAKE {
|
HANDSHAKE {
|
||||||
{
|
{
|
||||||
SERVERBOUND.register(Handshake.class, Handshake::new,
|
SERVERBOUND.register(Handshake.class, Handshake::new,
|
||||||
lowestVersion(0x00));
|
genericMapping(0x00));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
STATUS {
|
STATUS {
|
||||||
{
|
{
|
||||||
SERVERBOUND.register(StatusRequest.class, StatusRequest::new,
|
SERVERBOUND.register(StatusRequest.class, StatusRequest::new,
|
||||||
lowestVersion(0x00));
|
genericMapping(0x00));
|
||||||
SERVERBOUND.register(StatusPing.class, StatusPing::new,
|
SERVERBOUND.register(StatusPing.class, StatusPing::new,
|
||||||
lowestVersion(0x01));
|
genericMapping(0x01));
|
||||||
|
|
||||||
CLIENTBOUND.register(StatusResponse.class, StatusResponse::new,
|
CLIENTBOUND.register(StatusResponse.class, StatusResponse::new,
|
||||||
lowestVersion(0x00));
|
genericMapping(0x00));
|
||||||
CLIENTBOUND.register(StatusPing.class, StatusPing::new,
|
CLIENTBOUND.register(StatusPing.class, StatusPing::new,
|
||||||
lowestVersion(0x01));
|
genericMapping(0x01));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
PLAY {
|
PLAY {
|
||||||
@ -69,18 +69,18 @@ public enum StateRegistry {
|
|||||||
LOGIN {
|
LOGIN {
|
||||||
{
|
{
|
||||||
SERVERBOUND.register(ServerLogin.class, ServerLogin::new,
|
SERVERBOUND.register(ServerLogin.class, ServerLogin::new,
|
||||||
lowestVersion(0x00));
|
genericMapping(0x00));
|
||||||
SERVERBOUND.register(EncryptionResponse.class, EncryptionResponse::new,
|
SERVERBOUND.register(EncryptionResponse.class, EncryptionResponse::new,
|
||||||
lowestVersion(0x01));
|
genericMapping(0x01));
|
||||||
|
|
||||||
CLIENTBOUND.register(Disconnect.class, Disconnect::new,
|
CLIENTBOUND.register(Disconnect.class, Disconnect::new,
|
||||||
lowestVersion(0x00));
|
genericMapping(0x00));
|
||||||
CLIENTBOUND.register(EncryptionRequest.class, EncryptionRequest::new,
|
CLIENTBOUND.register(EncryptionRequest.class, EncryptionRequest::new,
|
||||||
lowestVersion(0x01));
|
genericMapping(0x01));
|
||||||
CLIENTBOUND.register(ServerLoginSuccess.class, ServerLoginSuccess::new,
|
CLIENTBOUND.register(ServerLoginSuccess.class, ServerLoginSuccess::new,
|
||||||
lowestVersion(0x02));
|
genericMapping(0x02));
|
||||||
CLIENTBOUND.register(SetCompression.class, SetCompression::new,
|
CLIENTBOUND.register(SetCompression.class, SetCompression::new,
|
||||||
lowestVersion(0x03));
|
genericMapping(0x03));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -104,6 +104,7 @@ public enum StateRegistry {
|
|||||||
for (int version : ProtocolConstants.SUPPORTED_VERSIONS) {
|
for (int version : ProtocolConstants.SUPPORTED_VERSIONS) {
|
||||||
versions.put(version, new ProtocolVersion(version));
|
versions.put(version, new ProtocolVersion(version));
|
||||||
}
|
}
|
||||||
|
versions.put(MINIMUM_GENERIC_VERSION, new ProtocolVersion(MINIMUM_GENERIC_VERSION));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProtocolVersion getVersion(final int version) {
|
public ProtocolVersion getVersion(final int version) {
|
||||||
@ -214,7 +215,7 @@ public enum StateRegistry {
|
|||||||
return new PacketMapping(id, version);
|
return new PacketMapping(id, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PacketMapping lowestVersion(int id) {
|
private static PacketMapping genericMapping(int id) {
|
||||||
return new PacketMapping(id, MINECRAFT_1_11);
|
return new PacketMapping(id, MINIMUM_GENERIC_VERSION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf> {
|
|||||||
public MinecraftDecoder(ProtocolConstants.Direction direction) {
|
public MinecraftDecoder(ProtocolConstants.Direction direction) {
|
||||||
this.state = StateRegistry.HANDSHAKE;
|
this.state = StateRegistry.HANDSHAKE;
|
||||||
this.direction = Preconditions.checkNotNull(direction, "direction");
|
this.direction = Preconditions.checkNotNull(direction, "direction");
|
||||||
this.setProtocolVersion(ProtocolConstants.MINIMUM_VERSION_SUPPORTED);
|
this.setProtocolVersion(ProtocolConstants.MINIMUM_GENERIC_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,7 +17,7 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
|||||||
public MinecraftEncoder(ProtocolConstants.Direction direction) {
|
public MinecraftEncoder(ProtocolConstants.Direction direction) {
|
||||||
this.state = StateRegistry.HANDSHAKE;
|
this.state = StateRegistry.HANDSHAKE;
|
||||||
this.direction = Preconditions.checkNotNull(direction, "direction");
|
this.direction = Preconditions.checkNotNull(direction, "direction");
|
||||||
this.setProtocolVersion(ProtocolConstants.MINIMUM_VERSION_SUPPORTED);
|
this.setProtocolVersion(ProtocolConstants.MINIMUM_GENERIC_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -5,10 +5,36 @@ import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
|||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class PluginMessage implements MinecraftPacket {
|
public class PluginMessage implements MinecraftPacket {
|
||||||
private String channel;
|
private String channel;
|
||||||
private byte[] data;
|
private byte[] data;
|
||||||
|
|
||||||
|
public String getChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChannel(String channel) {
|
||||||
|
this.channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(byte[] data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PluginMessage{" +
|
||||||
|
"channel='" + channel + '\'' +
|
||||||
|
", data=" + Arrays.toString(data) +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
||||||
this.channel = ProtocolUtils.readString(buf, 20);
|
this.channel = ProtocolUtils.readString(buf, 20);
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.velocitypowered.proxy.protocol.util;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.velocitypowered.proxy.protocol.packets.PluginMessage;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public enum PluginMessageUtil {
|
||||||
|
;
|
||||||
|
|
||||||
|
public static List<String> getChannels(PluginMessage message) {
|
||||||
|
Preconditions.checkArgument(message.getChannel().equals("REGISTER") ||
|
||||||
|
message.getChannel().equals("UNREGISTER"), "Unknown channel type " + message.getChannel());
|
||||||
|
return ImmutableList.copyOf(new String(message.getData()).split("\0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PluginMessage constructChannelsPacket(String channel, Collection<String> channels) {
|
||||||
|
PluginMessage message = new PluginMessage();
|
||||||
|
message.setChannel(channel);
|
||||||
|
message.setData(Joiner.on("\0").join(channels).getBytes(StandardCharsets.UTF_8));
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren