Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Minecraft protocol's method to get UUID from username #241

Open
joshtch opened this issue Jan 13, 2025 · 3 comments · May be fixed by #242
Open

Use Minecraft protocol's method to get UUID from username #241

joshtch opened this issue Jan 13, 2025 · 3 comments · May be fixed by #242
Assignees
Labels
api This issue is related to the API or its implementation enhancement New feature or request

Comments

@joshtch
Copy link

joshtch commented Jan 13, 2025

The Minecraft protocol specifies how servers obtain the offline UUID given the username. Portablemc should use that method to get the UUID in offline mode when a username is provided, so switching from offline mode in another launcher to offline mode in portablemc will appear the same to a remote server, and player data will carry over.

@joshtch
Copy link
Author

joshtch commented Jan 13, 2025

From the Minecraft protocol:

For offline-mode servers (the ones with authentication disabled), encryption is optional, and part of the process can be skipped. In that case Login Start is directly followed by Login Success. The Notchian server only uses UUID v3 for offline player UUIDs, deriving it from the string OfflinePlayer:<player's name> For example, Notch’s offline UUID would be chosen from the string OfflinePlayer:Notch.

There are various online services that will calculate the UUID for you, but we can also compute it ourselves.

@joshtch
Copy link
Author

joshtch commented Jan 13, 2025

In Java, the command would be: (thanks to Tomasan7 on SpigotMC forums)

UUID.nameUUIDFromBytes("OfflinePlayer:<player_name>".getBytes(StandardCharsets.UTF_8));

Ironically, there's no mention of a hashed namespace, and indeed, the Java function doesn't accept one, so Python's uuid.uuid3 won't work. Here's a working reimplementation of Java's UUID.nameUUIDFromBytes in Python:

import hashlib
import uuid

def nameUUIDFromBytes(name: bytes) -> uuid.UUID:
    md5_hash = hashlib.md5(name, usedforsecurity=False)
    md5_bytes = bytearray(md5_hash.digest())
    md5_bytes[6] &= 0x0f   # clear version
    md5_bytes[6] |= 0x30   # set to version 3
    md5_bytes[8] &= 0x3f   # clear variant
    md5_bytes[8] |= 0x80   # set to IETF variant
    return uuid.UUID(bytes=bytes(md5_bytes))

The offlineUUID function is then:

def offlineUUID(player_name: str) -> str:
    return nameUUIDFromBytes(b'OfflinePlayer:' + player_name.encode()).hex

As one function, with nameUUIDFromBytes inlined and uuid.UUID no longer necessary:

import hashlib

def offlineUUID(player_name: str) -> str:
    bytestring = b'OfflinePlayer:' + player_name.encode()
    md5_hash = hashlib.md5(bytestring, usedforsecurity=False)
    md5_bytes = bytearray(md5_hash.digest())
    md5_bytes[6] = md5_bytes[6] & 0x0f | 0x30
    md5_bytes[8] = md5_bytes[8] & 0x3f | 0x80
    return md5_bytes.hex()

joshtch added a commit to joshtch/portablemc that referenced this issue Jan 13, 2025
@mindstorm38
Copy link
Owner

I'm aware of this issue, and this is already the default offline mode in the upcomming Rust rewrite!
Thanks for the patch! I'll look into this in the coming days.

I'm concerned that the UUID computation will not be the same anymore and maybe cause issues with players who doesn't expect this? At least, this should not impact singleplayer because UUID is not used, as I'm aware, and for offline-mode servers the computation is done server-side anyway. Do you know of any other cases that would be detrimental to this change?

@mindstorm38 mindstorm38 added enhancement New feature or request api This issue is related to the API or its implementation labels Jan 14, 2025
@mindstorm38 mindstorm38 self-assigned this Jan 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api This issue is related to the API or its implementation enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants