Skip to content

Commit 8f51b35

Browse files
committed
fix: defer all level events to avoid clearing deferred state
1 parent cc314e7 commit 8f51b35

File tree

3 files changed

+63
-22
lines changed

3 files changed

+63
-22
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.ishland.c2me.rewrites.chunksystem.common.ducks;
2+
3+
import it.unimi.dsi.fastutil.longs.Long2IntLinkedOpenHashMap;
4+
5+
public interface TicketDistanceLevelPropagatorExtension {
6+
7+
Long2IntLinkedOpenHashMap c2me$getTicketLevelUpdates();
8+
9+
}

c2me-rewrites-chunk-system/src/main/java/com/ishland/c2me/rewrites/chunksystem/mixin/MixinChunkTicketManager.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,38 @@
11
package com.ishland.c2me.rewrites.chunksystem.mixin;
22

33
import com.bawnorton.mixinsquared.TargetHandler;
4-
import com.ishland.c2me.base.mixin.access.ITACSTicketManager;
5-
import com.ishland.c2me.base.mixin.access.IThreadedAnvilChunkStorage;
64
import com.ishland.c2me.rewrites.chunksystem.common.Config;
5+
import com.ishland.c2me.rewrites.chunksystem.common.ducks.TicketDistanceLevelPropagatorExtension;
76
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
87
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
8+
import it.unimi.dsi.fastutil.longs.Long2IntLinkedOpenHashMap;
99
import net.minecraft.server.world.ChunkHolder;
1010
import net.minecraft.server.world.ChunkTaskPrioritySystem;
1111
import net.minecraft.server.world.ChunkTicketManager;
12+
import net.minecraft.server.world.ServerChunkLoadingManager;
13+
import org.jetbrains.annotations.Nullable;
1214
import org.objectweb.asm.Opcodes;
1315
import org.spongepowered.asm.mixin.Dynamic;
16+
import org.spongepowered.asm.mixin.Final;
1417
import org.spongepowered.asm.mixin.Mixin;
18+
import org.spongepowered.asm.mixin.Shadow;
1519
import org.spongepowered.asm.mixin.injection.At;
20+
import org.spongepowered.asm.mixin.injection.Inject;
1621
import org.spongepowered.asm.mixin.injection.Redirect;
22+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
1723

1824
import java.util.List;
1925
import java.util.concurrent.Executor;
2026

2127
@Mixin(value = ChunkTicketManager.class, priority = 1051)
22-
public class MixinChunkTicketManager {
28+
public abstract class MixinChunkTicketManager {
29+
30+
@Shadow
31+
protected abstract @Nullable ChunkHolder setLevel(long pos, int level, @Nullable ChunkHolder holder, int i);
32+
33+
@Shadow
34+
@Final
35+
private ChunkTicketManager.TicketDistanceLevelPropagator distanceFromTicketTracker;
2336

2437
@Dynamic
2538
@TargetHandler(
@@ -60,4 +73,16 @@ private ChunkTaskPrioritySystem syncPlayerTickets(List actors, Executor executor
6073
}
6174
}
6275

76+
@Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ChunkTicketManager$TicketDistanceLevelPropagator;update(I)I", shift = At.Shift.AFTER))
77+
private void postTicketPropagator(ServerChunkLoadingManager chunkLoadingManager, CallbackInfoReturnable<Boolean> cir) {
78+
if (this.distanceFromTicketTracker != null) { // ignore if replaced
79+
Long2IntLinkedOpenHashMap updates = ((TicketDistanceLevelPropagatorExtension) this.distanceFromTicketTracker).c2me$getTicketLevelUpdates();
80+
while (!updates.isEmpty()) {
81+
long pos = updates.firstLongKey();
82+
int level = updates.removeFirstInt();
83+
this.setLevel(pos, level, null, Integer.MAX_VALUE - 1); // holder and old level is ignored
84+
}
85+
}
86+
}
87+
6388
}
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,37 @@
11
package com.ishland.c2me.rewrites.chunksystem.mixin;
22

3+
import com.ishland.c2me.rewrites.chunksystem.common.ducks.TicketDistanceLevelPropagatorExtension;
4+
import it.unimi.dsi.fastutil.longs.Long2IntLinkedOpenHashMap;
35
import it.unimi.dsi.fastutil.longs.Long2IntMap;
46
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
5-
import net.minecraft.server.world.ChunkHolder;
67
import net.minecraft.server.world.ChunkTicketManager;
7-
import org.objectweb.asm.Opcodes;
88
import org.spongepowered.asm.mixin.Final;
99
import org.spongepowered.asm.mixin.Mixin;
1010
import org.spongepowered.asm.mixin.Overwrite;
1111
import org.spongepowered.asm.mixin.Shadow;
12+
import org.spongepowered.asm.mixin.Unique;
1213
import org.spongepowered.asm.mixin.injection.At;
1314
import org.spongepowered.asm.mixin.injection.Inject;
14-
import org.spongepowered.asm.mixin.injection.Redirect;
1515
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
1616

1717
@Mixin(ChunkTicketManager.TicketDistanceLevelPropagator.class)
18-
public class MixinChunkTicketManagerTicketDistanceLevelPropagator {
18+
public class MixinChunkTicketManagerTicketDistanceLevelPropagator implements TicketDistanceLevelPropagatorExtension {
1919

2020
@Shadow @Final private static int UNLOADED;
2121

2222
@Shadow @Final private ChunkTicketManager field_18255;
23-
private final Long2IntMap levels = new Long2IntOpenHashMap();
23+
24+
@Unique
25+
private Long2IntMap c2me$levels;
26+
27+
@Unique
28+
private Long2IntLinkedOpenHashMap c2me$ticketLevelUpdates;
2429

2530
@Inject(method = "<init>", at = @At("RETURN"))
2631
private void postInit(CallbackInfo ci) {
27-
this.levels.defaultReturnValue(UNLOADED + 1);
32+
this.c2me$levels = new Long2IntOpenHashMap();
33+
this.c2me$levels.defaultReturnValue(UNLOADED + 1);
34+
this.c2me$ticketLevelUpdates = new Long2IntLinkedOpenHashMap();
2835
}
2936

3037
/**
@@ -33,26 +40,26 @@ private void postInit(CallbackInfo ci) {
3340
*/
3441
@Overwrite
3542
public int getLevel(long id) {
36-
return this.levels.get(id);
43+
return this.c2me$levels.get(id);
3744
}
3845

39-
@Inject(method = "setLevel", at = @At("HEAD"))
40-
private void preSetLevel(long id, int level, CallbackInfo ci) {
46+
/**
47+
* @author ishland
48+
* @reason use internal levels, plus defer update
49+
*/
50+
@Overwrite
51+
protected void setLevel(long id, int level) {
4152
if (level >= UNLOADED) {
42-
this.levels.remove(id);
53+
this.c2me$levels.remove(id);
4354
} else {
44-
this.levels.put(id, level);
55+
this.c2me$levels.put(id, level);
4556
}
57+
this.c2me$ticketLevelUpdates.putAndMoveToLast(id, level);
4658
}
4759

48-
@Redirect(method = "setLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ChunkTicketManager;getChunkHolder(J)Lnet/minecraft/server/world/ChunkHolder;"))
49-
private ChunkHolder fakeLevel(ChunkTicketManager instance, long l) {
50-
return null;
51-
}
52-
53-
@Redirect(method = "setLevel", at = @At(value = "FIELD", target = "Lnet/minecraft/server/world/ChunkTicketManager$TicketDistanceLevelPropagator;UNLOADED:I", opcode = Opcodes.GETSTATIC))
54-
private int fakeLevel() {
55-
return Integer.MAX_VALUE;
60+
@Override
61+
public Long2IntLinkedOpenHashMap c2me$getTicketLevelUpdates() {
62+
return this.c2me$ticketLevelUpdates;
5663
}
5764

5865
}

0 commit comments

Comments
 (0)