PaperMC/patches/server/0673-Improve-and-expand-AsyncCatcher.patch
2023-09-22 15:33:14 -07:00

191 lines
10 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Wed, 25 Aug 2021 20:17:12 -0700
Subject: [PATCH] Improve and expand AsyncCatcher
Log when the async catcher is tripped
The chunk system can swallow the exception given it's all
built with completablefuture, so ensure it is at least printed.
Add/move several async catchers
Async catch modifications to critical entity state
These used to be here from Spigot, but were dropped with 1.17.
Now in 1.17, this state is _even more_ critical than it was before,
so these must exist to catch stupid plugins.
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0b1030da1dc0a745f7a89d98636ff618dde4d5e4..08c4e9037d54e14d0a80f75e05a91a128fdc1446 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1543,6 +1543,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
public void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<RelativeMovement> set) { // Paper
+ org.spigotmc.AsyncCatcher.catchOp("teleport"); // Paper
// Paper start
if (player.isRemoved()) {
LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName());
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 6b80dd7cc1dcc248f7bc1ab4c3d988f8afad1b61..8ccdbfc7908f2b20f94e614009a2063e0a131d7b 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1119,7 +1119,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause) {
- org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot
+ // org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot // Paper - move to API
if (this.isTickingEffects) {
this.effectsToProcess.add(new ProcessableEffect(mobeffect, cause));
return true;
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
index 47bab513feec217d875192afef61f3af95b93d24..d3fb277878adb26c7d80cf21f27070380fdfacd1 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
@@ -77,6 +77,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private boolean addEntityUuid(T entity) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity add by UUID"); // Paper
if (!this.knownUuids.add(entity.getUUID())) {
PersistentEntitySectionManager.LOGGER.warn("UUID of added entity already exists: {}", entity);
return false;
@@ -90,6 +91,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private boolean addEntity(T entity, boolean existing) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity add"); // Paper
// Paper start - chunk system hooks
if (existing) {
// I don't want to know why this is a generic type.
@@ -145,19 +147,23 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
void startTicking(T entity) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity start ticking"); // Paper
this.callbacks.onTickingStart(entity);
}
void stopTicking(T entity) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity stop ticking"); // Paper
this.callbacks.onTickingEnd(entity);
}
void startTracking(T entity) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity start tracking"); // Paper
this.visibleEntityStorage.add(entity);
this.callbacks.onTrackingStart(entity);
}
void stopTracking(T entity) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity stop tracking"); // Paper
this.callbacks.onTrackingEnd(entity);
this.visibleEntityStorage.remove(entity);
}
@@ -169,6 +175,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void updateChunkStatus(ChunkPos chunkPos, Visibility trackingStatus) {
+ org.spigotmc.AsyncCatcher.catchOp("Update chunk status"); // Paper
long i = chunkPos.toLong();
if (trackingStatus == Visibility.HIDDEN) {
@@ -213,6 +220,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void ensureChunkQueuedForLoad(long chunkPos) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk save"); // Paper
PersistentEntitySectionManager.ChunkLoadStatus persistententitysectionmanager_b = (PersistentEntitySectionManager.ChunkLoadStatus) this.chunkLoadStatuses.get(chunkPos);
if (persistententitysectionmanager_b == PersistentEntitySectionManager.ChunkLoadStatus.FRESH) {
@@ -257,6 +265,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private void requestChunkLoad(long chunkPos) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk load request"); // Paper
this.chunkLoadStatuses.put(chunkPos, PersistentEntitySectionManager.ChunkLoadStatus.PENDING);
ChunkPos chunkcoordintpair = new ChunkPos(chunkPos);
CompletableFuture completablefuture = this.permanentStorage.loadEntities(chunkcoordintpair);
@@ -270,6 +279,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private boolean processChunkUnload(long chunkPos) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk unload process"); // Paper
boolean flag = this.storeChunkSections(chunkPos, (entityaccess) -> {
entityaccess.getPassengersAndSelf().forEach(this::unloadEntity);
}, true); // CraftBukkit - add boolean for event call
@@ -294,6 +304,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private void processPendingLoads() {
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk process pending loads"); // Paper
ChunkEntities<T> chunkentities; // CraftBukkit - decompile error
while ((chunkentities = (ChunkEntities) this.loadingInbox.poll()) != null) {
@@ -310,6 +321,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void tick() {
+ org.spigotmc.AsyncCatcher.catchOp("Entity manager tick"); // Paper
this.processPendingLoads();
this.processUnloads();
}
@@ -330,6 +342,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void autoSave() {
+ org.spigotmc.AsyncCatcher.catchOp("Entity manager autosave"); // Paper
this.getAllChunksToSave().forEach((java.util.function.LongConsumer) (i) -> { // CraftBukkit - decompile error
boolean flag = this.chunkVisibility.get(i) == Visibility.HIDDEN;
@@ -344,6 +357,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void saveAll() {
+ org.spigotmc.AsyncCatcher.catchOp("Entity manager save"); // Paper
LongSet longset = this.getAllChunksToSave();
while (!longset.isEmpty()) {
@@ -446,6 +460,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
long i = SectionPos.asLong(blockposition);
if (i != this.currentSectionKey) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity move"); // Paper
Visibility visibility = this.currentSection.getStatus();
if (!this.currentSection.remove(this.entity)) {
@@ -500,6 +515,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
@Override
public void onRemove(Entity.RemovalReason reason) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity remove"); // Paper
if (!this.currentSection.remove(this.entity)) {
PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (destroying due to {})", new Object[]{this.entity, SectionPos.of(this.currentSectionKey), reason});
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 1a911126ccb7b7e298b66d3fec832dcd0c0e58f7..661638716cd4d1b20745f3a196f6d060b3de570c 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -464,6 +464,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
@Override
public boolean addPotionEffect(PotionEffect effect, boolean force) {
+ org.spigotmc.AsyncCatcher.catchOp("effect add"); // Paper
this.getHandle().addEffect(new MobEffectInstance(CraftPotionEffectType.bukkitToMinecraft(effect.getType()), effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles(), effect.hasIcon()), EntityPotionEffectEvent.Cause.PLUGIN); // Paper - Don't ignore icon
return true;
}
diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java
index 05e94702e42b8f5c35d2a112c486d57948a3acba..d678ca116f9b81ab9d7d99a698e0ce066c132f34 100644
--- a/src/main/java/org/spigotmc/AsyncCatcher.java
+++ b/src/main/java/org/spigotmc/AsyncCatcher.java
@@ -11,6 +11,7 @@ public class AsyncCatcher
{
if ( !io.papermc.paper.util.TickThread.isTickThread() ) // Paper // Paper - rewrite chunk system
{
+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); // Paper
throw new IllegalStateException( "Asynchronous " + reason + "!" );
}
}