BungeeCord - обнаружен аутентифицированный игрок в автономном режиме - PullRequest
0 голосов
/ 27 октября 2018

Я несколько дней пытался определить, аутентифицирован ли аккаунт игрока Mojang, когда он находится в автономном режиме.

Почему я хочу это сделать?

В настоящее время у меня есть базовая система управления, которая состоит из проверки, существует ли псевдоним игрока в базе данных mojang, если для setOnlineMode установлено значение true, в противном случае для него установлено значение false.Система позволяет отображать обложку игрока и его UUID, но проблема в том, что если игрок, рассматриваемый как офлайн, покупает учетную запись Premium с тем же псевдонимом, у него нет обложки или его реального UUID, поскольку для setOnlineMode для false задано значение false.предотвратить потерю своего прогресса.Моя цель - создать систему, которая обнаружит, что офлайн-пользователь только что вошел в систему с аутентифицированной учетной записью Minecraft, чтобы сервер мог предложить ему автоматический перенос его прогресса на его новый аутентичный UUID.

Я сделал несколькоисследование попробуйте, например, здесь , я удалил условие онлайн-режима, чтобы разрешить проверку подлинности игрока, тогда здесь я удалил разъединение, если игрок был недействительным.Что дало мне чудесную ошибку.

13:13:31 [GRAVE] [Arbi13_] -> UpstreamBridge - encountered exception io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.SetCompression in phase GAME with direction TO_CLIENT
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:125)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:801)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:814)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:794)
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1066)
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:305)
    at net.md_5.bungee.netty.ChannelWrapper.write(ChannelWrapper.java:60)
    at net.md_5.bungee.UserConnection$1.sendPacket(UserConnection.java:148)
    at net.md_5.bungee.UserConnection.setCompressionThreshold(UserConnection.java:697)
    at net.md_5.bungee.connection.InitialHandler$6$1.run(InitialHandler.java:523)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
    at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:326)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
    at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.SetCompression in phase GAME with direction TO_CLIENT
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:399)
    at net.md_5.bungee.protocol.Protocol$DirectionData.getId(Protocol.java:462)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:23)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:9)
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107)
    ... 15 more
@Override
public void handle(LoginRequest loginRequest) throws Exception
{
    Preconditions.checkState( thisState == State.USERNAME, "Not expecting USERNAME" );
    this.loginRequest = loginRequest;

    if ( getName().contains( "." ) )
    {
        disconnect( bungee.getTranslation( "name_invalid" ) );
        return;
    }

    if ( getName().length() > 16 )
    {
        disconnect( bungee.getTranslation( "name_too_long" ) );
        return;
    }

    int limit = BungeeCord.getInstance().config.getPlayerLimit();
    if ( limit > 0 && bungee.getOnlineCount() > limit )
    {
        disconnect( bungee.getTranslation( "proxy_full" ) );
        return;
    }

    // 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 )
    {
        disconnect( bungee.getTranslation( "already_connected_proxy" ) );
        return;
    }

    Callback<PreLoginEvent> callback = new Callback<PreLoginEvent>()
    {

        @Override
        public void done(PreLoginEvent result, Throwable error)
        {
            if ( result.isCancelled() )
            {
                disconnect( result.getCancelReasonComponents() );
                return;
            }
            if ( ch.isClosed() )
            {
                return;
            }
            unsafe().sendPacket( request = EncryptionUtil.encryptRequest() );
            thisState = State.ENCRYPT;
        }
    };

    // fire pre login event
    bungee.getPluginManager().callEvent( new PreLoginEvent( InitialHandler.this, callback ) );
}

@Override
public void handle(final EncryptionResponse encryptResponse) throws Exception
{
    Preconditions.checkState( thisState == State.ENCRYPT, "Not expecting ENCRYPT" );

    SecretKey sharedKey = EncryptionUtil.getSecret( encryptResponse, request );
    BungeeCipher decrypt = EncryptionUtil.getCipher( false, sharedKey );
    ch.addBefore( PipelineUtils.FRAME_DECODER, PipelineUtils.DECRYPT_HANDLER, new CipherDecoder( decrypt ) );
    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" );

    MessageDigest sha = MessageDigest.getInstance( "SHA-1" );
    for ( byte[] bit : new byte[][]
    {
        request.getServerId().getBytes( "ISO_8859_1" ), sharedKey.getEncoded(), EncryptionUtil.keys.getPublic().getEncoded()
    } )
    {
        sha.update( bit );
    }
    String encodedHash = URLEncoder.encode( new BigInteger( sha.digest() ).toString( 16 ), "UTF-8" );

    String preventProxy = ( ( BungeeCord.getInstance().config.isPreventProxyConnections() ) ? "&ip=" + URLEncoder.encode( getAddress().getAddress().getHostAddress(), "UTF-8" ) : "" );
    String authURL = "https://sessionserver.mojang.com/session/minecraft/hasJoined?username=" + encName + "&serverId=" + encodedHash + preventProxy;

    Callback<String> handler = new Callback<String>()
    {
        @Override
        public void done(String result, Throwable error)
        {
            if ( error == null )
            {
                LoginResult obj = BungeeCord.getInstance().gson.fromJson( result, LoginResult.class );
                if ( obj != null && obj.getId() != null )
                {
                    loginProfile = obj;
                    name = obj.getName();
                    uniqueId = Util.getUUID( obj.getId() );
                    authenticated = true;
                    finish();
                    return;


          }
            if(isOnlineMode()) {
                disconnect(bungee.getTranslation("offline_mode_player"));
                return;
            }

            finish();
            return;
        } else
        {
            disconnect( bungee.getTranslation( "mojang_fail" ) );
            bungee.getLogger().log( Level.SEVERE, "Error authenticating " + getName() + " with minecraft.net", error );
        }
    }
};

HttpClient.get( authURL, ch.getHandle().eventLoop(), handler );
}
...