Skip to content

Commit 456bca4

Browse files
committed
Merge 1.20 into 1.20.4
2 parents d4fcc80 + c96f7ec commit 456bca4

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ private ModernFixEarlyConfig(File file) {
230230
}
231231

232232
checkBlockstateCacheRebuilds();
233+
checkModelDataManager();
233234
}
234235

235236
private void checkBlockstateCacheRebuilds() {
@@ -248,6 +249,16 @@ private void checkBlockstateCacheRebuilds() {
248249
}
249250
}
250251

252+
private void checkModelDataManager() {
253+
if(!isFabric && modPresent("rubidium") && !modPresent("embeddium")) {
254+
Option option = this.options.get("mixin.bugfix.model_data_manager_cme");
255+
if(option != null) {
256+
LOGGER.warn("ModelDataManager bugfixes have been disabled to prevent broken rendering with Rubidium installed. Please migrate to Embeddium.");
257+
option.addModOverride(false, "rubidium");
258+
}
259+
}
260+
}
261+
251262
private void disableIfModPresent(String configName, String... ids) {
252263
for(String id : ids) {
253264
if(!ModernFixPlatformHooks.INSTANCE.isEarlyLoadingNormally() || modPresent(id)) {
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package org.embeddedt.modernfix.forge.mixin.bugfix.model_data_manager_cme;
2+
3+
import net.minecraft.client.Minecraft;
4+
import net.minecraft.core.BlockPos;
5+
import net.minecraft.world.level.ChunkPos;
6+
import net.minecraftforge.client.model.data.ModelDataManager;
7+
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
8+
import org.spongepowered.asm.mixin.Mixin;
9+
import org.spongepowered.asm.mixin.Shadow;
10+
import org.spongepowered.asm.mixin.injection.At;
11+
import org.spongepowered.asm.mixin.injection.ModifyArg;
12+
import org.spongepowered.asm.mixin.injection.Redirect;
13+
14+
import java.util.Collections;
15+
import java.util.Set;
16+
import java.util.concurrent.ConcurrentHashMap;
17+
import java.util.function.Function;
18+
19+
/**
20+
* Fix several concurrency issues in the default ModelDataManager.
21+
*/
22+
@Mixin(ModelDataManager.class)
23+
@ClientOnlyMixin
24+
public abstract class ModelDataManagerMixin {
25+
@Shadow protected abstract void refreshAt(ChunkPos chunk);
26+
27+
/**
28+
* Make the set of positions to refresh a real concurrent hash set rather than relying on synchronizedSet,
29+
* because the returned iterator won't be thread-safe otherwise. See https://github.com/AppliedEnergistics/Applied-Energistics-2/issues/7511
30+
*/
31+
@ModifyArg(method = "requestRefresh", at = @At(value = "INVOKE", target = "Ljava/util/Map;computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;", ordinal = 0), index = 1, remap = false)
32+
private static Function<ChunkPos, Set<BlockPos>> changeTypeOfSetUsed(Function<ChunkPos, Set<BlockPos>> mappingFunction) {
33+
return pos -> Collections.newSetFromMap(new ConcurrentHashMap<>());
34+
}
35+
36+
@Redirect(method = "getAt(Lnet/minecraft/world/level/ChunkPos;)Ljava/util/Map;", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/client/model/data/ModelDataManager;refreshAt(Lnet/minecraft/world/level/ChunkPos;)V"), remap = false)
37+
private void onlyRefreshOnMainThread(ModelDataManager instance, ChunkPos pos) {
38+
// Only refresh model data on the main thread. This prevents calling getBlockEntity from worker threads
39+
// which could cause weird CMEs or other behavior.
40+
if(Minecraft.getInstance().isSameThread()) {
41+
// Refresh the given chunk, and all its neighbors. This is less efficient than the default code
42+
// but we have no choice since we need to not do refreshing on workers, and blocks might
43+
// try to access model data in neighboring chunks.
44+
for(int x = -1; x <= 1; x++) {
45+
for(int z = -1; z <= 1; z++) {
46+
refreshAt(new ChunkPos(pos.x + x, pos.z + z));
47+
}
48+
}
49+
}
50+
}
51+
}

settings.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ pluginManagement {
1010
include("test_agent")
1111
include("common")
1212

13+
startParameter.excludedTaskNames.add(':fabric:testmod:genSources')
14+
1315
def current_platforms = getProperty("enabled_platforms").tokenize(',')
1416
current_platforms.each { it ->
1517
def platform_name = it.trim()

0 commit comments

Comments
 (0)