mircokroon / minecraft-world-downloader

Download Minecraft worlds, extend server's render distance. 1.12.2 - 1.21
GNU General Public License v3.0
1.24k stars 80 forks source link

MultiMC support #36

Closed polymetric closed 4 years ago

polymetric commented 4 years ago

This is a really cool program! I tried it with MultiMC and since that doesn't have a launcher_profiles.json like the Mojang launcher does, it won't authenticate. A quick workaround would be to just provide a command line override for the auth tokens required.

ChillerDragon commented 4 years ago

Yea the workaround using a cli arg is probably a good idea also for other cases than MultiMC. Btw a hack you can try is just manually creating the launcher_profiles.json and put it in ~/.minecraft

But the nice fix for MultiMC would be to parse ~/.local/share/multimc/accounts.json which looks like this:

{
    "accounts": [
        {
            "accessToken": "xxx",
            "activeProfile": "xxx",
            "clientToken": "xxx",
            "profiles": [
                {
                    "id": "xxx",
                    "legacy": false,
                    "name": "ZillyHuhn"
                }
            ],
            "user": {
                "id": "xxx"
            },
            "username": "samplemail@foo.com"
        }
    ],
    "activeAccount": "samplemail@foo.com",
    "formatVersion": 2
}
ChillerDragon commented 4 years ago

Hmm my manual fix does not seem to work or something else is going on but i can not get MultiMC running :/

$ java -jar ./target/world-downloader.jar -s lgl.zillyhuhn.com -m ~/.minecraft                                                                             
Starting proxy for lgl.zillyhuhn.com. Make sure to connect to localhost:25565 instead of the regular server address.                                                                                              
Performed handshake with lgl.zillyhuhn.com:25565, protocol version 736 :: next state: login
Login by: ZillyHuhn
java.lang.NullPointerException
        at proxy.auth.LauncherProfiles.getAuthDetails(LauncherProfiles.java:17)
        at proxy.auth.ClientAuthenticator.makeRequest(ClientAuthenticator.java:63)
        at proxy.EncryptionManager.lambda$sendReplacementEncryptionConfirmation$7(EncryptionManager.java:250)                                                                                                     
        at proxy.EncryptionManager.disconnectOnError(EncryptionManager.java:93)
        at proxy.EncryptionManager.sendReplacementEncryptionConfirmation(EncryptionManager.java:250)
        at proxy.EncryptionManager.lambda$setClientEncryptionConfirmation$6(EncryptionManager.java:238)
        at proxy.EncryptionManager.attempt(EncryptionManager.java:80)
        at proxy.EncryptionManager.setClientEncryptionConfirmation(EncryptionManager.java:227)
        at packets.builder.ServerBoundLoginPacketBuilder.lambda$new$1(ServerBoundLoginPacketBuilder.java:28)                                                                                                      
        at packets.builder.PacketBuilder.build(PacketBuilder.java:46)
        at packets.DataReader.readPackets(DataReader.java:161)
        at packets.DataReader.pushData(DataReader.java:116)
        at proxy.ProxyServer.lambda$run$4(ProxyServer.java:93)
        at proxy.ProxyServer.attempt(ProxyServer.java:138)
        at proxy.ProxyServer.lambda$run$6(ProxyServer.java:90)
        at java.base/java.lang.Thread.run(Thread.java:834)
Client probably disconnected. Waiting for new connection...
WARNING: packet parsing may have been incorrect! Expected length: 261. Used bytes: 0
Server probably disconnected. Waiting for new connection...
polymetric commented 4 years ago

Yeah, MultiMC also uses a json file but I think it's structured differently. You could just try parsing the json as a normal Mojang launcher file first, then if that fails to return valid keys, try parsing it according to MultiMC's structure. I might take a crack at this later if no one else wants to.

Quick sidenote: Given that auth keys are session-dependent, expire fairly quickly, and are easily renewable, I'm surprised both the Mojang launcher and MultiMC store them on disk. But hey, this thing probably wouldn't work without it.

mircokroon commented 4 years ago

Well, the launcher has to store at least one thing to ensure the user doesn't need to type in their password every time. Storing the password is a bad idea so it stores the accessToken instead, not really a way around it.

I think the easiest is probably to just add support for passing the accessToken and UUID as arguments but it's a bit cumbersome.

mircokroon commented 4 years ago

I've implemented that now in #39, I added some information to hopefully help anyone that's not familiar with the accessToken/JSON files.

Minecraft username: [user input]
Found user '...' with UUID '...'

Your access token is needed for authentication. It...
    - Can be found in launcher_profiles.json, inside your .minecraft directory (for the default launcher)
    - Should be named 'accessToken'
    - Is quite long (over 300 characters)
    - Can change when starting the game, so launch Minecraft before entering it
If you have multiple accounts, make sure to pick the one matching the given username.
Access token: [user input]

I'll leave the PR open for a bit in case anyone has any further suggestions.