From dbb184d8af5fc7ce8a43d7038c33a97b018b10eb Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Thu, 16 Jan 2025 02:42:17 +0300 Subject: [PATCH] rollback to previous config system; fix patches --- .../0002-DivineMC-Configuration.patch | 140 ++------- .../features/0009-No-chat-sign.patch | 32 +- ...tch => 0010-Petal-Async-Pathfinding.patch} | 60 ++-- .../features/0011-Implement-Secure-Seed.patch | 68 +++-- .../0012-Multithreaded-Tracker.patch | 34 +-- .../dedicated/DedicatedServer.java.patch | 8 - .../server/level/ServerEntity.java.patch | 2 +- .../ServerGamePacketListenerImpl.java.patch | 4 +- .../ServerLoginPacketListenerImpl.java.patch | 2 +- .../FireworkRocketEntity.java.patch | 2 +- .../projectile/ShulkerBullet.java.patch | 2 +- .../block/entity/SignBlockEntity.java.patch | 2 +- .../dimension/end/EndDragonFight.java.patch | 2 +- .../0002-DivineMC-Configuration.patch | 168 +++------- .../0005-Implement-Secure-Seed.patch | 10 +- .../profile/CraftPlayerProfile.java.patch | 2 +- .../paper/adventure/ChatProcessor.java.patch | 2 +- .../manager/PaperEventManager.java.patch | 8 +- .../command/subcommands/ReloadCommand.java | 12 +- .../divinemc/configuration/DivineConfig.java | 203 ++++++++++++ .../configuration/DivineConfigurations.java | 289 ------------------ .../DivineGlobalConfiguration.java | 95 ------ .../DivineRemovedConfiguration.java | 9 - .../configuration/DivineWorldConfig.java | 94 ++++++ .../DivineWorldConfiguration.java | 61 ---- .../pathfinding/AsyncPathProcessor.java | 4 +- .../space/bxteam/divinemc/seed/Globals.java | 94 ++++++ .../space/bxteam/divinemc/seed/Hashing.java | 73 +++++ .../divinemc/seed/WorldgenCryptoRandom.java | 159 ++++++++++ .../tracker/MultithreadedTracker.java | 6 +- 30 files changed, 827 insertions(+), 820 deletions(-) rename divinemc-server/minecraft-patches/features/{0011-Petal-Async-Pathfinding.patch => 0010-Petal-Async-Pathfinding.patch} (93%) rename divinemc-archived-patches/work/server/0010-Implement-Secure-Seed.patch => divinemc-server/minecraft-patches/features/0011-Implement-Secure-Seed.patch (89%) rename {divinemc-archived-patches/work/server => divinemc-server/minecraft-patches/features}/0012-Multithreaded-Tracker.patch (90%) rename {divinemc-archived-patches/work/server => divinemc-server/paper-patches/features}/0005-Implement-Secure-Seed.patch (87%) create mode 100644 divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java delete mode 100644 divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineConfigurations.java delete mode 100644 divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineGlobalConfiguration.java delete mode 100644 divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineRemovedConfiguration.java create mode 100644 divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java delete mode 100644 divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfiguration.java create mode 100644 divinemc-server/src/main/java/space/bxteam/divinemc/seed/Globals.java create mode 100644 divinemc-server/src/main/java/space/bxteam/divinemc/seed/Hashing.java create mode 100644 divinemc-server/src/main/java/space/bxteam/divinemc/seed/WorldgenCryptoRandom.java diff --git a/divinemc-server/minecraft-patches/features/0002-DivineMC-Configuration.patch b/divinemc-server/minecraft-patches/features/0002-DivineMC-Configuration.patch index a994711..54bd755 100644 --- a/divinemc-server/minecraft-patches/features/0002-DivineMC-Configuration.patch +++ b/divinemc-server/minecraft-patches/features/0002-DivineMC-Configuration.patch @@ -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 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 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 paperWorldConfigCreator, // Paper - create paper world config -+ java.util.function.Function 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 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); diff --git a/divinemc-server/minecraft-patches/features/0009-No-chat-sign.patch b/divinemc-server/minecraft-patches/features/0009-No-chat-sign.patch index 677f54a..924e7c0 100644 --- a/divinemc-server/minecraft-patches/features/0009-No-chat-sign.patch +++ b/divinemc-server/minecraft-patches/features/0009-No-chat-sign.patch @@ -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 entries) { @@ -19,7 +19,7 @@ index 47cb25aa9c37bd84d156288c397321009f1d9ae2..9db90d39aa16208e421ba91527066166 + // DivineMC start - No chat sign + private static List 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 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 diff --git a/divinemc-server/minecraft-patches/features/0011-Petal-Async-Pathfinding.patch b/divinemc-server/minecraft-patches/features/0010-Petal-Async-Pathfinding.patch similarity index 93% rename from divinemc-server/minecraft-patches/features/0011-Petal-Async-Pathfinding.patch rename to divinemc-server/minecraft-patches/features/0010-Petal-Async-Pathfinding.patch index 5c76ae5..70bae88 100644 --- a/divinemc-server/minecraft-patches/features/0011-Petal-Async-Pathfinding.patch +++ b/divinemc-server/minecraft-patches/features/0010-Petal-Async-Pathfinding.patch @@ -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 { @@ -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 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 { @@ -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> { @@ -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 diff --git a/divinemc-archived-patches/work/server/0010-Implement-Secure-Seed.patch b/divinemc-server/minecraft-patches/features/0011-Implement-Secure-Seed.patch similarity index 89% rename from divinemc-archived-patches/work/server/0010-Implement-Secure-Seed.patch rename to divinemc-server/minecraft-patches/features/0011-Implement-Secure-Seed.patch index 4980f36..ba63ab3 100644 --- a/divinemc-archived-patches/work/server/0010-Implement-Secure-Seed.patch +++ b/divinemc-server/minecraft-patches/features/0011-Implement-Secure-Seed.patch @@ -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 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 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 { @@ -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 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 diff --git a/divinemc-archived-patches/work/server/0012-Multithreaded-Tracker.patch b/divinemc-server/minecraft-patches/features/0012-Multithreaded-Tracker.patch similarity index 90% rename from divinemc-archived-patches/work/server/0012-Multithreaded-Tracker.patch rename to divinemc-server/minecraft-patches/features/0012-Multithreaded-Tracker.patch index 5a34fe4..e093a59 100644 --- a/divinemc-archived-patches/work/server/0012-Multithreaded-Tracker.patch +++ b/divinemc-server/minecraft-patches/features/0012-Multithreaded-Tracker.patch @@ -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 seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl + // DivineMC start - Multithreaded tracker -+ public final Set seenBy = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedEnabled ++ public final Set 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 players = Sets.newHashSet(); + // DivineMC start - Multithreaded tracker - players can be removed in async tracking -+ private final Set players = space.bxteam.divinemc.configuration.DivineGlobalConfiguration.get().multithreadTracker.multithreadedEnabled ++ private final Set 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 attributesToSync = this.level.divineConfig().optimizations.suppressErrorsFromDirtyAttributes ? Collections.synchronizedSet(attributes) : attributes; + final Set 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 modifierById = new Object2ObjectArrayMap<>(); - private final Map 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 modifierById = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new Object2ObjectArrayMap<>(); + private final Map 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 attributesToSync = new ObjectOpenHashSet<>(); - private final Set 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, AttributeInstance> attributes = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(0); + private final Set attributesToSync = multiThreadedTrackingEnabled ? com.google.common.collect.Sets.newConcurrentHashSet() : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0); + private final Set attributesToUpdate = multiThreadedTrackingEnabled ? com.google.common.collect.Sets.newConcurrentHashSet() : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0); diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch index d057a48..f049cdd 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -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/"; diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/server/level/ServerEntity.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/server/level/ServerEntity.java.patch index 148bb94..4404eed 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/server/level/ServerEntity.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/server/level/ServerEntity.java.patch @@ -7,7 +7,7 @@ - Set attributesToSync = ((LivingEntity)this.entity).getAttributes().getAttributesToSync(); + // DivineMC start - Suppress errors from dirty attributes + Set attributes = ((LivingEntity) this.entity).getAttributes().getAttributesToSync(); -+ final Set attributesToSync = this.level.divineConfig().optimizations.suppressErrorsFromDirtyAttributes ? Collections.synchronizedSet(attributes) : attributes; ++ final Set 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 diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 874016b..a3499c5 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -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)); } diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch index 8071ca5..445899c 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch @@ -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) { diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch index 093325f..707c8b7 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch @@ -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 + diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch index c1a8adb..dfe8585 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch @@ -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()) { diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch index 53ecd18..1c48a1e 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch @@ -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 } diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/dimension/end/EndDragonFight.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/dimension/end/EndDragonFight.java.patch index 782ef77..899cf3a 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/dimension/end/EndDragonFight.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/dimension/end/EndDragonFight.java.patch @@ -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) { diff --git a/divinemc-server/paper-patches/features/0002-DivineMC-Configuration.patch b/divinemc-server/paper-patches/features/0002-DivineMC-Configuration.patch index bcdb3ca..8295eec 100644 --- a/divinemc-server/paper-patches/features/0002-DivineMC-Configuration.patch +++ b/divinemc-server/paper-patches/features/0002-DivineMC-Configuration.patch @@ -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 { - }; - } - -- static CheckedFunction reloader(Class type, T instance) { -+ public static CheckedFunction reloader(Class type, T instance) { // DivineMC - DivineMC Configuration - return node -> { - ObjectMapper.Factory factory = (ObjectMapper.Factory) Objects.requireNonNull(node.options().serializers().get(type)); - ObjectMapper.Mutable mutable = (ObjectMapper.Mutable) factory.get(type); -@@ -168,7 +168,7 @@ public abstract class Configurations { - 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 { - .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 { - 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 globalConfig() { -+ // DivineMC start - DivineMC configuration -+ public static FieldDiscoverer divineWorldConfig(io.papermc.paper.configuration.Configurations.ContextMap contextMap) { -+ final Map, 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() diff --git a/divinemc-archived-patches/work/server/0005-Implement-Secure-Seed.patch b/divinemc-server/paper-patches/features/0005-Implement-Secure-Seed.patch similarity index 87% rename from divinemc-archived-patches/work/server/0005-Implement-Secure-Seed.patch rename to divinemc-server/paper-patches/features/0005-Implement-Secure-Seed.patch index 8a5d92a..317e53a 100644 --- a/divinemc-archived-patches/work/server/0005-Implement-Secure-Seed.patch +++ b/divinemc-server/paper-patches/features/0005-Implement-Secure-Seed.patch @@ -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 diff --git a/divinemc-server/paper-patches/files/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java.patch b/divinemc-server/paper-patches/files/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java.patch index d90a4b0..88bc6e5 100644 --- a/divinemc-server/paper-patches/files/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java.patch +++ b/divinemc-server/paper-patches/files/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java.patch @@ -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 : "" diff --git a/divinemc-server/paper-patches/files/src/main/java/io/papermc/paper/adventure/ChatProcessor.java.patch b/divinemc-server/paper-patches/files/src/main/java/io/papermc/paper/adventure/ChatProcessor.java.patch index cebad95..d1cbdce 100644 --- a/divinemc-server/paper-patches/files/src/main/java/io/papermc/paper/adventure/ChatProcessor.java.patch +++ b/divinemc-server/paper-patches/files/src/main/java/io/papermc/paper/adventure/ChatProcessor.java.patch @@ -5,7 +5,7 @@ private void sendToServer(final ChatType.Bound chatType, final @Nullable Function 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 } } diff --git a/divinemc-server/paper-patches/files/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java.patch b/divinemc-server/paper-patches/files/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java.patch index fc7a89e..a9a4413 100644 --- a/divinemc-server/paper-patches/files/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java.patch +++ b/divinemc-server/paper-patches/files/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java.patch @@ -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."); } diff --git a/divinemc-server/src/main/java/space/bxteam/divinemc/command/subcommands/ReloadCommand.java b/divinemc-server/src/main/java/space/bxteam/divinemc/command/subcommands/ReloadCommand.java index de65e9d..d028307 100644 --- a/divinemc-server/src/main/java/space/bxteam/divinemc/command/subcommands/ReloadCommand.java +++ b/divinemc-server/src/main/java/space/bxteam/divinemc/command/subcommands/ReloadCommand.java @@ -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)); } diff --git a/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java new file mode 100644 index 0000000..a6b1b11 --- /dev/null +++ b/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java @@ -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 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 List getList(String path, T def) { + config.addDefault(path, def); + return config.getList(path, config.getList(path)); + } + + static Map getMap(String path, Map def) { + if (def != null && config.getConfigurationSection(path) == null) { + config.addDefault(path, def); + return def; + } + return toMap(config.getConfigurationSection(path)); + } + + private static Map toMap(ConfigurationSection section) { + ImmutableMap.Builder 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"); + } +} diff --git a/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineConfigurations.java b/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineConfigurations.java deleted file mode 100644 index 709c599..0000000 --- a/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineConfigurations.java +++ /dev/null @@ -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 { - 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 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>() {}, 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>() {}, new FastutilMapSerializer.SomethingToPrimitive>(Reference2IntOpenHashMap::new, Integer.TYPE)) - .register(new TypeToken>() {}, new FastutilMapSerializer.SomethingToPrimitive>(Reference2LongOpenHashMap::new, Long.TYPE)) - .register(new TypeToken>() {}, 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>() {}, access, Registries.ENTITY_TYPE, true)) - .register(new RegistryValueSerializer<>(Item.class, access, Registries.ITEM, true)) - .register(new RegistryHolderSerializer<>(new TypeToken>() {}, 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 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; - } -} diff --git a/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineGlobalConfiguration.java b/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineGlobalConfiguration.java deleted file mode 100644 index 91ce2f9..0000000 --- a/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineGlobalConfiguration.java +++ /dev/null @@ -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; - } -} diff --git a/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineRemovedConfiguration.java b/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineRemovedConfiguration.java deleted file mode 100644 index c918cbe..0000000 --- a/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineRemovedConfiguration.java +++ /dev/null @@ -1,9 +0,0 @@ -package space.bxteam.divinemc.configuration; - -import org.spongepowered.configurate.NodePath; - -interface DivineRemovedConfiguration { - NodePath[] REMOVED_WORLD_PATHS = {}; - - NodePath[] REMOVED_GLOBAL_PATHS = {}; -} diff --git a/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java b/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java new file mode 100644 index 0000000..8f0b2ce --- /dev/null +++ b/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java @@ -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 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 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 getMap(String path, Map def) { + final Map fallback = DivineConfig.getMap("world-settings.default." + path, def); + final Map 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); + } +} diff --git a/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfiguration.java b/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfiguration.java deleted file mode 100644 index 23475bb..0000000 --- a/divinemc-server/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfiguration.java +++ /dev/null @@ -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; - } - } -} diff --git a/divinemc-server/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPathProcessor.java b/divinemc-server/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPathProcessor.java index 4edd384..b3222ad 100644 --- a/divinemc-server/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPathProcessor.java +++ b/divinemc-server/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPathProcessor.java @@ -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") diff --git a/divinemc-server/src/main/java/space/bxteam/divinemc/seed/Globals.java b/divinemc-server/src/main/java/space/bxteam/divinemc/seed/Globals.java new file mode 100644 index 0000000..39d2d74 --- /dev/null +++ b/divinemc-server/src/main/java/space/bxteam/divinemc/seed/Globals.java @@ -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 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 parseSeed(String seedStr) { + if (seedStr.isEmpty()) return Optional.empty(); + + if (seedStr.length() != WORLD_SEED_BITS) { + throw new IllegalArgumentException("Secure seed length must be " + WORLD_SEED_BITS + "-bit but found " + seedStr.length() + "-bit."); + } + + long[] seed = new long[WORLD_SEED_LONGS]; + + for (int i = 0; i < WORLD_SEED_LONGS; i++) { + int start = i * 64; + int end = start + 64; + String seedSection = seedStr.substring(start, end); + + BigInteger seedInDecimal = new BigInteger(seedSection, 2); + seed[i] = seedInDecimal.longValue(); + } + + return Optional.of(seed); + } + + // 16 * 64 long[] -> 1024-bit string + public static String seedToString(long[] seed) { + StringBuilder sb = new StringBuilder(); + + for (long longV : seed) { + // Convert to 64-bit binary string per long + // Use format to keep 64-bit length, and use 0 to complete space + String binaryStr = String.format("%64s", Long.toBinaryString(longV)).replace(' ', '0'); + + sb.append(binaryStr); + } + + return sb.toString(); + } +} diff --git a/divinemc-server/src/main/java/space/bxteam/divinemc/seed/Hashing.java b/divinemc-server/src/main/java/space/bxteam/divinemc/seed/Hashing.java new file mode 100644 index 0000000..abedc9f --- /dev/null +++ b/divinemc-server/src/main/java/space/bxteam/divinemc/seed/Hashing.java @@ -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 + } +} diff --git a/divinemc-server/src/main/java/space/bxteam/divinemc/seed/WorldgenCryptoRandom.java b/divinemc-server/src/main/java/space/bxteam/divinemc/seed/WorldgenCryptoRandom.java new file mode 100644 index 0000000..f6e69a1 --- /dev/null +++ b/divinemc-server/src/main/java/space/bxteam/divinemc/seed/WorldgenCryptoRandom.java @@ -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 LAST_SEEN_WORLD_SEED = ThreadLocal.withInitial(() -> new long[Globals.WORLD_SEED_LONGS]); + private static final ThreadLocal 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); + } +} diff --git a/divinemc-server/src/main/java/space/bxteam/divinemc/tracker/MultithreadedTracker.java b/divinemc-server/src/main/java/space/bxteam/divinemc/tracker/MultithreadedTracker.java index 88a2b9c..f5f686d 100644 --- a/divinemc-server/src/main/java/space/bxteam/divinemc/tracker/MultithreadedTracker.java +++ b/divinemc-server/src/main/java/space/bxteam/divinemc/tracker/MultithreadedTracker.java @@ -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);