Skip to content

Commit 47a04c6

Browse files
committed
Fix chunk future chain not being bypassed during entity load
Backport of neoforged/NeoForge#99
1 parent 3492f9a commit 47a04c6

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package org.embeddedt.modernfix.forge.mixin.bugfix.chunk_deadlock;
2+
3+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
4+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
5+
import net.minecraft.server.level.ChunkHolder;
6+
import net.minecraft.server.level.ChunkMap;
7+
import net.minecraft.world.level.chunk.LevelChunk;
8+
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
9+
import org.embeddedt.modernfix.ModernFix;
10+
import org.jetbrains.annotations.Nullable;
11+
import org.spongepowered.asm.mixin.Mixin;
12+
import org.spongepowered.asm.mixin.Shadow;
13+
import org.spongepowered.asm.mixin.injection.At;
14+
15+
import java.lang.reflect.Field;
16+
17+
@Mixin(ChunkMap.class)
18+
public abstract class ChunkMapLoadMixin {
19+
@Shadow @Nullable protected abstract ChunkHolder getVisibleChunkIfPresent(long l);
20+
21+
private static final Field currentlyLoadingField = ObfuscationReflectionHelper.findField(ChunkHolder.class, "currentlyLoading");
22+
23+
private static void setCurrentlyLoading(ChunkHolder holder, LevelChunk value) {
24+
try {
25+
currentlyLoadingField.set(holder, value);
26+
} catch(ReflectiveOperationException e) {
27+
e.printStackTrace();
28+
}
29+
}
30+
31+
/**
32+
* Set currentlyLoading before calling runPostLoad and restore its old value afterwards. We track the old value
33+
* to avoid conflicting with Forge if/when this feature is added.
34+
*/
35+
@WrapOperation(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/chunk/LevelChunk;runPostLoad()V"))
36+
private void setCurrentLoadingThenPostLoad(LevelChunk chunk, Operation<Void> operation) {
37+
ChunkHolder holder = this.getVisibleChunkIfPresent(chunk.getPos().toLong());
38+
if(holder != null) {
39+
LevelChunk prevLoading = null;
40+
try {
41+
prevLoading = (LevelChunk)currentlyLoadingField.get(holder);
42+
} catch(ReflectiveOperationException e) {
43+
e.printStackTrace();
44+
}
45+
try {
46+
setCurrentlyLoading(holder, chunk);
47+
operation.call(chunk);
48+
} finally {
49+
setCurrentlyLoading(holder, prevLoading);
50+
}
51+
} else {
52+
ModernFix.LOGGER.warn("Unable to find chunk holder for loading chunk");
53+
operation.call(chunk);
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)