Skip to content

[Bug] Client crash/freeze in Proxy (Velocity) environments due to hash collision in WorldIdentifier #505

@addre98

Description

@addre98

!!English is not my native language,I have written this issue in my native language and used AI to translate it into English.Please forgive any unnatural phrasing or grammatical errors.

Description

In a multi-server environment (e.g., behind a Velocity proxy), the client may crash or freeze when switching between sub-servers. This happens because WorldIdentifier.getWorldId does not include the dimension_type in its hash calculation, leading to the same storage directory being assigned to different worlds despite them being logically distinct.

When two sub-servers have the same ResourceKey and biomeSeed but different dimension_type, Voxy attempts to open the same RocksDB database twice, resulting in a RocksDBException: Failed to create lock file.

Scenario

Server 1: Key=minecraft:overworld, BiomeSeed=xxxxx, dimension_type=minecraft:overworld

Server 2: Key=minecraft:overworld, BiomeSeed=xxxxx, dimension_type=custom:wild

Since the current getWorldId implementation only uses key and biomeSeed, both servers generate the same SHA-256 hash (e.g., cf5766fe82cbbdf473f51b8cfdc804d3), causing a path conflict.

Relevant Code

In WorldIdentifier.java, the constructor correctly includes the dimension in the hashCode:

public WorldIdentifier(@NotNull ResourceKey key, long biomeSeed, @Nullable ResourceKey dimension) {
// ...
this.hashCode = mixStafford13(registryKeyHashCode(key))^mixStafford13(registryKeyHashCode(dimension))^mixStafford13(biomeSeed);
}

However, getWorldId (which determines the save folder name) ignores it:

public static String getWorldId(WorldIdentifier identifier) {
// Current implementation ignores identifier.dimension
String data = identifier.biomeSeed + identifier.key.toString();
try {
return bytesToHex(MessageDigest.getInstance("SHA-256").digest(data.getBytes())).substring(0, 32);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}

Crash Log

Caused by: java.lang.RuntimeException: org.rocksdb.RocksDBException: Failed to create lock file: .../.voxy/saves/[server_address]/cf5766fe82cbbdf473f51b8cfdc804d3/storage//LOCK

Proposed Fix

I have tested adding the dimension to the hash data string in WorldIdentifier.java (around line 150), and it resolved the issue:

public static String getWorldId(WorldIdentifier identifier) {
String data = identifier.biomeSeed + identifier.key.toString() + identifier.dimension.toString();
// ... rest of the code
}

Note

I have verified that this fix resolves the crash in proxy-hopping scenarios. However, I am not sure whether this is intentional, and I do not know what other functionality this breaks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions