PandaCord/Waterfall-Proxy-Patches/0003-Multi-session-with-same-Minecraft-account-with-speci.patch

151 lines
6.0 KiB
Diff
Raw Normal View History

From dbb2441936118788203dc43a4c4582ee71e017c8 Mon Sep 17 00:00:00 2001
From: Marc Baloup <marc.baloup@laposte.net>
Date: Sun, 2 Oct 2016 07:54:16 +0200
Subject: [PATCH] Multi-session with same Minecraft account with specific
permission
Players with permission bungeecord.multiple_connect can have multiples
connections with the same Minecraft account. To manage UUID and Name conflict,
an increment value is appended to the player name, and the uuid used is the
offline one. So be carefull: Spigot servers and plugins will considers 2
players from the same account like if they were 2 different MC account.
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
index 0f1716c0..b07d2e06 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
@@ -110,6 +110,17 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Getter
private String extraDataInHandshake = "";
+ @Getter
+ private boolean duplication = false;
+
+ @Getter
+ private String realName = null;
+
+ @Getter
+ private UUID realId = null;
+
+ private String gameName = null;
+
@Override
public boolean shouldHandle(PacketWrapper packet) throws Exception
{
@@ -364,6 +375,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{
Preconditions.checkState( thisState == State.USERNAME, "Not expecting USERNAME" );
this.loginRequest = loginRequest;
+ this.realName = loginRequest.getData();
+ this.gameName = this.realName;
if ( getName().contains( " " ) )
{
@@ -378,9 +391,21 @@ public class InitialHandler extends PacketHandler implements PendingConnection
return;
}
+ ProxiedPlayer existingPlayer = bungee.getPlayer( getName() );
+
+ duplication = ( existingPlayer != null && existingPlayer.hasPermission( "bungeecord.multiple_connect" ) );
+
+ if ( duplication )
+ {
+ gameName = generateDuplicatedName( realName );
+ this.loginRequest.setData( gameName ); // gameName transmitted to Spigot server
+ }
+
+ offlineId = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + gameName ).getBytes( Charsets.UTF_8 ) );
+
// If offline mode and they are already on, don't allow connect
// We can just check by UUID here as names are based on UUID
- if ( !isOnlineMode() && bungee.getPlayer( getUniqueId() ) != null )
+ if ( !isOnlineMode() && bungee.getPlayer( offlineId ) != null && !duplication )
{
disconnect( bungee.getTranslation( "already_connected_proxy" ) );
return;
@@ -435,7 +460,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
BungeeCipher encrypt = EncryptionUtil.getCipher( true, sharedKey );
ch.addBefore( PipelineUtils.FRAME_PREPENDER, PipelineUtils.ENCRYPT_HANDLER, new CipherEncoder( encrypt ) );
- String encName = URLEncoder.encode( InitialHandler.this.getName(), "UTF-8" );
+ String encName = URLEncoder.encode( InitialHandler.this.realName, "UTF-8" );
MessageDigest sha = MessageDigest.getInstance( "SHA-1" );
for ( byte[] bit : new byte[][]
@@ -461,8 +486,10 @@ public class InitialHandler extends PacketHandler implements PendingConnection
if ( obj != null && obj.getId() != null )
{
loginProfile = obj;
- name = obj.getName();
- uniqueId = Util.getUUID( obj.getId() );
+ realName = obj.getName();
+ realId = Util.getUUID( obj.getId() );
+ if ( !duplication )
+ uniqueId = realId;
finish();
return;
}
@@ -470,7 +497,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
} else
{
disconnect( bungee.getTranslation( "mojang_fail" ) );
- bungee.getLogger().log( Level.SEVERE, "Error authenticating " + getName() + " with minecraft.net", error );
+ bungee.getLogger().log( Level.SEVERE, "Error authenticating " + realName + " with minecraft.net", error );
}
}
};
@@ -480,6 +507,12 @@ public class InitialHandler extends PacketHandler implements PendingConnection
private void finish()
{
+
+ if ( uniqueId == null )
+ {
+ uniqueId = offlineId;
+ }
+
if ( isOnlineMode() )
{
// Check for multiple connections
@@ -510,12 +543,6 @@ public class InitialHandler extends PacketHandler implements PendingConnection
}
- offlineId = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + getName() ).getBytes( Charsets.UTF_8 ) );
- if ( uniqueId == null )
- {
- uniqueId = offlineId;
- }
-
Callback<LoginEvent> complete = new Callback<LoginEvent>()
{
@Override
@@ -615,7 +642,22 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override
public String getName()
{
- return ( name != null ) ? name : ( loginRequest == null ) ? null : loginRequest.getData();
+ return gameName;
+ }
+
+ private String generateDuplicatedName(String original)
+ {
+ String newName;
+ int i = 0;
+ do
+ {
+ i++;
+ String strCount = Integer.toString( i );
+ if ( original.length() > 16 - strCount.length() )
+ original = original.substring( 0, 16 - strCount.length() );
+ newName = original + i;
+ } while ( bungee.getPlayer( newName ) != null );
+ return newName;
}
@Override
--
2.32.0.windows.2