Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-17 05:20:14 +01:00
First attempt at getting Forge working nicely with Velocity.
Dieser Commit ist enthalten in:
Ursprung
5a424f5cbb
Commit
9888f6f6f0
@ -57,7 +57,7 @@ public final class GameProfile {
|
|||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class Property {
|
public final static class Property {
|
||||||
private final String name;
|
private final String name;
|
||||||
private final String value;
|
private final String value;
|
||||||
private final String signature;
|
private final String signature;
|
||||||
|
@ -45,6 +45,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
private MinecraftSessionHandler sessionHandler;
|
private MinecraftSessionHandler sessionHandler;
|
||||||
private int protocolVersion;
|
private int protocolVersion;
|
||||||
private MinecraftConnectionAssociation association;
|
private MinecraftConnectionAssociation association;
|
||||||
|
private boolean isLegacyForge;
|
||||||
private final VelocityServer server;
|
private final VelocityServer server;
|
||||||
|
|
||||||
public MinecraftConnection(Channel channel, VelocityServer server) {
|
public MinecraftConnection(Channel channel, VelocityServer server) {
|
||||||
@ -222,4 +223,12 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
public void setAssociation(MinecraftConnectionAssociation association) {
|
public void setAssociation(MinecraftConnectionAssociation association) {
|
||||||
this.association = association;
|
this.association = association;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isLegacyForge() {
|
||||||
|
return isLegacyForge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLegacyForge(boolean isForge) {
|
||||||
|
this.isLegacyForge = isForge;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,4 +6,8 @@ public class VelocityConstants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final String VELOCITY_IP_FORWARDING_CHANNEL = "velocity:player_info";
|
public static final String VELOCITY_IP_FORWARDING_CHANNEL = "velocity:player_info";
|
||||||
|
|
||||||
|
public static final String FORGE_LEGACY_HANDSHAKE_CHANNEL = "FML|HS";
|
||||||
|
|
||||||
|
public static final byte[] FORGE_LEGACY_HANDSHAKE_RESET_DATA = new byte[] { -2, 0 };
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
|||||||
import com.velocitypowered.api.proxy.messages.ChannelSide;
|
import com.velocitypowered.api.proxy.messages.ChannelSide;
|
||||||
import com.velocitypowered.api.proxy.messages.MessageHandler;
|
import com.velocitypowered.api.proxy.messages.MessageHandler;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
|
import com.velocitypowered.proxy.connection.VelocityConstants;
|
||||||
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||||
@ -46,6 +47,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
connection.getPlayer().handleConnectionException(connection.getServerInfo(), original);
|
connection.getPlayer().handleConnectionException(connection.getServerInfo(), original);
|
||||||
} else if (packet instanceof JoinGame) {
|
} else if (packet instanceof JoinGame) {
|
||||||
playerHandler.handleBackendJoinGame((JoinGame) packet);
|
playerHandler.handleBackendJoinGame((JoinGame) packet);
|
||||||
|
connection.setHasCompletedJoin(true);
|
||||||
} else if (packet instanceof BossBar) {
|
} else if (packet instanceof BossBar) {
|
||||||
BossBar bossBar = (BossBar) packet;
|
BossBar bossBar = (BossBar) packet;
|
||||||
switch (bossBar.getAction()) {
|
switch (bossBar.getAction()) {
|
||||||
@ -68,6 +70,19 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!connection.hasCompletedJoin() && pm.getChannel().equals(VelocityConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL)) {
|
||||||
|
if (!connection.isModded()) {
|
||||||
|
connection.setModded(true);
|
||||||
|
|
||||||
|
// We must always reset the handshake before a modded connection is established.
|
||||||
|
connection.getPlayer().sendLegacyForgeHandshakeResetPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always forward these messages during login
|
||||||
|
connection.getPlayer().getConnection().write(pm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MessageHandler.ForwardStatus status = server.getChannelRegistrar().handlePluginMessage(connection,
|
MessageHandler.ForwardStatus status = server.getChannelRegistrar().handlePluginMessage(connection,
|
||||||
ChannelSide.FROM_SERVER, pm);
|
ChannelSide.FROM_SERVER, pm);
|
||||||
if (status == MessageHandler.ForwardStatus.FORWARD) {
|
if (status == MessageHandler.ForwardStatus.FORWARD) {
|
||||||
|
@ -84,6 +84,10 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
connection.getPlayer().getConnection().setSessionHandler(new ClientPlaySessionHandler(server, connection.getPlayer()));
|
connection.getPlayer().getConnection().setSessionHandler(new ClientPlaySessionHandler(server, connection.getPlayer()));
|
||||||
} else {
|
} else {
|
||||||
// The previous server connection should become obsolete.
|
// The previous server connection should become obsolete.
|
||||||
|
// Before we remove it, if the server we are departing is modded, we must always reset the client state.
|
||||||
|
if (existingConnection.isModded()) {
|
||||||
|
connection.getPlayer().sendLegacyForgeHandshakeResetPacket();
|
||||||
|
}
|
||||||
existingConnection.disconnect();
|
existingConnection.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,8 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
|||||||
private final ConnectedPlayer proxyPlayer;
|
private final ConnectedPlayer proxyPlayer;
|
||||||
private final VelocityServer server;
|
private final VelocityServer server;
|
||||||
private MinecraftConnection minecraftConnection;
|
private MinecraftConnection minecraftConnection;
|
||||||
|
private boolean isModded = false;
|
||||||
|
private boolean hasCompletedJoin = false;
|
||||||
|
|
||||||
public VelocityServerConnection(ServerInfo target, ConnectedPlayer proxyPlayer, VelocityServer server) {
|
public VelocityServerConnection(ServerInfo target, ConnectedPlayer proxyPlayer, VelocityServer server) {
|
||||||
this.serverInfo = target;
|
this.serverInfo = target;
|
||||||
@ -154,4 +156,20 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
|||||||
message.setData(data);
|
message.setData(data);
|
||||||
minecraftConnection.write(message);
|
minecraftConnection.write(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isModded() {
|
||||||
|
return isModded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModded(boolean modded) {
|
||||||
|
isModded = modded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasCompletedJoin() {
|
||||||
|
return hasCompletedJoin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHasCompletedJoin(boolean hasCompletedJoin) {
|
||||||
|
this.hasCompletedJoin = hasCompletedJoin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,6 +235,12 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player.getConnectedServer().isModded() && !player.getConnectedServer().hasCompletedJoin()) {
|
||||||
|
// Ensure that the messages are forwarded
|
||||||
|
player.getConnectedServer().getMinecraftConnection().write(packet);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MessageHandler.ForwardStatus status = server.getChannelRegistrar().handlePluginMessage(player,
|
MessageHandler.ForwardStatus status = server.getChannelRegistrar().handlePluginMessage(player,
|
||||||
ChannelSide.FROM_CLIENT, packet);
|
ChannelSide.FROM_CLIENT, packet);
|
||||||
if (status == MessageHandler.ForwardStatus.FORWARD) {
|
if (status == MessageHandler.ForwardStatus.FORWARD) {
|
||||||
|
@ -15,6 +15,7 @@ import com.velocitypowered.api.util.MessagePosition;
|
|||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
|
import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
|
||||||
|
import com.velocitypowered.proxy.connection.VelocityConstants;
|
||||||
import com.velocitypowered.proxy.connection.util.ConnectionMessages;
|
import com.velocitypowered.proxy.connection.util.ConnectionMessages;
|
||||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
|
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
|
||||||
import com.velocitypowered.api.util.GameProfile;
|
import com.velocitypowered.api.util.GameProfile;
|
||||||
@ -294,6 +295,13 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
this.connectedServer = serverConnection;
|
this.connectedServer = serverConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendLegacyForgeHandshakeResetPacket() {
|
||||||
|
PluginMessage resetPacket = new PluginMessage();
|
||||||
|
resetPacket.setChannel(VelocityConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL);
|
||||||
|
resetPacket.setData(VelocityConstants.FORGE_LEGACY_HANDSHAKE_RESET_DATA);
|
||||||
|
connection.write(resetPacket);
|
||||||
|
}
|
||||||
|
|
||||||
public void close(TextComponent reason) {
|
public void close(TextComponent reason) {
|
||||||
connection.closeWith(Disconnect.create(reason));
|
connection.closeWith(Disconnect.create(reason));
|
||||||
}
|
}
|
||||||
|
@ -70,9 +70,12 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure legacy forwarding is not in use on this connection. Make sure that we do _not_ reject Forge,
|
// Determine if we're using Forge (1.8 to 1.12, may not be the case in 1.13) and store that in the connection
|
||||||
// although Velocity does not yet support Forge.
|
boolean isForge = handshake.getServerAddress().endsWith("\0FML\0");
|
||||||
if (handshake.getServerAddress().contains("\0") && !handshake.getServerAddress().endsWith("\0FML\0")) {
|
connection.setLegacyForge(isForge);
|
||||||
|
|
||||||
|
// Make sure legacy forwarding is not in use on this connection. Make sure that we do _not_ reject Forge
|
||||||
|
if (handshake.getServerAddress().contains("\0") && !isForge) {
|
||||||
connection.closeWith(Disconnect.create(TextComponent.of("Running Velocity behind Velocity is unsupported.")));
|
connection.closeWith(Disconnect.create(TextComponent.of("Running Velocity behind Velocity is unsupported.")));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import com.velocitypowered.api.event.permission.PermissionsSetupEvent;
|
|||||||
import com.velocitypowered.api.event.player.GameProfileRequestEvent;
|
import com.velocitypowered.api.event.player.GameProfileRequestEvent;
|
||||||
import com.velocitypowered.api.proxy.InboundConnection;
|
import com.velocitypowered.api.proxy.InboundConnection;
|
||||||
import com.velocitypowered.api.proxy.server.ServerInfo;
|
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||||
|
import com.velocitypowered.proxy.config.PlayerInfoForwarding;
|
||||||
import com.velocitypowered.proxy.connection.VelocityConstants;
|
import com.velocitypowered.proxy.connection.VelocityConstants;
|
||||||
import com.velocitypowered.api.util.GameProfile;
|
import com.velocitypowered.api.util.GameProfile;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
@ -31,7 +32,9 @@ import java.net.MalformedURLException;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
@ -176,6 +179,12 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initializePlayer(GameProfile profile, boolean onlineMode) {
|
private void initializePlayer(GameProfile profile, boolean onlineMode) {
|
||||||
|
if (inbound.isLegacyForge() && server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.LEGACY) {
|
||||||
|
// We want to add the FML token to the properties
|
||||||
|
List<GameProfile.Property> properties = new ArrayList<>(profile.getProperties());
|
||||||
|
properties.add(new GameProfile.Property("forgeClient", "true", ""));
|
||||||
|
profile = new GameProfile(profile.getId(), profile.getName(), properties);
|
||||||
|
}
|
||||||
GameProfileRequestEvent profileRequestEvent = new GameProfileRequestEvent(apiInbound, profile, onlineMode);
|
GameProfileRequestEvent profileRequestEvent = new GameProfileRequestEvent(apiInbound, profile, onlineMode);
|
||||||
|
|
||||||
server.getEventManager().fire(profileRequestEvent).thenCompose(profileEvent -> {
|
server.getEventManager().fire(profileRequestEvent).thenCompose(profileEvent -> {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren