Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-23 23:00:35 +01:00
Implement bungee-style IP forwarding.
Dieser Commit ist enthalten in:
Ursprung
302df0299e
Commit
76e7ac5afc
@ -8,6 +8,7 @@ import com.velocitypowered.proxy.data.ServerInfo;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftPipelineUtils;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.util.UuidUtils;
|
||||
import io.netty.channel.*;
|
||||
|
||||
public class ServerConnection {
|
||||
@ -51,12 +52,23 @@ public class ServerConnection {
|
||||
});
|
||||
}
|
||||
|
||||
private String createBungeeForwardingAddress() {
|
||||
// BungeeCord IP forwarding is simply a special injection after the "address" in the handshake,
|
||||
// separated by \0 (the null byte). In order, you send the original host, the player's IP, their
|
||||
// UUID (undashed), and if you are in online-mode, their login properties (retrieved from Mojang).
|
||||
//
|
||||
// Velocity doesn't yet support online-mode, unfortunately. That will come soon.
|
||||
return serverInfo.getAddress().getHostString() + "\0" +
|
||||
proxyPlayer.getRemoteAddress().getHostString() + "\0" +
|
||||
UuidUtils.toUndashed(proxyPlayer.getUniqueId());
|
||||
}
|
||||
|
||||
private void startHandshake() {
|
||||
// Initiate a handshake.
|
||||
Handshake handshake = new Handshake();
|
||||
handshake.setNextStatus(2); // login
|
||||
handshake.setProtocolVersion(proxyPlayer.getConnection().getProtocolVersion());
|
||||
handshake.setServerAddress(serverInfo.getAddress().getHostString());
|
||||
handshake.setServerAddress(createBungeeForwardingAddress());
|
||||
handshake.setPort(serverInfo.getAddress().getPort());
|
||||
channel.write(handshake);
|
||||
|
||||
|
@ -10,6 +10,7 @@ import net.kyori.text.TextComponent;
|
||||
import net.kyori.text.format.TextColor;
|
||||
import net.kyori.text.serializer.ComponentSerializers;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ConnectedPlayer {
|
||||
@ -36,6 +37,10 @@ public class ConnectedPlayer {
|
||||
return connection;
|
||||
}
|
||||
|
||||
public InetSocketAddress getRemoteAddress() {
|
||||
return (InetSocketAddress) connection.getChannel().remoteAddress();
|
||||
}
|
||||
|
||||
public ServerConnection getConnectedServer() {
|
||||
return connectedServer;
|
||||
}
|
||||
@ -57,9 +62,7 @@ public class ConnectedPlayer {
|
||||
// The player isn't yet connected to a server - we should disconnect them.
|
||||
connection.closeWith(Disconnect.create(component));
|
||||
} else {
|
||||
Chat chat = new Chat();
|
||||
chat.setMessage(ComponentSerializers.JSON.serialize(component));
|
||||
connection.write(chat);
|
||||
connection.write(Chat.create(component));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,25 @@
|
||||
package com.velocitypowered.proxy.protocol.packets;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.kyori.text.TextComponent;
|
||||
import net.kyori.text.serializer.ComponentSerializers;
|
||||
|
||||
public class Chat implements MinecraftPacket {
|
||||
private String message;
|
||||
private byte position;
|
||||
|
||||
public Chat() {
|
||||
}
|
||||
|
||||
public Chat(String message, byte position) {
|
||||
this.message = message;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
@ -48,4 +59,13 @@ public class Chat implements MinecraftPacket {
|
||||
buf.writeByte(position);
|
||||
}
|
||||
}
|
||||
|
||||
public static Chat create(TextComponent component) {
|
||||
return create(component, (byte) 0);
|
||||
}
|
||||
|
||||
public static Chat create(TextComponent component, byte pos) {
|
||||
Preconditions.checkNotNull(component, "component");
|
||||
return new Chat(ComponentSerializers.JSON.serialize(component), pos);
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,11 @@ public enum UuidUtils {
|
||||
);
|
||||
}
|
||||
|
||||
public static String toUndashed(final UUID uuid) {
|
||||
Preconditions.checkNotNull(uuid, "uuid");
|
||||
return Long.toUnsignedString(uuid.getMostSignificantBits(), 16) + Long.toUnsignedString(uuid.getLeastSignificantBits(), 16);
|
||||
}
|
||||
|
||||
public static UUID generateOfflinePlayerUuid(String username) {
|
||||
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
@ -14,12 +14,17 @@ class UuidUtilsTest {
|
||||
private static final String TEST_OFFLINE_PLAYER = "tuxed";
|
||||
|
||||
@Test
|
||||
void testFromUndashed() {
|
||||
void generateOfflinePlayerUuid() {
|
||||
assertEquals(TEST_OFFLINE_PLAYER_UUID, UuidUtils.generateOfflinePlayerUuid(TEST_OFFLINE_PLAYER), "UUIDs do not match");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromUndashed() {
|
||||
assertEquals(EXPECTED_DASHED_UUID, UuidUtils.fromUndashed(ACTUAL_UNDASHED_UUID), "UUIDs do not match");
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateOfflinePlayerUuid() {
|
||||
assertEquals(TEST_OFFLINE_PLAYER_UUID, UuidUtils.generateOfflinePlayerUuid(TEST_OFFLINE_PLAYER), "UUIDs do not match");
|
||||
void toUndashed() {
|
||||
assertEquals(ACTUAL_UNDASHED_UUID, UuidUtils.toUndashed(EXPECTED_DASHED_UUID), "UUIDs do not match");
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren