[Bug] Client crash/freeze in Proxy (Velocity) environments due to hash collision in WorldIdentifier
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.2k
- Forks
- 1.1k
- PR merge metrics
- No merged PRs in 30d
Description
!!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.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in WorldIdentifier.java by reading the constructor and getWorldId, then inspect how the generated identifier is used for the Voxy save path. Reproduce or reason through switching between the two dimension types and the RocksDB lock-file conflict. Done means distinct dimension types no longer select the same storage directory without breaking existing world identification.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100