Skip to content

Commit 4630492

Browse files
committed
fix: defer all level events to avoid clearing deferred state
1 parent 899b76b commit 4630492

File tree

3 files changed

+63
-21
lines changed

3 files changed

+63
-21
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/MixinChunkLevelManager.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,38 @@
22

33
import com.bawnorton.mixinsquared.TargetHandler;
44
import com.ishland.c2me.rewrites.chunksystem.common.Config;
5+
import com.ishland.c2me.rewrites.chunksystem.common.ducks.TicketDistanceLevelPropagatorExtension;
56
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
67
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
8+
import it.unimi.dsi.fastutil.longs.Long2IntLinkedOpenHashMap;
79
import net.minecraft.server.world.ChunkHolder;
810
import net.minecraft.server.world.ChunkLevelManager;
11+
import net.minecraft.server.world.ServerChunkLoadingManager;
912
import net.minecraft.server.world.ThrottledChunkTaskScheduler;
13+
import net.minecraft.server.world.TicketDistanceLevelPropagator;
1014
import net.minecraft.util.thread.TaskExecutor;
15+
import org.jetbrains.annotations.Nullable;
1116
import org.objectweb.asm.Opcodes;
1217
import org.spongepowered.asm.mixin.Dynamic;
18+
import org.spongepowered.asm.mixin.Final;
1319
import org.spongepowered.asm.mixin.Mixin;
20+
import org.spongepowered.asm.mixin.Shadow;
1421
import org.spongepowered.asm.mixin.injection.At;
22+
import org.spongepowered.asm.mixin.injection.Inject;
1523
import org.spongepowered.asm.mixin.injection.Redirect;
24+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
1625

1726
import java.util.concurrent.Executor;
1827

1928
@Mixin(value = ChunkLevelManager.class, priority = 1051)
20-
public class MixinChunkLevelManager {
29+
public abstract class MixinChunkLevelManager {
30+
31+
@Shadow
32+
@Final
33+
private TicketDistanceLevelPropagator ticketDistanceLevelPropagator;
34+
35+
@Shadow
36+
protected abstract @Nullable ChunkHolder setLevel(long pos, int level, @Nullable ChunkHolder holder, int i);
2137

2238
@Dynamic
2339
@TargetHandler(
@@ -58,4 +74,16 @@ private ThrottledChunkTaskScheduler syncPlayerTickets(TaskExecutor<Runnable> exe
5874
}
5975
}
6076

77+
@Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/TicketDistanceLevelPropagator;update(I)I", shift = At.Shift.AFTER))
78+
private void postTicketPropagator(ServerChunkLoadingManager chunkLoadingManager, CallbackInfoReturnable<Boolean> cir) {
79+
if (this.ticketDistanceLevelPropagator != null) { // ignore if replaced
80+
Long2IntLinkedOpenHashMap updates = ((TicketDistanceLevelPropagatorExtension) this.ticketDistanceLevelPropagator).c2me$getTicketLevelUpdates();
81+
while (!updates.isEmpty()) {
82+
long pos = updates.firstLongKey();
83+
int level = updates.removeFirstInt();
84+
this.setLevel(pos, level, null, Integer.MAX_VALUE - 1); // holder and old level is ignored
85+
}
86+
}
87+
}
88+
6189
}
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,35 @@
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;
6-
import net.minecraft.server.world.ChunkLevelManager;
77
import net.minecraft.server.world.TicketDistanceLevelPropagator;
8-
import org.objectweb.asm.Opcodes;
98
import org.spongepowered.asm.mixin.Final;
109
import org.spongepowered.asm.mixin.Mixin;
1110
import org.spongepowered.asm.mixin.Overwrite;
1211
import org.spongepowered.asm.mixin.Shadow;
12+
import org.spongepowered.asm.mixin.Unique;
1313
import org.spongepowered.asm.mixin.injection.At;
1414
import org.spongepowered.asm.mixin.injection.Inject;
15-
import org.spongepowered.asm.mixin.injection.Redirect;
1615
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
1716

1817
@Mixin(TicketDistanceLevelPropagator.class)
19-
public class MixinChunkTicketManagerTicketDistanceLevelPropagator {
18+
public class MixinChunkTicketManagerTicketDistanceLevelPropagator implements TicketDistanceLevelPropagatorExtension {
2019

2120
@Shadow @Final private static int UNLOADED;
2221

23-
private final Long2IntMap levels = new Long2IntOpenHashMap();
22+
@Unique
23+
private Long2IntMap c2me$levels;
24+
25+
@Unique
26+
private Long2IntLinkedOpenHashMap c2me$ticketLevelUpdates;
2427

2528
@Inject(method = "<init>", at = @At("RETURN"))
2629
private void postInit(CallbackInfo ci) {
27-
this.levels.defaultReturnValue(UNLOADED + 1);
30+
this.c2me$levels = new Long2IntOpenHashMap();
31+
this.c2me$levels.defaultReturnValue(UNLOADED + 1);
32+
this.c2me$ticketLevelUpdates = new Long2IntLinkedOpenHashMap();
2833
}
2934

3035
/**
@@ -33,26 +38,26 @@ private void postInit(CallbackInfo ci) {
3338
*/
3439
@Overwrite
3540
public int getLevel(long id) {
36-
return this.levels.get(id);
41+
return this.c2me$levels.get(id);
3742
}
3843

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

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

5863
}

0 commit comments

Comments
 (0)