9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-19 14:59:25 +00:00

Updated Upstream (Purpur)

Upstream has released updates that appear to apply and compile correctly

Purpur Changes:
PurpurMC/Purpur@65d3665 Updated Upstream (Paper)
PurpurMC/Purpur@936c29a Updated Upstream (Paper)
This commit is contained in:
NONPLAYT
2024-07-20 22:39:54 +03:00
parent 025a630eca
commit 4114dd1685
8 changed files with 320 additions and 439 deletions

View File

@@ -64,7 +64,7 @@ Global settings affect all worlds on the server as well as the core server funct
- **description**: Enables or disables optimization of sheep color choosing from the CarpetFixes mod. The game determines the child sheep's color by getting a wool block from the parents, putting them in a crafting
recipe, getting the output wool and getting the color from that.
- #### misc
- ##### use-secure-seed (temporarily absent)
- ##### enable-secure-seed
- **default**: false
- **description**: Enabling this, default 64-bit seed will be changed to a 1024-bit seed, making it almost impossible to crack the seed.
- ##### disable-non-editable-sign-warning

View File

@@ -2,7 +2,7 @@ group = space.bxteam.divinemc
mcVersion = 1.21
version = 1.21-R0.1-SNAPSHOT
purpurRef = eadfff73eaf7a17a0191c539f9aed81b4e55d65d
purpurRef = 936c29ae2ab768b8b1cf3f69e9b3e89c2a4b3f14
org.gradle.caching = true
org.gradle.parallel = true

View File

