Port CB changes from Moonrise patch
This commit is contained in:
@@ -83,6 +83,12 @@ public class CraftChunk implements Chunk {
|
||||
}
|
||||
|
||||
public ChunkAccess getHandle(ChunkStatus chunkStatus) {
|
||||
// Paper start - chunk system
|
||||
net.minecraft.world.level.chunk.LevelChunk full = this.worldServer.getChunkIfLoaded(this.x, this.z);
|
||||
if (full != null) {
|
||||
return full;
|
||||
}
|
||||
// Paper end - chunk system
|
||||
ChunkAccess chunkAccess = this.worldServer.getChunk(this.x, this.z, chunkStatus);
|
||||
|
||||
// SPIGOT-7332: Get unwrapped extension
|
||||
@@ -117,60 +123,12 @@ public class CraftChunk implements Chunk {
|
||||
|
||||
@Override
|
||||
public boolean isEntitiesLoaded() {
|
||||
return this.getCraftWorld().getHandle().entityManager.areEntitiesLoaded(ChunkPos.asLong(this.x, this.z));
|
||||
return this.getCraftWorld().getHandle().areEntitiesLoaded(ChunkPos.asLong(this.x, this.z)); // Paper - chunk system
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity[] getEntities() {
|
||||
if (!this.isLoaded()) {
|
||||
this.getWorld().getChunkAt(this.x, this.z); // Transient load for this tick
|
||||
}
|
||||
|
||||
PersistentEntitySectionManager<net.minecraft.world.entity.Entity> entityManager = this.getCraftWorld().getHandle().entityManager;
|
||||
long pair = ChunkPos.asLong(this.x, this.z);
|
||||
|
||||
if (entityManager.areEntitiesLoaded(pair)) {
|
||||
return entityManager.getEntities(new ChunkPos(this.x, this.z)).stream()
|
||||
.map(net.minecraft.world.entity.Entity::getBukkitEntity)
|
||||
.filter(Objects::nonNull).toArray(Entity[]::new);
|
||||
}
|
||||
|
||||
entityManager.ensureChunkQueuedForLoad(pair); // Start entity loading
|
||||
|
||||
// SPIGOT-6772: Use entity mailbox and re-schedule entities if they get unloaded
|
||||
ConsecutiveExecutor mailbox = ((EntityStorage) entityManager.permanentStorage).entityDeserializerQueue;
|
||||
BooleanSupplier supplier = () -> {
|
||||
// only execute inbox if our entities are not present
|
||||
if (entityManager.areEntitiesLoaded(pair)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!entityManager.isPending(pair)) {
|
||||
// Our entities got unloaded, this should normally not happen.
|
||||
entityManager.ensureChunkQueuedForLoad(pair); // Re-start entity loading
|
||||
}
|
||||
|
||||
// tick loading inbox, which loads the created entities to the world
|
||||
// (if present)
|
||||
entityManager.tick();
|
||||
// check if our entities are loaded
|
||||
return entityManager.areEntitiesLoaded(pair);
|
||||
};
|
||||
|
||||
// now we wait until the entities are loaded,
|
||||
// the converting from NBT to entity object is done on the main Thread which is why we wait
|
||||
while (!supplier.getAsBoolean()) {
|
||||
if (mailbox.size() != 0) {
|
||||
mailbox.run();
|
||||
} else {
|
||||
Thread.yield();
|
||||
LockSupport.parkNanos("waiting for entity loading", 100000L);
|
||||
}
|
||||
}
|
||||
|
||||
return entityManager.getEntities(new ChunkPos(this.x, this.z)).stream()
|
||||
.map(net.minecraft.world.entity.Entity::getBukkitEntity)
|
||||
.filter(Objects::nonNull).toArray(Entity[]::new);
|
||||
return FeatureHooks.getChunkEntities(this.worldServer, this.x, this.z); // Paper - chunk system
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1448,7 +1448,7 @@ public final class CraftServer implements Server {
|
||||
// Paper - Put world into worldlist before initing the world; move up
|
||||
|
||||
this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal);
|
||||
internal.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API
|
||||
io.papermc.paper.FeatureHooks.tickEntityManager(internal); // SPIGOT-6526: Load pending entities so they are available to the API // Paper - chunk system
|
||||
|
||||
this.pluginManager.callEvent(new WorldLoadEvent(internal.getWorld()));
|
||||
return internal.getWorld();
|
||||
@@ -1493,7 +1493,7 @@ public final class CraftServer implements Server {
|
||||
}
|
||||
|
||||
handle.getChunkSource().close(save);
|
||||
handle.entityManager.close(save); // SPIGOT-6722: close entityManager
|
||||
io.papermc.paper.FeatureHooks.closeEntityManager(handle, save); // SPIGOT-6722: close entityManager // Paper - chunk system
|
||||
handle.levelStorageAccess.close();
|
||||
} catch (Exception ex) {
|
||||
this.getLogger().log(Level.SEVERE, null, ex);
|
||||
|
||||
@@ -502,14 +502,17 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z));
|
||||
if (playerChunk == null) return false;
|
||||
|
||||
playerChunk.getTickingChunkFuture().thenAccept(either -> {
|
||||
either.ifSuccess(chunk -> {
|
||||
// Paper start - chunk system
|
||||
net.minecraft.world.level.chunk.LevelChunk chunk = playerChunk.getChunkToSend();
|
||||
if (chunk == null) {
|
||||
return false;
|
||||
}
|
||||
// Paper end - chunk system
|
||||
List<ServerPlayer> playersInRange = playerChunk.playerProvider.getPlayers(playerChunk.getPos(), false);
|
||||
if (playersInRange.isEmpty()) return;
|
||||
if (playersInRange.isEmpty()) return true; // Paper - chunk system
|
||||
|
||||
FeatureHooks.sendChunkRefreshPackets(playersInRange, chunk);
|
||||
});
|
||||
});
|
||||
// Paper - chunk system
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -611,47 +614,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public Collection<Plugin> getPluginChunkTickets(int x, int z) {
|
||||
DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager;
|
||||
SortedArraySet<Ticket<?>> tickets = chunkDistanceManager.tickets.get(ChunkPos.asLong(x, z));
|
||||
|
||||
if (tickets == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
ImmutableList.Builder<Plugin> ret = ImmutableList.builder();
|
||||
for (Ticket<?> ticket : tickets) {
|
||||
if (ticket.getType() == TicketType.PLUGIN_TICKET) {
|
||||
ret.add((Plugin) ticket.key);
|
||||
}
|
||||
}
|
||||
|
||||
return ret.build();
|
||||
return FeatureHooks.getPluginChunkTickets(this.world, x, z); // Paper - chunk system
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Plugin, Collection<Chunk>> getPluginChunkTickets() {
|
||||
Map<Plugin, ImmutableList.Builder<Chunk>> ret = new HashMap<>();
|
||||
DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager;
|
||||
|
||||
for (Long2ObjectMap.Entry<SortedArraySet<Ticket<?>>> chunkTickets : chunkDistanceManager.tickets.long2ObjectEntrySet()) {
|
||||
long chunkKey = chunkTickets.getLongKey();
|
||||
SortedArraySet<Ticket<?>> tickets = chunkTickets.getValue();
|
||||
|
||||
Chunk chunk = null;
|
||||
for (Ticket<?> ticket : tickets) {
|
||||
if (ticket.getType() != TicketType.PLUGIN_TICKET) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (chunk == null) {
|
||||
chunk = this.getChunkAt(ChunkPos.getX(chunkKey), ChunkPos.getZ(chunkKey));
|
||||
}
|
||||
|
||||
ret.computeIfAbsent((Plugin) ticket.key, (key) -> ImmutableList.builder()).add(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
return ret.entrySet().stream().collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, (entry) -> entry.getValue().build()));
|
||||
return FeatureHooks.getPluginChunkTickets(this.world); // Paper - chunk system
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -1336,12 +1304,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public int getViewDistance() {
|
||||
return this.world.getChunkSource().chunkMap.serverViewDistance;
|
||||
return FeatureHooks.getViewDistance(this.world); // Paper - chunk system
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSimulationDistance() {
|
||||
return this.world.getChunkSource().chunkMap.getDistanceManager().simulationDistance;
|
||||
return FeatureHooks.getSimulationDistance(this.world); // Paper - chunk system
|
||||
}
|
||||
|
||||
public BlockMetadataStore getBlockMetadata() {
|
||||
@@ -2472,25 +2440,22 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public void setViewDistance(final int viewDistance) {
|
||||
if (viewDistance < 2 || viewDistance > 32) {
|
||||
throw new IllegalArgumentException("View distance " + viewDistance + " is out of range of [2, 32]");
|
||||
}
|
||||
this.getHandle().chunkSource.chunkMap.setServerViewDistance(viewDistance);
|
||||
FeatureHooks.setViewDistance(this.world, viewDistance); // Paper - chunk system
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSimulationDistance(final int simulationDistance) {
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
FeatureHooks.setSimulationDistance(this.world, simulationDistance); // Paper - chunk system
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSendViewDistance() {
|
||||
return this.getViewDistance();
|
||||
return FeatureHooks.getSendViewDistance(this.world); // Paper - chunk system
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSendViewDistance(final int viewDistance) {
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
FeatureHooks.setSendViewDistance(this.world, viewDistance); // Paper - chunk system
|
||||
}
|
||||
|
||||
// Paper start - implement pointers
|
||||
|
||||
@@ -3527,7 +3527,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public void setViewDistance(final int viewDistance) {
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
FeatureHooks.setViewDistance(this.getHandle(), viewDistance); // Paper - chunk system
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3537,7 +3537,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public void setSimulationDistance(final int simulationDistance) {
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
FeatureHooks.setSimulationDistance(this.getHandle(), simulationDistance); // Paper - chunk system
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3547,7 +3547,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public void setSendViewDistance(final int viewDistance) {
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
FeatureHooks.setSendViewDistance(this.getHandle(), viewDistance); // Paper - chunk system
|
||||
}
|
||||
|
||||
// Paper start - entity effect API
|
||||
|
||||
@@ -264,7 +264,7 @@ public class CustomChunkGenerator extends InternalChunkGenerator {
|
||||
return ichunkaccess1;
|
||||
};
|
||||
|
||||
return future == null ? CompletableFuture.supplyAsync(() -> function.apply(chunk), net.minecraft.Util.backgroundExecutor()) : future.thenApply(function);
|
||||
return future == null ? CompletableFuture.supplyAsync(() -> function.apply(chunk), io.papermc.paper.FeatureHooks.getWorldgenExecutor()) : future.thenApply(function); // Paper - chunk system
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,7 +7,7 @@ public class AsyncCatcher {
|
||||
public static boolean enabled = true;
|
||||
|
||||
public static void catchOp(String reason) {
|
||||
if (AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread) {
|
||||
if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) { // Paper - chunk system
|
||||
MinecraftServer.LOGGER.error("Thread {} failed main thread check: {}", Thread.currentThread().getName(), reason, new Throwable()); // Paper
|
||||
throw new IllegalStateException("Asynchronous " + reason + "!");
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public class WatchdogThread extends Thread {
|
||||
// Paper end - Different message for short timeout
|
||||
logger.log(Level.SEVERE, "------------------------------");
|
||||
logger.log(Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):"); // Paper
|
||||
FeatureHooks.dumpTickingInfo(); // Paper - log detailed tick information
|
||||
FeatureHooks.dumpAllChunkLoadInfo(MinecraftServer.getServer(), isLongTimeout); // Paper - log detailed tick information
|
||||
WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE), logger);
|
||||
logger.log(Level.SEVERE, "------------------------------");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user