geforkt von Mirrors/Velocity
Integrate BungeeQuack functionality into Velocity
Dieser Commit ist enthalten in:
Ursprung
9b570ff599
Commit
9d5930d96b
@ -31,6 +31,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
private final VelocityServerConnection serverConn;
|
||||
private final ClientPlaySessionHandler playerSessionHandler;
|
||||
private final MinecraftConnection playerConnection;
|
||||
private final BungeeCordMessageResponder bungeecordMessageResponder;
|
||||
private boolean exceptionTriggered = false;
|
||||
|
||||
BackendPlaySessionHandler(VelocityServer server, VelocityServerConnection serverConn) {
|
||||
@ -44,6 +45,9 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
"Initializing BackendPlaySessionHandler with no backing client play session handler!");
|
||||
}
|
||||
this.playerSessionHandler = (ClientPlaySessionHandler) psh;
|
||||
|
||||
this.bungeecordMessageResponder = new BungeeCordMessageResponder(server,
|
||||
serverConn.getPlayer());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -86,6 +90,10 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
@Override
|
||||
public boolean handle(PluginMessage packet) {
|
||||
if (bungeecordMessageResponder.process(packet)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!serverConn.getPlayer().canForwardPluginMessage(serverConn.ensureConnected()
|
||||
.getProtocolVersion(), packet)) {
|
||||
return true;
|
||||
|
@ -0,0 +1,325 @@
|
||||
package com.velocitypowered.proxy.connection.backend;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.ServerConnection;
|
||||
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.api.util.UuidUtils;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||
import com.velocitypowered.proxy.protocol.util.ByteBufDataInput;
|
||||
import com.velocitypowered.proxy.protocol.util.ByteBufDataOutput;
|
||||
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.stream.Collectors;
|
||||
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
class BungeeCordMessageResponder {
|
||||
|
||||
private static final MinecraftChannelIdentifier MODERN_CHANNEL = MinecraftChannelIdentifier
|
||||
.create("bungeecord", "main");
|
||||
private static final LegacyChannelIdentifier LEGACY_CHANNEL =
|
||||
new LegacyChannelIdentifier("BungeeCord");
|
||||
|
||||
private final VelocityServer proxy;
|
||||
private final ConnectedPlayer player;
|
||||
|
||||
BungeeCordMessageResponder(VelocityServer proxy, ConnectedPlayer player) {
|
||||
this.proxy = proxy;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
private void processConnect(ByteBufDataInput in) {
|
||||
String serverName = in.readUTF();
|
||||
proxy.getServer(serverName).ifPresent(server -> player.createConnectionRequest(server)
|
||||
.fireAndForget());
|
||||
}
|
||||
|
||||
private void processConnectOther(ByteBufDataInput in) {
|
||||
String playerName = in.readUTF();
|
||||
String serverName = in.readUTF();
|
||||
|
||||
proxy.getPlayer(playerName).ifPresent(player -> {
|
||||
proxy.getServer(serverName).ifPresent(server -> player.createConnectionRequest(server)
|
||||
.fireAndForget());
|
||||
});
|
||||
}
|
||||
|
||||
private void processIp(ByteBufDataInput in) {
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
ByteBufDataOutput out = new ByteBufDataOutput(buf);
|
||||
out.writeUTF("IP");
|
||||
out.writeUTF(player.getRemoteAddress().getHostString());
|
||||
out.writeInt(player.getRemoteAddress().getPort());
|
||||
sendResponse(buf);
|
||||
}
|
||||
|
||||
private void processPlayerCount(ByteBufDataInput in) {
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
ByteBufDataOutput out = new ByteBufDataOutput(buf);
|
||||
|
||||
String target = in.readUTF();
|
||||
if (target.equals("ALL")) {
|
||||
out.writeUTF("PlayerCount");
|
||||
out.writeUTF("ALL");
|
||||
out.writeInt(proxy.getPlayerCount());
|
||||
} else {
|
||||
proxy.getServer(target).ifPresent(rs -> {
|
||||
int playersOnServer = rs.getPlayersConnected().size();
|
||||
out.writeUTF("PlayerCount");
|
||||
out.writeUTF(rs.getServerInfo().getName());
|
||||
out.writeInt(playersOnServer);
|
||||
});
|
||||
}
|
||||
|
||||
if (buf.isReadable()) {
|
||||
sendResponse(buf);
|
||||
} else {
|
||||
buf.release();
|
||||
}
|
||||
}
|
||||
|
||||
private void processPlayerList(ByteBufDataInput in) {
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
ByteBufDataOutput out = new ByteBufDataOutput(buf);
|
||||
|
||||
String target = in.readUTF();
|
||||
if (target.equals("ALL")) {
|
||||
out.writeUTF("PlayerList");
|
||||
out.writeUTF("ALL");
|
||||
|
||||
StringJoiner joiner = new StringJoiner(", ");
|
||||
for (Player online : proxy.getAllPlayers()) {
|
||||
joiner.add(online.getUsername());
|
||||
}
|
||||
out.writeUTF(joiner.toString());
|
||||
} else {
|
||||
proxy.getServer(target).ifPresent(info -> {
|
||||
out.writeUTF("PlayerList");
|
||||
out.writeUTF(info.getServerInfo().getName());
|
||||
|
||||
StringJoiner joiner = new StringJoiner(", ");
|
||||
for (Player online : info.getPlayersConnected()) {
|
||||
joiner.add(online.getUsername());
|
||||
}
|
||||
out.writeUTF(joiner.toString());
|
||||
});
|
||||
}
|
||||
|
||||
if (buf.isReadable()) {
|
||||
sendResponse(buf);
|
||||
} else {
|
||||
buf.release();
|
||||
}
|
||||
}
|
||||
|
||||
private void processGetServers(ByteBufDataInput in) {
|
||||
StringJoiner joiner = new StringJoiner(", ");
|
||||
for (RegisteredServer server : proxy.getAllServers()) {
|
||||
joiner.add(server.getServerInfo().getName());
|
||||
}
|
||||
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
ByteBufDataOutput out = new ByteBufDataOutput(buf);
|
||||
out.writeUTF("GetServers");
|
||||
out.writeUTF(joiner.toString());
|
||||
|
||||
sendResponse(buf);
|
||||
}
|
||||
|
||||
private void processMessage(ByteBufDataInput in) {
|
||||
String target = in.readUTF();
|
||||
String message = in.readUTF();
|
||||
if (target.equals("ALL")) {
|
||||
for (Player player : proxy.getAllPlayers()) {
|
||||
player.sendMessage(LegacyComponentSerializer.INSTANCE.deserialize(message));
|
||||
}
|
||||
} else {
|
||||
proxy.getPlayer(target).ifPresent(player -> {
|
||||
player.sendMessage(LegacyComponentSerializer.INSTANCE.deserialize(message));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void processGetServer(ByteBufDataInput in) {
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
ByteBufDataOutput out = new ByteBufDataOutput(buf);
|
||||
|
||||
out.writeUTF("GetServer");
|
||||
out.writeUTF(player.ensureAndGetCurrentServer().getServerInfo().getName());
|
||||
|
||||
sendResponse(buf);
|
||||
}
|
||||
|
||||
private void processUuid(ByteBufDataInput in) {
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
ByteBufDataOutput out = new ByteBufDataOutput(buf);
|
||||
|
||||
out.writeUTF("UUID");
|
||||
out.writeUTF(UuidUtils.toUndashed(player.getUniqueId()));
|
||||
|
||||
sendResponse(buf);
|
||||
}
|
||||
|
||||
private void processUuidOther(ByteBufDataInput in) {
|
||||
proxy.getPlayer(in.readUTF()).ifPresent(player -> {
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
ByteBufDataOutput out = new ByteBufDataOutput(buf);
|
||||
|
||||
out.writeUTF("UUIDOther");
|
||||
out.writeUTF(player.getUsername());
|
||||
out.writeUTF(UuidUtils.toUndashed(player.getUniqueId()));
|
||||
|
||||
sendResponse(buf);
|
||||
});
|
||||
}
|
||||
|
||||
private void processServerIp(ByteBufDataInput in) {
|
||||
proxy.getServer(in.readUTF()).ifPresent(info -> {
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
ByteBufDataOutput out = new ByteBufDataOutput(buf);
|
||||
|
||||
out.writeUTF("ServerIP");
|
||||
out.writeUTF(info.getServerInfo().getName());
|
||||
out.writeUTF(info.getServerInfo().getAddress().getHostString());
|
||||
out.writeShort(info.getServerInfo().getAddress().getPort());
|
||||
|
||||
sendResponse(buf);
|
||||
});
|
||||
}
|
||||
|
||||
private void processKick(ByteBufDataInput in) {
|
||||
proxy.getPlayer(in.readUTF()).ifPresent(player -> {
|
||||
String kickReason = in.readUTF();
|
||||
player.disconnect(LegacyComponentSerializer.INSTANCE.deserialize(kickReason));
|
||||
});
|
||||
}
|
||||
|
||||
private ByteBuf prepareForwardMessage(ByteBufDataInput in) {
|
||||
String channel = in.readUTF();
|
||||
short messageLength = in.readShort();
|
||||
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
ByteBufDataOutput forwarded = new ByteBufDataOutput(buf);
|
||||
forwarded.writeUTF(channel);
|
||||
forwarded.writeShort(messageLength);
|
||||
buf.writeBytes(in.unwrap().readSlice(messageLength));
|
||||
return buf;
|
||||
}
|
||||
|
||||
private void processForwardToPlayer(ByteBufDataInput in) {
|
||||
proxy.getPlayer(in.readUTF())
|
||||
.flatMap(Player::getCurrentServer)
|
||||
.ifPresent(server -> sendResponse(player, prepareForwardMessage(in)));
|
||||
}
|
||||
|
||||
private void processForwardToServer(ByteBufDataInput in) {
|
||||
ByteBuf toForward = prepareForwardMessage(in);
|
||||
String target = in.readUTF();
|
||||
if (target.equals("ALL")) {
|
||||
ByteBuf unreleasableForward = Unpooled.unreleasableBuffer(toForward);
|
||||
try {
|
||||
for (RegisteredServer rs : proxy.getAllServers()) {
|
||||
((VelocityRegisteredServer) rs).sendPluginMessage(LEGACY_CHANNEL, unreleasableForward);
|
||||
}
|
||||
} finally {
|
||||
toForward.release();
|
||||
}
|
||||
} else {
|
||||
proxy.getServer(target).ifPresent(rs -> ((VelocityRegisteredServer) rs)
|
||||
.sendPluginMessage(LEGACY_CHANNEL, toForward));
|
||||
}
|
||||
}
|
||||
|
||||
// Note: this method will always release the buffer!
|
||||
private void sendResponse(ByteBuf buf) {
|
||||
sendResponse(this.player, buf);
|
||||
}
|
||||
|
||||
// Note: this method will always release the buffer!
|
||||
private static void sendResponse(ConnectedPlayer player, ByteBuf buf) {
|
||||
MinecraftConnection serverConnection = player.ensureAndGetCurrentServer().ensureConnected();
|
||||
String chan = serverConnection.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_13)
|
||||
>= 0 ? MODERN_CHANNEL.getId() : LEGACY_CHANNEL.getId();
|
||||
|
||||
PluginMessage msg = null;
|
||||
boolean released = false;
|
||||
|
||||
try {
|
||||
VelocityServerConnection vsc = player.getConnectedServer();
|
||||
if (vsc == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
MinecraftConnection serverConn = vsc.ensureConnected();
|
||||
msg = new PluginMessage(chan, buf);
|
||||
serverConn.write(msg);
|
||||
released = true;
|
||||
} finally {
|
||||
if (!released && msg != null) {
|
||||
msg.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean process(PluginMessage message) {
|
||||
if (!MODERN_CHANNEL.getId().equals(message.getChannel()) && !LEGACY_CHANNEL.getId()
|
||||
.equals(message.getChannel())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ByteBufDataInput in = new ByteBufDataInput(message.content());
|
||||
String subChannel = in.readUTF();
|
||||
if (subChannel.equals("ForwardToPlayer")) {
|
||||
this.processForwardToPlayer(in);
|
||||
}
|
||||
if (subChannel.equals("Forward")) {
|
||||
this.processForwardToServer(in);
|
||||
}
|
||||
if (subChannel.equals("Connect")) {
|
||||
this.processConnect(in);
|
||||
}
|
||||
if (subChannel.equals("ConnectOther")) {
|
||||
this.processConnectOther(in);
|
||||
}
|
||||
if (subChannel.equals("IP")) {
|
||||
this.processIp(in);
|
||||
}
|
||||
if (subChannel.equals("PlayerCount")) {
|
||||
this.processPlayerCount(in);
|
||||
}
|
||||
if (subChannel.equals("PlayerList")) {
|
||||
this.processPlayerList(in);
|
||||
}
|
||||
if (subChannel.equals("GetServers")) {
|
||||
this.processGetServers(in);
|
||||
}
|
||||
if (subChannel.equals("Message")) {
|
||||
this.processMessage(in);
|
||||
}
|
||||
if (subChannel.equals("GetServer")) {
|
||||
this.processGetServer(in);
|
||||
}
|
||||
if (subChannel.equals("UUID")) {
|
||||
this.processUuid(in);
|
||||
}
|
||||
if (subChannel.equals("UUIDOther")) {
|
||||
this.processUuidOther(in);
|
||||
}
|
||||
if (subChannel.equals("ServerIP")) {
|
||||
this.processServerIp(in);
|
||||
}
|
||||
if (subChannel.equals("KickPlayer")) {
|
||||
this.processKick(in);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -34,6 +34,7 @@ import com.velocitypowered.proxy.protocol.packet.Handshake;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLogin;
|
||||
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
@ -210,12 +211,16 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
||||
|
||||
@Override
|
||||
public boolean sendPluginMessage(ChannelIdentifier identifier, byte[] data) {
|
||||
return sendPluginMessage(identifier, Unpooled.wrappedBuffer(data));
|
||||
}
|
||||
|
||||
public boolean sendPluginMessage(ChannelIdentifier identifier, ByteBuf data) {
|
||||
Preconditions.checkNotNull(identifier, "identifier");
|
||||
Preconditions.checkNotNull(data, "data");
|
||||
|
||||
MinecraftConnection mc = ensureConnected();
|
||||
|
||||
PluginMessage message = new PluginMessage(identifier.getId(), Unpooled.wrappedBuffer(data));
|
||||
PluginMessage message = new PluginMessage(identifier.getId(), data);
|
||||
mc.write(message);
|
||||
return true;
|
||||
}
|
||||
|
@ -135,6 +135,14 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
return Optional.ofNullable(connectedServer);
|
||||
}
|
||||
|
||||
public VelocityServerConnection ensureAndGetCurrentServer() {
|
||||
VelocityServerConnection con = this.connectedServer;
|
||||
if (con == null) {
|
||||
throw new IllegalStateException("Not connected to server!");
|
||||
}
|
||||
return con;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameProfile getGameProfile() {
|
||||
return profile;
|
||||
|
@ -0,0 +1,110 @@
|
||||
package com.velocitypowered.proxy.protocol.util;
|
||||
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A wrapper around {@link io.netty.buffer.ByteBuf} that implements the exception-free
|
||||
* {@link ByteArrayDataInput} interface from Guava.
|
||||
*/
|
||||
public class ByteBufDataInput implements ByteArrayDataInput, DataInput {
|
||||
|
||||
private final ByteBuf in;
|
||||
|
||||
/**
|
||||
* Creates a new ByteBufDataInput instance. The ByteBufDataInput simply "borrows" the ByteBuf
|
||||
* while it is in use.
|
||||
*
|
||||
* @param buf the buffer to read from
|
||||
*/
|
||||
public ByteBufDataInput(ByteBuf buf) {
|
||||
this.in = buf;
|
||||
}
|
||||
|
||||
public ByteBuf unwrap() {
|
||||
return in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFully(byte[] b) {
|
||||
in.readBytes(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFully(byte[] b, int off, int len) {
|
||||
in.readBytes(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int skipBytes(int n) {
|
||||
in.skipBytes(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean readBoolean() {
|
||||
return in.readBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte() {
|
||||
return in.readByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUnsignedByte() {
|
||||
return in.readUnsignedByte() & 0xFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShort() {
|
||||
return in.readShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUnsignedShort() {
|
||||
return in.readUnsignedShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char readChar() {
|
||||
return in.readChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInt() {
|
||||
return in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readLong() {
|
||||
return in.readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float readFloat() {
|
||||
return in.readFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double readDouble() {
|
||||
return in.readDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readLine() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readUTF() {
|
||||
try {
|
||||
return DataInputStream.readUTF(this);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package com.velocitypowered.proxy.protocol.util;
|
||||
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* A {@link DataOutput} equivalent to {@link ByteBufDataInput}.
|
||||
*/
|
||||
public class ByteBufDataOutput extends OutputStream implements DataOutput, ByteArrayDataOutput {
|
||||
|
||||
private final ByteBuf buf;
|
||||
private final DataOutputStream utf8out;
|
||||
|
||||
public ByteBufDataOutput(ByteBuf buf) {
|
||||
this.buf = buf;
|
||||
this.utf8out = new DataOutputStream(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toByteArray() {
|
||||
return ByteBufUtil.getBytes(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) {
|
||||
buf.writeByte(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b) {
|
||||
buf.writeBytes(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) {
|
||||
buf.writeBytes(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBoolean(boolean v) {
|
||||
buf.writeBoolean(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(int v) {
|
||||
buf.writeByte(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeShort(int v) {
|
||||
buf.writeShort(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChar(int v) {
|
||||
buf.writeChar(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInt(int v) {
|
||||
buf.writeInt(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLong(long v) {
|
||||
buf.writeLong(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFloat(float v) {
|
||||
buf.writeFloat(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDouble(double v) {
|
||||
buf.writeDouble(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(String s) {
|
||||
buf.writeCharSequence(s, StandardCharsets.US_ASCII);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChars(String s) {
|
||||
for (char c : s.toCharArray()) {
|
||||
buf.writeChar(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeUTF(String s) {
|
||||
try {
|
||||
this.utf8out.writeUTF(s);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,12 +18,16 @@ import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintFrameDecoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintLengthEncoder;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
@ -119,8 +123,12 @@ public class VelocityRegisteredServer implements RegisteredServer {
|
||||
|
||||
@Override
|
||||
public boolean sendPluginMessage(ChannelIdentifier identifier, byte[] data) {
|
||||
return sendPluginMessage(identifier, Unpooled.wrappedBuffer(data));
|
||||
}
|
||||
|
||||
public boolean sendPluginMessage(ChannelIdentifier identifier, ByteBuf data) {
|
||||
for (ConnectedPlayer player : players) {
|
||||
ServerConnection connection = player.getConnectedServer();
|
||||
VelocityServerConnection connection = player.getConnectedServer();
|
||||
if (connection != null && connection.getServerInfo().equals(serverInfo)) {
|
||||
return connection.sendPluginMessage(identifier, data);
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren