!!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.
!!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:overworldServer 2: Key=
minecraft:overworld, BiomeSeed=xxxxx, dimension_type=custom:wildSince 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 thehashCode:However,
getWorldId(which determines the save folder name) ignores it:Crash Log
Proposed Fix
I have tested adding the
dimensionto the hash data string inWorldIdentifier.java(around line 150), and it resolved the issue: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.