diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index b4d56c53..48f6ca92 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -21,12 +21,22 @@ jobs: with: distribution: 'temurin' java-version: 17 - - name: Build ModernFix using Gradle + - name: Setup Gradle uses: gradle/gradle-build-action@v2 with: cache-read-only: ${{ !startsWith(github.ref, 'refs/heads/1.') }} gradle-home-cache-cleanup: true - arguments: build + - name: Setup project Loom cache + uses: actions/cache@v3 + with: + path: | + .gradle/loom-cache + key: ${{ runner.os }}-gradle-${{ hashFiles('**/gradle.properties', '**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: ${{ runner.os }}-gradle- + - name: Build ModernFix + run: | + chmod +x gradlew + ./gradlew build - name: Upload Artifacts to GitHub uses: actions/upload-artifact@v3 with: diff --git a/build.gradle b/build.gradle index b8220699..7c87d822 100644 --- a/build.gradle +++ b/build.gradle @@ -50,8 +50,8 @@ tasks.register('generateChangelog', se.bjurr.gitchangelog.plugin.gradle.GitChang fromRef = theVersionRef - file = new File("CHANGELOG.md"); - templateContent = new File('gradle/changelog.mustache').getText('UTF-8').replace("[[modernFixVersionRef]]", theVersionRef); + file = new File("${rootDir}/CHANGELOG.md"); + templateContent = new File("${rootDir}/gradle/changelog.mustache").getText('UTF-8').replace("[[modernFixVersionRef]]", theVersionRef); toCommit = "HEAD"; } diff --git a/buildSrc/src/main/groovy/modernfix.platform-conventions.gradle b/buildSrc/src/main/groovy/modernfix.platform-conventions.gradle index 5753965e..a989c5ed 100644 --- a/buildSrc/src/main/groovy/modernfix.platform-conventions.gradle +++ b/buildSrc/src/main/groovy/modernfix.platform-conventions.gradle @@ -40,7 +40,7 @@ curseforge { apiKey = System.getenv("CURSEFORGE_TOKEN") project { id = "790626" - changelog = file('../CHANGELOG.md') + changelog = file("${rootDir}/CHANGELOG.md") changelogType = "markdown" releaseType = isBeta ? "beta" : "release" addGameVersion project.name.capitalize() diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java index 2c209d88..2c217d0b 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java @@ -87,8 +87,19 @@ public abstract class BlockStateBaseMixin extends StateHolder // don't generate the full cache here as mods will iterate for the fluid state a lot // assume blockstates will not change their contained fluidstate at runtime more than once // this is how Lithium's implementation used to work, so it should be fine - if(this.cacheInvalid && this.fluidState == MFIX$VANILLA_DEFAULT_FLUID) - this.fluidState = this.owner.getFluidState(this.asState()); + if(this.cacheInvalid && this.fluidState == MFIX$VANILLA_DEFAULT_FLUID) { + synchronized (BlockBehaviour.BlockStateBase.class) { + if(!buildingCache) { + buildingCache = true; + try { + this.fluidState = this.owner.getFluidState(this.asState()); + } finally { + buildingCache = false; + } + } + } + + } return this.fluidState; } diff --git a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index a91f6c98..132bfb6a 100644 --- a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -212,7 +212,7 @@ public class ModernFixEarlyConfig { disableIfModPresent("mixin.bugfix.remove_block_chunkloading", "performant"); disableIfModPresent("mixin.bugfix.paper_chunk_patches", "c2me"); disableIfModPresent("mixin.bugfix.preserve_early_window_pos", "better_loading_screen"); - disableIfModPresent("mixin.perf.cache_strongholds", "littletiles"); + disableIfModPresent("mixin.perf.cache_strongholds", "littletiles", "c2me"); // content overlap disableIfModPresent("mixin.perf.deduplicate_wall_shapes", "dashloader"); disableIfModPresent("mixin.perf.nbt_memory_usage", "c2me"); @@ -227,6 +227,21 @@ public class ModernFixEarlyConfig { if(isFabric) { disableIfModPresent("mixin.bugfix.packet_leak", "memoryleakfix"); } + + checkBlockstateCacheRebuilds(); + } + + private void checkBlockstateCacheRebuilds() { + if(!ModernFixPlatformHooks.INSTANCE.isDevEnv()) + return; + try { + if(ModernFixEarlyConfig.class.getResource("/net/minecraft/world/level/Level.class") == null) { + LOGGER.warn("We are in a non-Mojmap dev environment. Disabling blockstate cache patch"); + this.options.get("mixin.perf.reduce_blockstate_cache_rebuilds").addModOverride(false, "[not mojmap]"); + } + } catch(Throwable e) { + e.printStackTrace(); + } } private void disableIfModPresent(String configName, String... ids) { diff --git a/common/src/main/resources/assets/modernfix/lang/en_us.json b/common/src/main/resources/assets/modernfix/lang/en_us.json index 29d2e454..ec27bf0f 100644 --- a/common/src/main/resources/assets/modernfix/lang/en_us.json +++ b/common/src/main/resources/assets/modernfix/lang/en_us.json @@ -114,5 +114,10 @@ "modernfix.option.mixin.perf.twilightforest.structure_spawn_fix": "Fixes lag caused by Twilight Forest worldgen checking structures very inefficiently", "modernfix.option.mixin.perf.fast_forge_dummies": "Speeds up Forge registry freezing during launch by using a faster code path", "modernfix.option.mixin.perf.tag_id_caching": "Speeds up uses of tag entries by caching the location object instead of recreating it every time", - "modernfix.option.mixin.feature.disable_unihex_font": "Remove the Unicode font, saves 10MB but causes special characters to no longer render" + "modernfix.option.mixin.feature.disable_unihex_font": "Remove the Unicode font, saves 10MB but causes special characters to no longer render", + "modernfix.option.mixin.bugfix.world_leaks": "Reduces the memory usage of old client-side worlds that aren't needed after switching dimensions. These are normally garbage collected in vanilla, but mods sometimes retain references to them.", + "modernfix.option.mixin.perf.compact_mojang_registries": "(Fabric) Experimental option that reduces the memory usage of registries by roughly 50%. Not useful in most modpacks unless they contain millions of blocks and items.", + "modernfix.option.mixin.perf.dynamic_block_codecs": "Avoids storing a codec for every block(state) and instead generates and caches it on the fly when needed. Generally not worth enabling unless you have a million blocks/items.", + "modernfix.option.mixin.perf.faster_command_suggestions": "Mitigate lag when there are hundreds of thousands of suggestions while typing a command", + "modernfix.option.mixin.perf.mojang_registry_size": "Fixes an issue causing registration of blocks/items to slow down proportional to the number already registered. This improves startup time." } diff --git a/common/src/main/resources/assets/modernfix/lang/zh_cn.json b/common/src/main/resources/assets/modernfix/lang/zh_cn.json index 11eba3e2..457d4a01 100644 --- a/common/src/main/resources/assets/modernfix/lang/zh_cn.json +++ b/common/src/main/resources/assets/modernfix/lang/zh_cn.json @@ -42,6 +42,7 @@ "modernfix.option.mixin.perf.deduplicate_location": "全版本共有,但由于会影响加载时间,默认禁用。对资源位置的命名空间和路径进行去重。这节省了内存,但也大大增加了新资源位置的构造成本。", "modernfix.option.mixin.perf.dynamic_dfu": "全版本共有。修改了DFU的初始化,使其仅在第一次需要升级数据时加载。这听起来类似DFU载入优化,但实现方式截然不同,因为它能避免加载§o任何§rDFU类/数据结构,而DFU载入优化只是禁用其规则优化。本质上说,这是一个DataFixerSlayer的安全版本,因为它仍然会在需要时加载DFU。\n\n即使启用了这个选项,你也应该继续使用DFU载入优化,否则DFU规则优化依然会导致卡顿。", "modernfix.option.mixin.perf.dynamic_resources": "全版本共有。详见https://github.com/Kasualix/ModernFix/wiki/动态资源加载---常见问题解答。", + "modernfix.option.mixin.perf.dynamic_sounds": "全版本共有。允许游戏卸载声音,而不是在加载声音后无限期地保留它们。", "modernfix.option.mixin.perf.dynamic_structure_manager": "全版本共有。允许游戏在结构生成结束后卸载结构文件,而非让它们永远处于已加载状态。", "modernfix.option.mixin.perf.fast_registry_validation": "全版本共有。每次验证注册时,Forge都会通过反射来查找一个方法,这完全没必要。这个补丁简单地缓存了方法的返回值,因为它每次都是一样的。", "modernfix.option.mixin.perf.faster_font_loading": "全版本共有。优化字体渲染器,以更快地加载字体,加快资源重载速度。", @@ -53,7 +54,7 @@ "modernfix.option.mixin.perf.model_optimizations": "全版本共有。通过优化以加快模型加载过程。", "modernfix.option.mixin.perf.nbt_memory_usage": "全版本共有。对复合NBT标签使用一个更加高效的支持映射(backing map),从而消除重复键名,对小型复合 NBT 也使用数组映射。这减少了在内存中存储许多复合NBT标签的开销。", "modernfix.option.mixin.perf.nuke_empty_chunk_sections": "仅1.16。灵感来自氢(Hydrogen)模组。将存储充满空气的区块部分标记为空(empty),避免在内存中存储它们。", - "modernfix.option.mixin.perf.reduce_blockstate_cache_rebuilds": "全版本共有。§l一项关键优化。§r较新的Minecraft(1.12以上)实现了一个方块状态缓存系统,它可以缓存方块状态的常用信息,譬如其是否为固体方块,它的碰撞箱形状等等。原版中重建此缓存非常快(只要一两秒钟),但在安装了许多模组后就相当慢了,因为游戏中多了很多其它的方块状态,它们的缓存都需要被其重建。\n\n在Forge的影响下,这个问题变得更加严重,因为缓存会在很多地方重建,但这些数据在下一次重建前几乎肯定不会被用到。至于在哪儿,比如,在到达主菜单之前(在“Freezing data”阶段),以及在加载世界时(会出现很多次!)。\n\n通过让缓存重建转为惰性,现代化修复解决了这个性能瓶颈问题。每个方块状态在第一次访问数据时都会重建其缓存。无论何时,原版或Forge试图重建所有方块状态缓存的行为都会被重定向,变成简单地使每个方块状态的缓存失效。\n\n此项优化不应该对启动后的TPS产生任何影响。", + "modernfix.option.mixin.perf.reduce_blockstate_cache_rebuilds": "全版本共有。§l一项关键优化。§r较新的Minecraft(1.12以上)实现了一个方块状态缓存系统,它可以缓存方块状态的常用信息,譬如其是否为固体方块,它的碰撞箱形状等等。原版中重建此缓存非常快(只要一两秒钟),但在安装了许多模组后就相当慢了,因为游戏中多了很多其它的方块状态,它们的缓存都需要被其重建。\n\n在Forge的影响下,这个问题变得更加严重,因为缓存会在很多地方重建,但这些数据在下一次重建前几乎肯定不会被用到。至于在哪儿,比如,在到达主菜单之前(在“Freezing data”阶段),以及在加载世界时(会出现很多次!)。\n\n通过让缓存重建转为惰性,现代化修复解决了这个性能瓶颈问题。每个方块状态在第一次访问数据时都会重建其缓存。无论何时,原版或Forge试图重建所有方块状态缓存的行为都会被重定向,变成简单地使每个方块状态的缓存失效。\n\n此项优化应该不会对启动后的TPS产生任何影响。", "modernfix.option.mixin.perf.remove_biome_temperature_cache": "全版本共有。移除生物群系温度缓存,以减少内存占用,就像新版本的锂所做的那样。", "modernfix.option.mixin.perf.resourcepacks": "全版本共有。§l一项关键优化。§r高版本的启动严重受到文件系统访问的瓶颈限制。资源包经常接受到很多请求,要列出资源或检查一项给定的资源是否存在,而每次请求都会调用一个效率极低的文件API。\n\n现代化修复通过简单地缓存模组和原版提供的所有资源的列表,完全消除了此处的大部分瓶颈。缓存在资源重载时会进行重建(除了原版资源,因为它们在游戏运行时不应改变)。\n\n高清修复不能正确加载它的连接纹理(CTM)资源,除此之外此补丁没有已知的兼容问题。不过,我不建议在任何情况下使用高清修复,因为它本身就会增加几分钟的启动时间,而且根本没有与现代化修复进行过任何测试。", "modernfix.option.mixin.perf.reuse_datapacks": "仅1.16。试图尽可能跳过数据包重载,来加快单人世界切换/重进时的速度。可能会导致一些模组的兼容性问题,但目前默认启用。", @@ -114,5 +115,10 @@ "modernfix.option.mixin.perf.twilightforest.structure_spawn_fix": "针对暮色森林模组,修复了其世界生成检查结构效率极低导致卡顿的问题", "modernfix.option.mixin.perf.fast_forge_dummies": "使用更快的代码路径,加快启动时Forge注册表的冻结速度", "modernfix.option.mixin.perf.tag_id_caching": "缓存位置对象,不再每次都重新创建它,这可以加快标签条目的使用速度", - "modernfix.option.mixin.feature.disable_unihex_font": "删除Unicode字体,可以节省10MB内存,但会导致特殊字符不再渲染" + "modernfix.option.mixin.feature.disable_unihex_font": "删除Unicode字体,可以节省10MB内存,但会导致特殊字符不再渲染", + "modernfix.option.mixin.bugfix.world_leaks": "减少切换维度后不需要的旧客户端世界的内存占用。这部分内存在原版中通常会被垃圾回收,但有时模组会保留对它们的引用。", + "modernfix.option.mixin.perf.compact_mojang_registries": "(Fabric)实验性选项,可将注册表的内存占用减少约 50%。在大多数整合包中没什么用,除非它们包含数百万个方块和物品。", + "modernfix.option.mixin.perf.dynamic_block_codecs": "不再给每个方块(状态)都存储一个编解码器,只在需要时动态生成、缓存它。通常不值得启用,除非你有一百万个方块/物品。", + "modernfix.option.mixin.perf.faster_command_suggestions": "在输入命令时,若有数十万个建议,可以缓解卡顿。", + "modernfix.option.mixin.perf.mojang_registry_size": "修复了一个问题,它会导致方块/物品的注册速度减慢,减慢的程度与已注册的数量成正比。这缩短了启动时间。" } diff --git a/common/src/main/resources/icon.png b/common/src/main/resources/icon.png index a32ac9a9..450e09f5 100644 Binary files a/common/src/main/resources/icon.png and b/common/src/main/resources/icon.png differ diff --git a/doc/logo.svg b/doc/logo.svg new file mode 100644 index 00000000..fb9be4f9 --- /dev/null +++ b/doc/logo.svg @@ -0,0 +1,208 @@ + + + + diff --git a/doc/logo_transparent.svg b/doc/logo_transparent.svg new file mode 100644 index 00000000..48a1bff4 --- /dev/null +++ b/doc/logo_transparent.svg @@ -0,0 +1,209 @@ + + + + diff --git a/fabric/src/test/java/net/minecraft/world/level/block/state/BlockStateCacheTest.java b/fabric/src/test/java/net/minecraft/world/level/block/state/BlockStateCacheTest.java index 3e54137b..26bc9c18 100644 --- a/fabric/src/test/java/net/minecraft/world/level/block/state/BlockStateCacheTest.java +++ b/fabric/src/test/java/net/minecraft/world/level/block/state/BlockStateCacheTest.java @@ -4,6 +4,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.world.level.EmptyBlockGetter; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.FluidState; import org.embeddedt.modernfix.duck.IBlockState; import org.embeddedt.modernfix.testing.util.BootstrapMinecraft; import org.junit.jupiter.api.*; @@ -74,4 +75,19 @@ public class BlockStateCacheTest { } } } + + @Test + @Order(5) + public void checkRecursiveFluidState() { + Block b = new Block(BlockBehaviour.Properties.copy(Blocks.STONE)) { + @Override + public FluidState getFluidState(BlockState state) { + return state.getFluidState(); + } + }; + BlockState state = b.getStateDefinition().any(); + ((IBlockState)state).clearCache(); + // this should not throw + state.getFluidState(); + } } diff --git a/fabric/testmod/build.gradle b/fabric/testmod/build.gradle index ae1635cb..a8dab8eb 100644 --- a/fabric/testmod/build.gradle +++ b/fabric/testmod/build.gradle @@ -18,9 +18,6 @@ dependencies { minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" mappings loom.layered() { officialMojangMappings() - if(rootProject.hasProperty("parchment_version")) { - parchment("org.parchmentmc.data:parchment-${minecraft_version}:${parchment_version}@zip") - } } modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java b/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java index f89d1c20..fed07281 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java @@ -27,7 +27,7 @@ import java.util.*; */ public class ModelBakeEventHelper { // TODO: make into config option - private static final Set INCOMPATIBLE_MODS = ImmutableSet.of("industrialforegoing"); + private static final Set INCOMPATIBLE_MODS = ImmutableSet.of("industrialforegoing", "vampirism"); private final Map modelRegistry; private final Set topLevelModelLocations; private final MutableGraph dependencyGraph;