2021-11-01 05:35:47 +01:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
2023-04-09 20:38:32 +02:00
Date: Wed, 25 Aug 2021 20:17:12 -0700
Subject: [PATCH] Improve and expand AsyncCatcher
2021-11-01 05:35:47 +01:00
2023-04-09 20:38:32 +02:00
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.
2021-11-01 05:35:47 +01:00
2023-04-09 20:38:32 +02:00
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 96897ccce68ecbff808077a07f213daccc57fa54..f2a96d282f65e405e8e396ef271ce0d5a094ac4b 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1652,6 +1652,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
}
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 a7046e42c1935e9a4e529726072d9f88caaa703a..7d100539ffd1c52c4bf514907a0cb1d848eb0236 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1102,7 +1102,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;
2021-11-01 05:35:47 +01:00
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
2022-12-07 17:46:46 +01:00
index 038abf2ac104ceecaab11b10d466ea69ec86623e..a77985b2dd7137d8eea03909403fc08e89376d73 100644
2021-11-01 05:35:47 +01:00
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
2022-09-26 10:02:51 +02:00
@@ -77,6 +77,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
2021-11-01 05:35:47 +01:00
}
private boolean addEntityUuid(T entity) {
2021-11-04 01:54:11 +01:00
+ org.spigotmc.AsyncCatcher.catchOp("Entity add by UUID"); // Paper
2021-11-01 05:35:47 +01:00
if (!this.knownUuids.add(entity.getUUID())) {
2022-09-26 10:02:51 +02:00
PersistentEntitySectionManager.LOGGER.warn("UUID of added entity already exists: {}", entity);
return false;
@@ -90,6 +91,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
2021-11-01 05:35:47 +01:00
}
private boolean addEntity(T entity, boolean existing) {
2021-11-04 01:54:11 +01:00
+ org.spigotmc.AsyncCatcher.catchOp("Entity add"); // Paper
2022-09-01 18:51:59 +02:00
// Paper start - chunk system hooks
if (existing) {
// I don't want to know why this is a generic type.
2022-09-26 10:02:51 +02:00
@@ -145,19 +147,23 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
2021-11-01 05:35:47 +01:00
}
void startTicking(T entity) {
2021-11-04 01:54:11 +01:00
+ org.spigotmc.AsyncCatcher.catchOp("Entity start ticking"); // Paper
2021-11-01 05:35:47 +01:00
this.callbacks.onTickingStart(entity);
}
void stopTicking(T entity) {
2021-11-04 01:54:11 +01:00
+ org.spigotmc.AsyncCatcher.catchOp("Entity stop ticking"); // Paper
2021-11-01 05:35:47 +01:00
this.callbacks.onTickingEnd(entity);
}
void startTracking(T entity) {
2021-11-04 01:54:11 +01:00
+ org.spigotmc.AsyncCatcher.catchOp("Entity start tracking"); // Paper
2021-11-01 05:35:47 +01:00
this.visibleEntityStorage.add(entity);
this.callbacks.onTrackingStart(entity);
}
void stopTracking(T entity) {
2021-11-04 01:54:11 +01:00
+ org.spigotmc.AsyncCatcher.catchOp("Entity stop tracking"); // Paper
2021-11-01 05:35:47 +01:00
this.callbacks.onTrackingEnd(entity);
this.visibleEntityStorage.remove(entity);
}
2022-09-26 10:02:51 +02:00
@@ -169,6 +175,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
2021-11-01 05:35:47 +01:00
}
public void updateChunkStatus(ChunkPos chunkPos, Visibility trackingStatus) {
+ org.spigotmc.AsyncCatcher.catchOp("Update chunk status"); // Paper
long i = chunkPos.toLong();
if (trackingStatus == Visibility.HIDDEN) {
2022-09-26 10:02:51 +02:00
@@ -213,6 +220,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
2021-11-25 09:10:26 +01:00
}
2021-11-04 19:20:14 +01:00
2021-11-25 09:10:26 +01:00
public void ensureChunkQueuedForLoad(long chunkPos) {
2021-11-01 05:35:47 +01:00
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk save"); // Paper
2021-11-04 19:20:14 +01:00
PersistentEntitySectionManager.ChunkLoadStatus persistententitysectionmanager_b = (PersistentEntitySectionManager.ChunkLoadStatus) this.chunkLoadStatuses.get(chunkPos);
2021-11-01 05:35:47 +01:00
2021-11-25 09:10:26 +01:00
if (persistententitysectionmanager_b == PersistentEntitySectionManager.ChunkLoadStatus.FRESH) {
2022-09-26 10:02:51 +02:00
@@ -257,6 +265,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
2021-11-01 05:35:47 +01:00
}
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);
2022-09-26 10:02:51 +02:00
@@ -270,6 +279,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
2021-11-04 19:20:14 +01:00
}
2021-11-01 05:35:47 +01:00
private boolean processChunkUnload(long chunkPos) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk unload process"); // Paper
2021-11-04 19:20:14 +01:00
boolean flag = this.storeChunkSections(chunkPos, (entityaccess) -> {
2021-11-01 05:35:47 +01:00
entityaccess.getPassengersAndSelf().forEach(this::unloadEntity);
}, true); // CraftBukkit - add boolean for event call
2022-09-26 10:02:51 +02:00
@@ -294,6 +304,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
2021-11-01 05:35:47 +01:00
}
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) {
2022-09-26 10:02:51 +02:00
@@ -310,6 +321,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
2021-11-01 05:35:47 +01:00
}
public void tick() {
+ org.spigotmc.AsyncCatcher.catchOp("Entity manager tick"); // Paper
this.processPendingLoads();
this.processUnloads();
}
2022-09-26 10:02:51 +02:00
@@ -330,6 +342,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
2021-11-01 05:35:47 +01:00
}
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;
2022-09-26 10:02:51 +02:00
@@ -344,6 +357,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
2021-11-01 05:35:47 +01:00
}
public void saveAll() {
+ org.spigotmc.AsyncCatcher.catchOp("Entity manager save"); // Paper
LongSet longset = this.getAllChunksToSave();
while (!longset.isEmpty()) {
2022-09-26 10:02:51 +02:00
@@ -446,6 +460,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
long i = SectionPos.asLong(blockposition);
2021-11-01 05:35:47 +01:00
if (i != this.currentSectionKey) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity move"); // Paper
2022-09-26 10:02:51 +02:00
Visibility visibility = this.currentSection.getStatus();
if (!this.currentSection.remove(this.entity)) {
@@ -500,6 +515,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
2021-11-01 05:35:47 +01:00
@Override
public void onRemove(Entity.RemovalReason reason) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity remove"); // Paper
if (!this.currentSection.remove(this.entity)) {
2022-03-01 06:43:03 +01:00
PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (destroying due to {})", new Object[]{this.entity, SectionPos.of(this.currentSectionKey), reason});
2021-11-01 05:35:47 +01:00
}
2023-04-09 20:38:32 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index cbb6b437358823cd52518682f32dd597c9aeb85a..205101e301bb4ea552459fe4e1f028f252136720 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -455,6 +455,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(MobEffect.byId(effect.getType().getId()), 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 5409f230fdd53b70fc03c58177438534731ad4e6..c02a04d284734b5f545b64307ed4aea337c1465f 100644
--- a/src/main/java/org/spigotmc/AsyncCatcher.java
+++ b/src/main/java/org/spigotmc/AsyncCatcher.java
@@ -12,6 +12,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 + "!" );
}
}