diff options
Diffstat (limited to 'patch-remap/mache-vineflower-stripped/net/minecraft/server/level/DistanceManager.java.patch')
-rw-r--r-- | patch-remap/mache-vineflower-stripped/net/minecraft/server/level/DistanceManager.java.patch | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/server/level/DistanceManager.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/server/level/DistanceManager.java.patch new file mode 100644 index 0000000000..064463f5c7 --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/server/level/DistanceManager.java.patch @@ -0,0 +1,173 @@ +--- a/net/minecraft/server/level/DistanceManager.java ++++ b/net/minecraft/server/level/DistanceManager.java +@@ -114,8 +122,25 @@ + } + + if (!this.chunksToUpdateFutures.isEmpty()) { +- this.chunksToUpdateFutures.forEach(chunkHolder -> chunkHolder.updateFutures(chunkManager, this.mainThreadExecutor)); +- this.chunksToUpdateFutures.clear(); ++ // CraftBukkit start ++ // Iterate pending chunk updates with protection against concurrent modification exceptions ++ java.util.Iterator<ChunkHolder> iter = this.chunksToUpdateFutures.iterator(); ++ int expectedSize = this.chunksToUpdateFutures.size(); ++ do { ++ ChunkHolder playerchunk = iter.next(); ++ iter.remove(); ++ expectedSize--; ++ ++ playerchunk.updateFutures(chunkManager, this.mainThreadExecutor); ++ ++ // Reset iterator if set was modified using add() ++ if (this.chunksToUpdateFutures.size() != expectedSize) { ++ expectedSize = this.chunksToUpdateFutures.size(); ++ iter = this.chunksToUpdateFutures.iterator(); ++ } ++ } while (iter.hasNext()); ++ // CraftBukkit end ++ + return true; + } else { + if (!this.ticketsToRelease.isEmpty()) { +@@ -146,26 +176,33 @@ + } + } + +- void addTicket(long chunkPos, Ticket<?> ticket) { +- SortedArraySet<Ticket<?>> tickets = this.getTickets(chunkPos); +- int ticketLevelAt = getTicketLevelAt(tickets); +- Ticket<?> ticket1 = tickets.addOrGet(ticket); ++ boolean addTicket(long i, Ticket<?> ticket) { // CraftBukkit - void -> boolean ++ SortedArraySet<Ticket<?>> arraysetsorted = this.getTickets(i); ++ int j = getTicketLevelAt(arraysetsorted); ++ Ticket<?> ticket1 = (Ticket) arraysetsorted.addOrGet(ticket); ++ + ticket1.setCreatedTick(this.ticketTickCounter); + if (ticket.getTicketLevel() < ticketLevelAt) { + this.ticketTracker.update(chunkPos, ticket.getTicketLevel(), true); + } ++ ++ return ticket == ticket1; // CraftBukkit + } + +- void removeTicket(long chunkPos, Ticket<?> ticket) { +- SortedArraySet<Ticket<?>> tickets = this.getTickets(chunkPos); +- if (tickets.remove(ticket)) { ++ boolean removeTicket(long i, Ticket<?> ticket) { // CraftBukkit - void -> boolean ++ SortedArraySet<Ticket<?>> arraysetsorted = this.getTickets(i); ++ ++ boolean removed = false; // CraftBukkit ++ if (arraysetsorted.remove(ticket)) { ++ removed = true; // CraftBukkit + } + + if (tickets.isEmpty()) { + this.tickets.remove(chunkPos); + } + +- this.ticketTracker.update(chunkPos, getTicketLevelAt(tickets), false); ++ this.ticketTracker.update(i, getTicketLevelAt(arraysetsorted), false); ++ return removed; // CraftBukkit + } + + public <T> void addTicket(TicketType<T> type, ChunkPos pos, int level, T value) { +@@ -178,19 +216,35 @@ + } + + public <T> void addRegionTicket(TicketType<T> type, ChunkPos pos, int distance, T value) { +- Ticket<T> ticket = new Ticket<>(type, ChunkLevel.byStatus(FullChunkStatus.FULL) - distance, value); +- long l = pos.toLong(); +- this.addTicket(l, ticket); +- this.tickingTicketsTracker.addTicket(l, ticket); ++ // CraftBukkit start ++ addRegionTicketAtDistance(type, pos, distance, value); + } + ++ public <T> boolean addRegionTicketAtDistance(TicketType<T> tickettype, ChunkPos chunkcoordintpair, int i, T t0) { ++ // CraftBukkit end ++ Ticket<T> ticket = new Ticket<>(tickettype, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0); ++ long j = chunkcoordintpair.toLong(); ++ ++ boolean added = this.addTicket(j, ticket); // CraftBukkit ++ this.tickingTicketsTracker.addTicket(j, ticket); ++ return added; // CraftBukkit ++ } ++ + public <T> void removeRegionTicket(TicketType<T> type, ChunkPos pos, int distance, T value) { +- Ticket<T> ticket = new Ticket<>(type, ChunkLevel.byStatus(FullChunkStatus.FULL) - distance, value); +- long l = pos.toLong(); +- this.removeTicket(l, ticket); +- this.tickingTicketsTracker.removeTicket(l, ticket); ++ // CraftBukkit start ++ removeRegionTicketAtDistance(type, pos, distance, value); + } + ++ public <T> boolean removeRegionTicketAtDistance(TicketType<T> tickettype, ChunkPos chunkcoordintpair, int i, T t0) { ++ // CraftBukkit end ++ Ticket<T> ticket = new Ticket<>(tickettype, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0); ++ long j = chunkcoordintpair.toLong(); ++ ++ boolean removed = this.removeTicket(j, ticket); // CraftBukkit ++ this.tickingTicketsTracker.removeTicket(j, ticket); ++ return removed; // CraftBukkit ++ } ++ + private SortedArraySet<Ticket<?>> getTickets(long chunkPos) { + return this.tickets.computeIfAbsent(chunkPos, l -> SortedArraySet.create(4)); + } +@@ -217,15 +278,17 @@ + } + + public void removePlayer(SectionPos sectionPos, ServerPlayer player) { +- ChunkPos chunkPos = sectionPos.chunk(); +- long l = chunkPos.toLong(); +- ObjectSet<ServerPlayer> set = this.playersPerChunk.get(l); +- set.remove(player); +- if (set.isEmpty()) { +- this.playersPerChunk.remove(l); +- this.naturalSpawnChunkCounter.update(l, Integer.MAX_VALUE, false); +- this.playerTicketManager.update(l, Integer.MAX_VALUE, false); +- this.tickingTicketsTracker.removeTicket(TicketType.PLAYER, chunkPos, this.getPlayerTicketLevel(), chunkPos); ++ ChunkPos chunkcoordintpair = sectionPos.chunk(); ++ long i = chunkcoordintpair.toLong(); ++ ObjectSet<ServerPlayer> objectset = (ObjectSet) this.playersPerChunk.get(i); ++ if (objectset == null) return; // CraftBukkit - SPIGOT-6208 ++ ++ objectset.remove(player); ++ if (objectset.isEmpty()) { ++ this.playersPerChunk.remove(i); ++ this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false); ++ this.playerTicketManager.update(i, Integer.MAX_VALUE, false); ++ this.tickingTicketsTracker.removeTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair); + } + } + +@@ -324,7 +411,28 @@ + return !this.tickets.isEmpty(); + } + +- class ChunkTicketTracker extends ChunkTracker { ++ // CraftBukkit start ++ public <T> void removeAllTicketsFor(TicketType<T> ticketType, int ticketLevel, T ticketIdentifier) { ++ Ticket<T> target = new Ticket<>(ticketType, ticketLevel, ticketIdentifier); ++ ++ for (java.util.Iterator<Entry<SortedArraySet<Ticket<?>>>> iterator = this.tickets.long2ObjectEntrySet().fastIterator(); iterator.hasNext();) { ++ Entry<SortedArraySet<Ticket<?>>> entry = iterator.next(); ++ SortedArraySet<Ticket<?>> tickets = entry.getValue(); ++ if (tickets.remove(target)) { ++ // copied from removeTicket ++ this.ticketTracker.update(entry.getLongKey(), getTicketLevelAt(tickets), false); ++ ++ // can't use entry after it's removed ++ if (tickets.isEmpty()) { ++ iterator.remove(); ++ } ++ } ++ } ++ } ++ // CraftBukkit end ++ ++ private class ChunkTicketTracker extends ChunkTracker { ++ + private static final int MAX_LEVEL = ChunkLevel.MAX_LEVEL + 1; + + public ChunkTicketTracker() { |