Skip to content

Commit a20d6f7

Browse files
committed
fix: handle reentrance in ServerEntityManager#unloadChunks
Cherry-picked from 4feda31
1 parent c2eea07 commit a20d6f7

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.ishland.c2me.rewrites.chunksystem.mixin.fixes;
2+
3+
import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet;
4+
import it.unimi.dsi.fastutil.longs.LongSet;
5+
import net.minecraft.server.world.ServerEntityManager;
6+
import org.spongepowered.asm.mixin.Final;
7+
import org.spongepowered.asm.mixin.Mixin;
8+
import org.spongepowered.asm.mixin.Mutable;
9+
import org.spongepowered.asm.mixin.Overwrite;
10+
import org.spongepowered.asm.mixin.Shadow;
11+
import org.spongepowered.asm.mixin.injection.At;
12+
import org.spongepowered.asm.mixin.injection.Inject;
13+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
14+
15+
@Mixin(ServerEntityManager.class)
16+
public abstract class MixinServerEntityManager {
17+
18+
@Mutable
19+
@Shadow @Final private LongSet pendingUnloads;
20+
21+
@Shadow protected abstract boolean unload(long chunkPos);
22+
23+
@Inject(method = "<init>", at = @At("RETURN"))
24+
private void replacePendingUnloads(CallbackInfo ci) {
25+
this.pendingUnloads = new LongLinkedOpenHashSet(this.pendingUnloads);
26+
}
27+
28+
/**
29+
* @author ishland
30+
* @reason use alternative method for unloading
31+
*/
32+
@Overwrite
33+
private void unloadChunks() {
34+
LongSet pendingUnloads = this.pendingUnloads;
35+
if (!(pendingUnloads instanceof LongLinkedOpenHashSet)) {
36+
// set is replaced by someone else, replace it again
37+
pendingUnloads = this.pendingUnloads = new LongLinkedOpenHashSet(pendingUnloads);
38+
}
39+
40+
// apparently vanilla also have a `this.trackingStatuses.get(pos) != EntityTrackingStatus.HIDDEN` check?????
41+
// removed here because chunks in pendingUnloads should always satisfy that constraint
42+
// if it does not, you have other serious problems
43+
LongLinkedOpenHashSet linkedOpenHashSet = (LongLinkedOpenHashSet) pendingUnloads;
44+
while (!linkedOpenHashSet.isEmpty()) {
45+
long pos = linkedOpenHashSet.removeFirstLong();
46+
this.unload(pos);
47+
}
48+
}
49+
50+
}

c2me-rewrites-chunk-system/src/main/resources/c2me-rewrites-chunk-system.mixins.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"async_serialization.MixinProtoChunk",
2222
"async_serialization.MixinStorageIoWorker",
2323
"async_serialization.MixinThreadedAnvilChunkStorage",
24-
"fluid_postprocessing.MixinWorldChunk"
24+
"fluid_postprocessing.MixinWorldChunk",
25+
"fixes.MixinServerEntityManager"
2526
]
2627
}

0 commit comments

Comments
 (0)