GeyserMC / MCProtocolLib

A library for communication with a Minecraft client/server.
MIT License
714 stars 201 forks source link

Invalid session on valid session. #837

Open tbvns opened 6 days ago

tbvns commented 6 days ago

When I generate a session token with

new StepMsaDeviceCode.MsaDeviceCodeCallback(msaDeviceCode -> {
       ChatManager.managers.get(proxiedSession).addEphemeral("Go to " + msaDeviceCode.getDirectVerificationUri(), 70);
       System.out.println(msaDeviceCode.getDirectVerificationUri());
}));

I get a valid session token (I can log in with a client that support token-logging) but I still can't log in to a premium server like Hypixel with my bot. I still get an invalid session when the session is clearly valid. Note that I also tried with the code in MinecraftProtocolTest.java, and I have the same issue.

tbvns commented 5 days ago

Here is my code:

package xyz.tbvns;

import net.kyori.adventure.text.Component;
import net.raphimc.minecraftauth.MinecraftAuth;
import net.raphimc.minecraftauth.step.java.StepMCProfile;
import net.raphimc.minecraftauth.step.java.StepMCToken;
import net.raphimc.minecraftauth.step.java.session.StepFullJavaSession;
import net.raphimc.minecraftauth.step.msa.MsaCodeStep;
import net.raphimc.minecraftauth.step.msa.StepCredentialsMsaCode;
import net.raphimc.minecraftauth.step.msa.StepMsaDeviceCode;
import net.raphimc.minecraftauth.util.OAuthEnvironment;
import org.geysermc.mcprotocollib.auth.GameProfile;
import org.geysermc.mcprotocollib.auth.SessionService;
import org.geysermc.mcprotocollib.network.ProxyInfo;
import org.geysermc.mcprotocollib.network.Session;
import org.geysermc.mcprotocollib.network.event.session.*;
import org.geysermc.mcprotocollib.network.packet.DefaultPacketHeader;
import org.geysermc.mcprotocollib.network.packet.Packet;
import org.geysermc.mcprotocollib.network.tcp.TcpClientSession;
import org.geysermc.mcprotocollib.protocol.MinecraftConstants;
import org.geysermc.mcprotocollib.protocol.MinecraftProtocol;
import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodec;
import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundCustomPayloadPacket;
import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundKeepAlivePacket;
import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundKeepAlivePacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundLoginPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundRespawnPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundSystemChatPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatPacket;

import java.io.IOException;
import java.net.Proxy;
import java.time.Instant;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;

public class ClientConnectionManager {
    public static HashMap<Session, Session> sessionHashMap = new HashMap<>();

    public void create(String host, int port, Session session) throws IOException {
        login(host, port, session);
    }

    TcpClientSession client;

    private void login(String host, int port, Session proxiedSession) throws IOException {
        MinecraftProtocol protocol;

        StepFullJavaSession.FullJavaSession fullJavaSession;
        try {
            fullJavaSession = MinecraftAuth.JAVA_DEVICE_CODE_LOGIN.getFromInput(
                    MinecraftAuth.createHttpClient(),
                    new StepMsaDeviceCode.MsaDeviceCodeCallback(msaDeviceCode -> {
                        ChatManager.managers.get(proxiedSession).addEphemeral("Go to " + msaDeviceCode.getDirectVerificationUri(), 70);
                        System.out.println(msaDeviceCode.getDirectVerificationUri());
                    }));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        StepMCProfile.MCProfile mcProfile = fullJavaSession.getMcProfile();
        StepMCToken.MCToken mcToken = mcProfile.getMcToken();

        GameProfile profile = new GameProfile(mcProfile.getId(), mcProfile.getName());

        SessionService sessionService = new SessionService();
        sessionService.fillProfileProperties(profile);

        protocol = new MinecraftProtocol(
                profile,
                mcToken.getAccessToken()
        );

        client = new TcpClientSession(host, port, protocol, null);
        client.setFlag(MinecraftConstants.ACCESS_TOKEN_KEY, mcToken.getAccessToken());
        client.setFlag(MinecraftConstants.PROFILE_KEY, profile);
        client.setFlag(MinecraftConstants.ACCEPT_TRANSFERS_KEY, true);
        client.setFlag(MinecraftConstants.FOLLOW_TRANSFERS, true);

        System.out.println(client.getFlag(MinecraftConstants.ACCESS_TOKEN_KEY));

        final boolean[] logedIn = {false};
        client.addListener(new SessionAdapter() {
            @Override
            public void packetReceived(Session session, Packet packet) {
                if (packet instanceof ClientboundLoginPacket) {
                    session.send(new ServerboundChatPacket("Hello, this is a test of MCProtocolLib.", Instant.now().toEpochMilli(), 0L, null, 0, new BitSet()));
                    proxiedSession.send(new ClientboundRespawnPacket(
                            ((ClientboundLoginPacket) packet).getCommonPlayerSpawnInfo(),
                            true,
                            true
                    ));
                    logedIn[0] = true;
                    sessionHashMap.put(proxiedSession, session);
                } else if (logedIn[0]) {
                    proxiedSession.send(packet);
                }
            }

            @Override
            public void disconnected(DisconnectedEvent event) {
                System.err.println("Disconnected: " + event.getReason().insertion());
                System.err.println(event.getCause().getMessage());
                event.getCause().printStackTrace();
            }

            //@Override
            //public void packetSending(PacketSendingEvent event) {
            //    if (ClientConnectionManager.sessionHashMap.containsKey(event.getSession())) {
            //        ClientConnectionManager.sessionHashMap.get(event.getSession()).send(event.getPacket());
            //    }
            //}
        });

        client.connect();
    }

}
tbvns commented 5 days ago

I also noticed that the "MinecraftConstants.ACCESS_TOKEN_KEY" was empty on the client session. That's why I tried:

            client = new TcpClientSession(host, port, protocol, null);
            client.setFlag(MinecraftConstants.ACCESS_TOKEN_KEY, mcToken.getAccessToken());
            client.setFlag(MinecraftConstants.PROFILE_KEY, profile);
            client.setFlag(MinecraftConstants.ACCEPT_TRANSFERS_KEY, true);
            client.setFlag(MinecraftConstants.FOLLOW_TRANSFERS, true);

Is there something to do to fix this thing ? Do I need to call something to link my "StepFullJavaSession.FullJavaSession" to my "TcpClientSession" ?