@@ -254,10 +254,10 @@ index 40689256711cc94a806ca1da346f4f62eda31526..f1beaa44a0f24b829923c351d0a0687b
private static CompoundTag readOversizedChunk(RegionFile regionfile, ChunkPos chunkCoordinate) throws IOException {
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index ca8ae8e1c51b937dac916e0b0dc94b5e2e61efeb..e68e13ac375a6418ad0785bc1c0f20af72bf6cf5 100644
index 48999a860a3b9ed691691c355beaf3e0674acb95..3cef3e99e0db3582465309b8bf485145acb5aa7b 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -503,7 +503,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -492,7 +492,7 @@ public class CraftScheduler implements BukkitScheduler {
this.parsePending();
} else {
// this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper

View File

@@ -190,7 +190,7 @@ index 7509b17414f836e8b53fc62b02b386ba4e8c5ca9..3ace9f8cb1e04887b5d2fd7af76eb768
public double maxLeashDistance = Leashable.LEASH_TOO_FAR_DIST;
public boolean disableSprintInterruptionOnAttack = false;
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 6833a7710cfb2716c8522d8a841bee665d98fd05..386fe1aca665e745babe3ca24f393fcaee36c663 100644
index ccde063ef8a5ee2dc5714c16aeda31f963745173..31a2779ede1595bbadb7b3dfe2c764ed4a53bfea 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -341,7 +341,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -216,10 +216,10 @@ index 54abd6874a64c669fc22448849febc9ef7c0f95e..59cf59bd127fd1fe1c8dbac2086ddbaf
useAlternateKeepAlive = getBoolean("settings.use-alternate-keepalive", useAlternateKeepAlive);
}
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index 0507182aa6d47da9693363f6b0fadd40d06d66b4..91e3c172140dd0ff30d2ffba2b937d3b87db3cce 100644
index 4dbb109d0526afee99b9190fc256585121aac9b5..85a5d8e26832c88afc212c3f600e686076596fbb 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -335,7 +335,7 @@ public class SpigotConfig
@@ -331,7 +331,7 @@ public class SpigotConfig
public static boolean saveUserCacheOnStopOnly;
private static void saveUserCacheOnStopOnly()
{
@@ -228,7 +228,7 @@ index 0507182aa6d47da9693363f6b0fadd40d06d66b4..91e3c172140dd0ff30d2ffba2b937d3b
}
public static double movedWronglyThreshold;
@@ -399,8 +399,10 @@ public class SpigotConfig
@@ -395,8 +395,10 @@ public class SpigotConfig
public static boolean logVillagerDeaths;
public static boolean logNamedDeaths;
private static void logDeaths() {

View File

@@ -826,7 +826,7 @@ index 01efbc507b3d58f13f78ee286f93df40cdc3f0cb..1f7f68aad97ee73763c042837f239bdc
} catch (Exception exception) {
if (exception instanceof ReportedException) {
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 2f170b3af816a096ec9e13888418f4bf00cce86b..cb6d77ba765a2700ffa2531a687b81a10b1a4df3 100644
index 932283d2385923c1777975970b631875aa7b4187..9f48bf88be9136bd358019f959a0039827a16484 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -3,7 +3,6 @@ package net.minecraft.server;
@@ -854,7 +854,7 @@ index 2f170b3af816a096ec9e13888418f4bf00cce86b..cb6d77ba765a2700ffa2531a687b81a1
// Purpur start
if (upnp) {
if (dev.omega24.upnp4j.UPnP4J.close(this.getPort(), dev.omega24.upnp4j.util.Protocol.TCP)) {
@@ -1611,15 +1607,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1610,15 +1606,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
public void tickServer(BooleanSupplier shouldKeepTicking) {
@@ -872,7 +872,7 @@ index 2f170b3af816a096ec9e13888418f4bf00cce86b..cb6d77ba765a2700ffa2531a687b81a1
// Paper end
new com.destroystokyo.paper.event.server.ServerTickStartEvent(this.tickCount+1).callEvent(); // Paper - Server Tick Events
@@ -1655,9 +1650,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1654,9 +1649,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
//this.profiler.pop(); // Purpur
// Paper end - Incremental chunk and player saving
// Paper start - move executeAll() into full server tick timing
@@ -883,7 +883,7 @@ index 2f170b3af816a096ec9e13888418f4bf00cce86b..cb6d77ba765a2700ffa2531a687b81a1
// Paper end
// Paper start - Server Tick Events
long endTime = System.nanoTime();
@@ -1680,7 +1673,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1679,7 +1672,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.logTickMethodTime(i);
//this.profiler.pop(); // Purpur
org.spigotmc.WatchdogThread.tick(); // Spigot
@@ -892,7 +892,7 @@ index 2f170b3af816a096ec9e13888418f4bf00cce86b..cb6d77ba765a2700ffa2531a687b81a1
private void logTickMethodTime(long tickStartTime) {
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 386fe1aca665e745babe3ca24f393fcaee36c663..25e05b03892cf1f8844cc2111348787d137ede1f 100644
index 31a2779ede1595bbadb7b3dfe2c764ed4a53bfea..9f39dea0e21057850c18903ce3d1cbabe60a114c 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -66,9 +66,6 @@ import org.apache.logging.log4j.Level;
@@ -928,7 +928,7 @@ index 386fe1aca665e745babe3ca24f393fcaee36c663..25e05b03892cf1f8844cc2111348787d
// Paper start
if (waitableArray[0] != null) {
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 34aa16cdfb12f20dba4e8e43cf9c1a0fb4061361..472ceaf17d15f783ff9c80bb060396a64431f53c 100644
index 64777b3431a0078c332e7b67566a61211722c59b..5beb5f883dfb465e431220b7d39dbe589c30937b 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1,6 +1,5 @@
@@ -969,7 +969,7 @@ index a4ea3eca166510e05bc53504d2f1040e3bead39a..87368cc8ed4746073a04521d221713f0
entity.postTick(); // CraftBukkit
} else { entity.inactiveTick(); } // Paper - EAR 2
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index b14e56c6b117b28c604259ad179d10e79f7c4cdd..65a4cb29bb99058e144ee7958970e41f7842c28a 100644
index 1b1008ffd544dcddc31238e10c06df0d7aa68793..f31d71b2afa12676e56dd0d5c67bfb7a79961f25 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -1,6 +1,5 @@
@@ -1128,7 +1128,7 @@ index cd0e43f4c53a746dd6183a8406269f9b11ad3571..54657ac895fb2fa9c58910d5421f0082
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
public CraftPersistentDataContainer persistentDataContainer;
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index e68e13ac375a6418ad0785bc1c0f20af72bf6cf5..e51a9ec41054750c38f95b06881980842c2c57f3 100644
index 3cef3e99e0db3582465309b8bf485145acb5aa7b..b66fbdd38b7c6d35b4a7e01d69dc1ec99e1db0d9 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -1,6 +1,5 @@
@@ -1138,7 +1138,7 @@ index e68e13ac375a6418ad0785bc1c0f20af72bf6cf5..e51a9ec41054750c38f95b0688198084
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.ArrayList;
@@ -304,7 +303,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -297,7 +296,7 @@ public class CraftScheduler implements BukkitScheduler {
}
return false;
}
@@ -1147,7 +1147,7 @@ index e68e13ac375a6418ad0785bc1c0f20af72bf6cf5..e51a9ec41054750c38f95b0688198084
this.handle(task, 0L);
for (CraftTask taskPending = this.head.getNext(); taskPending != null; taskPending = taskPending.getNext()) {
if (taskPending == task) {
@@ -344,7 +343,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -337,7 +336,7 @@ public class CraftScheduler implements BukkitScheduler {
}
}
}
@@ -1157,7 +1157,7 @@ index e68e13ac375a6418ad0785bc1c0f20af72bf6cf5..e51a9ec41054750c38f95b0688198084
for (CraftTask taskPending = this.head.getNext(); taskPending != null; taskPending = taskPending.getNext()) {
if (taskPending == task) {
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
index 5835dc236b3f5291a804f7fb14a12eb466d4e0ba..a6dc7679602df92cd3f825c5727b58ce759e9554 100644
index 8f181e03eda734b18f8c9ee80ee6e45f8689d178..f43561f7c8c4e63b5037d70bd1cde6d857656442 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
@@ -2,15 +2,10 @@ package org.bukkit.craftbukkit.scheduler;
@@ -1184,15 +1184,7 @@ index 5835dc236b3f5291a804f7fb14a12eb466d4e0ba..a6dc7679602df92cd3f825c5727b58ce
private final Plugin plugin;
private final int id;
private final long createdAt = System.nanoTime();
@@ -55,7 +49,6 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
this.id = id;
this.period = CraftTask.NO_REPEATING;
this.taskName = taskName;
- this.timings = MinecraftTimings.getInternalTaskName(taskName);
}
// Paper end
@@ -76,7 +69,6 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
@@ -61,7 +55,6 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
}
this.id = id;
this.period = period;
@@ -1222,10 +1214,10 @@ index d3ec817e95628f1fc8be4a29c9a0f13c7d5fd552..e9798517b9211c50a20ea5c69603aab3
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index eb5ca67ebfd008a0fcc3ab3fc2452a27d7b0a9f8..bdae2ce02a88f3a249d3562df53cd129d43999f1 100644
index 4f25368d55496667f1dc2cb2879b6d783464292b..153525f5c234d6bde9a783c24849cae66aa55798 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -216,7 +216,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
@@ -200,7 +200,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
// Paper start
@Override
public void reportTimings() {
@@ -1234,7 +1226,7 @@ index eb5ca67ebfd008a0fcc3ab3fc2452a27d7b0a9f8..bdae2ce02a88f3a249d3562df53cd129
}
// Paper end
@@ -493,7 +493,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
@@ -482,7 +482,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
// Paper start
@Override
public String getTimingsServerName() {

View File

@@ -105,7 +105,7 @@ index 5705cb920084b775cce4b361683b32c6b6e003ed..9c031dd0fa279a23405e5b7d77e4c11e
}
}
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 25e05b03892cf1f8844cc2111348787d137ede1f..527b062f2c041c18529802e2c86ff419b8a8f475 100644
index 9f39dea0e21057850c18903ce3d1cbabe60a114c..17f3bc4ebd326c0a338c9dca4e156c5753214b1f 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -709,7 +709,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -147,10 +147,10 @@ index fac2fb82c381d245f77b7288c34920660ac2c3af..b3ca62843b17c536840cb4edb700f9c2
if (packet == null || this.processedDisconnect) { // Spigot
return;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 65a4cb29bb99058e144ee7958970e41f7842c28a..278018c0f0a19d76337ab073340e91e85c4eacb5 100644
index f31d71b2afa12676e56dd0d5c67bfb7a79961f25..3af9bd57eea12a8dffab248631e290b3b368aca3 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -1450,7 +1450,7 @@ public abstract class PlayerList {
@@ -1451,7 +1451,7 @@ public abstract class PlayerList {
}
public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public

View File

@@ -35,10 +35,10 @@ index 73df26b27146bbad2106d57b22dd3c792ed3dd1d..a4d16996fae07f943ee078ce3d2e7b22
}
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java
index c833f78d083b8f661087471c35bc90f65af1b525..494c2593a10f660f9ae30d7258c84b9f0616e7b1 100644
index 3218cbf84f54daf06e84442d5eb1a36d8da6b215..0db1f8f64a261780e6692755669fa573a2c2b199 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java
@@ -1042,9 +1042,9 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread {
@@ -1043,9 +1043,9 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread {
return ((ChunkSystemRegionFileStorage)(Object)this.getCache()).moonrise$doesRegionFileNotExistNoIO(chunkX, chunkZ);
}
@@ -50,7 +50,7 @@ index c833f78d083b8f661087471c35bc90f65af1b525..494c2593a10f660f9ae30d7258c84b9f
synchronized (cache) {
try {
if (existingOnly) {
@@ -1060,9 +1060,9 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread {
@@ -1061,9 +1061,9 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread {
}
}
@@ -63,10 +63,10 @@ index c833f78d083b8f661087471c35bc90f65af1b525..494c2593a10f660f9ae30d7258c84b9f
synchronized (cache) {
regionFile = ((ChunkSystemRegionFileStorage)(Object)cache).moonrise$getRegionFileIfLoaded(chunkX, chunkZ);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 3e5368dbf43e2cc7e01cfd376e0651f681d5d844..59b77a83ab03570f58d9528effb2fc5c42eb9043 100644
index 9f48bf88be9136bd358019f959a0039827a16484..15f3cadf19407bba6f9783aed8c2ff7ad52af570 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -977,10 +977,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -978,10 +978,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
while (iterator1.hasNext()) {
ServerLevel worldserver2 = (ServerLevel) iterator1.next();
@@ -80,7 +80,7 @@ index 3e5368dbf43e2cc7e01cfd376e0651f681d5d844..59b77a83ab03570f58d9528effb2fc5c
return flag3;
diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
index 0382b6597a130d746f8954a93a756a9d1ac81d50..bc7693e0c1d56f3afa7ea65a2c048757e82d9c86 100644
index cb39c629af1827078f35904a373d35a63fea17ff..08a4a333ab294e95bee95376788df5229aca6598 100644
--- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
+++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
@@ -76,7 +76,7 @@ public class WorldUpgrader {
@@ -92,7 +92,7 @@ index 0382b6597a130d746f8954a93a756a9d1ac81d50..bc7693e0c1d56f3afa7ea65a2c048757
final DimensionDataStorage overworldDataStorage;
public WorldUpgrader(LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, RegistryAccess dynamicRegistryManager, boolean eraseCache, boolean recreateRegionFiles) {
@@ -394,7 +394,7 @@ public class WorldUpgrader {
@@ -400,7 +400,7 @@ public class WorldUpgrader {
private static List<WorldUpgrader.FileToUpgrade> getAllChunkPositions(RegionStorageInfo key, Path regionDirectory) {
File[] afile = regionDirectory.toFile().listFiles((file, s) -> {
@@ -101,7 +101,7 @@ index 0382b6597a130d746f8954a93a756a9d1ac81d50..bc7693e0c1d56f3afa7ea65a2c048757
});
if (afile == null) {
@@ -414,7 +414,7 @@ public class WorldUpgrader {
@@ -420,7 +420,7 @@ public class WorldUpgrader {
List<ChunkPos> list1 = Lists.newArrayList();
try {
@@ -110,7 +110,7 @@ index 0382b6597a130d746f8954a93a756a9d1ac81d50..bc7693e0c1d56f3afa7ea65a2c048757
try {
for (int i1 = 0; i1 < 32; ++i1) {
@@ -477,7 +477,7 @@ public class WorldUpgrader {
@@ -483,7 +483,7 @@ public class WorldUpgrader {
protected abstract boolean tryProcessOnePosition(T storage, ChunkPos chunkPos, ResourceKey<Level> worldKey);
@@ -119,7 +119,7 @@ index 0382b6597a130d746f8954a93a756a9d1ac81d50..bc7693e0c1d56f3afa7ea65a2c048757
if (WorldUpgrader.this.recreateRegionFiles) {
if (this.previousWriteFuture != null) {
this.previousWriteFuture.join();
@@ -502,7 +502,7 @@ public class WorldUpgrader {
@@ -508,7 +508,7 @@ public class WorldUpgrader {
}
}
@@ -129,7 +129,7 @@ index 0382b6597a130d746f8954a93a756a9d1ac81d50..bc7693e0c1d56f3afa7ea65a2c048757
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..add6311e12bd74c336bb9592e75493b5d8624824 100644
index eb0389ad86300665b6e057bcfa1d7c068dc6c6ab..bb3730bd34d40d079ff50fd40bf7b0c35589243f 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
@@ -28,7 +28,7 @@ import net.minecraft.nbt.NbtIo; // Paper
@@ -141,7 +141,16 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..add6311e12bd74c336bb9592e75493b5
private static final Logger LOGGER = LogUtils.getLogger();
private static final int SECTOR_BYTES = 4096;
@@ -465,10 +465,10 @@ public class RegionFile implements AutoCloseable {
@@ -129,7 +129,7 @@ public class RegionFile implements AutoCloseable {
}
// note: only call for CHUNK regionfiles
- boolean recalculateHeader() throws IOException {
+ public boolean recalculateHeader() throws IOException { // DivineMC - make public
if (!this.canRecalcHeader) {
return false;
}
@@ -928,10 +928,10 @@ public class RegionFile implements AutoCloseable {
private static int getChunkIndex(int x, int z) {
return (x & 31) + (z & 31) * 32;
}
@@ -154,7 +163,7 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..add6311e12bd74c336bb9592e75493b5
final int offset = getChunkIndex(x, z);
boolean previous = this.oversized[offset] == 1;
this.oversized[offset] = (byte) (oversized ? 1 : 0);
@@ -507,7 +507,7 @@ public class RegionFile implements AutoCloseable {
@@ -970,7 +970,7 @@ public class RegionFile implements AutoCloseable {
return this.path.getParent().resolve(this.path.getFileName().toString().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt");
}
@@ -164,7 +173,7 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..add6311e12bd74c336bb9592e75493b5
try (DataInputStream out = new DataInputStream(new java.io.BufferedInputStream(new InflaterInputStream(Files.newInputStream(file))))) {
return NbtIo.read((java.io.DataInput) out);
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
index 64b2608ae81373acb67e3e0453c61822c0d03087..04fa3b7789186f9eb1631cd81e7c04d1e1f322e0 100644
index f1beaa44a0f24b829923c351d0a0687b8138b6f9..b1a5885ce7307671fd2b4c37c110797e354ba3e7 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -21,7 +21,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@@ -224,8 +233,8 @@ index 64b2608ae81373acb67e3e0453c61822c0d03087..04fa3b7789186f9eb1631cd81e7c04d1
this.regionCache.putAndMoveToFirst(key, ret);
@@ -112,7 +114,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
this.info = storageKey;
@@ -143,7 +145,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
this.isChunkData = isChunkDataFolder(this.folder); // Paper - recalculate region file headers
}
- public RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - public
@@ -233,7 +242,7 @@ index 64b2608ae81373acb67e3e0453c61822c0d03087..04fa3b7789186f9eb1631cd81e7c04d1
// Paper start - rewrite chunk system
if (existingOnly) {
return this.moonrise$getRegionFileIfExists(chunkcoordintpair.x, chunkcoordintpair.z);
@@ -120,7 +122,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@@ -151,7 +153,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
synchronized (this) {
final long key = ChunkPos.asLong(chunkcoordintpair.x >> REGION_SHIFT, chunkcoordintpair.z >> REGION_SHIFT);
@@ -242,7 +251,7 @@ index 64b2608ae81373acb67e3e0453c61822c0d03087..04fa3b7789186f9eb1631cd81e7c04d1
if (ret != null) {
return ret;
}
@@ -129,13 +131,13 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@@ -160,13 +162,13 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
this.regionCache.removeLast().close();
}
@@ -258,7 +267,7 @@ index 64b2608ae81373acb67e3e0453c61822c0d03087..04fa3b7789186f9eb1631cd81e7c04d1
this.regionCache.putAndMoveToFirst(key, ret);
@@ -149,7 +151,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@@ -180,7 +182,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO DIVINEMC - You may ask for help on Discord, but do not file an issue. These error messages can not be removed.");
}
@@ -267,7 +276,7 @@ index 64b2608ae81373acb67e3e0453c61822c0d03087..04fa3b7789186f9eb1631cd81e7c04d1
synchronized (regionfile) {
try (DataInputStream datainputstream = regionfile.getChunkDataInputStream(chunkCoordinate)) {
CompoundTag oversizedData = regionfile.getOversizedData(chunkCoordinate.x, chunkCoordinate.z);
@@ -184,7 +186,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@@ -215,7 +217,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@Nullable
public CompoundTag read(ChunkPos pos) throws IOException {
// CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing
@@ -276,7 +285,7 @@ index 64b2608ae81373acb67e3e0453c61822c0d03087..04fa3b7789186f9eb1631cd81e7c04d1
if (regionfile == null) {
return null;
}
@@ -235,7 +237,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@@ -279,7 +281,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
public void scanChunk(ChunkPos chunkPos, StreamTagVisitor scanner) throws IOException {
// CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing
@@ -285,7 +294,7 @@ index 64b2608ae81373acb67e3e0453c61822c0d03087..04fa3b7789186f9eb1631cd81e7c04d1
if (regionfile == null) {
return;
}
@@ -265,7 +267,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@@ -309,7 +311,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
}
public void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { // Paper - public
@@ -294,7 +303,7 @@ index 64b2608ae81373acb67e3e0453c61822c0d03087..04fa3b7789186f9eb1631cd81e7c04d1
// Paper start - rewrite chunk system
if (regionfile == null) {
// if the RegionFile doesn't exist, no point in deleting from it
@@ -324,7 +326,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@@ -368,7 +370,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
// Paper start - rewrite chunk system
synchronized (this) {
final ExceptionCollector<IOException> exceptionCollector = new ExceptionCollector<>();
@@ -303,7 +312,7 @@ index 64b2608ae81373acb67e3e0453c61822c0d03087..04fa3b7789186f9eb1631cd81e7c04d1
try {
regionFile.close();
} catch (final IOException ex) {
@@ -341,7 +343,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@@ -385,7 +387,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
// Paper start - rewrite chunk system
synchronized (this) {
final ExceptionCollector<IOException> exceptionCollector = new ExceptionCollector<>();
@@ -338,10 +347,10 @@ index 6111631c6673948b266286894603cc5e30451b02..8bfc0fe2b8389359a682458fde5ef1b0
+ // DivineMC end
}
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
index 2580a13c80f6a8f6bb35b4c82014628732660019..047d44a8d47a6c7e1ab166fdd0d42e25374cbaee 100644
index 9d3d52e4798451ec4f30f735bcdef0ef4dde0cbf..0dd1fb7bfcf8e8b475987c5e46a1fbd3431a121c 100644
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
@@ -192,4 +192,16 @@ public class DivineConfig {
@@ -194,4 +194,16 @@ public class DivineConfig {
private static void chatMessageSignatures() {
noChatSign = getBoolean("settings.no-chat-sign", noChatSign);
}
@@ -349,8 +358,8 @@ index 2580a13c80f6a8f6bb35b4c82014628732660019..047d44a8d47a6c7e1ab166fdd0d42e25
+ public static int linearFlushFrequency = 10;
+ public static int linearFlushThreads = 1;
+ private static void linearSettings() {
+ linearFlushFrequency = getInt("region-format.linear.flush-frequency", linearFlushFrequency);
+ linearFlushThreads = getInt("region-format.linear.flush-max-threads", linearFlushThreads);
+ linearFlushFrequency = getInt("settings.region-format.linear.flush-frequency", linearFlushFrequency);
+ linearFlushThreads = getInt("settings.region-format.linear.flush-max-threads", linearFlushThreads);
+
+ if (linearFlushThreads < 0)
+ linearFlushThreads = Math.max(Runtime.getRuntime().availableProcessors() + linearFlushThreads, 1);
@@ -400,10 +409,10 @@ index d94c51ea18d299dd52b9a8521a9cdc0d95b79356..f216f728dd5ca6e7b67f4f1384ce73fa
}
diff --git a/src/main/java/space/bxteam/divinemc/region/AbstractRegionFile.java b/src/main/java/space/bxteam/divinemc/region/AbstractRegionFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..15ef37b50b153cfc89cfd8c0a5855dd5301765a4
index 0000000000000000000000000000000000000000..8bc4681e38ab29dae8173492d3430986d8baa164
--- /dev/null
+++ b/src/main/java/space/bxteam/divinemc/region/AbstractRegionFile.java
@@ -0,0 +1,25 @@
@@ -0,0 +1,26 @@
+package space.bxteam.divinemc.region;
+
+import java.io.DataInputStream;
@@ -423,6 +432,7 @@ index 0000000000000000000000000000000000000000..15ef37b50b153cfc89cfd8c0a5855dd5
+ boolean hasChunk(ChunkPos pos);
+ boolean doesChunkExist(ChunkPos pos);
+ boolean isOversized(int x, int z);
+ boolean recalculateHeader() throws IOException;
+
+ void flush() throws IOException;
+ void close() throws IOException;
@@ -459,10 +469,10 @@ index 0000000000000000000000000000000000000000..eb019b4863c2f812902318bdc8f3ab34
+}
diff --git a/src/main/java/space/bxteam/divinemc/region/LinearRegionFile.java b/src/main/java/space/bxteam/divinemc/region/LinearRegionFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..253dbd86a2b2febb4f3790dc6762a2afe9530950
index 0000000000000000000000000000000000000000..bcb69f307a63ae6aa2b1e8bdfbb1a499ad88d402
--- /dev/null
+++ b/src/main/java/space/bxteam/divinemc/region/LinearRegionFile.java
@@ -0,0 +1,300 @@
@@ -0,0 +1,304 @@
+package space.bxteam.divinemc.region;
+
+import com.github.luben.zstd.ZstdInputStream;
@@ -738,6 +748,10 @@ index 0000000000000000000000000000000000000000..253dbd86a2b2febb4f3790dc6762a2af
+ flush(); // sync
+ }
+
+ public boolean recalculateHeader() {
+ return false;
+ }
+
+ public void setOversized(int x, int z, boolean something) {
+ }
+

View File

@@ -1,32 +1,24 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Mon, 13 May 2024 18:29:34 +0300
Date: Sat, 20 Jul 2024 22:04:52 +0300
Subject: [PATCH] Implement Secure Seed
Original license: GPLv3
Original project: https://github.com/plasmoapp/matter
diff --git a/src/main/java/net/minecraft/server/commands/SeedCommand.java b/src/main/java/net/minecraft/server/commands/SeedCommand.java
index 0b500b19a99fa6c2740c0db350a166462668df9c..a67d29ddfa942cfc8cdf9d43b738727dc88a6450 100644
index 0b500b19a99fa6c2740c0db350a166462668df9c..f13185628dec90a044bf03cf38394b5be8ab2003 100644
--- a/src/main/java/net/minecraft/server/commands/SeedCommand.java
+++ b/src/main/java/net/minecraft/server/commands/SeedCommand.java
@@ -5,6 +5,7 @@ import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentUtils;
+import space.bxteam.divinemc.seed.WorldSeedUtils; // DivineMC
public class SeedCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, boolean dedicated) {
@@ -12,6 +13,17 @@ public class SeedCommand {
@@ -12,6 +12,17 @@ public class SeedCommand {
long l = context.getSource().getLevel().getSeed();
Component component = ComponentUtils.copyOnClickText(String.valueOf(l));
context.getSource().sendSuccess(() -> Component.translatable("commands.seed.success", component), false);
+
+ // DivineMC start - SecureSeed Command
+ if (space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed) {
+ WorldSeedUtils.setupGlobals(context.getSource().getLevel());
+ String seedStr = WorldSeedUtils.seedToString(WorldSeedUtils.worldSeed);
+ // DivineMC start - Implement Secure Seed
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ space.bxteam.divinemc.seed.Globals.setupGlobals(context.getSource().getLevel());
+ String seedStr = space.bxteam.divinemc.seed.Globals.seedToString(space.bxteam.divinemc.seed.Globals.worldSeed);
+ Component featureSeedComponent = ComponentUtils.copyOnClickText(seedStr);
+
+ context.getSource().sendSuccess(() -> Component.translatable(("Feature seed: %s"), featureSeedComponent), false);
@@ -37,31 +29,19 @@ index 0b500b19a99fa6c2740c0db350a166462668df9c..a67d29ddfa942cfc8cdf9d43b738727d
}));
}
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
index 842f382de43df5d5c321422372ec30ccdd7859d7..bd17ddefd6a9c640cc410cfa22859d323b343e9c 100644
index 9ebe1f1797b5be562bc4f6d92b9a4d6022ca2151..e29aae167eba565caf143645fd12fc200fae9655 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
@@ -42,6 +42,7 @@ import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
import net.minecraft.world.level.levelgen.presets.WorldPreset;
import net.minecraft.world.level.levelgen.presets.WorldPresets;
import org.slf4j.Logger;
+import space.bxteam.divinemc.seed.WorldSeedUtils; // DivineMC
// CraftBukkit start
import joptsimple.OptionSet;
@@ -164,7 +165,21 @@ public class DedicatedServerProperties extends Settings<DedicatedServerPropertie
@@ -165,7 +165,17 @@ public class DedicatedServerProperties extends Settings<DedicatedServerPropertie
boolean flag = this.get("generate-structures", true);
long i = WorldOptions.parseSeed(s).orElse(WorldOptions.randomSeed());
- this.worldOptions = new WorldOptions(i, flag, false);
+ // DivineMC start - Implement Secure Seed
+ if (space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed) {
+ String featureSeedString = this.get("feature-level-seed", "");
+ long[] featureSeed;
+ if (featureSeedString.isEmpty()) {
+ featureSeed = WorldSeedUtils.createRandomWorldSeed();
+ } else {
+ featureSeed = WorldSeedUtils.parseSeed(featureSeedString).orElseGet(WorldSeedUtils::createRandomWorldSeed);
+ }
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ String featureSeedStr = this.get("feature-level-seed", "");
+ long[] featureSeed = space.bxteam.divinemc.seed.Globals.parseSeed(featureSeedStr)
+ .orElse(space.bxteam.divinemc.seed.Globals.createRandomWorldSeed());
+
+ this.worldOptions = new WorldOptions(i, featureSeed, flag, false);
+ } else {
@@ -72,75 +52,52 @@ index 842f382de43df5d5c321422372ec30ccdd7859d7..bd17ddefd6a9c640cc410cfa22859d32
return GsonHelper.parse(!s1.isEmpty() ? s1 : "{}");
}, new JsonObject()), (String) this.get("level-type", (s1) -> {
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 25aff82dd74ee87f67632af48a2a8e7436fb1a84..e97f93d711aacee54c6aabd58ab76f42954f6aba 100644
index 74453c9f81f8c2c0dec96d25ccf2cb3449a73899..4ad1ad9d357994879ac10a6b19c207c0b3f19586 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -44,6 +44,7 @@ import net.minecraft.world.level.levelgen.RandomState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
import net.minecraft.world.level.storage.DimensionDataStorage;
import net.minecraft.world.level.storage.LevelStorageSource;
+import space.bxteam.divinemc.seed.WorldSeedUtils; // DivineMC
public class ServerChunkCache extends ChunkSource {
@@ -704,6 +705,7 @@ public class ServerChunkCache extends ChunkSource {
@@ -573,6 +573,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
}
public ChunkGenerator getGenerator() {
+ WorldSeedUtils.setupGlobals(level); // DivineMC - Implement Secure Seed
+ space.bxteam.divinemc.seed.Globals.setupGlobals(level); // DivineMC - Implement Secure Seed
return this.chunkMap.generator();
}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index d2e4587af693c819edd151cd93bfb4b6839d84a4..26163fc267841cb49375eb78e3165d25b26962dc 100644
index 87368cc8ed4746073a04521d221713f00ece4e6f..2f9ee85d5030b33c80042144c9829c0805fc3ecf 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -179,7 +179,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.server.MapInitializeEvent;
import org.bukkit.event.weather.LightningStrikeEvent;
import org.bukkit.event.world.TimeSkipEvent;
-// CraftBukkit end
+import space.bxteam.divinemc.seed.WorldSeedUtils; // DivineMC
public class ServerLevel extends Level implements WorldGenLevel {
@@ -751,6 +751,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -600,6 +600,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
chunkgenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkgenerator, gen);
}
// CraftBukkit end
+ WorldSeedUtils.setupGlobals(this); // DivineMC - Implement Secure Seed
+ space.bxteam.divinemc.seed.Globals.setupGlobals(this); // DivineMC - Implement Secure Seed
boolean flag2 = minecraftserver.forceSynchronousWrites();
DataFixer datafixer = minecraftserver.getFixerUpper();
this.entityStorage = new EntityRegionFileStorage(this.getLevel().divinemcConfig.regionFormatName, this.getLevel().divinemcConfig.regionFormatLinearCompressionLevel, new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), flag2); // Paper - rewrite chunk system
EntityPersistentStorage<Entity> entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver);
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
index ccf7fea215d3096e76db294daa5874fec00147ca..46f4db516567ea02fcb83360f94afc395b12d343 100644
index 40c00f73502be66f2a0f3cdb36b963fb25c60704..d924f0c2597a3211716be638183e9b72bc4ffa40 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
@@ -431,7 +431,10 @@ public class Slime extends Mob implements Enemy {
@@ -439,7 +439,12 @@ public class Slime extends Mob implements Enemy {
}
ChunkPos chunkcoordintpair = new ChunkPos(pos);
- boolean flag = world.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
+ // DivineMC start - Implement Secure Seed
+ boolean isSlimeChunk = space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed ? world.getChunk(chunkcoordintpair.x, chunkcoordintpair.z).isSlimeChunk() : WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
+ boolean isSlimeChunk = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? world.getChunk(chunkcoordintpair.x, chunkcoordintpair.z).isSlimeChunk()
+ : WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
+ boolean flag = world.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || isSlimeChunk;
+ // DivineMC end
// Paper start - Replace rules for Height in Slime Chunks
final double maxHeightSlimeChunk = world.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.slimeChunk.maximum;
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
index 1aac95b03a9e2e37c24f2a30bcb259c1424e1c78..253dfb24df08b3f3173cd23844320695d6b4c33c 100644
index 75c8125e20b70433fe9d143a3193d821043327c3..57433d0b5a14d4d8632d93850601e3fc115dcc14 100644
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
@@ -56,6 +56,7 @@ import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.ticks.SerializableTickContainer;
import net.minecraft.world.ticks.TickContainerAccess;
import org.slf4j.Logger;
+import space.bxteam.divinemc.seed.WorldgenCryptoRandom; // DivineMC
public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiomeSource, LightChunk, StructureAccess {
@@ -85,6 +86,11 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
@@ -85,6 +85,11 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
protected final LevelHeightAccessor levelHeightAccessor;
protected final LevelChunkSection[] sections;
@@ -152,7 +109,7 @@ index 1aac95b03a9e2e37c24f2a30bcb259c1424e1c78..253dfb24df08b3f3173cd23844320695
// CraftBukkit start - SPIGOT-6814: move to IChunkAccess to account for 1.17 to 1.18 chunk upgrading.
private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(ChunkAccess.DATA_TYPE_REGISTRY);
@@ -175,6 +181,17 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
@@ -189,6 +194,17 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
return GameEventListenerRegistry.NOOP;
}
@@ -160,7 +117,7 @@ index 1aac95b03a9e2e37c24f2a30bcb259c1424e1c78..253dfb24df08b3f3173cd23844320695
+ public boolean isSlimeChunk() {
+ if (!hasComputedSlimeChunk) {
+ hasComputedSlimeChunk = true;
+ slimeChunk = WorldgenCryptoRandom.seedSlimeChunk(chunkPos.x, chunkPos.z).nextInt(10) == 0;
+ slimeChunk = space.bxteam.divinemc.seed.WorldgenCryptoRandom.seedSlimeChunk(chunkPos.x, chunkPos.z).nextInt(10) == 0;
+ }
+
+ return slimeChunk;
@@ -171,34 +128,23 @@ index 1aac95b03a9e2e37c24f2a30bcb259c1424e1c78..253dfb24df08b3f3173cd23844320695
@Nullable
public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean moved);
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
index 927bdebdb8ae01613f0cea074b3367bd7ffe9ab1..01e83ad86d9dd952481891ce21d20adbf1d4db1b 100644
index 488938c32a48437721a71d294c77468f00c035b9..7557808c22a827564d23d42f365db5a2f3e1343a 100644
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
@@ -78,6 +78,10 @@ import net.minecraft.world.level.levelgen.structure.placement.RandomSpreadStruct
import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
import org.apache.commons.lang3.mutable.MutableBoolean;
+// DivineMC start
+import space.bxteam.divinemc.seed.WorldgenCryptoRandom;
+import space.bxteam.divinemc.seed.WorldSeedUtils;
+// DivineMC end
public abstract class ChunkGenerator {
@@ -345,7 +349,11 @@ public abstract class ChunkGenerator {
@@ -344,7 +344,11 @@ public abstract class ChunkGenerator {
return structure.step().ordinal();
}));
List<FeatureSorter.StepFeatureData> list = (List) this.featuresPerStep.get();
- WorldgenRandom seededrandom = new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed()));
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom seededrandom = space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed ? new WorldgenCryptoRandom(
+ blockposition.getX(), blockposition.getZ(), WorldSeedUtils.Salt.UNDEFINED, 0
+ ) : new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed()));
+ WorldgenRandom seededrandom = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(blockposition.getX(), blockposition.getZ(), space.bxteam.divinemc.seed.Globals.Salt.UNDEFINED, 0)
+ : new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed()));
+ // DivineMC end
long i = seededrandom.setDecorationSeed(generatoraccessseed.getSeed(), blockposition.getX(), blockposition.getZ());
Set<Holder<Biome>> set = new ObjectArraySet();
@@ -584,9 +592,18 @@ public abstract class ChunkGenerator {
@@ -583,9 +587,18 @@ public abstract class ChunkGenerator {
ArrayList<StructureSet.StructureSelectionEntry> arraylist = new ArrayList(list.size());
arraylist.addAll(list);
@@ -207,9 +153,9 @@ index 927bdebdb8ae01613f0cea074b3367bd7ffe9ab1..01e83ad86d9dd952481891ce21d20adb
- seededrandom.setLargeFeatureSeed(placementCalculator.getLevelSeed(), chunkcoordintpair.x, chunkcoordintpair.z);
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom seededrandom;
+ if (space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed) {
+ seededrandom = new WorldgenCryptoRandom(
+ chunkcoordintpair.x, chunkcoordintpair.z, WorldSeedUtils.Salt.GENERATE_FEATURE, 0
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ seededrandom = new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
+ chunkcoordintpair.x, chunkcoordintpair.z, space.bxteam.divinemc.seed.Globals.Salt.GENERATE_FEATURE, 0
+ );
+ } else {
+ seededrandom = new WorldgenRandom(new LegacyRandomSource(0L));
@@ -221,22 +167,10 @@ index 927bdebdb8ae01613f0cea074b3367bd7ffe9ab1..01e83ad86d9dd952481891ce21d20adb
StructureSet.StructureSelectionEntry structureset_a1;
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
index a6b6e5ea191c0e2cd7a2e4f01b89d8af40a83c1b..b3439eb652bfe4e34b1537c8a6bf85a3c7cfe78a 100644
index a6b6e5ea191c0e2cd7a2e4f01b89d8af40a83c1b..20b452803f954a085d6c4718400f9eceadee1bc0 100644
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
@@ -39,6 +39,11 @@ import net.minecraft.world.level.levelgen.structure.placement.RandomSpreadStruct
import org.spigotmc.SpigotWorldConfig;
// Spigot end
+// DivineMC start
+import space.bxteam.divinemc.seed.WorldgenCryptoRandom;
+import space.bxteam.divinemc.seed.WorldSeedUtils;
+// DivineMC end
+
public class ChunkGeneratorStructureState {
private static final Logger LOGGER = LogUtils.getLogger();
@@ -224,15 +229,19 @@ public class ChunkGeneratorStructureState {
@@ -224,15 +224,20 @@ public class ChunkGeneratorStructureState {
List<CompletableFuture<ChunkPos>> list = new ArrayList(j);
int k = placement.spread();
HolderSet<Biome> holderset = placement.preferredBiomes();
@@ -250,9 +184,11 @@ index a6b6e5ea191c0e2cd7a2e4f01b89d8af40a83c1b..b3439eb652bfe4e34b1537c8a6bf85a3
- randomsource.setSeed(this.concentricRingsSeed);
- } // Paper - Add missing structure set seed configs
+ // DivineMC start - Implement Secure Seed
+ RandomSource randomsource = space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed ? new WorldgenCryptoRandom(0, 0, WorldSeedUtils.Salt.STRONGHOLDS, 0) : RandomSource.create();
+ RandomSource randomsource = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(0, 0, space.bxteam.divinemc.seed.Globals.Salt.STRONGHOLDS, 0)
+ : RandomSource.create();
+
+ if (!space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed) {
+ if (!space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ // Paper start - Add missing structure set seed configs
+ if (this.conf.strongholdSeed != null && structureSetEntry.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) {
+ randomsource.setSeed(this.conf.strongholdSeed);
@@ -260,39 +196,32 @@ index a6b6e5ea191c0e2cd7a2e4f01b89d8af40a83c1b..b3439eb652bfe4e34b1537c8a6bf85a3
+ // Paper end - Add missing structure set seed configs
+ randomsource.setSeed(this.concentricRingsSeed);
+ } // Paper - Add missing structure set seed configs
+ }
+ // DivineMC end
+ } // DivineMC end
double d0 = randomsource.nextDouble() * Math.PI * 2.0D;
int l = 0;
int i1 = 0;
diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java
index b81c548c0e1ac53784e9c94b34b65db5f123309c..e8420f5701f909afd195a6226c5e5b274b5b45f4 100644
--- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java
+++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java
@@ -231,6 +231,7 @@ public class ChunkStatus {
diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStep.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStep.java
index 4e56398a6fb8b97199f4c74ebebc1055fb718dcf..8cb513fcd1a7c9abe82513165153a615ef747566 100644
--- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStep.java
+++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStep.java
@@ -60,6 +60,7 @@ public final class ChunkStep implements ca.spottedleaf.moonrise.patches.chunk_sy
}
public CompletableFuture<ChunkAccess> generate(WorldGenContext context, Executor executor, ToFullChunk fullChunkConverter, List<ChunkAccess> chunks) {
+ space.bxteam.divinemc.seed.WorldSeedUtils.setupGlobals(context.level()); // DivineMC - Implement Secure Seed
ChunkAccess chunkAccess = chunks.get(chunks.size() / 2);
ProfiledDuration profiledDuration = JvmProfiler.INSTANCE.onChunkGenerate(chunkAccess.getPos(), context.level().dimension(), this.toString());
return this.generationTask.doWork(context, this, executor, fullChunkConverter, chunks, chunkAccess).thenApply(chunk -> {
public CompletableFuture<ChunkAccess> apply(WorldGenContext context, StaticCache2D<GenerationChunkHolder> staticCache2D, ChunkAccess chunk) {
+ space.bxteam.divinemc.seed.Globals.setupGlobals(context.level()); // DivineMC - Implement Secure Seed
if (chunk.getPersistedStatus().isBefore(this.targetStatus)) {
ProfiledDuration profiledDuration = JvmProfiler.INSTANCE.onChunkGenerate(chunk.getPos(), context.level().dimension(), this.targetStatus.getName());
return this.task.doWork(context, this, staticCache2D, chunk).thenApply(generated -> this.completeChunkGeneration(generated, profiledDuration));
diff --git a/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java b/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java
index 5ae04ec610a885e2ed73e942879a27fe8640471c..1e04d6a2e13b10a3eaeea06959ee24241cf70120 100644
index 5ae04ec610a885e2ed73e942879a27fe8640471c..0ceb4e744938d98f7288b6690fb98ae012777270 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java
@@ -5,12 +5,25 @@ import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.Optional;
import java.util.OptionalLong;
+import java.util.stream.LongStream; // DivineMC
import net.minecraft.util.RandomSource;
@@ -9,8 +9,19 @@ import net.minecraft.util.RandomSource;
import org.apache.commons.lang3.StringUtils;
+import space.bxteam.divinemc.seed.WorldSeedUtils; // DivineMC
public class WorldOptions {
+ // DivineMC start - Implement Secure Seed
+ private static final boolean isSecureSeedEnabled = space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed;
+ private static final boolean isSecureSeedEnabled = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed;
public static final MapCodec<WorldOptions> CODEC = RecordCodecBuilder.mapCodec(
- instance -> instance.group(
+ instance -> isSecureSeedEnabled
@@ -308,21 +237,23 @@ index 5ae04ec610a885e2ed73e942879a27fe8640471c..1e04d6a2e13b10a3eaeea06959ee2424
Codec.LONG.fieldOf("seed").stable().forGetter(WorldOptions::seed),
Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldOptions::generateStructures),
Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldOptions::generateBonusChest),
@@ -18,18 +31,29 @@ public class WorldOptions {
@@ -18,8 +29,14 @@ public class WorldOptions {
)
.apply(instance, instance.stable(WorldOptions::new))
);
- public static final WorldOptions DEMO_OPTIONS = new WorldOptions((long)"North Carolina".hashCode(), true, true);
+ // DivineMC end
+ public static final WorldOptions DEMO_OPTIONS = isSecureSeedEnabled ? new WorldOptions((long) "North Carolina".hashCode(), WorldSeedUtils.createRandomWorldSeed(), true, true) : new WorldOptions("North Carolina".hashCode(), true, true); // DivineMC - Implement Secure Seed
+ // DivineMC start - Implement Secure Seed
+ public static final WorldOptions DEMO_OPTIONS = isSecureSeedEnabled
+ ? new WorldOptions((long) "North Carolina".hashCode(), space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(), true, true)
+ : new WorldOptions("North Carolina".hashCode(), true, true);
+ // DivineMC end
private final long seed;
+ private long[] featureSeed = WorldSeedUtils.createRandomWorldSeed(); // DivineMC - Implement Secure Seed
+ private long[] featureSeed = space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(); // DivineMC - Implement Secure Seed
private final boolean generateStructures;
private final boolean generateBonusChest;
private final Optional<String> legacyCustomOptions;
+ // DivineMC start - Implement Secure Seed
public WorldOptions(long seed, boolean generateStructures, boolean bonusChest) {
@@ -28,8 +45,18 @@ public class WorldOptions {
this(seed, generateStructures, bonusChest, Optional.empty());
}
@@ -332,18 +263,21 @@ index 5ae04ec610a885e2ed73e942879a27fe8640471c..1e04d6a2e13b10a3eaeea06959ee2424
+
public static WorldOptions defaultWithRandomSeed() {
- return new WorldOptions(randomSeed(), true, false);
+ return isSecureSeedEnabled ? new WorldOptions(randomSeed(), WorldSeedUtils.createRandomWorldSeed(), true, false) : new WorldOptions(randomSeed(), true, false);
+ return isSecureSeedEnabled
+ ? new WorldOptions(randomSeed(), space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(), true, false)
+ : new WorldOptions(randomSeed(), true, false);
+ }
+
+ private WorldOptions(long seed, LongStream featureSeed, boolean generateStructures, boolean bonusChest, Optional<String> legacyCustomOptions) {
+ private WorldOptions(long seed, java.util.stream.LongStream featureSeed, boolean generateStructures, boolean bonusChest, Optional<String> legacyCustomOptions) {
+ this(seed, featureSeed.toArray(), generateStructures, bonusChest, legacyCustomOptions);
}
private WorldOptions(long seed, boolean generateStructures, boolean bonusChest, Optional<String> legacyCustomOptions) {
@@ -39,10 +63,26 @@ public class WorldOptions {
@@ -39,10 +66,27 @@ public class WorldOptions {
this.legacyCustomOptions = legacyCustomOptions;
}
+ // DivineMC start - Implement Secure Seed
+ private WorldOptions(long seed, long[] featureSeed, boolean generateStructures, boolean bonusChest, Optional<String> legacyCustomOptions) {
+ this(seed, generateStructures, bonusChest, legacyCustomOptions);
+ this.featureSeed = featureSeed;
@@ -359,95 +293,72 @@ index 5ae04ec610a885e2ed73e942879a27fe8640471c..1e04d6a2e13b10a3eaeea06959ee2424
+ return this.featureSeed;
+ }
+
+ public LongStream featureSeedStream() {
+ return LongStream.of(this.featureSeed);
+ public java.util.stream.LongStream featureSeedStream() {
+ return java.util.stream.LongStream.of(this.featureSeed);
+ }
+ // DivineMC end
+
public boolean generateStructures() {
return this.generateStructures;
}
@@ -55,17 +95,19 @@ public class WorldOptions {
@@ -55,17 +99,25 @@ public class WorldOptions {
return this.legacyCustomOptions.isPresent();
}
+ // DivineMC start - Implement Secure Seed
public WorldOptions withBonusChest(boolean bonusChest) {
- return new WorldOptions(this.seed, this.generateStructures, bonusChest, this.legacyCustomOptions);
+ return isSecureSeedEnabled ? new WorldOptions(this.seed, this.featureSeed, this.generateStructures, bonusChest, this.legacyCustomOptions) : new WorldOptions(this.seed, this.generateStructures, bonusChest, this.legacyCustomOptions);
+ return isSecureSeedEnabled
+ ? new WorldOptions(this.seed, this.featureSeed, this.generateStructures, bonusChest, this.legacyCustomOptions)
+ : new WorldOptions(this.seed, this.generateStructures, bonusChest, this.legacyCustomOptions);
}
public WorldOptions withStructures(boolean structures) {
- return new WorldOptions(this.seed, structures, this.generateBonusChest, this.legacyCustomOptions);
+ return isSecureSeedEnabled ? new WorldOptions(this.seed, this.featureSeed, structures, this.generateBonusChest, this.legacyCustomOptions) : new WorldOptions(this.seed, structures, this.generateBonusChest, this.legacyCustomOptions);
+ return isSecureSeedEnabled
+ ? new WorldOptions(this.seed, this.featureSeed, structures, this.generateBonusChest, this.legacyCustomOptions)
+ : new WorldOptions(this.seed, structures, this.generateBonusChest, this.legacyCustomOptions);
}
public WorldOptions withSeed(OptionalLong seed) {
- return new WorldOptions(seed.orElse(randomSeed()), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions);
+ return isSecureSeedEnabled ? new WorldOptions(seed.orElse(randomSeed()), WorldSeedUtils.createRandomWorldSeed(), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions) : new WorldOptions(seed.orElse(randomSeed()), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions);
+ return isSecureSeedEnabled
+ ? new WorldOptions(seed.orElse(randomSeed()), space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions)
+ : new WorldOptions(seed.orElse(randomSeed()), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions);
}
+ // DivineMC end
public static OptionalLong parseSeed(String seed) {
seed = seed.trim();
@@ -75,7 +117,7 @@ public class WorldOptions {
try {
return OptionalLong.of(Long.parseLong(seed));
} catch (NumberFormatException var2) {
- return OptionalLong.of((long)seed.hashCode());
+ return OptionalLong.of((long) seed.hashCode());
}
}
}
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
index 17d2bb3f7d158ec1230a1ad7c52b9feeda586630..31997bc79a95079009b7545cc91da7efef1a0179 100644
index 17d2bb3f7d158ec1230a1ad7c52b9feeda586630..a1c922ae0962a32fd11d57cbf7a2d0ef47d13911 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
@@ -25,6 +25,11 @@ import net.minecraft.world.level.levelgen.feature.configurations.GeodeConfigurat
import net.minecraft.world.level.levelgen.synth.NormalNoise;
import net.minecraft.world.level.material.FluidState;
+// DivineMC start - Implement Secure Seed
+import space.bxteam.divinemc.seed.WorldSeedUtils;
+import space.bxteam.divinemc.seed.WorldgenCryptoRandom;
+// DivineMC end
+
public class GeodeFeature extends Feature<GeodeConfiguration> {
private static final Direction[] DIRECTIONS = Direction.values();
@@ -42,7 +47,7 @@ public class GeodeFeature extends Feature<GeodeConfiguration> {
@@ -42,7 +42,11 @@ public class GeodeFeature extends Feature<GeodeConfiguration> {
int j = geodeConfiguration.maxGenOffset;
List<Pair<BlockPos, Integer>> list = Lists.newLinkedList();
int k = geodeConfiguration.distributionPoints.sample(randomSource);
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed()));
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed ? new WorldgenCryptoRandom(0, 0, WorldSeedUtils.Salt.GEODE_FEATURE, 0) : new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed())); // DivineMC - Implement Secure Seed
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(0, 0, space.bxteam.divinemc.seed.Globals.Salt.GEODE_FEATURE, 0)
+ : new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed()));
+ // DivineMC end
NormalNoise normalNoise = NormalNoise.create(worldgenRandom, -4, 1.0);
List<BlockPos> list2 = Lists.newLinkedList();
double d = (double)k / (double)geodeConfiguration.outerWallDistance.getMaxValue();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/Structure.java b/src/main/java/net/minecraft/world/level/levelgen/structure/Structure.java
index 4d7398cbe2c400791e6598c9924202a454cb56ce..9d276cfddf124642a5fc07e9727c507b8544b854 100644
index 3fbd6e8d23f2e6020532530ef8ad7e64b8047d4b..3711cf43e6a853b68cb9689d496dfb9029094c2e 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/Structure.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/Structure.java
@@ -39,6 +39,11 @@ import net.minecraft.world.level.levelgen.structure.pieces.PiecesContainer;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
+// DivineMC start - Implement Secure Seed
+import space.bxteam.divinemc.seed.WorldSeedUtils;
+import space.bxteam.divinemc.seed.WorldgenCryptoRandom;
+// DivineMC end
+
public abstract class Structure {
public static final Codec<Structure> DIRECT_CODEC = BuiltInRegistries.STRUCTURE_TYPE.byNameCodec().dispatch(Structure::type, StructureType::codec);
public static final Codec<Holder<Structure>> CODEC = RegistryFileCodec.create(Registries.STRUCTURE, DIRECT_CODEC);
@@ -233,6 +238,14 @@ public abstract class Structure {
@@ -233,6 +233,14 @@ public abstract class Structure {
}
private static WorldgenRandom makeRandom(long seed, ChunkPos chunkPos) {
+ // DivineMC start - Implement Secure Seed
+ if (space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed) {
+ return new WorldgenCryptoRandom(
+ chunkPos.x, chunkPos.z, WorldSeedUtils.Salt.GENERATE_FEATURE, seed
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ return new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
+ chunkPos.x, chunkPos.z, space.bxteam.divinemc.seed.Globals.Salt.GENERATE_FEATURE, seed
+ );
+ }
+ // DivineMC end
@@ -456,22 +367,10 @@ index 4d7398cbe2c400791e6598c9924202a454cb56ce..9d276cfddf124642a5fc07e9727c507b
worldgenRandom.setLargeFeatureSeed(seed, chunkPos.x, chunkPos.z);
return worldgenRandom;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
index f873a0a0734b4fe74ba5b5f8ae0cc3c78fa76b9f..bc932b9160f818009fc9974078c784feac1c7de2 100644
index f873a0a0734b4fe74ba5b5f8ae0cc3c78fa76b9f..1e29d5554ac2be3219f075092778e49022788723 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
@@ -11,6 +11,11 @@ import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
import net.minecraft.world.level.levelgen.LegacyRandomSource;
import net.minecraft.world.level.levelgen.WorldgenRandom;
+// DivineMC start - Implement Secure Seed
+import space.bxteam.divinemc.seed.WorldSeedUtils;
+import space.bxteam.divinemc.seed.WorldgenCryptoRandom;
+// DivineMC end
+
public class RandomSpreadStructurePlacement extends StructurePlacement {
public static final MapCodec<RandomSpreadStructurePlacement> CODEC = RecordCodecBuilder.<RandomSpreadStructurePlacement>mapCodec(
instance -> placementCodec(instance)
@@ -71,8 +76,17 @@ public class RandomSpreadStructurePlacement extends StructurePlacement {
@@ -71,8 +71,17 @@ public class RandomSpreadStructurePlacement extends StructurePlacement {
public ChunkPos getPotentialStructureChunk(long seed, int chunkX, int chunkZ) {
int i = Math.floorDiv(chunkX, this.spacing);
int j = Math.floorDiv(chunkZ, this.spacing);
@@ -479,9 +378,9 @@ index f873a0a0734b4fe74ba5b5f8ae0cc3c78fa76b9f..bc932b9160f818009fc9974078c784fe
- worldgenRandom.setLargeFeatureWithSalt(seed, i, j, this.salt());
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom;
+ if (space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed) {
+ worldgenRandom = new WorldgenCryptoRandom(
+ i, j, WorldSeedUtils.Salt.POTENTIONAL_FEATURE, this.salt
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ worldgenRandom = new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
+ i, j, space.bxteam.divinemc.seed.Globals.Salt.POTENTIONAL_FEATURE, this.salt
+ );
+ } else {
+ worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
@@ -492,21 +391,10 @@ index f873a0a0734b4fe74ba5b5f8ae0cc3c78fa76b9f..bc932b9160f818009fc9974078c784fe
int l = this.spreadType.evaluate(worldgenRandom, k);
int m = this.spreadType.evaluate(worldgenRandom, k);
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
index cbf13e4f2da6a27619e9bc9a7cd73bb6e69cad2a..1f52d0de1a603037738b961873b9ee18125b786e 100644
index cbf13e4f2da6a27619e9bc9a7cd73bb6e69cad2a..8aebe917973f65123a3b0744172a307f95b05cb0 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
@@ -19,6 +19,10 @@ import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
import net.minecraft.world.level.levelgen.LegacyRandomSource;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import net.minecraft.world.level.levelgen.structure.StructureSet;
+// DivineMC start
+import space.bxteam.divinemc.seed.WorldgenCryptoRandom;
+import space.bxteam.divinemc.seed.WorldSeedUtils;
+// DivineMC end
public abstract class StructurePlacement {
public static final Codec<StructurePlacement> CODEC = BuiltInRegistries.STRUCTURE_PLACEMENT
@@ -118,8 +122,17 @@ public abstract class StructurePlacement {
@@ -118,8 +118,18 @@ public abstract class StructurePlacement {
public abstract StructurePlacementType<?> type();
private static boolean probabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs; ignore here
@@ -514,99 +402,188 @@ index cbf13e4f2da6a27619e9bc9a7cd73bb6e69cad2a..1f52d0de1a603037738b961873b9ee18
- worldgenRandom.setLargeFeatureWithSalt(seed, salt, chunkX, chunkZ);
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom;
+ if (space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed) {
+ worldgenRandom = new WorldgenCryptoRandom(
+ chunkX, chunkZ, WorldSeedUtils.Salt.UNDEFINED, salt
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ worldgenRandom = new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
+ chunkX, chunkZ, space.bxteam.divinemc.seed.Globals.Salt.UNDEFINED, salt
+ );
+ } else {
+ worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
+ worldgenRandom.setLargeFeatureWithSalt(seed, salt, chunkX, chunkZ);
+ }
+ // DivineMC end
+
return worldgenRandom.nextFloat() < frequency;
}
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java b/src/main/java/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
index 70dbf7267b43357578c07fcd46618f656410a8e2..c1ee25acabf60f78829176a77bfac377cab78c91 100644
index 139c6d974e4d68c75406760f7d79034abefd7c28..9287854d9ae51c7b0a4a1c0cb4a38c8d803d8ffa 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
@@ -43,6 +43,11 @@ import net.minecraft.world.phys.shapes.VoxelShape;
import org.apache.commons.lang3.mutable.MutableObject;
import org.slf4j.Logger;
+// DivineMC start - Implement Secure Seed
+import space.bxteam.divinemc.seed.WorldSeedUtils;
+import space.bxteam.divinemc.seed.WorldgenCryptoRandom;
+// DivineMC end
+
public class JigsawPlacement {
static final Logger LOGGER = LogUtils.getLogger();
@@ -61,7 +66,11 @@ public class JigsawPlacement {
@@ -65,7 +65,11 @@ public class JigsawPlacement {
ChunkGenerator chunkGenerator = context.chunkGenerator();
StructureTemplateManager structureTemplateManager = context.structureTemplateManager();
LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
- WorldgenRandom worldgenRandom = context.random();
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed ? new WorldgenCryptoRandom(
+ context.chunkPos().x, context.chunkPos().z, WorldSeedUtils.Salt.JIGSAW_PLACEMENT, 0
+ ) : context.random();
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(context.chunkPos().x, context.chunkPos().z, space.bxteam.divinemc.seed.Globals.Salt.JIGSAW_PLACEMENT, 0)
+ : context.random();
+ // DivineMC end
Registry<StructureTemplatePool> registry = registryAccess.registryOrThrow(Registries.TEMPLATE_POOL);
Rotation rotation = Rotation.getRandom(worldgenRandom);
StructureTemplatePool structureTemplatePool = structurePool.unwrapKey()
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
index 92f1ea81b5e90529905d9c508aca18c31443ff6a..ae1a1d4b86a41d4a1c149caf9df42fa580da9957 100644
index 45e262308aebafa377a2353661acdd122933b99e..dd78e5231e465957308a4e1b56b14e9e67ea592b 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
@@ -203,7 +203,10 @@ public class CraftChunk implements Chunk {
@@ -205,7 +205,12 @@ public class CraftChunk implements Chunk {
@Override
public boolean isSlimeChunk() {
// 987234911L is deterimined in EntitySlime when seeing if a slime can spawn in a chunk
- return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
+ // DivineMC start - Implement Secure Seed
+ boolean isSlimeChunk = space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed ? worldServer.getChunk(this.getX(), this.getZ()).isSlimeChunk() : WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
+ boolean isSlimeChunk = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? worldServer.getChunk(this.getX(), this.getZ()).isSlimeChunk()
+ : WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
+ return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || isSlimeChunk;
+ // DivineMC end
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index e21f1398c2efba9856718cb30328ac6ec5a4484e..1e0c88fa14819030376efe0208d09aebf47b4b09 100644
index 1a9964d77202df87b05fb47ba1edb62e7be17049..0dd7dddde9d39ebf3ad94f982daf7a051121bf33 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -266,6 +266,8 @@ import javax.annotation.Nonnull; // Paper
import space.bxteam.divinemc.configuration.DivineConfig; // DivineMC
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; // DivineMC
+import space.bxteam.divinemc.seed.WorldSeedUtils; // DivineMC
+import space.bxteam.divinemc.seed.WorldgenCryptoRandom; // DivineMC
public final class CraftServer implements Server {
private final String serverName = io.papermc.paper.ServerBuildInfo.buildInfo().brandName(); // Paper
@@ -1380,7 +1382,7 @@ public final class CraftServer implements Server {
@@ -1392,7 +1392,11 @@ public final class CraftServer implements Server {
iregistrycustom_dimension = leveldataanddimensions.dimensions().dimensionsRegistryAccess();
} else {
LevelSettings worldsettings;
- WorldOptions worldoptions = new WorldOptions(creator.seed(), creator.generateStructures(), false);
+ WorldOptions worldoptions = space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed ? new WorldOptions(creator.seed(), WorldSeedUtils.createRandomWorldSeed(), creator.generateStructures(), false) : new WorldOptions(creator.seed(), creator.generateStructures(), false); // DivineMC - Implement Secure Seed
+ // DivineMC start - Implement Secure Seed
+ WorldOptions worldoptions = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? new WorldOptions(creator.seed(), space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(), creator.generateStructures(), false)
+ : new WorldOptions(creator.seed(), creator.generateStructures(), false);
+ // DivineMC end
WorldDimensions worlddimensions;
DedicatedServerProperties.WorldDimensionData properties = new DedicatedServerProperties.WorldDimensionData(GsonHelper.parse((creator.generatorSettings().isEmpty()) ? "{}" : creator.generatorSettings()), creator.type().name().toLowerCase(Locale.ROOT));
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
index f0be52e3a72a7eaa5b7d840fa00b5be1edacf156..e2eac66da19b1e9bc5f776d85b487d769121a9b3 100644
index 0dd1fb7bfcf8e8b475987c5e46a1fbd3431a121c..2070e5e83c764b38351a2e28844b92dc4d37a308 100644
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
@@ -194,4 +194,9 @@ public class DivineConfig {
else
Bukkit.getLogger().log(Level.INFO, "Using " + asyncPathfindingMaxThreads + " threads for Async Pathfinding");
@@ -156,10 +156,12 @@ public class DivineConfig {
public static boolean disableNonEditableSignWarning = true;
public static boolean removeVanillaUsernameCheck = false;
public static boolean disableMovedWronglyThreshold = false;
+ public static boolean enableSecureSeed = false;
private static void miscSettings() {
disableNonEditableSignWarning = getBoolean("settings.misc.disable-non-editable-sign-warning", disableNonEditableSignWarning);
removeVanillaUsernameCheck = getBoolean("settings.misc.remove-vanilla-username-check", removeVanillaUsernameCheck);
disableMovedWronglyThreshold = getBoolean("settings.misc.disable-moved-wrongly-threshold", disableMovedWronglyThreshold);
+ enableSecureSeed = getBoolean("settings.misc.enable-secure-seed", enableSecureSeed);
}
public static boolean biomeManagerOptimization = true;
diff --git a/src/main/java/space/bxteam/divinemc/seed/Globals.java b/src/main/java/space/bxteam/divinemc/seed/Globals.java
new file mode 100644
index 0000000000000000000000000000000000000000..39d2d74f6a89ecbe42ef45d9fc500762a2dfce51
--- /dev/null
+++ b/src/main/java/space/bxteam/divinemc/seed/Globals.java
@@ -0,0 +1,94 @@
+package space.bxteam.divinemc.seed;
+
+ public static boolean useSecureSeed = false;
+ private static void miscSettings() {
+ useSecureSeed = getBoolean("settings.misc.use-secure-seed", useSecureSeed);
+import com.google.common.collect.Iterables;
+import net.minecraft.server.level.ServerLevel;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+import java.util.Optional;
+
+public class Globals {
+ public static final int WORLD_SEED_LONGS = 16;
+ public static final int WORLD_SEED_BITS = WORLD_SEED_LONGS * 64;
+
+ public static final long[] worldSeed = new long[WORLD_SEED_LONGS];
+ public static final ThreadLocal<Integer> dimension = ThreadLocal.withInitial(() -> 0);
+
+ public enum Salt {
+ UNDEFINED,
+ BASTION_FEATURE,
+ WOODLAND_MANSION_FEATURE,
+ MINESHAFT_FEATURE,
+ BURIED_TREASURE_FEATURE,
+ NETHER_FORTRESS_FEATURE,
+ PILLAGER_OUTPOST_FEATURE,
+ GEODE_FEATURE,
+ NETHER_FOSSIL_FEATURE,
+ OCEAN_MONUMENT_FEATURE,
+ RUINED_PORTAL_FEATURE,
+ POTENTIONAL_FEATURE,
+ GENERATE_FEATURE,
+ JIGSAW_PLACEMENT,
+ STRONGHOLDS,
+ POPULATION,
+ DECORATION,
+ SLIME_CHUNK
+ }
}
+
+ public static void setupGlobals(ServerLevel world) {
+ if (!space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) return;
+
+ long[] seed = world.getServer().getWorldData().worldGenOptions().featureSeed();
+ System.arraycopy(seed, 0, worldSeed, 0, WORLD_SEED_LONGS);
+ int worldIndex = Iterables.indexOf(world.getServer().levelKeys(), it -> it == world.dimension());
+ if (worldIndex == -1)
+ worldIndex = world.getServer().levelKeys().size(); // if we are in world construction it may not have been added to the map yet
+ dimension.set(worldIndex);
+ }
+
+ public static long[] createRandomWorldSeed() {
+ long[] seed = new long[WORLD_SEED_LONGS];
+ SecureRandom rand = new SecureRandom();
+ for (int i = 0; i < WORLD_SEED_LONGS; i++) {
+ seed[i] = rand.nextLong();
+ }
+ return seed;
+ }
+
+ // 1024-bit string -> 16 * 64 long[]
+ public static Optional<long[]> parseSeed(String seedStr) {
+ if (seedStr.isEmpty()) return Optional.empty();
+
+ if (seedStr.length() != WORLD_SEED_BITS) {
+ throw new IllegalArgumentException("Secure seed length must be " + WORLD_SEED_BITS + "-bit but found " + seedStr.length() + "-bit.");
+ }
+
+ long[] seed = new long[WORLD_SEED_LONGS];
+
+ for (int i = 0; i < WORLD_SEED_LONGS; i++) {
+ int start = i * 64;
+ int end = start + 64;
+ String seedSection = seedStr.substring(start, end);
+
+ BigInteger seedInDecimal = new BigInteger(seedSection, 2);
+ seed[i] = seedInDecimal.longValue();
+ }
+
+ return Optional.of(seed);
+ }
+
+ // 16 * 64 long[] -> 1024-bit string
+ public static String seedToString(long[] seed) {
+ StringBuilder sb = new StringBuilder();
+
+ for (long longV : seed) {
+ // Convert to 64-bit binary string per long
+ // Use format to keep 64-bit length, and use 0 to complete space
+ String binaryStr = String.format("%64s", Long.toBinaryString(longV)).replace(' ', '0');
+
+ sb.append(binaryStr);
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/src/main/java/space/bxteam/divinemc/seed/Hashing.java b/src/main/java/space/bxteam/divinemc/seed/Hashing.java
new file mode 100644
index 0000000000000000000000000000000000000000..5974e52ec4ad6422ef0eac19d0b32be233889a40
@@ -686,111 +663,9 @@ index 0000000000000000000000000000000000000000..5974e52ec4ad6422ef0eac19d0b32be2
+ internalState[posB] = Long.rotateRight(internalState[posB] ^ internalState[posC], 63); // replaces 11 of BLAKE
+ }
+}
diff --git a/src/main/java/space/bxteam/divinemc/seed/WorldSeedUtils.java b/src/main/java/space/bxteam/divinemc/seed/WorldSeedUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..2883213e32f47016d13427bc923c54ba9706d04a
--- /dev/null
+++ b/src/main/java/space/bxteam/divinemc/seed/WorldSeedUtils.java
@@ -0,0 +1,96 @@
+package space.bxteam.divinemc.seed;
+
+import com.google.common.collect.Iterables;
+import net.minecraft.server.level.ServerLevel;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+import java.util.Optional;
+
+public class WorldSeedUtils {
+ public static final int WORLD_SEED_LONGS = 16;
+ public static final int WORLD_SEED_BITS = WORLD_SEED_LONGS * 64;
+
+ public static final long[] worldSeed = new long[WORLD_SEED_LONGS];
+ public static final ThreadLocal<Integer> dimension = ThreadLocal.withInitial(() -> 0);
+
+ public enum Salt {
+ UNDEFINED,
+ BASTION_FEATURE,
+ WOODLAND_MANSION_FEATURE,
+ MINESHAFT_FEATURE,
+ BURIED_TREASURE_FEATURE,
+ NETHER_FORTRESS_FEATURE,
+ PILLAGER_OUTPOST_FEATURE,
+ GEODE_FEATURE,
+ NETHER_FOSSIL_FEATURE,
+ OCEAN_MONUMENT_FEATURE,
+ RUINED_PORTAL_FEATURE,
+ POTENTIONAL_FEATURE,
+ GENERATE_FEATURE,
+ JIGSAW_PLACEMENT,
+ STRONGHOLDS,
+ POPULATION,
+ DECORATION,
+ SLIME_CHUNK
+ }
+
+ public static void setupGlobals(ServerLevel world) {
+ if (!space.bxteam.divinemc.configuration.DivineConfig.useSecureSeed) return;
+
+ long[] seed = world.getServer().getWorldData().worldGenOptions().featureSeed();
+ System.arraycopy(seed, 0, worldSeed, 0, WORLD_SEED_LONGS);
+ int worldIndex = Iterables.indexOf(world.getServer().levelKeys(), it -> it == world.dimension());
+ if (worldIndex == -1)
+ worldIndex = world.getServer().levelKeys().size(); // if we are in world construction it may not have been added to the map yet
+ dimension.set(worldIndex);
+ }
+
+ public static long[] createRandomWorldSeed() {
+ long[] seed = new long[WORLD_SEED_LONGS];
+ SecureRandom rand = new SecureRandom();
+ for (int i = 0; i < WORLD_SEED_LONGS; i++) {
+ seed[i] = rand.nextLong();
+ }
+ return seed;
+ }
+
+ public static Optional<long[]> parseSeed(String seedStr) {
+ if (seedStr.isEmpty()) return Optional.empty();
+
+ try {
+ long[] seed = new long[WORLD_SEED_LONGS];
+ BigInteger seedBigInt = new BigInteger(seedStr);
+ if (seedBigInt.signum() < 0) {
+ seedBigInt = seedBigInt.and(BigInteger.ONE.shiftLeft(WORLD_SEED_BITS).subtract(BigInteger.ONE));
+ }
+ for (int i = 0; i < WORLD_SEED_LONGS; i++) {
+ BigInteger[] divRem = seedBigInt.divideAndRemainder(BigInteger.ONE.shiftLeft(64));
+ seed[i] = divRem[1].longValue();
+ seedBigInt = divRem[0];
+ }
+ return Optional.of(seed);
+ } catch (NumberFormatException ignored) {
+ return Optional.empty();
+ }
+ }
+
+ public static String seedToString(long[] seed) {
+ BigInteger seedBigInt = BigInteger.ZERO;
+ for (int i = WORLD_SEED_LONGS - 1; i >= 0; i--) {
+ BigInteger val = BigInteger.valueOf(seed[i]);
+ if (val.signum() < 0) {
+ val = val.add(BigInteger.ONE.shiftLeft(64));
+ }
+ seedBigInt = seedBigInt.shiftLeft(64).add(val);
+ }
+
+ // Ensure the output is 1024-bit length
+ int seedLength = seedBigInt.bitLength();
+ if (seedLength < 1024) {
+ seedBigInt = seedBigInt.add(BigInteger.ONE.shiftLeft(1025 - seedLength)); // Use 1025 since the first sign bit
+ }
+
+ return seedBigInt.toString();
+ }
+}
diff --git a/src/main/java/space/bxteam/divinemc/seed/WorldgenCryptoRandom.java b/src/main/java/space/bxteam/divinemc/seed/WorldgenCryptoRandom.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e26c7698d3994eb1f345195d93b866159384496
index 0000000000000000000000000000000000000000..f6e69a105c8267c1cf85e77e406ec9fc634a8dd6
--- /dev/null
+++ b/src/main/java/space/bxteam/divinemc/seed/WorldgenCryptoRandom.java
@@ -0,0 +1,159 @@
@@ -806,11 +681,11 @@ index 0000000000000000000000000000000000000000..3e26c7698d3994eb1f345195d93b8661
+
+public class WorldgenCryptoRandom extends WorldgenRandom {
+ // hash the world seed to guard against badly chosen world seeds
+ private static final long[] HASHED_ZERO_SEED = Hashing.hashWorldSeed(new long[WorldSeedUtils.WORLD_SEED_LONGS]);
+ private static final ThreadLocal<long[]> LAST_SEEN_WORLD_SEED = ThreadLocal.withInitial(() -> new long[WorldSeedUtils.WORLD_SEED_LONGS]);
+ private static final long[] HASHED_ZERO_SEED = Hashing.hashWorldSeed(new long[Globals.WORLD_SEED_LONGS]);
+ private static final ThreadLocal<long[]> LAST_SEEN_WORLD_SEED = ThreadLocal.withInitial(() -> new long[Globals.WORLD_SEED_LONGS]);
+ private static final ThreadLocal<long[]> HASHED_WORLD_SEED = ThreadLocal.withInitial(() -> HASHED_ZERO_SEED);
+
+ private final long[] worldSeed = new long[WorldSeedUtils.WORLD_SEED_LONGS];
+ private final long[] worldSeed = new long[Globals.WORLD_SEED_LONGS];
+ private final long[] randomBits = new long[8];
+ private int randomBitIndex;
+ private static final int MAX_RANDOM_BIT_INDEX = 64 * 8;
@@ -819,17 +694,17 @@ index 0000000000000000000000000000000000000000..3e26c7698d3994eb1f345195d93b8661
+ private final long[] message = new long[16];
+ private final long[] cachedInternalState = new long[16];
+
+ public WorldgenCryptoRandom(int x, int z, WorldSeedUtils.Salt typeSalt, long salt) {
+ public WorldgenCryptoRandom(int x, int z, Globals.Salt typeSalt, long salt) {
+ super(new LegacyRandomSource(0L));
+ if (typeSalt != null) {
+ this.setSecureSeed(x, z, typeSalt, salt);
+ }
+ }
+
+ public void setSecureSeed(int x, int z, WorldSeedUtils.Salt typeSalt, long salt) {
+ System.arraycopy(WorldSeedUtils.worldSeed, 0, this.worldSeed, 0, WorldSeedUtils.WORLD_SEED_LONGS);
+ public void setSecureSeed(int x, int z, Globals.Salt typeSalt, long salt) {
+ System.arraycopy(Globals.worldSeed, 0, this.worldSeed, 0, Globals.WORLD_SEED_LONGS);
+ message[0] = ((long) x << 32) | ((long) z & 0xffffffffL);
+ message[1] = ((long) WorldSeedUtils.dimension.get() << 32) | ((long) salt & 0xffffffffL);
+ message[1] = ((long) Globals.dimension.get() << 32) | ((long) salt & 0xffffffffL);
+ message[2] = typeSalt.ordinal();
+ message[3] = counter = 0;
+ randomBitIndex = MAX_RANDOM_BIT_INDEX;
@@ -838,7 +713,7 @@ index 0000000000000000000000000000000000000000..3e26c7698d3994eb1f345195d93b8661
+ private long[] getHashedWorldSeed() {
+ if (!Arrays.equals(worldSeed, LAST_SEEN_WORLD_SEED.get())) {
+ HASHED_WORLD_SEED.set(Hashing.hashWorldSeed(worldSeed));
+ System.arraycopy(worldSeed, 0, LAST_SEEN_WORLD_SEED.get(), 0, WorldSeedUtils.WORLD_SEED_LONGS);
+ System.arraycopy(worldSeed, 0, LAST_SEEN_WORLD_SEED.get(), 0, Globals.WORLD_SEED_LONGS);
+ }
+ return HASHED_WORLD_SEED.get();
+ }
@@ -879,7 +754,7 @@ index 0000000000000000000000000000000000000000..3e26c7698d3994eb1f345195d93b8661
+ public @NotNull RandomSource fork() {
+ WorldgenCryptoRandom fork = new WorldgenCryptoRandom(0, 0, null, 0);
+
+ System.arraycopy(WorldSeedUtils.worldSeed, 0, fork.worldSeed, 0, WorldSeedUtils.WORLD_SEED_LONGS);
+ System.arraycopy(Globals.worldSeed, 0, fork.worldSeed, 0, Globals.WORLD_SEED_LONGS);
+ fork.message[0] = this.message[0];
+ fork.message[1] = this.message[1];
+ fork.message[2] = this.message[2];
@@ -930,13 +805,13 @@ index 0000000000000000000000000000000000000000..3e26c7698d3994eb1f345195d93b8661
+
+ @Override
+ public long setDecorationSeed(long worldSeed, int blockX, int blockZ) {
+ setSecureSeed(blockX, blockZ, WorldSeedUtils.Salt.POPULATION, 0);
+ setSecureSeed(blockX, blockZ, Globals.Salt.POPULATION, 0);
+ return ((long) blockX << 32) | ((long) blockZ & 0xffffffffL);
+ }
+
+ @Override
+ public void setFeatureSeed(long populationSeed, int index, int step) {
+ setSecureSeed((int) (populationSeed >> 32), (int) populationSeed, WorldSeedUtils.Salt.DECORATION, index + 10000L * step);
+ setSecureSeed((int) (populationSeed >> 32), (int) populationSeed, Globals.Salt.DECORATION, index + 10000L * step);
+ }
+
+ @Override
@@ -950,6 +825,6 @@ index 0000000000000000000000000000000000000000..3e26c7698d3994eb1f345195d93b8661
+ }
+
+ public static RandomSource seedSlimeChunk(int chunkX, int chunkZ) {
+ return new WorldgenCryptoRandom(chunkX, chunkZ, WorldSeedUtils.Salt.SLIME_CHUNK, 0);
+ return new WorldgenCryptoRandom(chunkX, chunkZ, Globals.Salt.SLIME_CHUNK, 0);
+ }
+}