Fix CME when plugin load chunks during chunk load (#1056)
This commit is contained in:
parent
041b0b1fbc
commit
196bf7034d
|
@ -5,11 +5,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.server.level.DistanceManager;
|
import net.minecraft.server.level.*;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.server.level.Ticket;
|
|
||||||
import net.minecraft.server.level.TicketType;
|
|
||||||
import net.minecraft.server.level.TickingTracker;
|
|
||||||
import net.minecraft.util.SortedArraySet;
|
import net.minecraft.util.SortedArraySet;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
@ -18,10 +14,13 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@Mixin(DistanceManager.class)
|
@Mixin(DistanceManager.class)
|
||||||
public abstract class DistanceManagerMixin implements TicketManagerBridge {
|
public abstract class DistanceManagerMixin implements TicketManagerBridge {
|
||||||
|
@ -44,6 +43,26 @@ public abstract class DistanceManagerMixin implements TicketManagerBridge {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Redirect(method = "runAllUpdates", at = @At(value = "INVOKE", remap = false, target = "Ljava/util/Set;forEach(Ljava/util/function/Consumer;)V"))
|
||||||
|
private void arclight$safeIter(Set<ChunkHolder> instance, Consumer<ChunkHolder> consumer) {
|
||||||
|
// Iterate pending chunk updates with protection against concurrent modification exceptions
|
||||||
|
var iter = instance.iterator();
|
||||||
|
var expectedSize = instance.size();
|
||||||
|
do {
|
||||||
|
var chunkHolder = iter.next();
|
||||||
|
iter.remove();
|
||||||
|
expectedSize--;
|
||||||
|
|
||||||
|
consumer.accept(chunkHolder);
|
||||||
|
|
||||||
|
// Reset iterator if set was modified using add()
|
||||||
|
if (instance.size() != expectedSize) {
|
||||||
|
expectedSize = instance.size();
|
||||||
|
iter = instance.iterator();
|
||||||
|
}
|
||||||
|
} while (iter.hasNext());
|
||||||
|
}
|
||||||
|
|
||||||
public <T> boolean addRegionTicketAtDistance(TicketType<T> type, ChunkPos pos, int level, T value) {
|
public <T> boolean addRegionTicketAtDistance(TicketType<T> type, ChunkPos pos, int level, T value) {
|
||||||
var ticket = new Ticket<>(type, 33 - level, value);
|
var ticket = new Ticket<>(type, 33 - level, value);
|
||||||
var ret = this.addTicket(pos.toLong(), ticket);
|
var ret = this.addTicket(pos.toLong(), ticket);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user