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.objects.ObjectSet;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
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.server.level.*;
|
||||
import net.minecraft.util.SortedArraySet;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
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.injection.At;
|
||||
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.LocalCapture;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mixin(DistanceManager.class)
|
||||
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) {
|
||||
var ticket = new Ticket<>(type, 33 - level, value);
|
||||
var ret = this.addTicket(pos.toLong(), ticket);
|
||||
|
|
Loading…
Reference in New Issue
Block a user