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

rollback to previous config system; fix patches

This commit is contained in:
NONPLAYT
2025-01-16 02:42:17 +03:00
parent 568f501624
commit dbb184d8af
30 changed files with 827 additions and 820 deletions

View File

@@ -4,135 +4,45 @@ Date: Sun, 12 Jan 2025 16:19:14 +0300
Subject: [PATCH] DivineMC Configuration
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 96253bf49a6895524f6f606a9c434cb1b78948a6..2c7c1335d4524486ed701365e64920091c85eaac 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -301,6 +301,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public volatile boolean abnormalExit; // Paper - Improved watchdog support
public volatile Thread shutdownThread; // Paper - Improved watchdog support
public final io.papermc.paper.configuration.PaperConfigurations paperConfigurations; // Paper - add paper configuration files
+ public final space.bxteam.divinemc.configuration.DivineConfigurations divineConfigurations; // DivineMC - add divine configuration files
public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
public boolean lagging = false; // Purpur - Lagging threshold
@@ -474,6 +475,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this));
// CraftBukkit end
this.paperConfigurations = services.paperConfigurations(); // Paper - add paper configuration files
+ this.divineConfigurations = services.divineConfigurations(); // DivineMC - add divinemc configuration files
}
private void readScoreboard(DimensionDataStorage dataStorage) {
diff --git a/net/minecraft/server/Services.java b/net/minecraft/server/Services.java
index ee760cc9d6756c40f13fe6459725dcfc200b9630..f407553fa89e85412193f617d01f2e365b47064e 100644
--- a/net/minecraft/server/Services.java
+++ b/net/minecraft/server/Services.java
@@ -11,13 +11,18 @@ import net.minecraft.server.players.GameProfileCache;
import net.minecraft.util.SignatureValidator;
public record Services(
- MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache, @javax.annotation.Nullable io.papermc.paper.configuration.PaperConfigurations paperConfigurations // Paper - add paper configuration files
+ MinecraftSessionService sessionService,
+ ServicesKeySet servicesKeySet,
+ GameProfileRepository profileRepository,
+ GameProfileCache profileCache,
+ @javax.annotation.Nullable io.papermc.paper.configuration.PaperConfigurations paperConfigurations, // Paper - add paper configuration files
+ @javax.annotation.Nullable space.bxteam.divinemc.configuration.DivineConfigurations divineConfigurations // DivineMC - Add configuration files for DivineMC
) {
public static final String USERID_CACHE_FILE = "usercache.json"; // Paper - private -> public
// Paper start - add paper configuration files
public Services(MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache) {
- this(sessionService, servicesKeySet, profileRepository, profileCache, null);
+ this(sessionService, servicesKeySet, profileRepository, profileCache, null, null); // DivineMC - add null for divineConfigurations
}
@Override
@@ -26,6 +31,13 @@ public record Services(
}
// Paper end - add paper configuration files
+ // DivineMC start - DivineMC configuration
+ @Override
+ public space.bxteam.divinemc.configuration.DivineConfigurations divineConfigurations() {
+ return java.util.Objects.requireNonNull(this.divineConfigurations);
+ }
+ // DivineMC end - DivineMC configuration
+
public static Services create(YggdrasilAuthenticationService authenticationService, File profileRepository, File userCacheFile, joptsimple.OptionSet optionSet) throws Exception { // Paper - add optionset to load paper config files; add userCacheFile parameter
MinecraftSessionService minecraftSessionService = authenticationService.createMinecraftSessionService();
GameProfileRepository gameProfileRepository = authenticationService.createProfileRepository();
@@ -34,7 +46,8 @@ public record Services(
final java.nio.file.Path legacyConfigPath = ((File) optionSet.valueOf("paper-settings")).toPath();
final java.nio.file.Path configDirPath = ((File) optionSet.valueOf("paper-settings-directory")).toPath();
io.papermc.paper.configuration.PaperConfigurations paperConfigurations = io.papermc.paper.configuration.PaperConfigurations.setup(legacyConfigPath, configDirPath, profileRepository.toPath(), (File) optionSet.valueOf("spigot-settings"));
- return new Services(minecraftSessionService, authenticationService.getServicesKeySet(), gameProfileRepository, gameProfileCache, paperConfigurations);
+ space.bxteam.divinemc.configuration.DivineConfigurations divineConfigurations = space.bxteam.divinemc.configuration.DivineConfigurations.setup(configDirPath); // DivineMC - setup divine configurations
+ return new Services(minecraftSessionService, authenticationService.getServicesKeySet(), gameProfileRepository, gameProfileCache, paperConfigurations, divineConfigurations); // DivineMC - add divineConfigurations
// Paper end - load paper config files from cli options
}
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 236b698ebc1dc8355dce35a3f27fdea877b7c599..5ec864a48aa2582458f741b9e81be8805d55913c 100644
index 2d7493122db9067ecbc9ca66cc62e7df4ae78a90..c85023893fbb227894f8f888244f1f53e25dff3f 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -222,6 +222,10 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess());
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
// Paper end - initialize global and world-defaults configuration
@@ -243,6 +243,17 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
}
org.purpurmc.purpur.PurpurConfig.registerCommands();
// Purpur end - Purpur config files
+
+ // DivineMC start - DivineMC configuration
+ divineConfigurations.initializeGlobalConfiguration(this.registryAccess());
+ divineConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
+ try {
+ space.bxteam.divinemc.configuration.DivineConfig.init((java.io.File) options.valueOf("divinemc-settings"));
+ } catch (Exception e) {
+ DedicatedServer.LOGGER.error("Unable to load server configuration", e);
+ return false;
+ }
+ space.bxteam.divinemc.command.DivineCommands.registerCommands(this); // DivineMC - register commands
+ // DivineMC end - DivineMC configuration
this.server.spark.enableEarlyIfRequested(); // Paper - spark
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
if (this.convertOldUsers()) {
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index fd84a5aac26bbf2de2c2fa8bb5bc76bcbd09c3e4..069f793b6dcc1e560ca0b1070b97f4f0006ae377 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -591,7 +591,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
org.bukkit.generator.BiomeProvider biomeProvider // CraftBukkit
) {
// CraftBukkit start
- super(serverLevelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, biomeZoomSeed, server.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> server.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(levelStorageAccess.levelDirectory.path(), serverLevelData.getLevelName(), dimension.location(), spigotConfig, server.registryAccess(), serverLevelData.getGameRules())), dispatcher); // Paper - create paper world configs; Async-Anti-Xray: Pass executor
+ super(serverLevelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, biomeZoomSeed, server.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> server.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(levelStorageAccess.levelDirectory.path(), serverLevelData.getLevelName(), dimension.location(), spigotConfig, server.registryAccess(), serverLevelData.getGameRules())), spigotConfig -> server.divineConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(levelStorageAccess.levelDirectory.path(), serverLevelData.getLevelName(), dimension.location(), spigotConfig, server.registryAccess(), serverLevelData.getGameRules())), dispatcher); // Paper - create paper world configs; Async-Anti-Xray: Pass executor // DivineMC - DivineMC configuration
this.pvpMode = server.isPvpAllowed();
this.levelStorageAccess = levelStorageAccess;
this.uuid = org.bukkit.craftbukkit.util.WorldUUID.getUUID(levelStorageAccess.levelDirectory.path().toFile());
+
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
this.setPvpAllowed(properties.pvp);
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index 1b2d152649bc12b37db1cd7a4f54517f417d46e8..953a302aa4a1196b5e32bcf25f5e5f991a6f352d 100644
index 1b2d152649bc12b37db1cd7a4f54517f417d46e8..71c4c79d94473a95479bc73cfb7415e1813970de 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -169,6 +169,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
}
// Paper end - add paper world config
@@ -171,6 +171,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
+ // DivineMC start - DivineMC configuration
+ private final space.bxteam.divinemc.configuration.DivineWorldConfiguration divineConfig;
+ public space.bxteam.divinemc.configuration.DivineWorldConfiguration divineConfig() {
+ return this.divineConfig;
+ }
+ // DivineMC end - DivineMC configuration
+
public final io.papermc.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray
public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur - Purpur config files
+ public final space.bxteam.divinemc.configuration.DivineWorldConfig divinemcConfig; // DivineMC - DivineMC config files
public static BlockPos lastPhysicsProblem; // Spigot
@@ -882,6 +889,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
org.bukkit.World.Environment env, // CraftBukkit
java.util.function.Function<org.spigotmc.SpigotWorldConfig, // Spigot - create per world config
io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, // Paper - create paper world config
+ java.util.function.Function<org.spigotmc.SpigotWorldConfig, // DivineMC - DivineMC configuration
+ space.bxteam.divinemc.configuration.DivineWorldConfiguration> divinemcWorldConfigCreator, // DivineMC - DivineMC configuration
java.util.concurrent.Executor executor // Paper - Anti-Xray
) {
// Paper start - getblock optimisations - cache world height/sections
@@ -895,6 +904,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
// Paper end - getblock optimisations - cache world height/sections
private int tileTickPosition;
public final Map<ServerExplosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
@@ -896,6 +897,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName()); // Spigot
this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config
+ this.divineConfig = divinemcWorldConfigCreator.apply(this.spigotConfig); // DivineMC - DivineMC configuration
this.purpurConfig = new org.purpurmc.purpur.PurpurWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName(), env); // Purpur - Purpur config files
+ this.divinemcConfig = new space.bxteam.divinemc.configuration.DivineWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName(), env); // DivineMC - DivineMC configuration
this.playerBreedingCooldowns = this.getNewBreedingCooldownCache(); // Purpur - Add adjustable breeding cooldown to config
this.generator = gen;
this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env);

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] No chat sign
diff --git a/net/minecraft/commands/arguments/ArgumentSignatures.java b/net/minecraft/commands/arguments/ArgumentSignatures.java
index 47cb25aa9c37bd84d156288c397321009f1d9ae2..9db90d39aa16208e421ba915270661668ec7773b 100644
index 47cb25aa9c37bd84d156288c397321009f1d9ae2..259fd0401a4a0547cf83ba1793f2b3d2898a58fe 100644
--- a/net/minecraft/commands/arguments/ArgumentSignatures.java
+++ b/net/minecraft/commands/arguments/ArgumentSignatures.java
@@ -14,9 +14,16 @@ public record ArgumentSignatures(List<ArgumentSignatures.Entry> entries) {
@@ -19,7 +19,7 @@ index 47cb25aa9c37bd84d156288c397321009f1d9ae2..9db90d39aa16208e421ba91527066166
+ // DivineMC start - No chat sign
+ private static List<ArgumentSignatures.Entry> readSign(FriendlyByteBuf buf) {
+ var entries = buf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 8), Entry::new);
+ return space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().chat.noChatSign ? List.of() : entries;
+ return space.bxteam.divinemc.configuration.DivineConfig.noChatSign ? List.of() : entries;
+ }
+ // DivineMC end - No chat sign
+
@@ -27,7 +27,7 @@ index 47cb25aa9c37bd84d156288c397321009f1d9ae2..9db90d39aa16208e421ba91527066166
buffer.writeCollection(this.entries, (buffer1, entry) -> entry.write(buffer1));
}
diff --git a/net/minecraft/network/FriendlyByteBuf.java b/net/minecraft/network/FriendlyByteBuf.java
index e5e5d9bc095ccd9fbf1c8aaa09e5c4ebb1d1c920..d864f894a2a609a6d74e5d655f8408b55021e0a2 100644
index e5e5d9bc095ccd9fbf1c8aaa09e5c4ebb1d1c920..d8c98e596f938f103f8155269a2096a6d1b7ffbb 100644
--- a/net/minecraft/network/FriendlyByteBuf.java
+++ b/net/minecraft/network/FriendlyByteBuf.java
@@ -114,6 +114,17 @@ public class FriendlyByteBuf extends ByteBuf {
@@ -38,7 +38,7 @@ index e5e5d9bc095ccd9fbf1c8aaa09e5c4ebb1d1c920..d864f894a2a609a6d74e5d655f8408b5
+ // DivineMC start - No chat sign
+ if (codec == net.minecraft.network.protocol.status.ServerStatus.CODEC) {
+ JsonElement element = dataResult.getOrThrow(string -> new EncoderException("Failed to encode: " + string + " " + value));
+ element.getAsJsonObject().addProperty("preventsChatReports", space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().chat.noChatSign);
+ element.getAsJsonObject().addProperty("preventsChatReports", space.bxteam.divinemc.configuration.DivineConfig.noChatSign);
+
+ this.writeUtf(GSON.toJson(element));
+ return;
@@ -49,7 +49,7 @@ index e5e5d9bc095ccd9fbf1c8aaa09e5c4ebb1d1c920..d864f894a2a609a6d74e5d655f8408b5
}
diff --git a/net/minecraft/network/protocol/game/ServerboundChatPacket.java b/net/minecraft/network/protocol/game/ServerboundChatPacket.java
index b5afc05924ae899e020c303c8b86398e1d4ab8a0..db3bc1cc33be082f708615a1f9957c6f92dcbcfa 100644
index b5afc05924ae899e020c303c8b86398e1d4ab8a0..468ec7f1a9ee73c7748ca36850bf810a1811e372 100644
--- a/net/minecraft/network/protocol/game/ServerboundChatPacket.java
+++ b/net/minecraft/network/protocol/game/ServerboundChatPacket.java
@@ -16,7 +16,7 @@ public record ServerboundChatPacket(String message, Instant timeStamp, long salt
@@ -69,7 +69,7 @@ index b5afc05924ae899e020c303c8b86398e1d4ab8a0..db3bc1cc33be082f708615a1f9957c6f
+ private static MessageSignature readSign(FriendlyByteBuf buf) {
+ byte[] bs = new byte[256];
+ buf.readBytes(bs);
+ return space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().chat.noChatSign ? null : new MessageSignature(bs);
+ return space.bxteam.divinemc.configuration.DivineConfig.noChatSign ? null : new MessageSignature(bs);
+ }
+ // DivineMC end - No chat sign
+
@@ -77,7 +77,7 @@ index b5afc05924ae899e020c303c8b86398e1d4ab8a0..db3bc1cc33be082f708615a1f9957c6f
public PacketType<ServerboundChatPacket> type() {
return GamePacketTypes.SERVERBOUND_CHAT;
diff --git a/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java b/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java
index 1df628ac0b414511aaed6e09d78f884c4170f730..598a46662a64b1e8ba37977b67c8311881acc84d 100644
index 1df628ac0b414511aaed6e09d78f884c4170f730..2d674c7ef305469c0483f24720e673e04a8fd963 100644
--- a/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java
+++ b/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java
@@ -26,6 +26,11 @@ public record ServerboundChatSessionUpdatePacket(RemoteChatSession.Data chatSess
@@ -85,7 +85,7 @@ index 1df628ac0b414511aaed6e09d78f884c4170f730..598a46662a64b1e8ba37977b67c83118
@Override
public void handle(ServerGamePacketListener handler) {
+ // DivineMC start - No chat sign
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().chat.noChatSign) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.noChatSign) {
+ return;
+ }
+ // DivineMC end - No chat sign
@@ -93,20 +93,20 @@ index 1df628ac0b414511aaed6e09d78f884c4170f730..598a46662a64b1e8ba37977b67c83118
}
}
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 5ec864a48aa2582458f741b9e81be8805d55913c..db08fe9ad7789876efb657c4274b84b11b6dad72 100644
index c85023893fbb227894f8f888244f1f53e25dff3f..0755bd59ab467da4a42cf5dae0f2e409d3132fea 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -662,7 +662,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -668,7 +668,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
// Paper start - Add setting for proxy online mode status
return properties.enforceSecureProfile
&& io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()
- && this.services.canValidateProfileKeys();
+ && this.services.canValidateProfileKeys() && !space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().chat.noChatSign; // DivineMC - No chat sign
+ && this.services.canValidateProfileKeys() && !space.bxteam.divinemc.configuration.DivineConfig.noChatSign; // DivineMC - No chat sign
// Paper end - Add setting for proxy online mode status
}
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
index 398c1733824b689520170de0be94006731afa5cd..b38e6837c6582e63089c67ae6450a0281ceb49b2 100644
index 398c1733824b689520170de0be94006731afa5cd..289d8d2420f6298a4fc10e0563e99cc13c18880a 100644
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
@@ -312,10 +312,24 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
@@ -114,7 +114,7 @@ index 398c1733824b689520170de0be94006731afa5cd..b38e6837c6582e63089c67ae6450a028
public void send(Packet<?> packet) {
+ // DivineMC start - No chat sign
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().chat.noChatSign) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.noChatSign) {
+ if (this instanceof ServerGamePacketListenerImpl && packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) {
+ packet = new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(chat.chatType().decorate(chat.unsignedContent() != null ? chat.unsignedContent() : Component.literal(chat.body().content())), false);
+ }
@@ -125,7 +125,7 @@ index 398c1733824b689520170de0be94006731afa5cd..b38e6837c6582e63089c67ae6450a028
public void send(Packet<?> packet, @Nullable PacketSendListener listener) {
+ // DivineMC start - No chat sign
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().chat.noChatSign) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.noChatSign) {
+ if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat && listener != null) {
+ listener = null;
+ }
@@ -135,7 +135,7 @@ index 398c1733824b689520170de0be94006731afa5cd..b38e6837c6582e63089c67ae6450a028
if (packet == null || this.processedDisconnect) { // Spigot
return;
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 94abb9d8f6381aee000dbd0720477db8b7ca279c..f8ad9aa0355c9f85a314f198666cb5fa376dabae 100644
index 94abb9d8f6381aee000dbd0720477db8b7ca279c..cb43a189e286afd858738e2590f8e812c510c3d3 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -1319,7 +1319,7 @@ public abstract class PlayerList {
@@ -143,7 +143,7 @@ index 94abb9d8f6381aee000dbd0720477db8b7ca279c..f8ad9aa0355c9f85a314f198666cb5fa
public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public
- return message.hasSignature() && !message.hasExpiredServer(Instant.now());
+ return space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().chat.noChatSign || (message.hasSignature() && !message.hasExpiredServer(Instant.now())); // DivineMC - No chat sign
+ return space.bxteam.divinemc.configuration.DivineConfig.noChatSign || (message.hasSignature() && !message.hasExpiredServer(Instant.now())); // DivineMC - No chat sign
}
// CraftBukkit start

View File

@@ -9,7 +9,7 @@ You can find the original code on https://github.com/Bloom-host/Petal
Makes most pathfinding-related work happen asynchronously
diff --git a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
index 67cbf9f5760fae5db6f31e64095cd1b6be6ade8e..7f93cd227a4d86ce08ac8fb95e214aa72acb3dec 100644
index 67cbf9f5760fae5db6f31e64095cd1b6be6ade8e..3f4e42c6ee1a1aa14250de4f71ae61f324d335e9 100644
--- a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
+++ b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
@@ -94,21 +94,54 @@ public class AcquirePoi {
@@ -26,7 +26,7 @@ index 67cbf9f5760fae5db6f31e64095cd1b6be6ade8e..7f93cd227a4d86ce08ac8fb95e214aa7
- map.clear();
- DebugPackets.sendPoiTicketCountPacket(level, target);
+ // DivineMC start - Async path processing
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ // await on path async
+ Path possiblePath = findPathToPois(mob, set);
+
@@ -79,7 +79,7 @@ index 67cbf9f5760fae5db6f31e64095cd1b6be6ade8e..7f93cd227a4d86ce08ac8fb95e214aa7
return true;
}
diff --git a/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java b/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
index 621ba76784f2b92790eca62be4d0688834335ab6..d5727defaddbfb2ddfbbcce4b00b5db9c8037cb0 100644
index 621ba76784f2b92790eca62be4d0688834335ab6..11a124ad7df99b3ddfc92496a8950dc6e46cdf07 100644
--- a/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
+++ b/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
@@ -21,6 +21,7 @@ public class MoveToTargetSink extends Behavior<Mob> {
@@ -95,10 +95,10 @@ index 621ba76784f2b92790eca62be4d0688834335ab6..d5727defaddbfb2ddfbbcce4b00b5db9
WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get();
boolean flag = this.reachedTarget(owner, walkTarget);
- if (!flag && this.tryComputePath(owner, walkTarget, level.getGameTime())) {
+ if (!space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding && !flag && this.tryComputePath(owner, walkTarget, level.getGameTime())) { // DivineMC - async path processing
+ if (!space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding && !flag && this.tryComputePath(owner, walkTarget, level.getGameTime())) { // DivineMC - async path processing
this.lastTargetPos = walkTarget.getTarget().currentBlockPosition();
return true;
+ } else if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding && !flag) { // DivineMC - async pathfinding
+ } else if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding && !flag) { // DivineMC - async pathfinding
+ return true;
} else {
brain.eraseMemory(MemoryModuleType.WALK_TARGET);
@@ -107,7 +107,7 @@ index 621ba76784f2b92790eca62be4d0688834335ab6..d5727defaddbfb2ddfbbcce4b00b5db9
@Override
protected boolean canStillUse(ServerLevel level, Mob entity, long gameTime) {
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding && !this.finishedProcessing) return true; // DivineMC - wait for processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding && !this.finishedProcessing) return true; // DivineMC - wait for processing
if (this.path != null && this.lastTargetPos != null) {
Optional<WalkTarget> memory = entity.getBrain().getMemory(MemoryModuleType.WALK_TARGET);
boolean flag = memory.map(MoveToTargetSink::isWalkTargetSpectator).orElse(false);
@@ -116,7 +116,7 @@ index 621ba76784f2b92790eca62be4d0688834335ab6..d5727defaddbfb2ddfbbcce4b00b5db9
@Override
protected void start(ServerLevel level, Mob entity, long gameTime) {
+ // DivineMC start - start processing
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ Brain<?> brain = entity.getBrain();
+ WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get();
+
@@ -139,7 +139,7 @@ index 621ba76784f2b92790eca62be4d0688834335ab6..d5727defaddbfb2ddfbbcce4b00b5db9
- brain.setMemory(MemoryModuleType.PATH, path);
- }
+ // DivineMC start - Async path processing
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ if (this.path != null && !this.path.isProcessed()) return; // wait for processing
- if (path != null && this.lastTargetPos != null) {
@@ -222,7 +222,7 @@ index 621ba76784f2b92790eca62be4d0688834335ab6..d5727defaddbfb2ddfbbcce4b00b5db9
private boolean tryComputePath(Mob mob, WalkTarget target, long time) {
BlockPos blockPos = target.getTarget().currentBlockPosition();
diff --git a/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java b/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java
index 4f9f3367b1ca3903df03a80fa2b01a3d24e6e77d..402261abf67268c929323c0ad7618dbe10e59d89 100644
index 4f9f3367b1ca3903df03a80fa2b01a3d24e6e77d..8308934ec65d1f49ea356e19c940407bae7041f2 100644
--- a/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java
+++ b/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java
@@ -60,17 +60,38 @@ public class SetClosestHomeAsWalkTarget {
@@ -237,7 +237,7 @@ index 4f9f3367b1ca3903df03a80fa2b01a3d24e6e77d..402261abf67268c929323c0ad7618dbe
- walkTarget.set(new WalkTarget(target, speedModifier, 1));
- DebugPackets.sendPoiTicketCountPacket(level, target);
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ // await on path async
+ Path possiblePath = AcquirePoi.findPathToPois(mob, set);
+
@@ -287,7 +287,7 @@ index d8f532c5e68ff4dff933556c4f981e9474c044e6..37f3d3888ea2a862d006cf2b201f9715
Node node = path.getNode(i);
this.doorPos = new BlockPos(node.x, node.y + 1, node.z);
diff --git a/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java b/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java
index 66a02fe7594522ef391d67e09856bf3f70fe597d..2a373a8de2b7387a38da4777bf36e485ebfc967f 100644
index 66a02fe7594522ef391d67e09856bf3f70fe597d..d560bbfb1272f8fd9b0d9b7af80f748afa61246c 100644
--- a/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java
+++ b/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java
@@ -12,9 +12,25 @@ public class AmphibiousPathNavigation extends PathNavigation {
@@ -309,7 +309,7 @@ index 66a02fe7594522ef391d67e09856bf3f70fe597d..2a373a8de2b7387a38da4777bf36e485
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.nodeEvaluator = new AmphibiousNodeEvaluator(false);
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
+ }
+ // DivineMC end - async path processing
@@ -317,7 +317,7 @@ index 66a02fe7594522ef391d67e09856bf3f70fe597d..2a373a8de2b7387a38da4777bf36e485
}
diff --git a/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java b/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
index 71ea68b56b3069bdf8e47931156b6ef49ea8ce5d..f0b80771e1823548003134d328c2476448c9f51d 100644
index 71ea68b56b3069bdf8e47931156b6ef49ea8ce5d..da804d3feef49555677ab6485d7aa6b1114b9d7f 100644
--- a/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
+++ b/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
@@ -16,9 +16,25 @@ public class FlyingPathNavigation extends PathNavigation {
@@ -339,7 +339,7 @@ index 71ea68b56b3069bdf8e47931156b6ef49ea8ce5d..f0b80771e1823548003134d328c24764
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.nodeEvaluator = new FlyNodeEvaluator();
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
+ }
+ // DivineMC end - async path processing
@@ -355,7 +355,7 @@ index 71ea68b56b3069bdf8e47931156b6ef49ea8ce5d..f0b80771e1823548003134d328c24764
if (!this.isDone()) {
if (this.canUpdatePath()) {
diff --git a/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java b/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
index 045cfafb3afe8271d60852ae3c7cdcb039b44d4f..11aac7e7d7df7b5e9cc71c8a8ba16f1f3820069e 100644
index 045cfafb3afe8271d60852ae3c7cdcb039b44d4f..fc02c7ca984dd2bcfca47002d7353427a1a70264 100644
--- a/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
+++ b/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
@@ -24,9 +24,25 @@ public class GroundPathNavigation extends PathNavigation {
@@ -377,7 +377,7 @@ index 045cfafb3afe8271d60852ae3c7cdcb039b44d4f..11aac7e7d7df7b5e9cc71c8a8ba16f1f
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.nodeEvaluator = new WalkNodeEvaluator();
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
+ }
+ // DivineMC end - async path processing
@@ -385,7 +385,7 @@ index 045cfafb3afe8271d60852ae3c7cdcb039b44d4f..11aac7e7d7df7b5e9cc71c8a8ba16f1f
}
diff --git a/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/net/minecraft/world/entity/ai/navigation/PathNavigation.java
index b44f2c49509d847817a78e9c4fb1499fb378054b..01234c1f3000f88d73596620944c48b5a120d88c 100644
index b44f2c49509d847817a78e9c4fb1499fb378054b..aaa4e1d36d486baa767d427be51390b013214905 100644
--- a/net/minecraft/world/entity/ai/navigation/PathNavigation.java
+++ b/net/minecraft/world/entity/ai/navigation/PathNavigation.java
@@ -169,6 +169,10 @@ public abstract class PathNavigation {
@@ -409,7 +409,7 @@ index b44f2c49509d847817a78e9c4fb1499fb378054b..01234c1f3000f88d73596620944c48b5
- this.reachRange = accuracy;
- this.resetStuckTimeout();
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ // assign early a target position. most calls will only have 1 position
+ if (!targets.isEmpty()) this.targetPos = targets.iterator().next();
+
@@ -472,7 +472,7 @@ index b44f2c49509d847817a78e9c4fb1499fb378054b..01234c1f3000f88d73596620944c48b5
Vec3 vec3 = new Vec3((endNode.x + this.mob.getX()) / 2.0, (endNode.y + this.mob.getY()) / 2.0, (endNode.z + this.mob.getZ()) / 2.0);
return pos.closerToCenterThan(vec3, this.path.getNodeCount() - this.path.getNextNodeIndex());
diff --git a/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java b/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java
index 2979846853898d78a2df19df2287da16dbe4ae71..a7b18ddc61f06071c6f575169ee3d58a41b094f7 100644
index 2979846853898d78a2df19df2287da16dbe4ae71..fbecca6fa274bcc6d07b9d300c31873fdb64c773 100644
--- a/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java
+++ b/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java
@@ -15,11 +15,27 @@ public class WaterBoundPathNavigation extends PathNavigation {
@@ -496,7 +496,7 @@ index 2979846853898d78a2df19df2287da16dbe4ae71..a7b18ddc61f06071c6f575169ee3d58a
this.nodeEvaluator = new SwimNodeEvaluator(this.allowBreaching);
this.nodeEvaluator.setCanPassDoors(false);
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
+ }
+ // DivineMC end - async path processing
@@ -504,7 +504,7 @@ index 2979846853898d78a2df19df2287da16dbe4ae71..a7b18ddc61f06071c6f575169ee3d58a
}
diff --git a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
index 1f96fd5085bacb4c584576c7cb9f51e7898e9b03..9bacb520abcd851cfb1b17cc4a353890991adfb6 100644
index 1f96fd5085bacb4c584576c7cb9f51e7898e9b03..cc202eb0848a2faecd556fa279565717be11b382 100644
--- a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
+++ b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
@@ -57,17 +57,37 @@ public class NearestBedSensor extends Sensor<Mob> {
@@ -519,7 +519,7 @@ index 1f96fd5085bacb4c584576c7cb9f51e7898e9b03..9bacb520abcd851cfb1b17cc4a353890
- if (type.isPresent()) {
- entity.getBrain().setMemory(MemoryModuleType.NEAREST_BED, target);
+ // DivineMC start - async pathfinding
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ Path possiblePath = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes));
+ space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(possiblePath, path -> {
+ // read canReach check
@@ -576,7 +576,7 @@ index 57c50ce5724b073b1aedf4df3129285143097303..5bdf82df2dbb79b8933813b61e617c48
}
}
diff --git a/net/minecraft/world/entity/animal/frog/Frog.java b/net/minecraft/world/entity/animal/frog/Frog.java
index d286d4a45b6c8d5c684ad11500d2ad1a10a70c18..4a51fc69d56bdbfabb927dc95403123560d7d709 100644
index d286d4a45b6c8d5c684ad11500d2ad1a10a70c18..9c97f7bd3eaf1a962793287d1b6c7911cdf149fd 100644
--- a/net/minecraft/world/entity/animal/frog/Frog.java
+++ b/net/minecraft/world/entity/animal/frog/Frog.java
@@ -496,6 +496,17 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
@@ -602,7 +602,7 @@ index d286d4a45b6c8d5c684ad11500d2ad1a10a70c18..4a51fc69d56bdbfabb927dc954031235
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.nodeEvaluator = new Frog.FrogNodeEvaluator(true);
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
+ }
+ // DivineMC end - async path processing
@@ -623,7 +623,7 @@ index 6c73245b8d04f194e72165aa0000ca79a95db59d..2686df57d9d48db1438278d0d053bdbd
if (target != null) {
double d = this.distanceToSqr(target.getX(), target.getY(), target.getZ());
diff --git a/net/minecraft/world/entity/monster/Strider.java b/net/minecraft/world/entity/monster/Strider.java
index 241526239bdbd5d9276f85e7fca46a7051f46a25..30e970613252fbf3472cf66285b101e111631f3e 100644
index 241526239bdbd5d9276f85e7fca46a7051f46a25..026ec71bff3e4e0c2098e331f6a2bd9ba5955ccb 100644
--- a/net/minecraft/world/entity/monster/Strider.java
+++ b/net/minecraft/world/entity/monster/Strider.java
@@ -579,9 +579,25 @@ public class Strider extends Animal implements ItemSteerable, Saddleable {
@@ -645,7 +645,7 @@ index 241526239bdbd5d9276f85e7fca46a7051f46a25..30e970613252fbf3472cf66285b101e1
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.nodeEvaluator = new WalkNodeEvaluator();
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
+ }
+ // DivineMC end
@@ -653,7 +653,7 @@ index 241526239bdbd5d9276f85e7fca46a7051f46a25..30e970613252fbf3472cf66285b101e1
}
diff --git a/net/minecraft/world/entity/monster/warden/Warden.java b/net/minecraft/world/entity/monster/warden/Warden.java
index f74c784906208034f51b31bd9aba45733c3ebebe..ae58cd9e5ef3848e56960dc08a0147a75c108623 100644
index f74c784906208034f51b31bd9aba45733c3ebebe..a1fa17eaef088e36284fc79d6afd4c43b8a0a1a9 100644
--- a/net/minecraft/world/entity/monster/warden/Warden.java
+++ b/net/minecraft/world/entity/monster/warden/Warden.java
@@ -619,6 +619,16 @@ public class Warden extends Monster implements VibrationSystem {
@@ -661,7 +661,7 @@ index f74c784906208034f51b31bd9aba45733c3ebebe..ae58cd9e5ef3848e56960dc08a0147a7
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.nodeEvaluator = new WalkNodeEvaluator();
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, GroundPathNavigation.nodeEvaluatorGenerator) {
+ @Override
+ protected float distance(Node first, Node second) {
@@ -704,7 +704,7 @@ index d6d3c8f5e5dd4a8cab0d3fcc131c3a59f06130c6..839653a997f1e10970fa2956fadaf493
return false;
} else if (pathentity.nodes.size() != this.nodes.size()) {
diff --git a/net/minecraft/world/level/pathfinder/PathFinder.java b/net/minecraft/world/level/pathfinder/PathFinder.java
index 81de6c1bbef1cafd3036e736dd305fbedc8368c6..6a75eae8c53d7ea618817e07173b29489d6fdf74 100644
index 81de6c1bbef1cafd3036e736dd305fbedc8368c6..4b8182414ca9aa22e096babb25a32f2b5ba60312 100644
--- a/net/minecraft/world/level/pathfinder/PathFinder.java
+++ b/net/minecraft/world/level/pathfinder/PathFinder.java
@@ -25,11 +25,19 @@ public class PathFinder {
@@ -736,7 +736,7 @@ index 81de6c1bbef1cafd3036e736dd305fbedc8368c6..6a75eae8c53d7ea618817e07173b2948
- this.nodeEvaluator.prepare(region, mob);
- Node start = this.nodeEvaluator.getStart();
+ // DivineMC start - use a generated evaluator if we have one otherwise run sync
+ if (!space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfinding)
+ if (!space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding)
+ this.openSet.clear(); // it's always cleared in processPath
+ NodeEvaluator nodeEvaluator = this.nodeEvaluatorGenerator == null
+ ? this.nodeEvaluator

View File

@@ -6,8 +6,30 @@ Subject: [PATCH] Implement Secure Seed
Original license: GPLv3
Original project: https://github.com/plasmoapp/matter
diff --git a/net/minecraft/server/commands/SeedCommand.java b/net/minecraft/server/commands/SeedCommand.java
index a65affc41a4fc299bc2281f0f53f2e075633899d..2ba3b8150bb753eebd5694275917c2ca8464b12e 100644
--- a/net/minecraft/server/commands/SeedCommand.java
+++ b/net/minecraft/server/commands/SeedCommand.java
@@ -12,6 +12,17 @@ public class SeedCommand {
long seed = context.getSource().getLevel().getSeed();
Component component = ComponentUtils.copyOnClickText(String.valueOf(seed));
context.getSource().sendSuccess(() -> Component.translatable("commands.seed.success", component), false);
+
+ // 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);
+ }
+ // DivineMC end - Implement Secure Seed
+
return (int)seed;
}));
}
diff --git a/net/minecraft/server/dedicated/DedicatedServerProperties.java b/net/minecraft/server/dedicated/DedicatedServerProperties.java
index 5748658abf0b90812005ae9d426df92daf5532f0..a010ff015ea8f2aa3f53681865e3ce95942b7525 100644
index 5748658abf0b90812005ae9d426df92daf5532f0..f4af49555bcf69cfaf7467f1fa7d4292a5652fa5 100644
--- a/net/minecraft/server/dedicated/DedicatedServerProperties.java
+++ b/net/minecraft/server/dedicated/DedicatedServerProperties.java
@@ -114,7 +114,17 @@ public class DedicatedServerProperties extends Settings<DedicatedServerPropertie
@@ -16,7 +38,7 @@ index 5748658abf0b90812005ae9d426df92daf5532f0..a010ff015ea8f2aa3f53681865e3ce95
long l = WorldOptions.parseSeed(string).orElse(WorldOptions.randomSeed());
- this.worldOptions = new WorldOptions(l, flag, false);
+ // DivineMC start - Implement Secure Seed
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.enableSecureSeed) {
+ 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());
@@ -42,7 +64,7 @@ index 6540b2d6a1062d883811ce240c49d30d1925b291..bceaf150f7e9b5c4a08be6102571d8fe
}
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 069f793b6dcc1e560ca0b1070b97f4f0006ae377..e90014f10c4d6b63a6f9307cdbf6adc208811f68 100644
index 3770dc90d9412c6378c0bd57a651b9c3e62b9a72..8127a71fd7d45541525be75e6699c2a5bae95f5f 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -634,6 +634,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -54,7 +76,7 @@ index 069f793b6dcc1e560ca0b1070b97f4f0006ae377..e90014f10c4d6b63a6f9307cdbf6adc2
DataFixer fixerUpper = server.getFixerUpper();
// Paper - rewrite chunk system
diff --git a/net/minecraft/world/entity/monster/Slime.java b/net/minecraft/world/entity/monster/Slime.java
index 240a54b210e23d5b79e6bcaf3806aa454668135d..bea5f39e3d9a3546c3092aeda12edc597725e0f2 100644
index 240a54b210e23d5b79e6bcaf3806aa454668135d..f8cf35cf6837b810a28b64e834d810fc92bdb9d3 100644
--- a/net/minecraft/world/entity/monster/Slime.java
+++ b/net/minecraft/world/entity/monster/Slime.java
@@ -423,8 +423,13 @@ public class Slime extends Mob implements Enemy {
@@ -65,7 +87,7 @@ index 240a54b210e23d5b79e6bcaf3806aa454668135d..bea5f39e3d9a3546c3092aeda12edc59
- boolean flag = level.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkPos.x, chunkPos.z, ((WorldGenLevel) level).getSeed(), level.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
+ ChunkPos chunkPos = new ChunkPos(pos);
+ // DivineMC start - Implement Secure Seed
+ boolean isSlimeChunk = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.enableSecureSeed
+ boolean isSlimeChunk = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? level.getChunk(chunkPos.x, chunkPos.z).isSlimeChunk()
+ : WorldgenRandom.seedSlimeChunk(chunkPos.x, chunkPos.z, ((WorldGenLevel) level).getSeed(), level.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
+ boolean flag = level.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || isSlimeChunk;
@@ -107,7 +129,7 @@ index 6d565b52552534ce9cacfc35ad1bf4adcb69eac3..7c3321b43e9eb1e6d15a571a8292853b
@Nullable
public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving);
diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java
index 6ed51cf42b5864194d671b5b56f5b9bdf0291dc0..ebf6bdace2ac4cb0e1bba3cd3a567e4087fcf58e 100644
index 6ed51cf42b5864194d671b5b56f5b9bdf0291dc0..a565b61cd0919fa874d9ab8d00e879b860d3dab5 100644
--- a/net/minecraft/world/level/chunk/ChunkGenerator.java
+++ b/net/minecraft/world/level/chunk/ChunkGenerator.java
@@ -343,7 +343,11 @@ public abstract class ChunkGenerator {
@@ -116,7 +138,7 @@ index 6ed51cf42b5864194d671b5b56f5b9bdf0291dc0..ebf6bdace2ac4cb0e1bba3cd3a567e40
List<FeatureSorter.StepFeatureData> list = this.featuresPerStep.get();
- WorldgenRandom worldgenRandom = new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed()));
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.enableSecureSeed
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(blockPos.getX(), blockPos.getZ(), space.bxteam.divinemc.seed.Globals.Salt.UNDEFINED, 0)
+ : new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed()));
+ // DivineMC end - Implement Secure Seed
@@ -131,7 +153,7 @@ index 6ed51cf42b5864194d671b5b56f5b9bdf0291dc0..ebf6bdace2ac4cb0e1bba3cd3a567e40
- worldgenRandom.setLargeFeatureSeed(structureState.getLevelSeed(), pos.x, pos.z);
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom;
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.enableSecureSeed) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ worldgenRandom = new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
+ pos.x, pos.z, space.bxteam.divinemc.seed.Globals.Salt.GENERATE_FEATURE, 0
+ );
@@ -145,7 +167,7 @@ index 6ed51cf42b5864194d671b5b56f5b9bdf0291dc0..ebf6bdace2ac4cb0e1bba3cd3a567e40
for (StructureSet.StructureSelectionEntry structureSelectionEntry1 : list1) {
diff --git a/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java b/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
index 619b98e42e254c0c260c171a26a2472ddf59b885..66faaf1a7350ed3561e630ca0aab7dd3dc84dd9f 100644
index 619b98e42e254c0c260c171a26a2472ddf59b885..797d0c8e836150b17dedb8ee00e0f245aff434ee 100644
--- a/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
+++ b/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
@@ -205,14 +205,21 @@ public class ChunkGeneratorStructureState {
@@ -161,11 +183,11 @@ index 619b98e42e254c0c260c171a26a2472ddf59b885..66faaf1a7350ed3561e630ca0aab7dd3
- randomSource.setSeed(this.concentricRingsSeed);
- } // Paper - Add missing structure set seed configs
+ // DivineMC start - Implement Secure Seed
+ RandomSource randomSource = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.enableSecureSeed
+ 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.DivineGlobalConfiguration.get().misc.enableSecureSeed) {
+ if (!space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ // Paper start - Add missing structure set seed configs
+ if (this.conf.strongholdSeed != null && structureSet.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) {
+ randomSource.setSeed(this.conf.strongholdSeed);
@@ -191,7 +213,7 @@ index b8348976e80578d9eff64eea68c04c603fed49ad..d84099c67704881a99d371ff79177257
ProfiledDuration profiledDuration = JvmProfiler.INSTANCE
.onChunkGenerate(chunk.getPos(), worldGenContext.level().dimension(), this.targetStatus.getName());
diff --git a/net/minecraft/world/level/levelgen/WorldOptions.java b/net/minecraft/world/level/levelgen/WorldOptions.java
index c92508741439a8d0d833ea02d0104416adb83c92..15799548cae858ed7421f0f8cb07fa2f3db67e2b 100644
index c92508741439a8d0d833ea02d0104416adb83c92..05a2c2e7830fda9d7c22904ee3ff44734e3a38af 100644
--- a/net/minecraft/world/level/levelgen/WorldOptions.java
+++ b/net/minecraft/world/level/levelgen/WorldOptions.java
@@ -9,17 +9,28 @@ import net.minecraft.util.RandomSource;
@@ -199,7 +221,7 @@ index c92508741439a8d0d833ea02d0104416adb83c92..15799548cae858ed7421f0f8cb07fa2f
public class WorldOptions {
+ // DivineMC start - Implement Secure Seed
+ private static final boolean isSecureSeedEnabled = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.enableSecureSeed;
+ private static final boolean isSecureSeedEnabled = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed;
public static final MapCodec<WorldOptions> CODEC = RecordCodecBuilder.mapCodec(
- instance -> instance.group(
+ instance -> isSecureSeedEnabled
@@ -309,7 +331,7 @@ index c92508741439a8d0d833ea02d0104416adb83c92..15799548cae858ed7421f0f8cb07fa2f
public static OptionalLong parseSeed(String seed) {
seed = seed.trim();
diff --git a/net/minecraft/world/level/levelgen/feature/GeodeFeature.java b/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
index 38475f6975533909924c8d54f438cf43cdfe31a3..c5a75c27242698fe2bc0415b8df6657f57024d86 100644
index 38475f6975533909924c8d54f438cf43cdfe31a3..528a69cf7c1f0f31988cc3902f41559826c4d27d 100644
--- a/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
+++ b/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
@@ -41,7 +41,11 @@ public class GeodeFeature extends Feature<GeodeConfiguration> {
@@ -318,7 +340,7 @@ index 38475f6975533909924c8d54f438cf43cdfe31a3..c5a75c27242698fe2bc0415b8df6657f
int i2 = geodeConfiguration.distributionPoints.sample(randomSource);
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed()));
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.enableSecureSeed
+ 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 - Implement Secure Seed
@@ -326,7 +348,7 @@ index 38475f6975533909924c8d54f438cf43cdfe31a3..c5a75c27242698fe2bc0415b8df6657f
List<BlockPos> list1 = Lists.newLinkedList();
double d = (double)i2 / geodeConfiguration.outerWallDistance.getMaxValue();
diff --git a/net/minecraft/world/level/levelgen/structure/Structure.java b/net/minecraft/world/level/levelgen/structure/Structure.java
index 8328e864c72b7a358d6bb1f33459b8c4df2ecb1a..fcec1e0110c539b12d1153c2982d165cf032197e 100644
index 8328e864c72b7a358d6bb1f33459b8c4df2ecb1a..c8bf9b3c08903b95dd92c5eb7135d3426580c004 100644
--- a/net/minecraft/world/level/levelgen/structure/Structure.java
+++ b/net/minecraft/world/level/levelgen/structure/Structure.java
@@ -249,6 +249,14 @@ public abstract class Structure {
@@ -334,7 +356,7 @@ index 8328e864c72b7a358d6bb1f33459b8c4df2ecb1a..fcec1e0110c539b12d1153c2982d165c
private static WorldgenRandom makeRandom(long seed, ChunkPos chunkPos) {
+ // DivineMC start - Implement Secure Seed
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.enableSecureSeed) {
+ 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
+ );
@@ -345,7 +367,7 @@ index 8328e864c72b7a358d6bb1f33459b8c4df2ecb1a..fcec1e0110c539b12d1153c2982d165c
worldgenRandom.setLargeFeatureSeed(seed, chunkPos.x, chunkPos.z);
return worldgenRandom;
diff --git a/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java b/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
index ee0d9dddb36b6879fa113299e24f1aa3b2b151cc..f256173d032ca506f34cd55779239d6d5ccae593 100644
index ee0d9dddb36b6879fa113299e24f1aa3b2b151cc..3859e80ef432a27df09fe89ef25e0a401cf970b5 100644
--- a/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
+++ b/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
@@ -67,8 +67,17 @@ public class RandomSpreadStructurePlacement extends StructurePlacement {
@@ -356,7 +378,7 @@ index ee0d9dddb36b6879fa113299e24f1aa3b2b151cc..f256173d032ca506f34cd55779239d6d
- worldgenRandom.setLargeFeatureWithSalt(seed, i, i1, this.salt());
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom;
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.enableSecureSeed) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ worldgenRandom = new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
+ i, i1, space.bxteam.divinemc.seed.Globals.Salt.POTENTIONAL_FEATURE, this.salt
+ );
@@ -369,7 +391,7 @@ index ee0d9dddb36b6879fa113299e24f1aa3b2b151cc..f256173d032ca506f34cd55779239d6d
int i3 = this.spreadType.evaluate(worldgenRandom, i2);
int i4 = this.spreadType.evaluate(worldgenRandom, i2);
diff --git a/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java b/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
index 670335a7bbfbc9da64c389977498c22dfcd03251..771320f999c63671db6ad64c15dfee18ecff65c7 100644
index 670335a7bbfbc9da64c389977498c22dfcd03251..7b49200486e59a6546aa50d098492280e51d5873 100644
--- a/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
+++ b/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
@@ -118,8 +118,17 @@ public abstract class StructurePlacement {
@@ -380,7 +402,7 @@ index 670335a7bbfbc9da64c389977498c22dfcd03251..771320f999c63671db6ad64c15dfee18
- worldgenRandom.setLargeFeatureWithSalt(levelSeed, regionX, regionZ, salt);
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom;
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.enableSecureSeed) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ worldgenRandom = new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
+ regionX, regionZ, space.bxteam.divinemc.seed.Globals.Salt.UNDEFINED, salt
+ );
@@ -393,7 +415,7 @@ index 670335a7bbfbc9da64c389977498c22dfcd03251..771320f999c63671db6ad64c15dfee18
}
diff --git a/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java b/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
index eb85edaa3b7fab4f11545b0fa8bfea882dedb67d..0e8f96a420735298db4be4a2184829d5114b34c5 100644
index eb85edaa3b7fab4f11545b0fa8bfea882dedb67d..b9b15705ee20175451cfcac5795939d787ce0cef 100644
--- a/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
+++ b/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
@@ -64,7 +64,11 @@ public class JigsawPlacement {
@@ -402,7 +424,7 @@ index eb85edaa3b7fab4f11545b0fa8bfea882dedb67d..0e8f96a420735298db4be4a2184829d5
LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
- WorldgenRandom worldgenRandom = context.random();
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.enableSecureSeed
+ 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 - Implement Secure Seed

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Multithreaded Tracker
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 718487155b923bfffa215b70a12d42681a8ae141..8c67ee3d5eaa7ab02f8b22c2e41af0b1d59bcdcd 100644
index 718487155b923bfffa215b70a12d42681a8ae141..19e98a8d905541f72becd0f61a86cc5c08e09daa 100644
--- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java
@@ -250,9 +250,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -15,7 +15,7 @@ index 718487155b923bfffa215b70a12d42681a8ae141..8c67ee3d5eaa7ab02f8b22c2e41af0b1
- for (int i = 0, len = inRange.size(); i < len; i++) {
- ++(backingSet[i].mobCounts[index]);
+ // DivineMC start - Multithreaded tracker
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedEnabled) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled) {
+ for (int i = 0, len = inRange.size(); i < len; i++) {
+ final ServerPlayer player = backingSet[i];
+ if (player == null) continue;
@@ -57,7 +57,7 @@ index 718487155b923bfffa215b70a12d42681a8ae141..8c67ee3d5eaa7ab02f8b22c2e41af0b1
protected void tick() {
+ // DivineMC start - Multithreaded tracker
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedEnabled) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled) {
+ final ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel level = this.level;
+ space.bxteam.divinemc.tracker.MultithreadedTracker.tick(level);
+ return;
@@ -72,7 +72,7 @@ index 718487155b923bfffa215b70a12d42681a8ae141..8c67ee3d5eaa7ab02f8b22c2e41af0b1
SectionPos lastSectionPos;
- public final Set<ServerPlayerConnection> seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl
+ // DivineMC start - Multithreaded tracker
+ public final Set<ServerPlayerConnection> seenBy = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedEnabled
+ public final Set<ServerPlayerConnection> seenBy = space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled
+ ? com.google.common.collect.Sets.newConcurrentHashSet()
+ : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl
+ // DivineMC end - Multithreaded tracker
@@ -86,7 +86,7 @@ index 718487155b923bfffa215b70a12d42681a8ae141..8c67ee3d5eaa7ab02f8b22c2e41af0b1
+ final int playersLen = players.size(); // Ensure length won't change in the future tasks
+
+ // DivineMC start - Multithreaded tracker
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedEnabled && space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedCompatModeEnabled) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled && space.bxteam.divinemc.configuration.DivineConfig.multithreadedCompatModeEnabled) {
+ final boolean isServerPlayer = this.entity instanceof ServerPlayer;
+ final boolean isRealPlayer = isServerPlayer && ((ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer) this.entity).moonrise$isRealPlayer();
+ Runnable updatePlayerTasks = () -> {
@@ -178,12 +178,12 @@ index 718487155b923bfffa215b70a12d42681a8ae141..8c67ee3d5eaa7ab02f8b22c2e41af0b1
- org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
+ //org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // DivineMC - Multithreaded tracker - we don't need this
if (player != this.entity) {
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedEnabled && player == null) return; // DivineMC - Multithreaded tracker
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled && player == null) return; // DivineMC - Multithreaded tracker
// Paper start - remove allocation of Vec3D here
// Vec3 vec3 = player.position().subtract(this.entity.position());
double vec3_dx = player.getX() - this.entity.getX();
diff --git a/net/minecraft/server/level/ServerBossEvent.java b/net/minecraft/server/level/ServerBossEvent.java
index f106373ef3ac4a8685c2939c9e8361688a285913..4a5c4eb52b069baf87b28dffc1598cfb42e83b89 100644
index f106373ef3ac4a8685c2939c9e8361688a285913..7b0663caa87fa91c6eba3b88dfe9fe83a1cf5cbf 100644
--- a/net/minecraft/server/level/ServerBossEvent.java
+++ b/net/minecraft/server/level/ServerBossEvent.java
@@ -13,7 +13,11 @@ import net.minecraft.util.Mth;
@@ -192,7 +192,7 @@ index f106373ef3ac4a8685c2939c9e8361688a285913..4a5c4eb52b069baf87b28dffc1598cfb
public class ServerBossEvent extends BossEvent {
- private final Set<ServerPlayer> players = Sets.newHashSet();
+ // DivineMC start - Multithreaded tracker - players can be removed in async tracking
+ private final Set<ServerPlayer> players = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedEnabled
+ private final Set<ServerPlayer> players = space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled
+ ? Sets.newConcurrentHashSet()
+ : Sets.newHashSet();
+ // DivineMC end - Multithreaded tracker
@@ -200,7 +200,7 @@ index f106373ef3ac4a8685c2939c9e8361688a285913..4a5c4eb52b069baf87b28dffc1598cfb
public boolean visible = true;
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
index 12a5c87d6e10ff8c1a19a041606a0016f7379901..7bac96ab1fde3dfbc9a72d832a7e48013736e1d7 100644
index 6d2c892207c2299c64f59630fb7740d6407e76a7..50195569421527faf7d3a65cb6be3b559936af07 100644
--- a/net/minecraft/server/level/ServerEntity.java
+++ b/net/minecraft/server/level/ServerEntity.java
@@ -110,8 +110,13 @@ public class ServerEntity {
@@ -210,7 +210,7 @@ index 12a5c87d6e10ff8c1a19a041606a0016f7379901..7bac96ab1fde3dfbc9a72d832a7e4801
- serverPlayer1.connection
- .teleport(serverPlayer1.getX(), serverPlayer1.getY(), serverPlayer1.getZ(), serverPlayer1.getYRot(), serverPlayer1.getXRot());
+ // DivineMC start - Multithreaded tracker
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedEnabled && Thread.currentThread() instanceof space.bxteam.divinemc.tracker.MultithreadedTracker.MultithreadedTrackerThread) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled && Thread.currentThread() instanceof space.bxteam.divinemc.tracker.MultithreadedTracker.MultithreadedTrackerThread) {
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> serverPlayer1.connection.teleport(serverPlayer1.getX(), serverPlayer1.getY(), serverPlayer1.getZ(), serverPlayer1.getYRot(), serverPlayer1.getXRot()));
+ } else {
+ serverPlayer1.connection.teleport(serverPlayer1.getX(), serverPlayer1.getY(), serverPlayer1.getZ(), serverPlayer1.getYRot(), serverPlayer1.getXRot());
@@ -246,7 +246,7 @@ index 12a5c87d6e10ff8c1a19a041606a0016f7379901..7bac96ab1fde3dfbc9a72d832a7e4801
if (this.entity instanceof LivingEntity) {
@@ -413,12 +426,17 @@ public class ServerEntity {
final Set<AttributeInstance> attributesToSync = this.level.divineConfig().optimizations.suppressErrorsFromDirtyAttributes ? Collections.synchronizedSet(attributes) : attributes;
final Set<AttributeInstance> attributesToSync = this.level.divinemcConfig.suppressErrorsFromDirtyAttributes ? Collections.synchronizedSet(attributes) : attributes;
// DivineMC end - Suppress errors from dirty attributes
if (!attributesToSync.isEmpty()) {
- // CraftBukkit start - Send scaled max health
@@ -270,7 +270,7 @@ index 12a5c87d6e10ff8c1a19a041606a0016f7379901..7bac96ab1fde3dfbc9a72d832a7e4801
attributes.clear();
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index c186cfc4f821cb6449e0eb060cd87c267bcdc069..43391e40cc72af39415fb989fc3369d1b46d4623 100644
index 8127a71fd7d45541525be75e6699c2a5bae95f5f..e6a55f6fa9f4b827d14ae29c82cb7e30cfa5d56a 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -2512,7 +2512,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -283,7 +283,7 @@ index c186cfc4f821cb6449e0eb060cd87c267bcdc069..43391e40cc72af39415fb989fc3369d1
}
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0be1ee79461fcae88e6cb61adb16c132567d0001..19d30bdcc5ad497d5fe4fc879703d22bcd35b860 100644
index b2f2682c44eeed9ed4f5421113cc7cc704454ba5..33730967df54467b2f046f66a1590c7069e44c5d 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1806,7 +1806,7 @@ public class ServerGamePacketListenerImpl
@@ -296,7 +296,7 @@ index 0be1ee79461fcae88e6cb61adb16c132567d0001..19d30bdcc5ad497d5fe4fc879703d22b
if (this.player.isRemoved()) {
LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName());
diff --git a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
index 8013594bb4844e7a8abf28123958e7f632d39341..cfd14b1388638b167c2081909320bca6a2139d19 100644
index 8013594bb4844e7a8abf28123958e7f632d39341..55a2777ed76baef8fa6ed899e96028db0d4682f8 100644
--- a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
+++ b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
@@ -24,8 +24,11 @@ public class AttributeInstance {
@@ -306,7 +306,7 @@ index 8013594bb4844e7a8abf28123958e7f632d39341..cfd14b1388638b167c2081909320bca6
- private final Map<ResourceLocation, AttributeModifier> modifierById = new Object2ObjectArrayMap<>();
- private final Map<ResourceLocation, AttributeModifier> permanentModifiers = new Object2ObjectArrayMap<>();
+ // DivineMC start - Multithreaded tracker
+ private final boolean multiThreadedTrackingEnabled = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedEnabled;
+ private final boolean multiThreadedTrackingEnabled = space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled;
+ private final Map<ResourceLocation, AttributeModifier> modifierById = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new Object2ObjectArrayMap<>();
+ private final Map<ResourceLocation, AttributeModifier> permanentModifiers = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new Object2ObjectArrayMap<>();
+ // DivineMC end - Multithreaded tracker
@@ -314,7 +314,7 @@ index 8013594bb4844e7a8abf28123958e7f632d39341..cfd14b1388638b167c2081909320bca6
private boolean dirty = true;
private double cachedValue;
diff --git a/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
index a25d74592e89e3d6339479c6dc2b6f45d1932cfc..57fee93f53464fb249aedf9f7319fcab14dadffe 100644
index a25d74592e89e3d6339479c6dc2b6f45d1932cfc..328474691eb42505cd535494c04fab0bdeb0a953 100644
--- a/net/minecraft/world/entity/ai/attributes/AttributeMap.java
+++ b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
@@ -19,9 +19,12 @@ import org.slf4j.Logger;
@@ -325,7 +325,7 @@ index a25d74592e89e3d6339479c6dc2b6f45d1932cfc..57fee93f53464fb249aedf9f7319fcab
- private final Set<AttributeInstance> attributesToSync = new ObjectOpenHashSet<>();
- private final Set<AttributeInstance> attributesToUpdate = new ObjectOpenHashSet<>();
+ // DivineMC start - Multithreaded tracker
+ private final boolean multiThreadedTrackingEnabled = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedEnabled;
+ private final boolean multiThreadedTrackingEnabled = space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled;
+ private final Map<Holder<Attribute>, AttributeInstance> attributes = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(0);
+ private final Set<AttributeInstance> attributesToSync = multiThreadedTrackingEnabled ? com.google.common.collect.Sets.newConcurrentHashSet() : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0);
+ private final Set<AttributeInstance> attributesToUpdate = multiThreadedTrackingEnabled ? com.google.common.collect.Sets.newConcurrentHashSet() : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0);

View File

@@ -1,13 +1,5 @@
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -232,6 +_,7 @@
org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash); // Paper - start watchdog thread
thread.start(); // Paper - Enhance console tab completions for brigadier commands; start console thread after MinecraftServer.console & PaperConfig are initialized
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
+ space.bxteam.divinemc.command.DivineCommands.registerCommands(this); // DivineMC - register commands
this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
// Purpur start - Purpur config files
@@ -326,7 +_,7 @@
String proxyFlavor = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "Velocity" : "BungeeCord";
String proxyLink = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "https://docs.papermc.io/velocity/security" : "http://www.spigotmc.org/wiki/firewall-guide/";

View File

@@ -7,7 +7,7 @@
- Set<AttributeInstance> attributesToSync = ((LivingEntity)this.entity).getAttributes().getAttributesToSync();
+ // DivineMC start - Suppress errors from dirty attributes
+ Set<AttributeInstance> attributes = ((LivingEntity) this.entity).getAttributes().getAttributesToSync();
+ final Set<AttributeInstance> attributesToSync = this.level.divineConfig().optimizations.suppressErrorsFromDirtyAttributes ? Collections.synchronizedSet(attributes) : attributes;
+ final Set<AttributeInstance> attributesToSync = this.level.divinemcConfig.suppressErrorsFromDirtyAttributes ? Collections.synchronizedSet(attributes) : attributes;
+ // DivineMC end - Suppress errors from dirty attributes
if (!attributesToSync.isEmpty()) {
// CraftBukkit start - Send scaled max health

View File

@@ -5,7 +5,7 @@
}
// Paper end - Prevent moving into unloaded chunks
- if (d7 - d6 > Math.max(100.0, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) {
+ if (!space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.disableMovedWronglyThreshold && d7 - d6 > Math.max(100.0, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { // DivineMC - Option to disable moved wrongly threshold
+ if (!space.bxteam.divinemc.configuration.DivineConfig.disableMovedWronglyThreshold && d7 - d6 > Math.max(100.0, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { // DivineMC - Option to disable moved wrongly threshold
// CraftBukkit end
LOGGER.warn(
"{} (vehicle of {}) moved too quickly! {},{},{}", rootVehicle.getName().getString(), this.player.getName().getString(), d3, d4, d5
@@ -14,7 +14,7 @@
d7 = d3 * d3 + d4 * d4 + d5 * d5;
boolean flag2 = false;
- if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
+ if (!space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.disableMovedWronglyThreshold && d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot // DivineMC - Option to disable moved wrongly threshold
+ if (!space.bxteam.divinemc.configuration.DivineConfig.disableMovedWronglyThreshold && d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot // DivineMC - Option to disable moved wrongly threshold
flag2 = true; // Paper - diff on change, this should be moved wrongly
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7));
}

View File

@@ -5,7 +5,7 @@
Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet");
// Paper start - Validate usernames
- if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()
+ if (!space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.removeVanillaUsernameCheck // DivineMC - Remove vanilla username check
+ if (!space.bxteam.divinemc.configuration.DivineConfig.removeVanillaUsernameCheck // DivineMC - Remove vanilla username check
+ && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()
&& io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation
&& !this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation) {

View File

@@ -7,7 +7,7 @@
+ // DivineMC start - Don't save Fireworks
+ @Override
+ public boolean shouldBeSaved() {
+ return this.level().divineConfig().gameplayMechanics.projectiles.saveFireworks;
+ return this.level().divinemcConfig.saveFireworks;
+ }
+ // DivineMC end - Don't save Fireworks
+

View File

@@ -5,7 +5,7 @@
HitResult hitResult = null;
if (!this.level().isClientSide) {
+ // DivineMC start - despawn shulker bullets on owner death
+ if (this.level().divineConfig().gameplayMechanics.mob.shulker.despawnShulkerBulletsOnOwnerDeath) {
+ if (this.level().divinemcConfig.despawnShulkerBulletsOnOwnerDeath) {
+ if (!isInvulnerable()) {
+ var owner = getOwner();
+ if (owner == null || !owner.isAlive()) {

View File

@@ -5,7 +5,7 @@
this.level.sendBlockUpdated(this.getBlockPos(), this.getBlockState(), this.getBlockState(), 3);
} else {
- LOGGER.warn("Player {} just tried to change non-editable sign", player.getName().getString());
+ if (!space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.disableNonEditableSignWarning) LOGGER.warn("Player {} just tried to change non-editable sign", player.getName().getString()); // DivineMC - Option to disable warning
+ if (!space.bxteam.divinemc.configuration.DivineConfig.disableNonEditableSignWarning) LOGGER.warn("Player {} just tried to change non-editable sign", player.getName().getString()); // DivineMC - Option to disable warning
if (player.distanceToSqr(this.getBlockPos().getX(), this.getBlockPos().getY(), this.getBlockPos().getZ()) < Mth.square(32)) // Paper - Don't send far away sign update
((net.minecraft.server.level.ServerPlayer) player).connection.send(this.getUpdatePacket()); // CraftBukkit
}

View File

@@ -11,7 +11,7 @@
+
@Nullable
public BlockPattern.BlockPatternMatch findExitPortal() {
+ if (space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().optimizations.optimizedDragonRespawn) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.optimizedDragonRespawn) {
+ int i, j;
+ for (i = cachePortalChunkIteratorX; i <= 8; ++i) {
+ for (j = cachePortalChunkIteratorZ; j <= 8; ++j) {

View File

@@ -4,157 +4,57 @@ Date: Sun, 12 Jan 2025 16:19:01 +0300
Subject: [PATCH] DivineMC Configuration
diff --git a/src/main/java/io/papermc/paper/configuration/Configurations.java b/src/main/java/io/papermc/paper/configuration/Configurations.java
index 4a9258b62db3a9d1150f0dfbe916fa549b596686..bfccf82b57c23537e83bc0b83feef5e632cabef7 100644
--- a/src/main/java/io/papermc/paper/configuration/Configurations.java
+++ b/src/main/java/io/papermc/paper/configuration/Configurations.java
@@ -94,7 +94,7 @@ public abstract class Configurations<G, W> {
};
}
- static <T> CheckedFunction<ConfigurationNode, T, SerializationException> reloader(Class<T> type, T instance) {
+ public static <T> CheckedFunction<ConfigurationNode, T, SerializationException> reloader(Class<T> type, T instance) { // DivineMC - DivineMC Configuration
return node -> {
ObjectMapper.Factory factory = (ObjectMapper.Factory) Objects.requireNonNull(node.options().serializers().get(type));
ObjectMapper.Mutable<T> mutable = (ObjectMapper.Mutable<T>) factory.get(type);
@@ -168,7 +168,7 @@ public abstract class Configurations<G, W> {
final YamlConfigurationLoader loader = result.loader();
final ConfigurationNode node = loader.load();
if (result.isNewFile()) { // add version to new files
- node.node(Configuration.VERSION_FIELD).raw(this.worldConfigVersion());
+ node.node(Configuration.VERSION_FIELD).raw(getWorldConfigurationCurrentVersion()); // DivineMC - DivineMC Configuration
} else {
this.verifyWorldConfigVersion(contextMap, node);
}
@@ -230,7 +230,7 @@ public abstract class Configurations<G, W> {
.build();
final ConfigurationNode worldNode = worldLoader.load();
if (newFile) { // set the version field if new file
- worldNode.node(Configuration.VERSION_FIELD).set(this.worldConfigVersion());
+ worldNode.node(Configuration.VERSION_FIELD).set(getWorldConfigurationCurrentVersion()); // DivineMC - DivineMC Configuration
} else {
this.verifyWorldConfigVersion(contextMap, worldNode);
}
@@ -356,4 +356,22 @@ public abstract class Configurations<G, W> {
return "ContextKey{" + this.name + "}";
}
}
+
+ // DivineMC start - DivineMC Configuration
+ public static final String legacyWorldsSectionKey = "__________WORLDS__________";
+ public static final String legacyWorldDefaultsSectionKey = "__defaults__";
+
+ @Deprecated
+ public org.bukkit.configuration.file.YamlConfiguration createLegacyObject(final net.minecraft.server.MinecraftServer server) {
+ org.bukkit.configuration.file.YamlConfiguration global = org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(this.globalFolder.resolve(this.globalConfigFileName).toFile());
+ org.bukkit.configuration.ConfigurationSection worlds = global.createSection(legacyWorldsSectionKey);
+ worlds.set(legacyWorldDefaultsSectionKey, org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(this.globalFolder.resolve(this.defaultWorldConfigFileName).toFile()));
+ for (ServerLevel level : server.getAllLevels()) {
+ worlds.set(level.getWorld().getName(), org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(getWorldConfigFile(level).toFile()));
+ }
+ return global;
+ }
+
+ public abstract int getWorldConfigurationCurrentVersion();
+ // DivineMC end - DivineMC Configuration
}
diff --git a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java
index e319d6337811051de478d584a37015c450960701..6955c448adc0a995c6bbe6d507eee4232ffda5b1 100644
--- a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java
+++ b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java
@@ -331,7 +331,7 @@ public class PaperConfigurations extends Configurations<GlobalConfiguration, Wor
}
}
- private static ContextMap createWorldContextMap(ServerLevel level) {
+ public static ContextMap createWorldContextMap(ServerLevel level) { // DivineMC - DivineMC Configuration
return createWorldContextMap(level.levelStorageAccess.levelDirectory.path(), level.serverLevelData.getLevelName(), level.dimension().location(), level.spigotConfig, level.registryAccess(), level.getGameRules());
}
@@ -434,17 +434,6 @@ public class PaperConfigurations extends Configurations<GlobalConfiguration, Wor
return Files.exists(legacyConfig) && Files.isRegularFile(legacyConfig);
}
- @Deprecated
- public YamlConfiguration createLegacyObject(final MinecraftServer server) {
- YamlConfiguration global = YamlConfiguration.loadConfiguration(this.globalFolder.resolve(this.globalConfigFileName).toFile());
- ConfigurationSection worlds = global.createSection("__________WORLDS__________");
- worlds.set("__defaults__", YamlConfiguration.loadConfiguration(this.globalFolder.resolve(this.defaultWorldConfigFileName).toFile()));
- for (ServerLevel level : server.getAllLevels()) {
- worlds.set(level.getWorld().getName(), YamlConfiguration.loadConfiguration(getWorldConfigFile(level).toFile()));
- }
- return global;
- }
-
@Deprecated
public static YamlConfiguration loadLegacyConfigFile(File configFile) throws Exception {
YamlConfiguration config = new YamlConfiguration();
@@ -467,9 +456,16 @@ public class PaperConfigurations extends Configurations<GlobalConfiguration, Wor
}
// Symlinks are not correctly checked in createDirectories
- static void createDirectoriesSymlinkAware(Path path) throws IOException {
+ public static void createDirectoriesSymlinkAware(Path path) throws IOException { // DivineMC - DivineMC Configuration
if (!Files.isDirectory(path)) {
Files.createDirectories(path);
}
}
+
+ // DivineMC start - DivineMC configuration
+ @Override
+ public int getWorldConfigurationCurrentVersion() {
+ return WorldConfiguration.CURRENT_VERSION;
+ }
+ // DivineMC end - DivineMC configuration
}
diff --git a/src/main/java/io/papermc/paper/configuration/mapping/InnerClassFieldDiscoverer.java b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassFieldDiscoverer.java
index 05339a176083af667c16f77d76dc1878dafce3f0..0a1428b826fe4057058cf24284bd5f6fed8230cb 100644
--- a/src/main/java/io/papermc/paper/configuration/mapping/InnerClassFieldDiscoverer.java
+++ b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassFieldDiscoverer.java
@@ -46,7 +46,19 @@ public final class InnerClassFieldDiscoverer implements FieldDiscoverer<Map<Fiel
return new InnerClassFieldDiscoverer(overrides);
}
- public static FieldDiscoverer<?> globalConfig() {
+ // DivineMC start - DivineMC configuration
+ public static FieldDiscoverer<?> divineWorldConfig(io.papermc.paper.configuration.Configurations.ContextMap contextMap) {
+ final Map<Class<?>, Object> overrides = Map.of(
+ space.bxteam.divinemc.configuration.DivineWorldConfiguration.class, new space.bxteam.divinemc.configuration.DivineWorldConfiguration(
+ contextMap.require(io.papermc.paper.configuration.PaperConfigurations.SPIGOT_WORLD_CONFIG_CONTEXT_KEY).get(),
+ contextMap.require(io.papermc.paper.configuration.Configurations.WORLD_KEY)
+ )
+ );
+ return new InnerClassFieldDiscoverer(overrides);
+ }
+ // DivineMC end - DivineMC configuration
+
+ public static FieldDiscoverer<?> globalConfig() { // DivineMC - DivineMC configuration
return new InnerClassFieldDiscoverer(Collections.emptyMap());
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index cc80fb07272393acc1b7d5f269789fd92eb10dfc..64f0c861c6ff4e523a882c11aef26f801fc14487 100644
index d072bd2e46abfa9366bc973028e068849c0a0a45..55f9267c83427dbe4ab28580ec515539565f3bdb 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1102,6 +1102,7 @@ public final class CraftServer implements Server {
@@ -1103,6 +1103,7 @@ public final class CraftServer implements Server {
org.spigotmc.SpigotConfig.init((File) this.console.options.valueOf("spigot-settings")); // Spigot
this.console.paperConfigurations.reloadConfigs(this.console);
+ this.console.divineConfigurations.reloadConfigs(this.console); // DivineMC - DivineMC configuration
org.purpurmc.purpur.PurpurConfig.init((File) console.options.valueOf("purpur-settings")); // Purpur - Purpur config files
+ space.bxteam.divinemc.configuration.DivineConfig.init((File) console.options.valueOf("divinemc-settings")); // DivineMC - DivineMC config files
for (ServerLevel world : this.console.getAllLevels()) {
// world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty
@@ -3130,6 +3131,13 @@ public final class CraftServer implements Server {
world.setSpawnSettings(world.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && config.spawnMonsters); // Paper - per level difficulty (from MinecraftServer#setDifficulty(ServerLevel, Difficulty, boolean))
@@ -1119,6 +1120,7 @@ public final class CraftServer implements Server {
}
world.spigotConfig.init(); // Spigot
world.purpurConfig.init(); // Purpur - Purpur config files
+ world.divinemcConfig.init(); // DivineMC - DivineMC config files
}
Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper
@@ -3130,6 +3132,13 @@ public final class CraftServer implements Server {
return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console);
}
+ // DivineMC start - DivineMC configuration
+ @Override
+ public YamlConfiguration getDivineConfig() {
+ return CraftServer.this.console.divineConfigurations.createLegacyObject(CraftServer.this.console);
+ return space.bxteam.divinemc.configuration.DivineConfig.config;
+ }
+ // DivineMC end - DivineMC configuration
+
// Purpur start - Purpur config files
@Override
public YamlConfiguration getPurpurConfig() {
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
index 90fb036607e752fcf43575be4f03bbf00bbb05c7..cefb51630b26cac0dd3d69973437b14532f59710 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -183,6 +183,15 @@ public class Main {
.defaultsTo(new File("purpur.yml"))
.describedAs("Yml file");
// Purpur end - Purpur config files
+
+ // DivineMC start - DivineMC config files
+ acceptsAll(asList("divinemc", "divinemc-settings"), "File for divinemc settings")
+ .withRequiredArg()
+ .ofType(File.class)
+ .defaultsTo(new File("divinemc.yml"))
+ .describedAs("Yml file");
+ // DivineMC end - DivineMC config files
+
// Paper start
acceptsAll(asList("server-name"), "Name of the server")
.withRequiredArg()

View File

@@ -7,7 +7,7 @@ Original license: GPLv3
Original project: https://github.com/plasmoapp/matter
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
index de8b9048c8395c05b8688bc9d984b8ad680f15b3..832b5743c9b64be1401bda821484730436d88dc0 100644
index de8b9048c8395c05b8688bc9d984b8ad680f15b3..287fd2f3931ab776203f322fb05dfa236d94c59b 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
@@ -206,7 +206,12 @@ public class CraftChunk implements Chunk {
@@ -16,7 +16,7 @@ index de8b9048c8395c05b8688bc9d984b8ad680f15b3..832b5743c9b64be1401bda8214847304
// 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.DivineGlobalConfiguration.get().misc.enableSecureSeed
+ 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;
@@ -25,16 +25,16 @@ index de8b9048c8395c05b8688bc9d984b8ad680f15b3..832b5743c9b64be1401bda8214847304
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index dc16de7d177b50dd58eb38a078b161e31426ccb8..a9078ced817f35dd75f02d8a11f6283db95e3e34 100644
index 55f9267c83427dbe4ab28580ec515539565f3bdb..bfcf494a34fad26f282b705270725b724d5719a7 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1403,7 +1403,11 @@ public final class CraftServer implements Server {
@@ -1404,7 +1404,11 @@ public final class CraftServer implements Server {
registryAccess = levelDataAndDimensions.dimensions().dimensionsRegistryAccess();
} else {
LevelSettings levelSettings;
- WorldOptions worldOptions = new WorldOptions(creator.seed(), creator.generateStructures(), false);
+ // DivineMC start - Implement Secure Seed
+ WorldOptions worldOptions = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.enableSecureSeed
+ 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 - Implement Secure Seed

View File

@@ -5,7 +5,7 @@
private static GameProfile createAuthLibProfile(UUID uniqueId, String name) {
Preconditions.checkArgument(name == null || name.length() <= 16, "Name cannot be longer than 16 characters");
- Preconditions.checkArgument(name == null || StringUtil.isValidPlayerName(name), "The name of the profile contains invalid characters: %s", name);
+ Preconditions.checkArgument(name == null || space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().misc.removeVanillaUsernameCheck || StringUtil.isValidPlayerName(name), "The name of the profile contains invalid characters: %s", name); // DivineMC - Remove vanilla username check
+ Preconditions.checkArgument(name == null || space.bxteam.divinemc.configuration.DivineConfig.removeVanillaUsernameCheck || StringUtil.isValidPlayerName(name), "The name of the profile contains invalid characters: %s", name); // DivineMC - Remove vanilla username check
return new GameProfile(
uniqueId != null ? uniqueId : Util.NIL_UUID,
name != null ? name : ""

View File

@@ -5,7 +5,7 @@
private void sendToServer(final ChatType.Bound chatType, final @Nullable Function<Audience, net.minecraft.network.chat.Component> msgFunction) {
final PlayerChatMessage toConsoleMessage = msgFunction == null ? ChatProcessor.this.message : ChatProcessor.this.message.withUnsignedContent(msgFunction.apply(ChatProcessor.this.server.console));
- ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage) ? null : "Not Secure");
+ ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage) || space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().chat.noChatSign ? null : "Not Secure"); // DivineMC - No chat sign
+ ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage) || space.bxteam.divinemc.configuration.DivineConfig.noChatSign ? null : "Not Secure"); // DivineMC - No chat sign
}
}

View File

@@ -7,7 +7,7 @@
import com.destroystokyo.paper.event.server.ServerExceptionEvent;
import com.destroystokyo.paper.exception.ServerEventException;
import com.google.common.collect.Sets;
@@ -36,15 +_,16 @@
@@ -36,15 +_,22 @@
// SimplePluginManager
public void callEvent(@NotNull Event event) {
@@ -18,6 +18,12 @@
if (event.isAsynchronous() && this.server.isPrimaryThread()) {
throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously.");
} else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) {
+ // DivineMC start - Multithreaded tracker
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled) {
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(event::callEvent);
+ return;
+ }
+ // DivineMC end - Multithreaded tracker
throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously.");
}

View File

@@ -1,12 +1,16 @@
package space.bxteam.divinemc.command.subcommands;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.permissions.PermissionDefault;
import space.bxteam.divinemc.command.DivineCommand;
import space.bxteam.divinemc.command.DivineSubCommandPermission;
import space.bxteam.divinemc.configuration.DivineConfig;
import java.io.File;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
@@ -31,8 +35,12 @@ public final class ReloadCommand extends DivineSubCommandPermission {
Command.broadcastCommandMessage(sender, text("If you encounter any issues please use the /stop command to restart your server.", RED));
MinecraftServer server = ((CraftServer) sender.getServer()).getServer();
server.divineConfigurations.reloadConfigs(server);
server.server.reloadCount++;
DivineConfig.init((File) server.options.valueOf("divinemc-settings"));
for (ServerLevel level : server.getAllLevels()) {
level.divinemcConfig.init();
level.resetBreedingCooldowns();
}
server.server.reloadCount++;
Command.broadcastCommandMessage(sender, text("DivineMC config reload complete.", GREEN));
}

View File

@@ -0,0 +1,203 @@
package space.bxteam.divinemc.configuration;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
@SuppressWarnings("unused")
public class DivineConfig {
private static final String HEADER = "This is the main configuration file for DivineMC.\n"
+ "If you need help with the configuration or have any questions related to DivineMC,\n"
+ "join us in our Discord server.\n"
+ "\n"
+ "Discord: https://discord.gg/p7cxhw7E2M \n"
+ "Docs: https://docs.bx-team.space/documentation/divinemc/about \n"
+ "New builds: https://github.com/DivineMC/DivineMC/releases/latest";
private static File CONFIG_FILE;
public static YamlConfiguration config;
private static Map<String, Command> commands;
public static int version;
static boolean verbose;
public static void init(File configFile) {
CONFIG_FILE = configFile;
config = new YamlConfiguration();
try {
config.load(CONFIG_FILE);
} catch (IOException ignore) {
} catch (InvalidConfigurationException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Could not load divinemc.yml, please correct your syntax errors", ex);
throw Throwables.propagate(ex);
}
config.options().header(HEADER);
config.options().copyDefaults(true);
verbose = getBoolean("verbose", false);
version = getInt("config-version", 4);
set("config-version", 4);
readConfig(DivineConfig.class, null);
Block.BLOCK_STATE_REGISTRY.forEach(BlockBehaviour.BlockStateBase::initCache);
}
protected static void log(String s) {
if (verbose) {
log(Level.INFO, s);
}
}
protected static void log(Level level, String s) {
Bukkit.getLogger().log(level, s);
}
static void readConfig(Class<?> clazz, Object instance) {
for (Method method : clazz.getDeclaredMethods()) {
if (Modifier.isPrivate(method.getModifiers())) {
if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) {
try {
method.setAccessible(true);
method.invoke(instance);
} catch (InvocationTargetException ex) {
throw Throwables.propagate(ex.getCause());
} catch (Exception ex) {
Bukkit.getLogger().log(Level.SEVERE, "Error invoking " + method, ex);
}
}
}
}
try {
config.save(CONFIG_FILE);
} catch (IOException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Could not save " + CONFIG_FILE, ex);
}
}
private static void set(String path, Object val) {
config.addDefault(path, val);
config.set(path, val);
}
private static String getString(String path, String def) {
config.addDefault(path, def);
return config.getString(path, config.getString(path));
}
private static boolean getBoolean(String path, boolean def) {
config.addDefault(path, def);
return config.getBoolean(path, config.getBoolean(path));
}
private static double getDouble(String path, double def) {
config.addDefault(path, def);
return config.getDouble(path, config.getDouble(path));
}
private static int getInt(String path, int def) {
config.addDefault(path, def);
return config.getInt(path, config.getInt(path));
}
private static <T> List getList(String path, T def) {
config.addDefault(path, def);
return config.getList(path, config.getList(path));
}
static Map<String, Object> getMap(String path, Map<String, Object> def) {
if (def != null && config.getConfigurationSection(path) == null) {
config.addDefault(path, def);
return def;
}
return toMap(config.getConfigurationSection(path));
}
private static Map<String, Object> toMap(ConfigurationSection section) {
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
if (section != null) {
for (String key : section.getKeys(false)) {
Object obj = section.get(key);
if (obj != null) {
builder.put(key, obj instanceof ConfigurationSection val ? toMap(val) : obj);
}
}
}
return builder.build();
}
public static boolean noChatSign = true;
private static void chatMessageSignatures() {
noChatSign = getBoolean("settings.no-chat-sign", noChatSign);
}
public static boolean optimizedDragonRespawn = true;
private static void optimizations() {
optimizedDragonRespawn = getBoolean("settings.optimizations.optimized-dragon-respawn", optimizedDragonRespawn);
}
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 asyncPathfinding = true;
public static int asyncPathfindingMaxThreads = 0;
public static int asyncPathfindingKeepalive = 60;
private static void asyncPathfinding() {
asyncPathfinding = getBoolean("settings.async-pathfinding.enable", asyncPathfinding);
asyncPathfindingMaxThreads = getInt("settings.async-pathfinding.max-threads", asyncPathfindingMaxThreads);
asyncPathfindingKeepalive = getInt("settings.async-pathfinding.keepalive", asyncPathfindingKeepalive);
if (asyncPathfindingMaxThreads < 0)
asyncPathfindingMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncPathfindingMaxThreads, 1);
else if (asyncPathfindingMaxThreads == 0)
asyncPathfindingMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1);
if (!asyncPathfinding)
asyncPathfindingMaxThreads = 0;
else
Bukkit.getLogger().log(Level.INFO, "Using " + asyncPathfindingMaxThreads + " threads for Async Pathfinding");
}
public static boolean multithreadedEnabled = false;
public static boolean multithreadedCompatModeEnabled = false;
public static int asyncEntityTrackerMaxThreads = 0;
public static int asyncEntityTrackerKeepalive = 60;
private static void multithreadedTracker() {
multithreadedEnabled = getBoolean("settings.multithreaded-tracker.enable", multithreadedEnabled);
multithreadedCompatModeEnabled = getBoolean("settings.multithreaded-tracker.compat-mode", multithreadedCompatModeEnabled);
asyncEntityTrackerMaxThreads = getInt("settings.multithreaded-tracker.max-threads", asyncEntityTrackerMaxThreads);
asyncEntityTrackerKeepalive = getInt("settings.multithreaded-tracker.keepalive", asyncEntityTrackerKeepalive);
if (asyncEntityTrackerMaxThreads < 0)
asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncEntityTrackerMaxThreads, 1);
else if (asyncEntityTrackerMaxThreads == 0)
asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1);
if (!multithreadedEnabled)
asyncEntityTrackerMaxThreads = 0;
else
Bukkit.getLogger().log(Level.INFO, "Using " + asyncEntityTrackerMaxThreads + " threads for Async Entity Tracker");
}
}

View File

@@ -1,289 +0,0 @@
package space.bxteam.divinemc.configuration;
import com.google.common.collect.Table;
import com.mojang.logging.LogUtils;
import io.leangen.geantyref.TypeToken;
import io.papermc.paper.configuration.Configuration;
import io.papermc.paper.configuration.ConfigurationPart;
import io.papermc.paper.configuration.Configurations;
import io.papermc.paper.configuration.NestedSetting;
import io.papermc.paper.configuration.PaperConfigurations;
import io.papermc.paper.configuration.legacy.RequiresSpigotInitialization;
import io.papermc.paper.configuration.mapping.InnerClassFieldDiscoverer;
import io.papermc.paper.configuration.serializer.ComponentSerializer;
import io.papermc.paper.configuration.serializer.EnumValueSerializer;
import io.papermc.paper.configuration.serializer.PacketClassSerializer;
import io.papermc.paper.configuration.serializer.StringRepresentableSerializer;
import io.papermc.paper.configuration.serializer.collections.FastutilMapSerializer;
import io.papermc.paper.configuration.serializer.collections.MapSerializer;
import io.papermc.paper.configuration.serializer.collections.TableSerializer;
import io.papermc.paper.configuration.serializer.registry.RegistryHolderSerializer;
import io.papermc.paper.configuration.serializer.registry.RegistryValueSerializer;
import io.papermc.paper.configuration.transformation.Transformations;
import io.papermc.paper.configuration.type.BooleanOrDefault;
import io.papermc.paper.configuration.type.Duration;
import io.papermc.paper.configuration.type.EngineMode;
import io.papermc.paper.configuration.type.fallback.FallbackValueSerializer;
import io.papermc.paper.configuration.type.number.DoubleOr;
import io.papermc.paper.configuration.type.number.IntOr;
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.Reference2LongMap;
import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.registries.Registries;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.ConfigurationOptions;
import org.spongepowered.configurate.NodePath;
import org.spongepowered.configurate.objectmapping.ObjectMapper;
import org.spongepowered.configurate.transformation.ConfigurationTransformation;
import org.spongepowered.configurate.transformation.TransformAction;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import static io.leangen.geantyref.GenericTypeReflector.erase;
@SuppressWarnings("Convert2Diamond")
public class DivineConfigurations extends Configurations<DivineGlobalConfiguration, DivineWorldConfiguration> {
private static final Logger LOGGER = LogUtils.getLogger();
static final String GLOBAL_CONFIG_FILE_NAME = "divinemc-global.yml";
static final String WORLD_DEFAULTS_CONFIG_FILE_NAME = "divinemc-world-defaults.yml";
static final String WORLD_CONFIG_FILE_NAME = "divinemc-world.yml";
public static final String CONFIG_DIR = "config";
private static final String GLOBAL_HEADER = String.format("""
This is the global configuration file for DivineMC.
If you need help with the configuration or have any questions related to DivineMC,
join us in our Discord, or check our Documentation website.
The world configuration options are inside
their respective world folder. The files are named %s
Documentation: https://docs.bx-team.space/documentation/divinemc/about
Discord: https://discord.gg/p7cxhw7E2M""", WORLD_CONFIG_FILE_NAME);
private static final String WORLD_DEFAULTS_HEADER = """
This is the world defaults configuration file for DivineMC.
If you need help with the configuration or have any questions related to DivineMC,
join us in our Discord, or check our Documentation website.
Configuration options here apply to all worlds, unless you specify overrides inside
the world-specific config file inside each world folder.
Documentation: https://docs.bx-team.space/documentation/divinemc/about
Discord: https://discord.gg/p7cxhw7E2M""";
private static final Function<ContextMap, String> WORLD_HEADER = map -> String.format("""
This is a world configuration file for DivineMC.
This file may start empty but can be filled with settings to override ones in the %s/%s
World: %s (%s)""",
CONFIG_DIR,
WORLD_DEFAULTS_CONFIG_FILE_NAME,
map.require(WORLD_NAME),
map.require(WORLD_KEY)
);
public DivineConfigurations(final Path globalFolder) {
super(globalFolder, DivineGlobalConfiguration.class, DivineWorldConfiguration.class, GLOBAL_CONFIG_FILE_NAME, WORLD_DEFAULTS_CONFIG_FILE_NAME, WORLD_CONFIG_FILE_NAME);
}
@Override
protected YamlConfigurationLoader.Builder createLoaderBuilder() {
return super.createLoaderBuilder()
.defaultOptions(DivineConfigurations::defaultOptions);
}
private static ConfigurationOptions defaultOptions(ConfigurationOptions options) {
return options.serializers(builder -> builder
.register(MapSerializer.TYPE, new MapSerializer(false))
.register(new EnumValueSerializer())
.register(new ComponentSerializer())
);
}
@Override
protected ObjectMapper.Factory.Builder createGlobalObjectMapperFactoryBuilder() {
return defaultGlobalFactoryBuilder(super.createGlobalObjectMapperFactoryBuilder());
}
private static ObjectMapper.Factory.Builder defaultGlobalFactoryBuilder(ObjectMapper.Factory.Builder builder) {
return builder.addDiscoverer(InnerClassFieldDiscoverer.globalConfig());
}
@Override
protected YamlConfigurationLoader.Builder createGlobalLoaderBuilder(RegistryAccess registryAccess) {
return super.createGlobalLoaderBuilder(registryAccess)
.defaultOptions((options) -> defaultGlobalOptions(registryAccess, options));
}
private static ConfigurationOptions defaultGlobalOptions(RegistryAccess registryAccess, ConfigurationOptions options) {
return options
.header(GLOBAL_HEADER)
.serializers(builder -> builder.register(new PacketClassSerializer())
.register(new RegistryValueSerializer<>(new TypeToken<DataComponentType<?>>() {}, registryAccess, Registries.DATA_COMPONENT_TYPE, false))
);
}
@Override
public DivineGlobalConfiguration initializeGlobalConfiguration(final RegistryAccess registryAccess) throws ConfigurateException {
DivineGlobalConfiguration configuration = super.initializeGlobalConfiguration(registryAccess);
DivineGlobalConfiguration.set(configuration);
return configuration;
}
@Override
protected ContextMap.Builder createDefaultContextMap(final RegistryAccess registryAccess) {
return super.createDefaultContextMap(registryAccess)
.put(PaperConfigurations.SPIGOT_WORLD_CONFIG_CONTEXT_KEY, PaperConfigurations.SPIGOT_WORLD_DEFAULTS);
}
@Override
protected ObjectMapper.Factory.Builder createWorldObjectMapperFactoryBuilder(final ContextMap contextMap) {
return super.createWorldObjectMapperFactoryBuilder(contextMap)
.addNodeResolver(new RequiresSpigotInitialization.Factory(contextMap.require(PaperConfigurations.SPIGOT_WORLD_CONFIG_CONTEXT_KEY).get()))
.addNodeResolver(new NestedSetting.Factory())
.addDiscoverer(InnerClassFieldDiscoverer.divineWorldConfig(contextMap));
}
@Override
protected YamlConfigurationLoader.Builder createWorldConfigLoaderBuilder(final ContextMap contextMap) {
final RegistryAccess access = contextMap.require(REGISTRY_ACCESS);
return super.createWorldConfigLoaderBuilder(contextMap)
.defaultOptions(options -> options
.header(contextMap.require(WORLD_NAME).equals(WORLD_DEFAULTS) ? WORLD_DEFAULTS_HEADER : WORLD_HEADER.apply(contextMap))
.serializers(serializers -> serializers
.register(new TypeToken<Reference2IntMap<?>>() {}, new FastutilMapSerializer.SomethingToPrimitive<Reference2IntMap<?>>(Reference2IntOpenHashMap::new, Integer.TYPE))
.register(new TypeToken<Reference2LongMap<?>>() {}, new FastutilMapSerializer.SomethingToPrimitive<Reference2LongMap<?>>(Reference2LongOpenHashMap::new, Long.TYPE))
.register(new TypeToken<Table<?, ?, ?>>() {}, new TableSerializer())
.register(new StringRepresentableSerializer())
.register(IntOr.Default.SERIALIZER)
.register(IntOr.Disabled.SERIALIZER)
.register(DoubleOr.Default.SERIALIZER)
.register(BooleanOrDefault.SERIALIZER)
.register(Duration.SERIALIZER)
.register(EngineMode.SERIALIZER)
.register(FallbackValueSerializer.create(contextMap.require(PaperConfigurations.SPIGOT_WORLD_CONFIG_CONTEXT_KEY).get(), MinecraftServer::getServer))
.register(new RegistryValueSerializer<>(new TypeToken<EntityType<?>>() {}, access, Registries.ENTITY_TYPE, true))
.register(new RegistryValueSerializer<>(Item.class, access, Registries.ITEM, true))
.register(new RegistryHolderSerializer<>(new TypeToken<ConfiguredFeature<?, ?>>() {}, access, Registries.CONFIGURED_FEATURE, false))
.register(new RegistryHolderSerializer<>(Item.class, access, Registries.ITEM, true))
)
);
}
@Override
protected void applyWorldConfigTransformations(final ContextMap contextMap, final ConfigurationNode node, final @Nullable ConfigurationNode defaultsNode) throws ConfigurateException {
final ConfigurationNode version = node.node(Configuration.VERSION_FIELD);
final String world = contextMap.require(WORLD_NAME);
if (version.virtual()) {
LOGGER.warn("The DivineMC world config file for " + world + " didn't have a version set, assuming latest");
version.raw(DivineWorldConfiguration.CURRENT_VERSION);
}
if (DivineRemovedConfiguration.REMOVED_WORLD_PATHS.length > 0) {
ConfigurationTransformation.Builder builder = ConfigurationTransformation.builder();
for (NodePath path : DivineRemovedConfiguration.REMOVED_WORLD_PATHS) {
builder.addAction(path, TransformAction.remove());
}
builder.build().apply(node);
}
// ADD FUTURE TRANSFORMS HERE
}
@Override
protected void applyGlobalConfigTransformations(ConfigurationNode node) throws ConfigurateException {
if (DivineRemovedConfiguration.REMOVED_GLOBAL_PATHS.length > 0) {
ConfigurationTransformation.Builder builder = ConfigurationTransformation.builder();
for (NodePath path : DivineRemovedConfiguration.REMOVED_GLOBAL_PATHS) {
builder.addAction(path, TransformAction.remove());
}
builder.build().apply(node);
}
// ADD FUTURE TRANSFORMS HERE
}
private static final List<Transformations.DefaultsAware> DEFAULT_AWARE_TRANSFORMATIONS = Collections.emptyList();
@Override
protected void applyDefaultsAwareWorldConfigTransformations(final ContextMap contextMap, final ConfigurationNode worldNode, final ConfigurationNode defaultsNode) throws ConfigurateException {
final ConfigurationTransformation.Builder builder = ConfigurationTransformation.builder();
// ADD FUTURE TRANSFORMS HERE (these transforms run after the defaults have been merged into the node)
DEFAULT_AWARE_TRANSFORMATIONS.forEach(transform -> transform.apply(builder, contextMap, defaultsNode));
ConfigurationTransformation transformation;
try {
transformation = builder.build(); // build throws IAE if no actions were provided (bad zml)
} catch (IllegalArgumentException ignored) {
return;
}
transformation.apply(worldNode);
}
@Override
public DivineWorldConfiguration createWorldConfig(final ContextMap contextMap) {
final String levelName = contextMap.require(WORLD_NAME);
try {
return super.createWorldConfig(contextMap);
} catch (IOException exception) {
throw new RuntimeException("Could not create DivineMC world config for " + levelName, exception);
}
}
@Override
protected boolean isConfigType(final Type type) {
return ConfigurationPart.class.isAssignableFrom(erase(type));
}
public void reloadConfigs(MinecraftServer server) {
try {
this.initializeGlobalConfiguration(server.registryAccess(), reloader(this.globalConfigClass, DivineGlobalConfiguration.get()));
this.initializeWorldDefaultsConfiguration(server.registryAccess());
for (ServerLevel level : server.getAllLevels()) {
this.createWorldConfig(PaperConfigurations.createWorldContextMap(level), reloader(this.worldConfigClass, level.divineConfig()));
}
} catch (Exception ex) {
throw new RuntimeException("Could not reload DivineMC configuration files", ex);
}
}
public static DivineConfigurations setup(final Path configDir) throws Exception {
try {
PaperConfigurations.createDirectoriesSymlinkAware(configDir);
return new DivineConfigurations(configDir);
} catch (final IOException ex) {
throw new RuntimeException("Could not setup DivineConfigurations", ex);
}
}
@Override
protected int globalConfigVersion() {
return DivineGlobalConfiguration.CURRENT_VERSION;
}
@Override
protected int worldConfigVersion() {
return getWorldConfigurationCurrentVersion();
}
@Override
public int getWorldConfigurationCurrentVersion() {
return DivineWorldConfiguration.CURRENT_VERSION;
}
}

View File

@@ -1,95 +0,0 @@
package space.bxteam.divinemc.configuration;
import io.papermc.paper.configuration.Configuration;
import io.papermc.paper.configuration.ConfigurationPart;
import org.bukkit.Bukkit;
import org.spongepowered.configurate.objectmapping.meta.PostProcess;
import org.spongepowered.configurate.objectmapping.meta.Setting;
import java.util.logging.Level;
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal", "FieldMayBeFinal", "NotNullFieldNotInitialized", "InnerClassMayBeStatic"})
public class DivineGlobalConfiguration extends ConfigurationPart {
static final int CURRENT_VERSION = 4;
private static DivineGlobalConfiguration instance;
public static DivineGlobalConfiguration get() {
return instance;
}
static void set(DivineGlobalConfiguration instance) {
DivineGlobalConfiguration.instance = instance;
}
@Setting(Configuration.VERSION_FIELD)
public int version = CURRENT_VERSION;
public AsyncPathfinding asyncPathfinding;
public class AsyncPathfinding extends ConfigurationPart {
public boolean asyncPathfinding = true;
public int asyncPathfindingMaxThreads = 0;
public int asyncPathfindingKeepalive = 60;
@PostProcess
public void init() {
if (asyncPathfindingMaxThreads < 0) {
asyncPathfindingMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncPathfindingMaxThreads, 1);
} else if (asyncPathfindingMaxThreads == 0) {
asyncPathfindingMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1);
}
if (!asyncPathfinding) {
asyncPathfindingMaxThreads = 0;
} else {
Bukkit.getLogger().log(Level.INFO, "Using " + asyncPathfindingMaxThreads + " threads for Async Pathfinding");
}
}
}
public MultithreadTracker multithreadTracker;
public class MultithreadTracker extends ConfigurationPart {
public boolean multithreadedEnabled = false;
public boolean multithreadedCompatModeEnabled = false;
public int asyncEntityTrackerMaxThreads = 0;
public int asyncEntityTrackerKeepalive = 60;
@PostProcess
public void init() {
if (asyncEntityTrackerMaxThreads < 0) {
asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncEntityTrackerMaxThreads, 1);
} else if (asyncEntityTrackerMaxThreads == 0) {
asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1);
}
if (!multithreadedEnabled) {
asyncEntityTrackerMaxThreads = 0;
} else {
Bukkit.getLogger().log(Level.INFO, "Using " + asyncEntityTrackerMaxThreads + " threads for Async Entity Tracker");
}
}
}
public Optimizations optimizations;
public class Optimizations extends ConfigurationPart {
public boolean optimizedDragonRespawn = true;
}
public Chat chat;
public class Chat extends ConfigurationPart {
public boolean noChatSign = true;
}
public Misc misc;
public class Misc extends ConfigurationPart {
public boolean disableNonEditableSignWarning = true;
public boolean removeVanillaUsernameCheck = false;
public boolean disableMovedWronglyThreshold = false;
public boolean enableSecureSeed = false;
}
}

View File

@@ -1,9 +0,0 @@
package space.bxteam.divinemc.configuration;
import org.spongepowered.configurate.NodePath;
interface DivineRemovedConfiguration {
NodePath[] REMOVED_WORLD_PATHS = {};
NodePath[] REMOVED_GLOBAL_PATHS = {};
}

View File

@@ -0,0 +1,94 @@
package space.bxteam.divinemc.configuration;
import org.apache.commons.lang.BooleanUtils;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import static space.bxteam.divinemc.configuration.DivineConfig.log;
@SuppressWarnings("unused")
public class DivineWorldConfig {
private final String worldName;
private final World.Environment environment;
public DivineWorldConfig(String worldName, World.Environment environment) {
this.worldName = worldName;
this.environment = environment;
init();
}
public void init() {
log("-------- World Settings For [" + worldName + "] --------");
DivineConfig.readConfig(DivineWorldConfig.class, this);
}
private void set(String path, Object val) {
DivineConfig.config.addDefault("world-settings.default." + path, val);
DivineConfig.config.set("world-settings.default." + path, val);
if (DivineConfig.config.get("world-settings." + worldName + "." + path) != null) {
DivineConfig.config.addDefault("world-settings." + worldName + "." + path, val);
DivineConfig.config.set("world-settings." + worldName + "." + path, val);
}
}
private ConfigurationSection getConfigurationSection(String path) {
ConfigurationSection section = DivineConfig.config.getConfigurationSection("world-settings." + worldName + "." + path);
return section != null ? section : DivineConfig.config.getConfigurationSection("world-settings.default." + path);
}
private String getString(String path, String def) {
DivineConfig.config.addDefault("world-settings.default." + path, def);
return DivineConfig.config.getString("world-settings." + worldName + "." + path, DivineConfig.config.getString("world-settings.default." + path));
}
private boolean getBoolean(String path, boolean def) {
DivineConfig.config.addDefault("world-settings.default." + path, def);
return DivineConfig.config.getBoolean("world-settings." + worldName + "." + path, DivineConfig.config.getBoolean("world-settings.default." + path));
}
private boolean getBoolean(String path, Predicate<Boolean> predicate) {
String val = getString(path, "default").toLowerCase();
Boolean bool = BooleanUtils.toBooleanObject(val, "true", "false", "default");
return predicate.test(bool);
}
private double getDouble(String path, double def) {
DivineConfig.config.addDefault("world-settings.default." + path, def);
return DivineConfig.config.getDouble("world-settings." + worldName + "." + path, DivineConfig.config.getDouble("world-settings.default." + path));
}
private int getInt(String path, int def) {
DivineConfig.config.addDefault("world-settings.default." + path, def);
return DivineConfig.config.getInt("world-settings." + worldName + "." + path, DivineConfig.config.getInt("world-settings.default." + path));
}
private <T> List<?> getList(String path, T def) {
DivineConfig.config.addDefault("world-settings.default." + path, def);
return DivineConfig.config.getList("world-settings." + worldName + "." + path, DivineConfig.config.getList("world-settings.default." + path));
}
private Map<String, Object> getMap(String path, Map<String, Object> def) {
final Map<String, Object> fallback = DivineConfig.getMap("world-settings.default." + path, def);
final Map<String, Object> value = DivineConfig.getMap("world-settings." + worldName + "." + path, null);
return value.isEmpty() ? fallback : value;
}
public boolean despawnShulkerBulletsOnOwnerDeath = true;
private void despawnShulkerBulletsOnOwnerDeath() {
despawnShulkerBulletsOnOwnerDeath = getBoolean("gameplay-mechanics.mob.shulker.despawn-bullets-on-player-death", despawnShulkerBulletsOnOwnerDeath);
}
public boolean saveFireworks = false;
private void projectiles() {
saveFireworks = getBoolean("gameplay-mechanics.should-save-fireworks", saveFireworks);
}
public boolean suppressErrorsFromDirtyAttributes = true;
private void suppressErrorsFromDirtyAttributes() {
suppressErrorsFromDirtyAttributes = getBoolean("suppress-errors-from-dirty-attributes", suppressErrorsFromDirtyAttributes);
}
}

View File

@@ -1,61 +0,0 @@
package space.bxteam.divinemc.configuration;
import com.mojang.logging.LogUtils;
import io.papermc.paper.configuration.Configuration;
import io.papermc.paper.configuration.ConfigurationPart;
import io.papermc.paper.configuration.PaperConfigurations;
import net.minecraft.resources.ResourceLocation;
import org.slf4j.Logger;
import org.spigotmc.SpigotWorldConfig;
import org.spongepowered.configurate.objectmapping.meta.Comment;
import org.spongepowered.configurate.objectmapping.meta.Setting;
@SuppressWarnings({"FieldCanBeLocal", "FieldMayBeFinal", "NotNullFieldNotInitialized", "InnerClassMayBeStatic"})
public class DivineWorldConfiguration extends ConfigurationPart {
private static final Logger LOGGER = LogUtils.getLogger();
public static final int CURRENT_VERSION = 4;
private transient final SpigotWorldConfig spigotConfig;
private transient final ResourceLocation worldKey;
public DivineWorldConfiguration(SpigotWorldConfig spigotConfig, ResourceLocation worldKey) {
this.spigotConfig = spigotConfig;
this.worldKey = worldKey;
}
public boolean isDefault() {
return this.worldKey.equals(PaperConfigurations.WORLD_DEFAULTS_KEY);
}
@Setting(Configuration.VERSION_FIELD)
public int version = CURRENT_VERSION;
public Optimizations optimizations;
public class Optimizations extends ConfigurationPart {
public boolean suppressErrorsFromDirtyAttributes = true;
}
public GameplayMechanics gameplayMechanics;
public class GameplayMechanics extends ConfigurationPart {
public Mob mob;
public class Mob extends ConfigurationPart {
public Shulker shulker;
public class Shulker extends ConfigurationPart {
@Comment("If true, shulker bullets will despawn when their owner dies.")
public boolean despawnShulkerBulletsOnOwnerDeath = true;
}
}
public Projectiles projectiles;
public class Projectiles extends ConfigurationPart {
public boolean snowballCanKnockback = true;
public boolean eggCanKnockback = true;
public boolean saveFireworks = false;
}
}
}

View File

@@ -15,8 +15,8 @@ import java.util.function.Consumer;
public class AsyncPathProcessor {
private static final Executor pathProcessingExecutor = new ThreadPoolExecutor(
1,
space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfindingMaxThreads,
space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().asyncPathfinding.asyncPathfindingKeepalive, TimeUnit.SECONDS,
space.bxteam.divinemc.configuration.DivineConfig.asyncPathfindingMaxThreads,
space.bxteam.divinemc.configuration.DivineConfig.asyncPathfindingKeepalive, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
new ThreadFactoryBuilder()
.setNameFormat("DivineMC Async Pathfinding Thread - %d")

View File

@@ -0,0 +1,94 @@
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 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();
}
}

View File

@@ -0,0 +1,73 @@
package space.bxteam.divinemc.seed;
public class Hashing {
// https://en.wikipedia.org/wiki/BLAKE_(hash_function)
// https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/digests/Blake2bDigest.java
private final static long[] blake2b_IV = {
0x6a09e667f3bcc908L, 0xbb67ae8584caa73bL, 0x3c6ef372fe94f82bL,
0xa54ff53a5f1d36f1L, 0x510e527fade682d1L, 0x9b05688c2b3e6c1fL,
0x1f83d9abfb41bd6bL, 0x5be0cd19137e2179L
};
private final static byte[][] blake2b_sigma = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
{11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
{7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
{9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
{2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
{12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
{13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
{6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
{10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}
};
public static long[] hashWorldSeed(long[] worldSeed) {
long[] result = blake2b_IV.clone();
result[0] ^= 0x01010040;
hash(worldSeed, result, new long[16], 0, false);
return result;
}
public static void hash(long[] message, long[] chainValue, long[] internalState, long messageOffset, boolean isFinal) {
assert message.length == 16;
assert chainValue.length == 8;
assert internalState.length == 16;
System.arraycopy(chainValue, 0, internalState, 0, chainValue.length);
System.arraycopy(blake2b_IV, 0, internalState, chainValue.length, 4);
internalState[12] = messageOffset ^ blake2b_IV[4];
internalState[13] = blake2b_IV[5];
if (isFinal) internalState[14] = ~blake2b_IV[6];
internalState[15] = blake2b_IV[7];
for (int round = 0; round < 12; round++) {
G(message[blake2b_sigma[round][0]], message[blake2b_sigma[round][1]], 0, 4, 8, 12, internalState);
G(message[blake2b_sigma[round][2]], message[blake2b_sigma[round][3]], 1, 5, 9, 13, internalState);
G(message[blake2b_sigma[round][4]], message[blake2b_sigma[round][5]], 2, 6, 10, 14, internalState);
G(message[blake2b_sigma[round][6]], message[blake2b_sigma[round][7]], 3, 7, 11, 15, internalState);
G(message[blake2b_sigma[round][8]], message[blake2b_sigma[round][9]], 0, 5, 10, 15, internalState);
G(message[blake2b_sigma[round][10]], message[blake2b_sigma[round][11]], 1, 6, 11, 12, internalState);
G(message[blake2b_sigma[round][12]], message[blake2b_sigma[round][13]], 2, 7, 8, 13, internalState);
G(message[blake2b_sigma[round][14]], message[blake2b_sigma[round][15]], 3, 4, 9, 14, internalState);
}
for (int i = 0; i < 8; i++) {
chainValue[i] ^= internalState[i] ^ internalState[i + 8];
}
}
private static void G(long m1, long m2, int posA, int posB, int posC, int posD, long[] internalState) {
internalState[posA] = internalState[posA] + internalState[posB] + m1;
internalState[posD] = Long.rotateRight(internalState[posD] ^ internalState[posA], 32);
internalState[posC] = internalState[posC] + internalState[posD];
internalState[posB] = Long.rotateRight(internalState[posB] ^ internalState[posC], 24); // replaces 25 of BLAKE
internalState[posA] = internalState[posA] + internalState[posB] + m2;
internalState[posD] = Long.rotateRight(internalState[posD] ^ internalState[posA], 16);
internalState[posC] = internalState[posC] + internalState[posD];
internalState[posB] = Long.rotateRight(internalState[posB] ^ internalState[posC], 63); // replaces 11 of BLAKE
}
}

View File

@@ -0,0 +1,159 @@
package space.bxteam.divinemc.seed;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.levelgen.LegacyRandomSource;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
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[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[Globals.WORLD_SEED_LONGS];
private final long[] randomBits = new long[8];
private int randomBitIndex;
private static final int MAX_RANDOM_BIT_INDEX = 64 * 8;
private static final int LOG2_MAX_RANDOM_BIT_INDEX = 9;
private long counter;
private final long[] message = new long[16];
private final long[] cachedInternalState = new long[16];
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, 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) Globals.dimension.get() << 32) | ((long) salt & 0xffffffffL);
message[2] = typeSalt.ordinal();
message[3] = counter = 0;
randomBitIndex = MAX_RANDOM_BIT_INDEX;
}
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, Globals.WORLD_SEED_LONGS);
}
return HASHED_WORLD_SEED.get();
}
private void moreRandomBits() {
message[3] = counter++;
System.arraycopy(getHashedWorldSeed(), 0, randomBits, 0, 8);
Hashing.hash(message, randomBits, cachedInternalState, 64, true);
}
private long getBits(int count) {
if (randomBitIndex >= MAX_RANDOM_BIT_INDEX) {
moreRandomBits();
randomBitIndex -= MAX_RANDOM_BIT_INDEX;
}
int alignment = randomBitIndex & 63;
if ((randomBitIndex >>> 6) == ((randomBitIndex + count) >>> 6)) {
long result = (randomBits[randomBitIndex >>> 6] >>> alignment) & ((1L << count) - 1);
randomBitIndex += count;
return result;
} else {
long result = (randomBits[randomBitIndex >>> 6] >>> alignment) & ((1L << (64 - alignment)) - 1);
randomBitIndex += count;
if (randomBitIndex >= MAX_RANDOM_BIT_INDEX) {
moreRandomBits();
randomBitIndex -= MAX_RANDOM_BIT_INDEX;
}
alignment = randomBitIndex & 63;
result <<= alignment;
result |= (randomBits[randomBitIndex >>> 6] >>> (64 - alignment)) & ((1L << alignment) - 1);
return result;
}
}
@Override
public @NotNull RandomSource fork() {
WorldgenCryptoRandom fork = new WorldgenCryptoRandom(0, 0, null, 0);
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];
fork.message[3] = this.message[3];
fork.randomBitIndex = this.randomBitIndex;
fork.counter = this.counter;
fork.nextLong();
return fork;
}
@Override
public int next(int bits) {
return (int) getBits(bits);
}
@Override
public void consumeCount(int count) {
randomBitIndex += count;
if (randomBitIndex >= MAX_RANDOM_BIT_INDEX * 2) {
randomBitIndex -= MAX_RANDOM_BIT_INDEX;
counter += randomBitIndex >>> LOG2_MAX_RANDOM_BIT_INDEX;
randomBitIndex &= MAX_RANDOM_BIT_INDEX - 1;
randomBitIndex += MAX_RANDOM_BIT_INDEX;
}
}
@Override
public int nextInt(int bound) {
int bits = Mth.ceillog2(bound);
int result;
do {
result = (int) getBits(bits);
} while (result >= bound);
return result;
}
@Override
public long nextLong() {
return getBits(64);
}
@Override
public double nextDouble() {
return getBits(53) * 0x1.0p-53;
}
@Override
public long setDecorationSeed(long worldSeed, int blockX, int blockZ) {
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, Globals.Salt.DECORATION, index + 10000L * step);
}
@Override
public void setLargeFeatureSeed(long worldSeed, int chunkX, int chunkZ) {
super.setLargeFeatureSeed(worldSeed, chunkX, chunkZ);
}
@Override
public void setLargeFeatureWithSalt(long worldSeed, int regionX, int regionZ, int salt) {
super.setLargeFeatureWithSalt(worldSeed, regionX, regionZ, salt);
}
public static RandomSource seedSlimeChunk(int chunkX, int chunkZ) {
return new WorldgenCryptoRandom(chunkX, chunkZ, Globals.Salt.SLIME_CHUNK, 0);
}
}

View File

@@ -31,8 +31,8 @@ public class MultithreadedTracker {
private static final Executor trackerExecutor = new ThreadPoolExecutor(
1,
space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.asyncEntityTrackerMaxThreads,
space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.asyncEntityTrackerKeepalive, TimeUnit.SECONDS,
space.bxteam.divinemc.configuration.DivineConfig.asyncEntityTrackerMaxThreads,
space.bxteam.divinemc.configuration.DivineConfig.asyncEntityTrackerKeepalive, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
new ThreadFactoryBuilder()
.setThreadFactory(
@@ -55,7 +55,7 @@ public class MultithreadedTracker {
public static void tick(ChunkSystemServerLevel level) {
try {
if (!space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedCompatModeEnabled) {
if (!space.bxteam.divinemc.configuration.DivineConfig.multithreadedCompatModeEnabled) {
tickAsync(level);
} else {
tickAsyncWithCompatMode(level);