151 lines
6.0 KiB
Diff
151 lines
6.0 KiB
Diff
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
|
|
|