Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-25 15:50:19 +01:00
More proper plugin messaging support.
Dieser Commit ist enthalten in:
Ursprung
b345d3aba3
Commit
8a73e3f12b
@ -4,6 +4,7 @@ import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
|||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
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.protocol.util.PluginMessageUtil;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||||
@ -41,7 +42,16 @@ 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) {
|
||||||
playerHandler.handlePluginMessage((PluginMessage) packet, true);
|
PluginMessage pm = (PluginMessage) packet;
|
||||||
|
if (!canForwardMessage(pm)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pm.getChannel().equals("MC|Brand")) {
|
||||||
|
pm = PluginMessageUtil.rewriteMCBrand(pm);
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.getProxyPlayer().getConnection().write(pm);
|
||||||
} 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);
|
||||||
@ -57,4 +67,14 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
public void exception(Throwable throwable) {
|
public void exception(Throwable throwable) {
|
||||||
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), throwable);
|
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean canForwardMessage(PluginMessage message) {
|
||||||
|
// TODO: Update for 1.13
|
||||||
|
ClientPlaySessionHandler playerHandler =
|
||||||
|
(ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler();
|
||||||
|
return message.getChannel().startsWith("MC|") ||
|
||||||
|
message.getChannel().startsWith("FML") ||
|
||||||
|
message.getChannel().equals("FORGE") ||
|
||||||
|
playerHandler.getClientPluginMsgChannels().contains(message.getChannel());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,11 @@ 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.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.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;
|
||||||
@ -31,6 +30,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
private long lastPing = -1;
|
private long lastPing = -1;
|
||||||
private boolean spawned = false;
|
private boolean spawned = false;
|
||||||
private final List<UUID> serverBossBars = new ArrayList<>();
|
private final List<UUID> serverBossBars = new ArrayList<>();
|
||||||
|
private final Set<String> clientPluginMsgChannels = new HashSet<>();
|
||||||
|
private PluginMessage brandMessage;
|
||||||
private int currentDimension;
|
private int currentDimension;
|
||||||
|
|
||||||
public ClientPlaySessionHandler(ConnectedPlayer player) {
|
public ClientPlaySessionHandler(ConnectedPlayer player) {
|
||||||
@ -78,7 +79,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (packet instanceof PluginMessage) {
|
if (packet instanceof PluginMessage) {
|
||||||
handlePluginMessage((PluginMessage) packet, false);
|
handleClientPluginMessage((PluginMessage) packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +134,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
// Resend client settings packet to remote server if we have it, this preserves client settings across
|
// Resend client settings packet to remote server if we have it, this preserves client settings across
|
||||||
// transitions.
|
// transitions.
|
||||||
if (player.getClientSettings() != null) {
|
if (player.getClientSettings() != null) {
|
||||||
player.getConnectedServer().getChannel().write(player.getClientSettings());
|
player.getConnectedServer().getChannel().delayedWrite(player.getClientSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove old boss bars.
|
// Remove old boss bars.
|
||||||
@ -143,9 +144,22 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
deletePacket.setAction(1); // remove
|
deletePacket.setAction(1); // remove
|
||||||
player.getConnection().delayedWrite(deletePacket);
|
player.getConnection().delayedWrite(deletePacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
serverBossBars.clear();
|
serverBossBars.clear();
|
||||||
|
|
||||||
|
// Tell the server about this client's plugin messages. Velocity will forward them on to the client.
|
||||||
|
if (!clientPluginMsgChannels.isEmpty()) {
|
||||||
|
player.getConnectedServer().getChannel().delayedWrite(
|
||||||
|
PluginMessageUtil.constructChannelsPacket("REGISTER", clientPluginMsgChannels));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell the server the client's brand
|
||||||
|
if (brandMessage != null) {
|
||||||
|
player.getConnectedServer().getChannel().delayedWrite(brandMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush everything
|
||||||
player.getConnection().flush();
|
player.getConnection().flush();
|
||||||
|
player.getConnectedServer().getChannel().flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrentDimension(int currentDimension) {
|
public void setCurrentDimension(int currentDimension) {
|
||||||
@ -156,18 +170,18 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
return serverBossBars;
|
return serverBossBars;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handlePluginMessage(PluginMessage packet, boolean fromBackend) {
|
public void handleClientPluginMessage(PluginMessage packet) {
|
||||||
logger.info("Got plugin message packet {}", packet);
|
logger.info("Got client plugin message packet {}", packet);
|
||||||
|
|
||||||
// TODO: this certainly isn't the right approach, need a better way!
|
if (packet.getChannel().equals("REGISTER")) {
|
||||||
/*if (packet.getChannel().equals("REGISTER")) {
|
|
||||||
List<String> actuallyRegistered = new ArrayList<>();
|
List<String> actuallyRegistered = new ArrayList<>();
|
||||||
List<String> channels = PluginMessageUtil.getChannels(packet);
|
List<String> channels = PluginMessageUtil.getChannels(packet);
|
||||||
for (String channel : channels) {
|
for (String channel : channels) {
|
||||||
if (pluginMessageChannels.size() >= MAX_PLUGIN_CHANNELS && !pluginMessageChannels.contains(channel)) {
|
if (clientPluginMsgChannels.size() >= MAX_PLUGIN_CHANNELS &&
|
||||||
|
!clientPluginMsgChannels.contains(channel)) {
|
||||||
throw new IllegalStateException("Too many plugin message channels registered");
|
throw new IllegalStateException("Too many plugin message channels registered");
|
||||||
}
|
}
|
||||||
if (pluginMessageChannels.add(channel)) {
|
if (clientPluginMsgChannels.add(channel)) {
|
||||||
actuallyRegistered.add(channel);
|
actuallyRegistered.add(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,11 +189,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
if (actuallyRegistered.size() > 0) {
|
if (actuallyRegistered.size() > 0) {
|
||||||
logger.info("Rewritten register packet: {}", actuallyRegistered);
|
logger.info("Rewritten register packet: {}", actuallyRegistered);
|
||||||
PluginMessage newRegisterPacket = PluginMessageUtil.constructChannelsPacket("REGISTER", actuallyRegistered);
|
PluginMessage newRegisterPacket = PluginMessageUtil.constructChannelsPacket("REGISTER", actuallyRegistered);
|
||||||
if (fromBackend) {
|
player.getConnectedServer().getChannel().write(newRegisterPacket);
|
||||||
player.getConnection().write(newRegisterPacket);
|
|
||||||
} else {
|
|
||||||
player.getConnectedServer().getChannel().write(newRegisterPacket);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -187,32 +197,20 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
if (packet.getChannel().equals("UNREGISTER")) {
|
if (packet.getChannel().equals("UNREGISTER")) {
|
||||||
List<String> channels = PluginMessageUtil.getChannels(packet);
|
List<String> channels = PluginMessageUtil.getChannels(packet);
|
||||||
pluginMessageChannels.removeAll(channels);
|
clientPluginMsgChannels.removeAll(channels);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
if (packet.getChannel().equals("MC|Brand")) {
|
if (packet.getChannel().equals("MC|Brand")) {
|
||||||
// Rewrite this packet to indicate that Velocity is running. Hurrah!
|
// Rewrite this packet to indicate that Velocity is running. Hurrah!
|
||||||
ByteBuf currentBrandBuf = Unpooled.wrappedBuffer(packet.getData());
|
packet = PluginMessageUtil.rewriteMCBrand(packet);
|
||||||
|
this.brandMessage = packet;
|
||||||
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?
|
// No other special handling?
|
||||||
if (fromBackend) {
|
player.getConnectedServer().getChannel().write(packet);
|
||||||
player.getConnection().write(packet);
|
}
|
||||||
} else {
|
|
||||||
player.getConnectedServer().getChannel().write(packet);
|
public Set<String> getClientPluginMsgChannels() {
|
||||||
}
|
return clientPluginMsgChannels;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,10 @@ package com.velocitypowered.proxy.protocol.util;
|
|||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
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.Unpooled;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -24,4 +27,23 @@ public enum PluginMessageUtil {
|
|||||||
message.setData(Joiner.on("\0").join(channels).getBytes(StandardCharsets.UTF_8));
|
message.setData(Joiner.on("\0").join(channels).getBytes(StandardCharsets.UTF_8));
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PluginMessage rewriteMCBrand(PluginMessage message) {
|
||||||
|
ByteBuf currentBrandBuf = Unpooled.wrappedBuffer(message.getData());
|
||||||
|
ByteBuf rewrittenBuf = Unpooled.buffer();
|
||||||
|
byte[] rewrittenBrand;
|
||||||
|
try {
|
||||||
|
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();
|
||||||
|
newMsg.setChannel("MC|Brand");
|
||||||
|
newMsg.setData(rewrittenBrand);
|
||||||
|
return newMsg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren