Merge 1.20 into 1.20.4
This commit is contained in:
commit
456bca47b6
|
|
@ -230,6 +230,7 @@ public class ModernFixEarlyConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
checkBlockstateCacheRebuilds();
|
checkBlockstateCacheRebuilds();
|
||||||
|
checkModelDataManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkBlockstateCacheRebuilds() {
|
private void checkBlockstateCacheRebuilds() {
|
||||||
|
|
@ -248,6 +249,16 @@ public class ModernFixEarlyConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkModelDataManager() {
|
||||||
|
if(!isFabric && modPresent("rubidium") && !modPresent("embeddium")) {
|
||||||
|
Option option = this.options.get("mixin.bugfix.model_data_manager_cme");
|
||||||
|
if(option != null) {
|
||||||
|
LOGGER.warn("ModelDataManager bugfixes have been disabled to prevent broken rendering with Rubidium installed. Please migrate to Embeddium.");
|
||||||
|
option.addModOverride(false, "rubidium");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void disableIfModPresent(String configName, String... ids) {
|
private void disableIfModPresent(String configName, String... ids) {
|
||||||
for(String id : ids) {
|
for(String id : ids) {
|
||||||
if(!ModernFixPlatformHooks.INSTANCE.isEarlyLoadingNormally() || modPresent(id)) {
|
if(!ModernFixPlatformHooks.INSTANCE.isEarlyLoadingNormally() || modPresent(id)) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package org.embeddedt.modernfix.forge.mixin.bugfix.model_data_manager_cme;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraftforge.client.model.data.ModelDataManager;
|
||||||
|
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix several concurrency issues in the default ModelDataManager.
|
||||||
|
*/
|
||||||
|
@Mixin(ModelDataManager.class)
|
||||||
|
@ClientOnlyMixin
|
||||||
|
public abstract class ModelDataManagerMixin {
|
||||||
|
@Shadow protected abstract void refreshAt(ChunkPos chunk);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the set of positions to refresh a real concurrent hash set rather than relying on synchronizedSet,
|
||||||
|
* because the returned iterator won't be thread-safe otherwise. See https://github.com/AppliedEnergistics/Applied-Energistics-2/issues/7511
|
||||||
|
*/
|
||||||
|
@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)
|
||||||
|
private static Function<ChunkPos, Set<BlockPos>> changeTypeOfSetUsed(Function<ChunkPos, Set<BlockPos>> mappingFunction) {
|
||||||
|
return pos -> Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
@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)
|
||||||
|
private void onlyRefreshOnMainThread(ModelDataManager instance, ChunkPos pos) {
|
||||||
|
// Only refresh model data on the main thread. This prevents calling getBlockEntity from worker threads
|
||||||
|
// which could cause weird CMEs or other behavior.
|
||||||
|
if(Minecraft.getInstance().isSameThread()) {
|
||||||
|
// Refresh the given chunk, and all its neighbors. This is less efficient than the default code
|
||||||
|
// but we have no choice since we need to not do refreshing on workers, and blocks might
|
||||||
|
// try to access model data in neighboring chunks.
|
||||||
|
for(int x = -1; x <= 1; x++) {
|
||||||
|
for(int z = -1; z <= 1; z++) {
|
||||||
|
refreshAt(new ChunkPos(pos.x + x, pos.z + z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,8 @@ pluginManagement {
|
||||||
include("test_agent")
|
include("test_agent")
|
||||||
include("common")
|
include("common")
|
||||||
|
|
||||||
|
startParameter.excludedTaskNames.add(':fabric:testmod:genSources')
|
||||||
|
|
||||||
def current_platforms = getProperty("enabled_platforms").tokenize(',')
|
def current_platforms = getProperty("enabled_platforms").tokenize(',')
|
||||||
current_platforms.each { it ->
|
current_platforms.each { it ->
|
||||||
def platform_name = it.trim()
|
def platform_name = it.trim()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user