diff --git a/patches/api/0004-Vine-Config.patch b/patches/api/0004-Vine-Config.patch index 5099263..29f8a1f 100644 --- a/patches/api/0004-Vine-Config.patch +++ b/patches/api/0004-Vine-Config.patch @@ -6,30 +6,23 @@ Subject: [PATCH] Vine Config diff --git a/src/main/java/one/tranic/vine/config/VineConfig.java b/src/main/java/one/tranic/vine/config/VineConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..bb1e000da94076d668b19d5cf6e898605ea57751 +index 0000000000000000000000000000000000000000..b743c171d46ec07cd5c2da71b272fe073ec4da81 --- /dev/null +++ b/src/main/java/one/tranic/vine/config/VineConfig.java -@@ -0,0 +1,124 @@ +@@ -0,0 +1,95 @@ +package one.tranic.vine.config; + ++import one.tranic.vine.region.Compression; ++import one.tranic.vine.region.Format; ++ +public class VineConfig { -+ /** -+ * This is some fix -+ */ + public static class Fix { -+ /** -+ * Ensures correct destinations when travelling back and forth through Nether Portals in Multiplayer. -+ */ -+ public static boolean netherPortal = false; -+ /** -+ * Fixed the bug that the display frame in water was destroyed by TNT. -+ */ ++ /**Fixed the bug that the display frame in water was destroyed by TNT.*/ + public static boolean explosionBreaksItemFrameInWater = false; -+ /** -+ * Fixes some entities not bouncing on slime blocks and getting stuck -+ */ ++ /**Fixes some entities not bouncing on slime blocks and getting stuck*/ + public static boolean incorrectBounceLogic = false; -+ ++ /**Ensures correct destinations when travelling back and forth through Nether Portals in Multiplayer.*/ ++ public static boolean netherPortal = false; + /** + * Fixed a bug in Paper where anvils could become drops at y=0 or y=-1. + * This may not be useful as the implementation is crude, you can install the fix plugin to fix it additionally if you can. @@ -41,88 +34,66 @@ index 0000000000000000000000000000000000000000..bb1e000da94076d668b19d5cf6e89860 + } + + public static class Feature { -+ /** -+ * Try virtual threads. Once enabled, all explicit platform threads -+ * will be replaced with virtual threads as much as possible, which -+ * may have some adverse consequences. Please enable it with caution. -+ */ -+ public static boolean tryVirtualThreads = false; -+ -+ public static boolean vanillaHopper = false; -+ -+ public static boolean flattenTriangularDistribution = false; -+ -+ /** -+ * zero tick plants is back now! -+ */ -+ public static boolean zeroTickPlants = false; -+ ++ /**This just removes spark from being loaded by default, if you disable it, or install spark yourself, it will still be loaded.*/ ++ public static boolean disableSpark = true; ++ /**If the player is blocked on the top of the player's head, he will not try to rebirth the player on the ceiling.*/ + public static boolean disableRespawnCeiling = false; -+ ++ public static boolean flattenTriangularDistribution = false; + /** + * Switch to a 1024-bit secure seed to protect it from being cracked. + * Destroy the ambitions of those cheaters. + * Of course I haven't confirmed whether it's really possible XD + */ + public static boolean secureSeed = false; -+ + /** -+ * This just removes spark from being loaded by default, if you disable it, or install spark yourself, it will still be loaded. ++ * Try virtual threads. Once enabled, all explicit platform threads ++ * will be replaced with virtual threads as much as possible, which ++ * may have some adverse consequences. Please enable it with caution. + */ -+ public static boolean disableSpark = true; ++ public static boolean tryVirtualThreads = false; ++ public static boolean vanillaHopper = false; ++ /**zero tick plants is back now*/ ++ public static boolean zeroTickPlants = false; + ++ public static class cachePlayerProfileResult { ++ public static boolean enabled = true; ++ public static int timeout = 1440; ++ } + /** + * This can prevent some devices that utilize vanilla abilities from being + * damaged when the server crashes or shuts down suddenly, but it is not a + * panacea, so take precautions. + */ + public static class DSE { -+ /** -+ * Do not save tnt entities -+ */ ++ /**Do not save tnt entities*/ + public static boolean primedTNT = false; -+ -+ /** -+ * Do not save falling blocks -+ */ ++ /** Do not save falling blocks*/ + public static boolean fallingBlock = false; + } + -+ public static class cachePlayerProfileResult { -+ public static boolean enabled = true; -+ public static int timeout = 1440; -+ } -+ + public static class Region { + /**Support: ANVIL (Vanilla), LINEAR, SECTORFILE*/ -+ public static String format = "ANVIL"; ++ public static Format format = Format.ANVIL; + /**Only SECTORFILE | Support: GZIP, ZLIB, LZ4, BROTLI (Only Tranic Server), ZSTD*/ -+ public static String compressionFormat = "ZSTD"; -+ /**Only LINEAR | 1-22*/ ++ public static Compression compressionFormat = Compression.ZSTD; ++ /**Only LINEAR | 1-15*/ + public static int compressionLevel = 1; -+ /**Only LINEAR | second*/ ++ /**Only LINEAR | flush second*/ + public static int flushFrequency = 5; + } + } + + public static class Optimize { + public static boolean floatingPointPositive = false; -+ -+ public static boolean skipSelfRaidCheck = false; -+ -+ /** -+ * As the name suggests, it can slightly improve world generation performance, maybe. -+ */ -+ public static boolean noiseGeneration = true; + /** + * Entity re-pathing optimization + * If the entity has already determined the path, it will not search the path as frequently. + */ + public static boolean mobRePathfinding = true; -+ -+ /** -+ * Optimize stacked minecarts -+ */ ++ /**As the name suggests, it can slightly improve world generation performance, maybe.*/ ++ public static boolean noiseGeneration = true; ++ public static boolean skipSelfRaidCheck = false; ++ /**Optimize stacked minecarts*/ + public static class Minecart { + public static boolean enabled = true; + public static int skipTickCount = 30; @@ -134,3 +105,94 @@ index 0000000000000000000000000000000000000000..bb1e000da94076d668b19d5cf6e89860 + } + } +} +diff --git a/src/main/java/one/tranic/vine/region/Compression.java b/src/main/java/one/tranic/vine/region/Compression.java +new file mode 100644 +index 0000000000000000000000000000000000000000..598d967fc91b3301015523a4698312200c17d45f +--- /dev/null ++++ b/src/main/java/one/tranic/vine/region/Compression.java +@@ -0,0 +1,44 @@ ++package one.tranic.vine.region; ++ ++public enum Compression { ++ GZIP, ++ ZLIB, ++ LZ4, ++ NONE, ++ ZSTD, ++ BROTLI; ++ ++ public static Compression now; ++ ++ @Override ++ public String toString() { ++ return switch (this) { ++ case GZIP -> "GZIP"; ++ case ZLIB -> "ZLIB"; ++ case LZ4 -> "LZ4"; ++ case ZSTD -> "ZSTD"; ++ case BROTLI -> "BROTLI"; ++ default -> "NONE"; ++ }; ++ } ++ ++ public static Compression getCompression(final String name) { ++ return switch (name) { ++ case "GZIP" -> GZIP; ++ case "ZLIB" -> ZLIB; ++ case "LZ4" -> LZ4; ++ case "ZSTD" -> ZSTD; ++ case "BROTLI" -> BROTLI; ++ default -> NONE; ++ }; ++ } ++ ++ public static Compression getNow() { ++ return now; ++ } ++ ++ public static void setNow(final Compression now) { ++ one.tranic.vine.config.VineConfig.Feature.Region.compressionFormat = now; ++ Compression.now = now; ++ } ++} +diff --git a/src/main/java/one/tranic/vine/region/Format.java b/src/main/java/one/tranic/vine/region/Format.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0e302de56b2a294a975d5b257012c16d78fd57ea +--- /dev/null ++++ b/src/main/java/one/tranic/vine/region/Format.java +@@ -0,0 +1,35 @@ ++package one.tranic.vine.region; ++ ++public enum Format { ++ ANVIL, ++ LINEAR, ++ SECTORFILE; ++ ++ public static Format now; ++ ++ @Override ++ public String toString() { ++ return switch (this) { ++ case ANVIL -> "ANVIL"; ++ case LINEAR -> "LINEAR"; ++ case SECTORFILE -> "SECTORFILE"; ++ }; ++ } ++ ++ public static Format getFormat(String format) { ++ return switch (format) { ++ case "LINEAR" -> LINEAR; ++ case "SECTORFILE" -> SECTORFILE; ++ default -> ANVIL; ++ }; ++ } ++ ++ public static Format getNow() { ++ return now; ++ } ++ ++ public static void setNow(Format now) { ++ one.tranic.vine.config.VineConfig.Feature.Region.format = now; ++ Format.now = now; ++ } ++} diff --git a/patches/server/0002-Add-some-required-dependencies.patch b/patches/server/0002-Add-some-required-dependencies.patch index e6bab0d..c2d4816 100644 --- a/patches/server/0002-Add-some-required-dependencies.patch +++ b/patches/server/0002-Add-some-required-dependencies.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add some required dependencies diff --git a/build.gradle.kts b/build.gradle.kts -index 124dd83b65ed62c851981065745d8762e952beee..68511111980f4727310cacd8b0d23a5a81efd8dc 100644 +index 124dd83b65ed62c851981065745d8762e952beee..02e7b95515ef53fc586bcd49f23d628ecb5664db 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -85,6 +85,23 @@ dependencies { +@@ -85,6 +85,25 @@ dependencies { implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1") // Vine end @@ -16,6 +16,8 @@ index 124dd83b65ed62c851981065745d8762e952beee..68511111980f4727310cacd8b0d23a5a + implementation("com.github.luben:zstd-jni:1.5.6-4") + implementation("org.lz4:lz4-java:1.8.0") + ++ implementation("org.reflections:reflections:0.10.2") ++ + val brotli4jVersion = "1.16.0" + implementation ( group = "com.aayushatharva.brotli4j", name = "brotli4j", version = brotli4jVersion ) + runtimeOnly ( group = "com.aayushatharva.brotli4j", name = "native-windows-x86_64", version = brotli4jVersion ) diff --git a/patches/server/0003-Vine-Config.patch b/patches/server/0003-Vine-Config.patch index cd97df2..398da68 100644 --- a/patches/server/0003-Vine-Config.patch +++ b/patches/server/0003-Vine-Config.patch @@ -140,10 +140,10 @@ index 0000000000000000000000000000000000000000..67b571d421779c699aebf7312a2c2de4 \ No newline at end of file diff --git a/src/main/kotlin/one/tranic/vine/config/ConfigUtil.kt b/src/main/kotlin/one/tranic/vine/config/ConfigUtil.kt new file mode 100644 -index 0000000000000000000000000000000000000000..e45e91e6e5294bbd88041ea7e585cf90eb94f892 +index 0000000000000000000000000000000000000000..61bb276a0f099888911aa630bb9e9e5b06ed53dc --- /dev/null +++ b/src/main/kotlin/one/tranic/vine/config/ConfigUtil.kt -@@ -0,0 +1,151 @@ +@@ -0,0 +1,152 @@ +package one.tranic.vine.config + +import com.aayushatharva.brotli4j.Brotli4jLoader @@ -152,7 +152,8 @@ index 0000000000000000000000000000000000000000..e45e91e6e5294bbd88041ea7e585cf90 +import java.io.File + +import one.tranic.vine.commands.* -+import one.tranic.vine.config.module.Feature ++import one.tranic.vine.region.Compression ++import one.tranic.vine.region.Format + +object ConfigUtil { + private lateinit var configuration: YamlConfiguration @@ -195,7 +196,7 @@ index 0000000000000000000000000000000000000000..e45e91e6e5294bbd88041ea7e585cf90 + reload() + // If SECTORFILE is enabled and BROTLI is selected as the compression format, + // initialize the dependent libraries. -+ if (Feature.isRegionFormat == "SECTORFILE" && Feature.regionCompressionFormat == "BROTLI") { ++ if (Format.getNow().equals(Format.SECTORFILE) && Compression.getNow().equals(Compression.BROTLI)) { + Brotli4jLoader.ensureAvailability() + } + } @@ -354,205 +355,36 @@ index 0000000000000000000000000000000000000000..58ad9bdcba665b54bcde3ad05a01127a \ No newline at end of file diff --git a/src/main/kotlin/one/tranic/vine/config/module/Feature.kt b/src/main/kotlin/one/tranic/vine/config/module/Feature.kt new file mode 100644 -index 0000000000000000000000000000000000000000..a109f00733081fe8a015fcf178e46b208de11aec +index 0000000000000000000000000000000000000000..1d324af7e5b7b2298bc85bf8f40934435e7b384a --- /dev/null +++ b/src/main/kotlin/one/tranic/vine/config/module/Feature.kt -@@ -0,0 +1,196 @@ +@@ -0,0 +1,27 @@ +package one.tranic.vine.config.module + +import one.tranic.vine.config.ConfigImpl -+import one.tranic.vine.config.ConfigUtil.addDefault -+import one.tranic.vine.config.ConfigUtil.getBoolean -+import one.tranic.vine.config.ConfigUtil.getInt -+import one.tranic.vine.config.ConfigUtil.getString -+import one.tranic.vine.config.VineConfig.Feature +import one.tranic.vine.config.VineLogger ++import one.tranic.vine.util.Ref + +object Feature : ConfigImpl { -+ var isPlatform: Boolean? = null -+ private var isSecureSeed: Boolean? = null -+ var isRegionFormat: String? = null -+ var regionCompressionFormat: String? = null -+ private var isRegionCompressionLevel: Int? = null ++ val clazz: ArrayList = ArrayList() + -+ override fun default() { -+ addDefault( -+ "feature.try-virtual-threads", -+ false, -+ listOf( -+ "Try virtual threads. Once enabled, all explicit platform threads will ", -+ "be replaced with virtual threads as much as possible, which may have ", -+ "some adverse consequences. Please enable it with caution." -+ ) -+ ) -+ addDefault("feature.vanilla-hopper", false) -+ addDefault( -+ "feature.flatten-triangular-distribution", -+ false, -+ listOf( -+ "Change all triangle distribution in Minecraft randomizers into uniform distribution", -+ "With that edge cases are more likely to happen" -+ ) -+ ) -+ addDefault("feature.zero-tick-plants", false) -+ addDefault( -+ "feature.disable-respawn-ceiling", -+ false, -+ listOf( -+ "If the player is blocked on the top of the player's head, he will not try to rebirth ", -+ "the player on the ceiling.", -+ "This is suitable for those servers with ceilings." -+ ) -+ ) -+ addDefault( -+ "feature.secure-seed", false, listOf( -+ "Changes the seed from 64bit to 1024bit, this will strictly secure your seed,", -+ "making it almost impossible to crack.", -+ "Warning: You must delete existing maps to switch the state of the secure seed,", -+ "and do not modify it during hot loading, otherwise the server will crash and", -+ "cannot continue to load maps." -+ ) -+ ) -+ addDefault("feature.disable-spark", true) -+ -+ addDefault( -+ "feature.dont-save-entity.primed-tnt", false, listOf( -+ "Disable save primed tnt on chunk unloads.", -+ "Useful for redstone server, can prevent machine be exploded by TNT,", -+ "when player disconnected caused by Internet issue." -+ ) -+ ) -+ addDefault("feature.dont-save-entity.falling-block", false) -+ -+ addDefault( -+ "feature.cache-player-profile-result.enabled", -+ true, -+ listOf( -+ "Cache the player profile result on they first join.", -+ "It's useful if Mojang's verification server is down." -+ ) -+ ) -+ addDefault("feature.cache-player-profile-result.timeout", 1440, "The timeout of the cache. Unit: Minutes.") -+ -+ addDefault( -+ "feature.region.format", -+ "ANVIL", -+ listOf( -+ "Region Format: ANVIL (Default), LINEAR, SECTORFILE", -+ "LINEAR: https://github.com/xymb-endcrystalme/LinearRegionFileFormatTools", -+ "SECTORFILE: https://github.com/PaperMC/SectorTool/blob/master/SPECIFICATION.MD", -+ "If you are not worried about disk capacity, please do not use Linear, it is still", -+ "experimental and may cause data corruption." -+ ) -+ ) -+ addDefault( -+ "feature.region.compression-format", "ZSTD", listOf( -+ "Only applicable to SECTORFILE, support list:", -+ "\"GZIP, ZLIB, LZ4, BROTLI, ZSTD\"", -+ "Brotli is only available on TranicServer for Vine.", -+ "There is currently no tool to convert it back to ANVIL. Enable with caution!" -+ ) -+ ) -+ addDefault( -+ "feature.region.compression-level", -+ 1, -+ listOf( -+ "Only applicable to Linear, this is the compression level provided by ZSTD.", -+ "The available range is 1-22. When the compression level exceeds 14, ", -+ "the CPU pressure, chunk refresh time and memory usage will increase significantly, ", -+ "and high compression levels have the risk of losing chunk data, ", -+ "so we will limit it to the range of 1-15 to avoid some simple problems." -+ ) -+ ) -+ addDefault("feature.region.flush-frequency", 5, "Only applicable to Linear, chunk refresh interval, default is 5 (seconds)") ++ init { ++ val b = Ref.findConfigImpl("one.tranic.vine.config.module.feature") ++ clazz.addAll(b) ++ VineLogger.info("is ${b.size}") + } + -+ override fun load() { -+ getBoolean("feature.try-virtual-threads") { -+ if (isPlatform == null) { -+ if (it) { -+ VineLogger.warn( -+ listOf( -+ "Virtual threads are enabled.", -+ "Vine will try to replace all explicit platform threads with virtual threads,", -+ "which may have some undesirable consequences. Do not use it in production if", -+ "you are not sure it will be stable.", -+ "The ShreddedPaper thread will continue to use the platform thread." -+ ) -+ ) -+ } -+ Feature.tryVirtualThreads = it -+ isPlatform = !it -+ } else if (it == isPlatform) { -+ VineLogger.error("Forbidden to modify the parameter \"feature.try-virtual-threads\" during runtime!!!") -+ } -+ } -+ Feature.vanillaHopper = getBoolean("feature.vanilla-hopper") -+ Feature.flattenTriangularDistribution = getBoolean("feature.flatten-triangular-distribution") -+ Feature.zeroTickPlants = getBoolean("feature.zero-tick-plants") -+ Feature.disableRespawnCeiling = getBoolean("feature.disable-respawn-ceiling") -+ getBoolean("feature.secure-seed") { -+ if (isSecureSeed == null) { -+ Feature.secureSeed = it -+ isSecureSeed = it -+ if (it) VineLogger.warn("SecureSeed has been enabled, and this value cannot be modified before deleting the map.") -+ } else if (isSecureSeed != it) { -+ VineLogger.error("Forbidden to modify the parameter \"feature.secure-seed\" during runtime!!!") -+ } ++ override fun default() { ++ for (c in clazz) { ++ c.default() + } -+ Feature.disableSpark = getBoolean("feature.disable-spark") -+ -+ Feature.DSE.primedTNT = getBoolean("feature.dont-save-entity.primed-tnt") -+ Feature.DSE.fallingBlock = getBoolean("feature.dont-save-entity.falling-block") -+ -+ Feature.cachePlayerProfileResult.enabled = getBoolean("feature.cache-player-profile-result.enabled") -+ Feature.cachePlayerProfileResult.timeout = getInt("feature.cache-player-profile-result.timeout") ++ } + -+ getString("feature.region.format") { -+ if (isRegionFormat == null) { -+ when(it) { -+ "ANVIL", "LINEAR", "SECTORFILE" -> isRegionFormat = it -+ else -> { -+ VineLogger.error("What is $it in \"feature.region.format\"? It has been changed to the default \"ANVIL\".") -+ isRegionFormat = "ANVIL" -+ } -+ } -+ Feature.Region.format = isRegionFormat -+ } else if (isRegionFormat != it) { -+ VineLogger.error("Forbidden to modify the parameter \"feature.region.format\" during runtime!!!") -+ } -+ } -+ getString("feature.region.compression-format") { -+ if (regionCompressionFormat == null) { -+ when(it) { -+ "GZIP", "ZLIB", "LZ4", "BROTLI", "ZSTD" -> regionCompressionFormat = it -+ else -> { -+ VineLogger.error("What is $it in \"feature.region.compression-format\"? It has been changed to the default \"ZSTD\".") -+ regionCompressionFormat = "ZSTD" -+ } -+ } -+ Feature.Region.compressionFormat = regionCompressionFormat -+ } else if (regionCompressionFormat != it) { -+ VineLogger.error("Forbidden to modify the parameter \"feature.region.compression-format\" during runtime!!!") -+ } -+ } -+ getInt("feature.region.compression-level") { -+ if (isRegionCompressionLevel == null) { -+ isRegionCompressionLevel = if (it < 1) { -+ 1 -+ } else if (it > 15) { -+ 15 -+ } else { -+ it -+ } -+ Feature.Region.compressionLevel = isRegionCompressionLevel!! -+ } else if (isRegionCompressionLevel != it) { -+ VineLogger.error("Forbidden to modify the parameter \"feature.region.compression-level\" during runtime!!!") -+ } ++ override fun load() { ++ for (c in clazz) { ++ c.load() + } -+ Feature.Region.flushFrequency = getInt("feature.region.flush-frequency") + } -+ +} \ No newline at end of file diff --git a/src/main/kotlin/one/tranic/vine/config/module/Fix.kt b/src/main/kotlin/one/tranic/vine/config/module/Fix.kt @@ -615,6 +447,25 @@ index 0000000000000000000000000000000000000000..afdf8f0c98d9b42f3cce19d3387c716a + +} \ No newline at end of file +diff --git a/src/main/kotlin/one/tranic/vine/config/module/Locker.kt b/src/main/kotlin/one/tranic/vine/config/module/Locker.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..d336332ccdd0fb8d78da01004981fea5716fa29e +--- /dev/null ++++ b/src/main/kotlin/one/tranic/vine/config/module/Locker.kt +@@ -0,0 +1,12 @@ ++package one.tranic.vine.config.module ++ ++import one.tranic.vine.region.Compression ++import one.tranic.vine.region.Format ++ ++object Locker { ++ var compressionFormat: Compression? = null ++ var regionFormat: Format? = null ++ var regionCompressionLevel: Int? = null ++ var secureSeed: Boolean? = null ++ var virtualThread: Boolean? = null ++} +\ No newline at end of file diff --git a/src/main/kotlin/one/tranic/vine/config/module/Optimize.kt b/src/main/kotlin/one/tranic/vine/config/module/Optimize.kt new file mode 100644 index 0000000000000000000000000000000000000000..98160f1489e7f38ebf8fbc5c5336a297acab832c @@ -686,3 +537,283 @@ index 0000000000000000000000000000000000000000..98160f1489e7f38ebf8fbc5c5336a297 + +} \ No newline at end of file +diff --git a/src/main/kotlin/one/tranic/vine/config/module/feature/DontSaveEntity.kt b/src/main/kotlin/one/tranic/vine/config/module/feature/DontSaveEntity.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..37f75b1efc059c8df3f90b4b2c589ea816a2a5e4 +--- /dev/null ++++ b/src/main/kotlin/one/tranic/vine/config/module/feature/DontSaveEntity.kt +@@ -0,0 +1,24 @@ ++package one.tranic.vine.config.module.feature ++ ++import one.tranic.vine.config.ConfigImpl ++import one.tranic.vine.config.ConfigUtil.addDefault ++import one.tranic.vine.config.ConfigUtil.getBoolean ++import one.tranic.vine.config.VineConfig.Feature ++ ++object DontSaveEntity: ConfigImpl { ++ override fun default() { ++ addDefault( ++ "feature.dont-save-entity.primed-tnt", false, listOf( ++ "Disable save primed tnt on chunk unloads.", ++ "Useful for redstone server, can prevent machine be exploded by TNT,", ++ "when player disconnected caused by Internet issue." ++ ) ++ ) ++ addDefault("feature.dont-save-entity.falling-block", false) ++ } ++ ++ override fun load() { ++ Feature.DSE.primedTNT = getBoolean("feature.dont-save-entity.primed-tnt") ++ Feature.DSE.fallingBlock = getBoolean("feature.dont-save-entity.falling-block") ++ } ++} +\ No newline at end of file +diff --git a/src/main/kotlin/one/tranic/vine/config/module/feature/PlayerProfile.kt b/src/main/kotlin/one/tranic/vine/config/module/feature/PlayerProfile.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..d788040a93cb9c178729018e9ce912ec31cdb547 +--- /dev/null ++++ b/src/main/kotlin/one/tranic/vine/config/module/feature/PlayerProfile.kt +@@ -0,0 +1,26 @@ ++package one.tranic.vine.config.module.feature ++ ++import one.tranic.vine.config.ConfigImpl ++import one.tranic.vine.config.ConfigUtil.addDefault ++import one.tranic.vine.config.ConfigUtil.getBoolean ++import one.tranic.vine.config.ConfigUtil.getInt ++import one.tranic.vine.config.VineConfig.Feature ++ ++object PlayerProfile: ConfigImpl { ++ override fun default() { ++ addDefault( ++ "feature.cache-player-profile-result.enabled", ++ true, ++ listOf( ++ "Cache the player profile result on they first join.", ++ "It's useful if Mojang's verification server is down." ++ ) ++ ) ++ addDefault("feature.cache-player-profile-result.timeout", 1440, "The timeout of the cache. Unit: Minutes.") ++ } ++ ++ override fun load() { ++ Feature.cachePlayerProfileResult.enabled = getBoolean("feature.cache-player-profile-result.enabled") ++ Feature.cachePlayerProfileResult.timeout = getInt("feature.cache-player-profile-result.timeout") ++ } ++} +\ No newline at end of file +diff --git a/src/main/kotlin/one/tranic/vine/config/module/feature/Region.kt b/src/main/kotlin/one/tranic/vine/config/module/feature/Region.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..386114b552f18c210be77bdc45ea202cc04aeaa3 +--- /dev/null ++++ b/src/main/kotlin/one/tranic/vine/config/module/feature/Region.kt +@@ -0,0 +1,83 @@ ++package one.tranic.vine.config.module.feature ++ ++import one.tranic.vine.config.ConfigImpl ++import one.tranic.vine.config.ConfigUtil.addDefault ++import one.tranic.vine.config.ConfigUtil.getInt ++import one.tranic.vine.config.ConfigUtil.getString ++import one.tranic.vine.config.VineConfig.Feature ++import one.tranic.vine.config.VineLogger ++import one.tranic.vine.config.module.Locker ++import one.tranic.vine.region.Compression ++import one.tranic.vine.region.Format ++ ++object Region: ConfigImpl { ++ override fun default() { ++ addDefault( ++ "feature.region.format", ++ "ANVIL", ++ listOf( ++ "Region Format: ANVIL (Default), LINEAR, SECTORFILE", ++ "LINEAR: https://github.com/xymb-endcrystalme/LinearRegionFileFormatTools", ++ "SECTORFILE: https://github.com/PaperMC/SectorTool/blob/master/SPECIFICATION.MD", ++ "If you are not worried about disk capacity, please do not use Linear, it is still", ++ "experimental and may cause data corruption." ++ ) ++ ) ++ addDefault( ++ "feature.region.compression-format", "ZSTD", listOf( ++ "Only applicable to SECTORFILE, support list:", ++ "\"GZIP, ZLIB, LZ4, BROTLI, ZSTD\"", ++ "Brotli is only available on TranicServer for Vine.", ++ "There is currently no tool to convert it back to ANVIL. Enable with caution!" ++ ) ++ ) ++ addDefault( ++ "feature.region.compression-level", ++ 1, ++ listOf( ++ "Only applicable to Linear, this is the compression level provided by ZSTD.", ++ "The available range is 1-22. When the compression level exceeds 14, ", ++ "the CPU pressure, chunk refresh time and memory usage will increase significantly, ", ++ "and high compression levels have the risk of losing chunk data, ", ++ "so we will limit it to the range of 1-15 to avoid some simple problems." ++ ) ++ ) ++ addDefault("feature.region.flush-frequency", 5, "Only applicable to Linear, chunk refresh interval, default is 5 (seconds)") ++ } ++ ++ override fun load() { ++ getString("feature.region.format") { ++ if (Locker.regionFormat == null) { ++ val b = Format.getFormat(it) ++ Locker.regionFormat = b ++ Format.setNow(Feature.Region.format) ++ } else if (Locker.regionFormat != Format.getFormat(it)) { ++ VineLogger.error("Forbidden to modify the parameter \"feature.region.format\" during runtime!!!") ++ } ++ } ++ getString("feature.region.compression-format") { ++ if (Locker.compressionFormat == null) { ++ val b = Compression.getCompression(it) ++ Locker.compressionFormat = b ++ Compression.setNow(b) ++ } else if (Locker.compressionFormat != Compression.getCompression(it)) { ++ VineLogger.error("Forbidden to modify the parameter \"feature.region.compression-format\" during runtime!!!") ++ } ++ } ++ getInt("feature.region.compression-level") { ++ if (Locker.regionCompressionLevel == null) { ++ Locker.regionCompressionLevel = if (it < 1) { ++ 1 ++ } else if (it > 15) { ++ 15 ++ } else { ++ it ++ } ++ Feature.Region.compressionLevel = Locker.regionCompressionLevel!! ++ } else if (Locker.regionCompressionLevel != it) { ++ VineLogger.error("Forbidden to modify the parameter \"feature.region.compression-level\" during runtime!!!") ++ } ++ } ++ Feature.Region.flushFrequency = getInt("feature.region.flush-frequency") ++ } ++} +\ No newline at end of file +diff --git a/src/main/kotlin/one/tranic/vine/config/module/feature/Value.kt b/src/main/kotlin/one/tranic/vine/config/module/feature/Value.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..f0b11e612f7c0d9ccb31d3970a3534be7df37906 +--- /dev/null ++++ b/src/main/kotlin/one/tranic/vine/config/module/feature/Value.kt +@@ -0,0 +1,87 @@ ++package one.tranic.vine.config.module.feature ++ ++import one.tranic.vine.config.ConfigImpl ++import one.tranic.vine.config.ConfigUtil.addDefault ++import one.tranic.vine.config.ConfigUtil.getBoolean ++import one.tranic.vine.config.VineConfig.Feature ++import one.tranic.vine.config.VineLogger ++import one.tranic.vine.config.module.Locker ++ ++object Value: ConfigImpl { ++ override fun default() { ++ addDefault("feature.disable-spark", true) ++ addDefault( ++ "feature.disable-respawn-ceiling", ++ false, ++ listOf( ++ "If the player is blocked on the top of the player's head, he will not try to rebirth ", ++ "the player on the ceiling.", ++ "This is suitable for those servers with ceilings." ++ ) ++ ) ++ addDefault( ++ "feature.flatten-triangular-distribution", ++ false, ++ listOf( ++ "Change all triangle distribution in Minecraft randomizers into uniform distribution", ++ "With that edge cases are more likely to happen" ++ ) ++ ) ++ addDefault( ++ "feature.secure-seed", false, listOf( ++ "Changes the seed from 64bit to 1024bit, this will strictly secure your seed,", ++ "making it almost impossible to crack.", ++ "Warning: You must delete existing maps to switch the state of the secure seed,", ++ "and do not modify it during hot loading, otherwise the server will crash and", ++ "cannot continue to load maps." ++ ) ++ ) ++ addDefault( ++ "feature.try-virtual-threads", ++ false, ++ listOf( ++ "Try virtual threads. Once enabled, all explicit platform threads will ", ++ "be replaced with virtual threads as much as possible, which may have ", ++ "some adverse consequences. Please enable it with caution." ++ ) ++ ) ++ addDefault("feature.vanilla-hopper", false) ++ addDefault("feature.zero-tick-plants", false) ++ } ++ ++ override fun load() { ++ getBoolean("feature.try-virtual-threads") { ++ if (Locker.virtualThread == null) { ++ if (it) { ++ VineLogger.warn( ++ listOf( ++ "Virtual threads are enabled.", ++ "Vine will try to replace all explicit platform threads with virtual threads,", ++ "which may have some undesirable consequences. Do not use it in production if", ++ "you are not sure it will be stable.", ++ "The ShreddedPaper thread will continue to use the platform thread." ++ ) ++ ) ++ } ++ Feature.tryVirtualThreads = it ++ Locker.virtualThread = it ++ } else if (it == Locker.virtualThread) { ++ VineLogger.error("Forbidden to modify the parameter \"feature.try-virtual-threads\" during runtime!!!") ++ } ++ } ++ Feature.vanillaHopper = getBoolean("feature.vanilla-hopper") ++ Feature.flattenTriangularDistribution = getBoolean("feature.flatten-triangular-distribution") ++ Feature.zeroTickPlants = getBoolean("feature.zero-tick-plants") ++ Feature.disableRespawnCeiling = getBoolean("feature.disable-respawn-ceiling") ++ getBoolean("feature.secure-seed") { ++ if (Locker.secureSeed == null) { ++ Feature.secureSeed = it ++ Locker.secureSeed = it ++ if (it) VineLogger.warn("SecureSeed has been enabled, and this value cannot be modified before deleting the map.") ++ } else if (Locker.secureSeed != it) { ++ VineLogger.error("Forbidden to modify the parameter \"feature.secure-seed\" during runtime!!!") ++ } ++ } ++ Feature.disableSpark = getBoolean("feature.disable-spark") ++ } ++} +\ No newline at end of file +diff --git a/src/main/kotlin/one/tranic/vine/util/Ref.kt b/src/main/kotlin/one/tranic/vine/util/Ref.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..c4393503d2ea9a38c42d66c2e55ea3a807886242 +--- /dev/null ++++ b/src/main/kotlin/one/tranic/vine/util/Ref.kt +@@ -0,0 +1,25 @@ ++package one.tranic.vine.util ++ ++import com.google.common.reflect.ClassPath ++import one.tranic.vine.config.ConfigImpl ++import java.io.IOException ++import java.util.stream.Collectors ++import kotlin.reflect.full.isSubclassOf ++ ++ ++object Ref { ++ @Throws(IOException::class) ++ fun findConfigImpl(packageName: String): Set { ++ val implSet = mutableSetOf() ++ val classs = ClassPath.from(Thread.currentThread().contextClassLoader) ++ val classes = classs.getTopLevelClasses(packageName) ++ for (classInfo in classes) { ++ val clazz = Class.forName(classInfo.name).kotlin ++ if (clazz.objectInstance != null && clazz.isSubclassOf(ConfigImpl::class)) { ++ val objInstance = clazz.objectInstance as ConfigImpl ++ implSet.add(objInstance) ++ } ++ } ++ return implSet ++ } ++} +\ No newline at end of file diff --git a/patches/server/0005-AnyThread-Utils.patch b/patches/server/0005-AnyThread-Utils.patch index 3729603..6533fdf 100644 --- a/patches/server/0005-AnyThread-Utils.patch +++ b/patches/server/0005-AnyThread-Utils.patch @@ -6,7 +6,7 @@ Subject: [PATCH] AnyThread Utils diff --git a/src/main/kotlin/one/tranic/vine/util/AnyThread.kt b/src/main/kotlin/one/tranic/vine/util/AnyThread.kt new file mode 100644 -index 0000000000000000000000000000000000000000..a3e82062ea75ae1d0de986415a705b91d747a8f6 +index 0000000000000000000000000000000000000000..33f9b39e6382f2ee9e573fd5fb7c1348852e9eca --- /dev/null +++ b/src/main/kotlin/one/tranic/vine/util/AnyThread.kt @@ -0,0 +1,106 @@ @@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..a3e82062ea75ae1d0de986415a705b91 +import kotlinx.coroutines.* +import kotlinx.coroutines.Runnable +import net.minecraft.server.MinecraftServer -+import one.tranic.vine.config.module.Feature ++import one.tranic.vine.config.module.Locker +import java.lang.reflect.InaccessibleObjectException +import java.lang.reflect.Method +import java.lang.reflect.ReflectPermission @@ -76,31 +76,31 @@ index 0000000000000000000000000000000000000000..a3e82062ea75ae1d0de986415a705b91 + + @JvmStatic + fun getFactory(): ThreadFactory { -+ if (Feature.isPlatform == false) return Thread.ofVirtual().factory() ++ if (Locker.virtualThread == true) return Thread.ofVirtual().factory() + return Thread.ofPlatform().factory() + } + + @JvmStatic + fun getThread(): Thread { -+ if (Feature.isPlatform == false) return Thread.ofVirtual().unstarted(null) ++ if (Locker.virtualThread == true) return Thread.ofVirtual().unstarted(null) + return Thread() + } + + @JvmStatic + fun getThread(name: String): Thread { -+ if (Feature.isPlatform == false) return Thread.ofVirtual().name(name).unstarted(null) ++ if (Locker.virtualThread == true) return Thread.ofVirtual().name(name).unstarted(null) + return Thread(name) + } + + @JvmStatic + fun getThread(runnable: Runnable): Thread { -+ if (Feature.isPlatform == false) return Thread.ofVirtual().unstarted(runnable) ++ if (Locker.virtualThread == true) return Thread.ofVirtual().unstarted(runnable) + return Thread(runnable) + } + + @JvmStatic + fun getThread(runnable: Runnable, name: String): Thread { -+ if (Feature.isPlatform == false) return Thread.ofVirtual().name(name).unstarted(runnable) ++ if (Locker.virtualThread == true) return Thread.ofVirtual().name(name).unstarted(runnable) + return Thread(runnable, name) + } + diff --git a/patches/server/0006-ThreadInfoCommand.patch b/patches/server/0006-ThreadInfoCommand.patch index a0cc679..101e717 100644 --- a/patches/server/0006-ThreadInfoCommand.patch +++ b/patches/server/0006-ThreadInfoCommand.patch @@ -79,10 +79,10 @@ index 0000000000000000000000000000000000000000..ecc2ed943f88454406bca71780678e41 +} \ No newline at end of file diff --git a/src/main/kotlin/one/tranic/vine/config/ConfigUtil.kt b/src/main/kotlin/one/tranic/vine/config/ConfigUtil.kt -index e45e91e6e5294bbd88041ea7e585cf90eb94f892..eeba87f9b4cdc03b02e78567130af5964d63ea8f 100644 +index 61bb276a0f099888911aa630bb9e9e5b06ed53dc..d170d8be4e84247bba06e3ac296045c2ffab574c 100644 --- a/src/main/kotlin/one/tranic/vine/config/ConfigUtil.kt +++ b/src/main/kotlin/one/tranic/vine/config/ConfigUtil.kt -@@ -14,6 +14,7 @@ object ConfigUtil { +@@ -15,6 +15,7 @@ object ConfigUtil { @JvmStatic fun setCommand() { Bukkit.getCommandMap().register("vinecfg", "vine", VineCfgCommand()) diff --git a/patches/server/0009-SectorFile.patch b/patches/server/0009-SectorFile.patch index 699c6e8..c34826a 100644 --- a/patches/server/0009-SectorFile.patch +++ b/patches/server/0009-SectorFile.patch @@ -2988,7 +2988,7 @@ index 0000000000000000000000000000000000000000..4b49dc3df3f3352e4447b66a3207d948 \ No newline at end of file diff --git a/src/main/java/ca/spottedleaf/io/region/SectorFileCache.java b/src/main/java/ca/spottedleaf/io/region/SectorFileCache.java new file mode 100644 -index 0000000000000000000000000000000000000000..a9b89f24418346d0666b4e6d5acb53423a35e3c0 +index 0000000000000000000000000000000000000000..af55a9ba5f07fddf91f709cc2f8772144f2d5531 --- /dev/null +++ b/src/main/java/ca/spottedleaf/io/region/SectorFileCache.java @@ -0,0 +1,392 @@ @@ -3039,12 +3039,12 @@ index 0000000000000000000000000000000000000000..a9b89f24418346d0666b4e6d5acb5342 + } + + private static ca.spottedleaf.io.region.SectorFileCompressionType getCompressionType() { -+ return switch (one.tranic.vine.config.VineConfig.Feature.Region.compressionFormat) { -+ case "GZIP" -> ca.spottedleaf.io.region.SectorFileCompressionType.GZIP; -+ case "ZLIB" -> ca.spottedleaf.io.region.SectorFileCompressionType.DEFLATE; -+ case "LZ4" -> ca.spottedleaf.io.region.SectorFileCompressionType.LZ4; -+ case "ZSTD" -> ca.spottedleaf.io.region.SectorFileCompressionType.ZSTD; -+ case "BROTLI" -> ca.spottedleaf.io.region.SectorFileCompressionType.BROTLI; ++ return switch (one.tranic.vine.region.Compression.getNow()) { ++ case GZIP -> ca.spottedleaf.io.region.SectorFileCompressionType.GZIP; ++ case ZLIB -> ca.spottedleaf.io.region.SectorFileCompressionType.DEFLATE; ++ case LZ4 -> ca.spottedleaf.io.region.SectorFileCompressionType.LZ4; ++ case ZSTD -> ca.spottedleaf.io.region.SectorFileCompressionType.ZSTD; ++ case BROTLI -> ca.spottedleaf.io.region.SectorFileCompressionType.BROTLI; + default -> SectorFileCompressionType.NONE; + }; + } diff --git a/patches/server/0025-Leaf-Cache-player-profileResult.patch b/patches/server/0025-Leaf-Cache-player-profileResult.patch index 9f85f4c..e2c7b89 100644 --- a/patches/server/0025-Leaf-Cache-player-profileResult.patch +++ b/patches/server/0025-Leaf-Cache-player-profileResult.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Leaf: Cache player profileResult diff --git a/build.gradle.kts b/build.gradle.kts -index 68511111980f4727310cacd8b0d23a5a81efd8dc..67d02f1a51cbf088ae2345a44a136907c03b98b1 100644 +index 02e7b95515ef53fc586bcd49f23d628ecb5664db..cb856c05fa3870ef83c55644e63ed381419c5528 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -102,6 +102,7 @@ dependencies { +@@ -104,6 +104,7 @@ dependencies { runtimeOnly ( group = "com.aayushatharva.brotli4j", name = "native-osx-x86_64", version = brotli4jVersion ) runtimeOnly ( group = "com.aayushatharva.brotli4j", name = "native-osx-aarch64", version = brotli4jVersion ) // Vine end