Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-26 08:10:14 +01:00
More efficient message handling
Dieser Commit ist enthalten in:
Ursprung
8a73e3f12b
Commit
dde6560a5a
@ -6,6 +6,7 @@ import com.velocitypowered.proxy.protocol.packets.*;
|
|||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.util.ReferenceCountUtil;
|
||||||
|
|
||||||
public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||||
private final ServerConnection connection;
|
private final ServerConnection connection;
|
||||||
@ -43,15 +44,20 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
connection.getProxyPlayer().getConnection().write(packet);
|
connection.getProxyPlayer().getConnection().write(packet);
|
||||||
} else if (packet instanceof PluginMessage) {
|
} else if (packet instanceof PluginMessage) {
|
||||||
PluginMessage pm = (PluginMessage) packet;
|
PluginMessage pm = (PluginMessage) packet;
|
||||||
if (!canForwardMessage(pm)) {
|
try {
|
||||||
return;
|
PluginMessage newPacket = pm;
|
||||||
}
|
if (!canForwardMessage(newPacket)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (pm.getChannel().equals("MC|Brand")) {
|
if (newPacket.getChannel().equals("MC|Brand")) {
|
||||||
pm = PluginMessageUtil.rewriteMCBrand(pm);
|
newPacket = PluginMessageUtil.rewriteMCBrand(pm);
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.getProxyPlayer().getConnection().write(pm);
|
connection.getProxyPlayer().getConnection().write(newPacket);
|
||||||
|
} finally {
|
||||||
|
ReferenceCountUtil.release(pm.getData());
|
||||||
|
}
|
||||||
} 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);
|
||||||
|
@ -10,6 +10,7 @@ import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
|||||||
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.channel.EventLoop;
|
import io.netty.channel.EventLoop;
|
||||||
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import net.kyori.text.TextComponent;
|
import net.kyori.text.TextComponent;
|
||||||
import net.kyori.text.format.TextColor;
|
import net.kyori.text.format.TextColor;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
@ -173,41 +174,46 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
public void handleClientPluginMessage(PluginMessage packet) {
|
public void handleClientPluginMessage(PluginMessage packet) {
|
||||||
logger.info("Got client plugin message packet {}", packet);
|
logger.info("Got client plugin message packet {}", packet);
|
||||||
|
|
||||||
if (packet.getChannel().equals("REGISTER")) {
|
PluginMessage original = packet;
|
||||||
List<String> actuallyRegistered = new ArrayList<>();
|
try {
|
||||||
List<String> channels = PluginMessageUtil.getChannels(packet);
|
if (packet.getChannel().equals("REGISTER")) {
|
||||||
for (String channel : channels) {
|
List<String> actuallyRegistered = new ArrayList<>();
|
||||||
if (clientPluginMsgChannels.size() >= MAX_PLUGIN_CHANNELS &&
|
List<String> channels = PluginMessageUtil.getChannels(packet);
|
||||||
!clientPluginMsgChannels.contains(channel)) {
|
for (String channel : channels) {
|
||||||
throw new IllegalStateException("Too many plugin message channels registered");
|
if (clientPluginMsgChannels.size() >= MAX_PLUGIN_CHANNELS &&
|
||||||
|
!clientPluginMsgChannels.contains(channel)) {
|
||||||
|
throw new IllegalStateException("Too many plugin message channels registered");
|
||||||
|
}
|
||||||
|
if (clientPluginMsgChannels.add(channel)) {
|
||||||
|
actuallyRegistered.add(channel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (clientPluginMsgChannels.add(channel)) {
|
|
||||||
actuallyRegistered.add(channel);
|
if (actuallyRegistered.size() > 0) {
|
||||||
|
logger.info("Rewritten register packet: {}", actuallyRegistered);
|
||||||
|
PluginMessage newRegisterPacket = PluginMessageUtil.constructChannelsPacket("REGISTER", actuallyRegistered);
|
||||||
|
player.getConnectedServer().getChannel().write(newRegisterPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actuallyRegistered.size() > 0) {
|
if (packet.getChannel().equals("UNREGISTER")) {
|
||||||
logger.info("Rewritten register packet: {}", actuallyRegistered);
|
List<String> channels = PluginMessageUtil.getChannels(packet);
|
||||||
PluginMessage newRegisterPacket = PluginMessageUtil.constructChannelsPacket("REGISTER", actuallyRegistered);
|
clientPluginMsgChannels.removeAll(channels);
|
||||||
player.getConnectedServer().getChannel().write(newRegisterPacket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
if (packet.getChannel().equals("MC|Brand")) {
|
||||||
}
|
// Rewrite this packet to indicate that Velocity is running. Hurrah!
|
||||||
|
packet = PluginMessageUtil.rewriteMCBrand(packet);
|
||||||
|
this.brandMessage = packet;
|
||||||
|
}
|
||||||
|
|
||||||
if (packet.getChannel().equals("UNREGISTER")) {
|
// No other special handling?
|
||||||
List<String> channels = PluginMessageUtil.getChannels(packet);
|
player.getConnectedServer().getChannel().write(packet);
|
||||||
clientPluginMsgChannels.removeAll(channels);
|
} finally {
|
||||||
|
ReferenceCountUtil.release(original.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet.getChannel().equals("MC|Brand")) {
|
|
||||||
// Rewrite this packet to indicate that Velocity is running. Hurrah!
|
|
||||||
packet = PluginMessageUtil.rewriteMCBrand(packet);
|
|
||||||
this.brandMessage = packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No other special handling?
|
|
||||||
player.getConnectedServer().getChannel().write(packet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getClientPluginMsgChannels() {
|
public Set<String> getClientPluginMsgChannels() {
|
||||||
|
@ -2,6 +2,7 @@ package com.velocitypowered.proxy.protocol;
|
|||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufUtil;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -40,15 +41,15 @@ public enum ProtocolUtils { ;
|
|||||||
public static String readString(ByteBuf buf, int cap) {
|
public static String readString(ByteBuf buf, int cap) {
|
||||||
int length = readVarInt(buf);
|
int length = readVarInt(buf);
|
||||||
Preconditions.checkArgument(length <= cap, "Bad string size (got %s, maximum is %s)", length, cap);
|
Preconditions.checkArgument(length <= cap, "Bad string size (got %s, maximum is %s)", length, cap);
|
||||||
byte[] str = new byte[length];
|
String str = buf.toString(buf.readerIndex(), length, StandardCharsets.UTF_8);
|
||||||
buf.readBytes(str);
|
buf.skipBytes(length);
|
||||||
return new String(str, StandardCharsets.UTF_8);
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeString(ByteBuf buf, String str) {
|
public static void writeString(ByteBuf buf, String str) {
|
||||||
byte[] asUtf8 = str.getBytes(StandardCharsets.UTF_8);
|
int size = ByteBufUtil.utf8Bytes(str);
|
||||||
writeVarInt(buf, asUtf8.length);
|
writeVarInt(buf, size);
|
||||||
buf.writeBytes(asUtf8);
|
ByteBufUtil.writeUtf8(buf, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] readByteArray(ByteBuf buf) {
|
public static byte[] readByteArray(ByteBuf buf) {
|
||||||
|
@ -4,12 +4,13 @@ import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
|||||||
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
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 io.netty.buffer.ByteBufUtil;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class PluginMessage implements MinecraftPacket {
|
public class PluginMessage implements MinecraftPacket {
|
||||||
private String channel;
|
private String channel;
|
||||||
private byte[] data;
|
private ByteBuf data;
|
||||||
|
|
||||||
public String getChannel() {
|
public String getChannel() {
|
||||||
return channel;
|
return channel;
|
||||||
@ -19,11 +20,11 @@ public class PluginMessage implements MinecraftPacket {
|
|||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getData() {
|
public ByteBuf getData() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setData(byte[] data) {
|
public void setData(ByteBuf data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,15 +32,14 @@ public class PluginMessage implements MinecraftPacket {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "PluginMessage{" +
|
return "PluginMessage{" +
|
||||||
"channel='" + channel + '\'' +
|
"channel='" + channel + '\'' +
|
||||||
", data=" + Arrays.toString(data) +
|
", data=" + ByteBufUtil.hexDump(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);
|
||||||
this.data = new byte[buf.readableBytes()];
|
this.data = buf.readRetainedSlice(buf.readableBytes());
|
||||||
buf.readBytes(this.data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,6 +6,7 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.packets.PluginMessage;
|
import com.velocitypowered.proxy.protocol.packets.PluginMessage;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufUtil;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@ -18,32 +19,33 @@ public enum PluginMessageUtil {
|
|||||||
public static List<String> getChannels(PluginMessage message) {
|
public static List<String> getChannels(PluginMessage message) {
|
||||||
Preconditions.checkArgument(message.getChannel().equals("REGISTER") ||
|
Preconditions.checkArgument(message.getChannel().equals("REGISTER") ||
|
||||||
message.getChannel().equals("UNREGISTER"), "Unknown channel type " + message.getChannel());
|
message.getChannel().equals("UNREGISTER"), "Unknown channel type " + message.getChannel());
|
||||||
return ImmutableList.copyOf(new String(message.getData()).split("\0"));
|
String channels = message.getData().toString(StandardCharsets.UTF_8);
|
||||||
|
return ImmutableList.copyOf(channels.split("\0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PluginMessage constructChannelsPacket(String channel, Collection<String> channels) {
|
public static PluginMessage constructChannelsPacket(String channel, Collection<String> channels) {
|
||||||
PluginMessage message = new PluginMessage();
|
PluginMessage message = new PluginMessage();
|
||||||
message.setChannel(channel);
|
message.setChannel(channel);
|
||||||
message.setData(Joiner.on("\0").join(channels).getBytes(StandardCharsets.UTF_8));
|
|
||||||
|
ByteBuf data = Unpooled.buffer();
|
||||||
|
for (String s : channels) {
|
||||||
|
ByteBufUtil.writeUtf8(data, s);
|
||||||
|
data.writeByte(0);
|
||||||
|
}
|
||||||
|
data.writerIndex(data.writerIndex() - 1);
|
||||||
|
|
||||||
|
message.setData(data);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PluginMessage rewriteMCBrand(PluginMessage message) {
|
public static PluginMessage rewriteMCBrand(PluginMessage message) {
|
||||||
ByteBuf currentBrandBuf = Unpooled.wrappedBuffer(message.getData());
|
|
||||||
ByteBuf rewrittenBuf = Unpooled.buffer();
|
ByteBuf rewrittenBuf = Unpooled.buffer();
|
||||||
byte[] rewrittenBrand;
|
String currentBrand = ProtocolUtils.readString(message.getData());
|
||||||
try {
|
ProtocolUtils.writeString(rewrittenBuf, currentBrand + " (Velocity)");
|
||||||
String currentBrand = ProtocolUtils.readString(currentBrandBuf);
|
|
||||||
ProtocolUtils.writeString(rewrittenBuf, currentBrand + " (Velocity)");
|
|
||||||
rewrittenBrand = new byte[rewrittenBuf.readableBytes()];
|
|
||||||
rewrittenBuf.readBytes(rewrittenBrand);
|
|
||||||
} finally {
|
|
||||||
rewrittenBuf.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
PluginMessage newMsg = new PluginMessage();
|
PluginMessage newMsg = new PluginMessage();
|
||||||
newMsg.setChannel("MC|Brand");
|
newMsg.setChannel("MC|Brand");
|
||||||
newMsg.setData(rewrittenBrand);
|
newMsg.setData(rewrittenBuf);
|
||||||
return newMsg;
|
return newMsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren