#3602: Minecraft 24w04a support

This commit is contained in:
Outfluencer
2024-01-30 06:55:58 +11:00
committed by md_5
parent c69acf728c
commit 02c5c1ee76
21 changed files with 501 additions and 38 deletions

View File

@@ -73,7 +73,8 @@ public class EncryptionUtil
byte[] pubKey = keys.getPublic().getEncoded();
byte[] verify = new byte[ 4 ];
random.nextBytes( verify );
return new EncryptionRequest( hash, pubKey, verify );
// always auth for now
return new EncryptionRequest( hash, pubKey, verify, true );
}
public static boolean check(PlayerPublicKey publicKey, UUID uuid) throws GeneralSecurityException

View File

@@ -243,7 +243,7 @@ public class ServerConnector extends PacketHandler
// Set tab list size, TODO: what shall we do about packet mutability
Login modLogin = new Login( login.getEntityId(), login.isHardcore(), login.getGameMode(), login.getPreviousGameMode(), login.getWorldNames(), login.getDimensions(), login.getDimension(), login.getWorldName(), login.getSeed(), login.getDifficulty(),
(byte) user.getPendingConnection().getListener().getTabListSize(), login.getLevelType(), login.getViewDistance(), login.getSimulationDistance(), login.isReducedDebugInfo(), login.isNormalRespawn(), login.isLimitedCrafting(), login.isDebug(), login.isFlat(), login.getDeathLocation(),
login.getPortalCooldown() );
login.getPortalCooldown(), login.isSecureProfile() );
user.unsafe().sendPacket( modLogin );

View File

@@ -20,6 +20,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import lombok.Getter;
@@ -60,7 +61,9 @@ import net.md_5.bungee.protocol.packet.Kick;
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
import net.md_5.bungee.protocol.packet.PluginMessage;
import net.md_5.bungee.protocol.packet.SetCompression;
import net.md_5.bungee.protocol.packet.StoreCookie;
import net.md_5.bungee.protocol.packet.SystemChat;
import net.md_5.bungee.protocol.packet.Transfer;
import net.md_5.bungee.tab.ServerUnique;
import net.md_5.bungee.tab.TabList;
import net.md_5.bungee.util.CaseInsensitiveSet;
@@ -771,4 +774,26 @@ public final class UserConnection implements ProxiedPlayer
{
return serverSentScoreboard;
}
@Override
public CompletableFuture<byte[]> retrieveCookie(String cookie)
{
return pendingConnection.retrieveCookie( cookie );
}
@Override
public void storeCookie(String cookie, byte[] data)
{
Preconditions.checkState( getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_20_5, "Cookies are only supported in 1.20.5 and above" );
unsafe().sendPacket( new StoreCookie( cookie, data ) );
}
@Override
public void transfer(String host, int port)
{
Preconditions.checkState( getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_20_5, "Transfers are only supported in 1.20.5 and above" );
unsafe().sendPacket( new Transfer( host, port ) );
}
}

View File

@@ -68,6 +68,7 @@ public class Configuration implements ProxyConfig
private int compressionThreshold = 256;
private boolean preventProxyConnections;
private boolean forgeSupport;
private boolean rejectTransfers;
public void load()
{
@@ -103,6 +104,7 @@ public class Configuration implements ProxyConfig
compressionThreshold = adapter.getInt( "network_compression_threshold", compressionThreshold );
preventProxyConnections = adapter.getBoolean( "prevent_proxy_connections", preventProxyConnections );
forgeSupport = adapter.getBoolean( "forge_support", forgeSupport );
rejectTransfers = adapter.getBoolean( "reject_transfers", rejectTransfers );
disabledCommands = new CaseInsensitiveSet( (Collection<String>) adapter.getList( "disabled_commands", Arrays.asList( "disabledcommandhere" ) ) );

View File

@@ -11,12 +11,19 @@ import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.time.Instant;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import javax.crypto.SecretKey;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.BungeeServerInfo;
import net.md_5.bungee.EncryptionUtil;
@@ -51,6 +58,8 @@ import net.md_5.bungee.protocol.PacketWrapper;
import net.md_5.bungee.protocol.PlayerPublicKey;
import net.md_5.bungee.protocol.Protocol;
import net.md_5.bungee.protocol.ProtocolConstants;
import net.md_5.bungee.protocol.packet.CookieRequest;
import net.md_5.bungee.protocol.packet.CookieResponse;
import net.md_5.bungee.protocol.packet.EncryptionRequest;
import net.md_5.bungee.protocol.packet.EncryptionResponse;
import net.md_5.bungee.protocol.packet.Handshake;
@@ -86,6 +95,19 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Getter
private final Set<String> registeredChannels = new HashSet<>();
private State thisState = State.HANDSHAKE;
private final Queue<CookieFuture> requestedCookies = new LinkedList<>();
@Data
@ToString
@EqualsAndHashCode
@AllArgsConstructor
public static class CookieFuture
{
private String cookie;
private CompletableFuture<byte[]> future;
}
private final Unsafe unsafe = new Unsafe()
{
@Override
@@ -109,6 +131,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
private boolean legacy;
@Getter
private String extraDataInHandshake = "";
@Getter
private boolean transferred;
private UserConnection userCon;
@Override
@@ -349,6 +373,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
ch.setProtocol( Protocol.STATUS );
break;
case 2:
case 3:
transferred = handshake.getRequestedProtocol() == 3;
// Login
bungee.getLogger().log( Level.INFO, "{0} has connected", this );
thisState = State.USERNAME;
@@ -365,6 +391,12 @@ public class InitialHandler extends PacketHandler implements PendingConnection
}
return;
}
if ( transferred && bungee.config.isRejectTransfers() )
{
disconnect( bungee.getTranslation( "reject_transfer" ) );
return;
}
break;
default:
throw new QuietException( "Cannot request protocol " + handshake.getRequestedProtocol() );
@@ -643,6 +675,34 @@ public class InitialHandler extends PacketHandler implements PendingConnection
disconnect( "Unexpected custom LoginPayloadResponse" );
}
@Override
public void handle(CookieResponse cookieResponse)
{
// be careful, backend server could also make the client send a cookie response
CookieFuture future;
synchronized ( requestedCookies )
{
future = requestedCookies.peek();
if ( future != null )
{
if ( future.cookie.equals( cookieResponse.getCookie() ) )
{
Preconditions.checkState( future == requestedCookies.poll(), "requestedCookies queue mismatch" );
} else
{
future = null; // leave for handling by backend
}
}
}
if ( future != null )
{
future.getFuture().complete( cookieResponse.getData() );
throw CancelSendSignal.INSTANCE;
}
}
@Override
public void disconnect(String reason)
{
@@ -775,4 +835,26 @@ public class InitialHandler extends PacketHandler implements PendingConnection
brandMessage = input;
}
}
@Override
public CompletableFuture<byte[]> retrieveCookie(String cookie)
{
Preconditions.checkState( getVersion() >= ProtocolConstants.MINECRAFT_1_20_5, "Cookies are only supported in 1.20.5 and above" );
Preconditions.checkState( loginRequest != null, "Cannot retrieve cookies for status or legacy connections" );
if ( cookie.indexOf( ':' ) == -1 )
{
// if we request an invalid resource location (no prefix) the client will respond with "minecraft:" prefix
cookie = "minecraft:" + cookie;
}
CompletableFuture<byte[]> future = new CompletableFuture<>();
synchronized ( requestedCookies )
{
requestedCookies.add( new CookieFuture( cookie, future ) );
}
unsafe.sendPacket( new CookieRequest( cookie ) );
return future;
}
}

View File

@@ -32,6 +32,7 @@ import net.md_5.bungee.protocol.packet.Chat;
import net.md_5.bungee.protocol.packet.ClientChat;
import net.md_5.bungee.protocol.packet.ClientCommand;
import net.md_5.bungee.protocol.packet.ClientSettings;
import net.md_5.bungee.protocol.packet.CookieResponse;
import net.md_5.bungee.protocol.packet.FinishConfiguration;
import net.md_5.bungee.protocol.packet.KeepAlive;
import net.md_5.bungee.protocol.packet.LoginAcknowledged;
@@ -363,6 +364,12 @@ public class UpstreamBridge extends PacketHandler
con.sendQueuedPackets();
}
@Override
public void handle(CookieResponse cookieResponse) throws Exception
{
con.getPendingConnection().handle( cookieResponse );
}
@Override
public String toString()
{

View File

@@ -86,6 +86,8 @@ public abstract class EntityMap
return EntityMap_1_16_2.INSTANCE_1_20_2;
case ProtocolConstants.MINECRAFT_1_20_3:
return EntityMap_1_16_2.INSTANCE_1_20_3;
case ProtocolConstants.MINECRAFT_1_20_5:
return EntityMap_1_16_2.INSTANCE_1_20_5;
}
throw new RuntimeException( "Version " + version + " has no entity map" );
}

View File

@@ -22,6 +22,7 @@ class EntityMap_1_16_2 extends EntityMap
static final EntityMap_1_16_2 INSTANCE_1_19_4 = new EntityMap_1_16_2( 0x03, 0x30 );
static final EntityMap_1_16_2 INSTANCE_1_20_2 = new EntityMap_1_16_2( -1, 0x33 );
static final EntityMap_1_16_2 INSTANCE_1_20_3 = new EntityMap_1_16_2( -1, 0x34 );
static final EntityMap_1_16_2 INSTANCE_1_20_5 = new EntityMap_1_16_2( -1, 0x6F );
//
private final int spawnPlayerId;
private final int spectateId;

View File

@@ -40,3 +40,4 @@ command_perms_permission=\u00a79- {0}
command_ip=\u00a79IP of {0} is {1}
illegal_chat_characters=\u00a7cIllegal characters in chat ({0})
kick_message=\u00a7cYou have been kicked off the proxy.
reject_transfer=\u00a7cYour transfer was rejected.