diff --git a/paper-server/patches/sources/net/minecraft/advancements/triggers/SimpleCriterionTrigger.java.patch b/paper-server/patches/sources/net/minecraft/advancements/triggers/SimpleCriterionTrigger.java.patch index 5e4628730ff0..5c3c8bc03b9d 100644 --- a/paper-server/patches/sources/net/minecraft/advancements/triggers/SimpleCriterionTrigger.java.patch +++ b/paper-server/patches/sources/net/minecraft/advancements/triggers/SimpleCriterionTrigger.java.patch @@ -1,6 +1,10 @@ --- a/net/minecraft/advancements/triggers/SimpleCriterionTrigger.java +++ b/net/minecraft/advancements/triggers/SimpleCriterionTrigger.java -@@ -20,14 +_,14 @@ +@@ -17,17 +_,18 @@ + + public abstract class SimpleCriterionTrigger implements CriterionTrigger { + protected void trigger(final ServerPlayer player, final Predicate matcher) { ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(player, "Cannot trigger criterion async"); // Paper - block async calls PlayerAdvancements advancements = player.getAdvancements(); Map listenersForType = advancements.getTriggerMapForType(this); if (listenersForType != null && !listenersForType.isEmpty()) { diff --git a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch index f3ef38ec840e..13cedbd3bfee 100644 --- a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch @@ -25,7 +25,12 @@ LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", id, this.playerSavePath); } else { this.startProgress(advancement, progress); -@@ -168,14 +_,31 @@ +@@ -164,18 +_,36 @@ + } + + public boolean award(final AdvancementHolder holder, final String criterion) { ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.player, "Cannot award advancement async"); // Paper - block async calls + boolean result = false; AdvancementProgress progress = this.getOrStartProgress(holder); boolean wasDone = progress.isDone(); if (progress.grantProgress(criterion)) { @@ -59,6 +64,14 @@ } }); } +@@ -189,6 +_,7 @@ + } + + public boolean revoke(final AdvancementHolder advancement, final String criterion) { ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.player, "Cannot revoke advancement async"); // Paper - block async calls + boolean result = false; + AdvancementProgress progress = this.getOrStartProgress(advancement); + boolean wasDone = progress.isDone(); @@ -238,7 +_,7 @@ public void flushDirty(final ServerPlayer player, final boolean showAdvancements) { if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) { diff --git a/paper-server/patches/sources/net/minecraft/server/level/ChunkMap.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ChunkMap.java.patch index 704059c3e0bb..9e01bd16a8e7 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ChunkMap.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ChunkMap.java.patch @@ -264,7 +264,7 @@ } protected void addEntity(final Entity entity) { -+ org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Cannot track entity async"); // Paper - block async calls + // Paper start - ignore and warn about illegal addEntity calls instead of crashing server + if (!entity.valid || entity.level() != this.level || this.entityMap.containsKey(entity.getId())) { + LOGGER.error("Illegal ChunkMap::addEntity for world " + io.papermc.paper.util.MCUtil.getLevelName(this.level) @@ -284,7 +284,7 @@ } protected void removeEntity(final Entity entity) { -+ org.spigotmc.AsyncCatcher.catchOp("entity untrack"); // Spigot ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Cannot untrack entity async"); // Paper - block async calls if (entity instanceof ServerPlayer player) { this.updatePlayerStatus(player, false); @@ -305,7 +305,7 @@ } public void removePlayer(final ServerPlayer player) { -+ org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.entity, "Cannot remove tracking player async"); // Paper - block async calls if (this.seenBy.remove(player.connection)) { this.serverEntity.removePairing(player); if (this.seenBy.isEmpty()) { @@ -313,7 +313,7 @@ } public void updatePlayer(final ServerPlayer player) { -+ org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.entity, "Cannot update tracking player async"); // Paper - block async calls if (player != this.entity) { - Vec3 deltaToPlayer = player.position().subtract(this.entity.position()); + // Paper start - remove allocation of Vec3D here diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch index 2e4dc8485ff0..265374b93498 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -642,7 +642,7 @@ - private boolean addEntity(final Entity entity) { + // CraftBukkit start + private boolean addEntity(final Entity entity, final org.bukkit.event.entity.CreatureSpawnEvent.@Nullable SpawnReason spawnReason) { -+ org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Cannot add entity async"); // Paper - block async calls + entity.generation = false; // Paper - Don't fire sync event during generation; Reset flag if it was added during a ServerLevel generation process + // Paper start - extra debug info + if (entity.valid) { @@ -1135,7 +1135,7 @@ @Override public void onTrackingStart(final Entity entity) { - ServerLevel.this.getChunkSource().addEntity(entity); -+ org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Cannot start tracking entity async"); // Paper - block async calls + // ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server; moved down below valid=true if (entity instanceof ServerPlayer player) { ServerLevel.this.players.add(player); diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch index fc4746f898f7..628c19a5be2c 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch @@ -210,6 +210,14 @@ if (enderPearl.isRemoved()) { LOGGER.warn("Trying to save removed ender pearl, skipping"); } else { +@@ -548,6 +_,7 @@ + } + + public void initMenu(final AbstractContainerMenu container) { ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot init menu async"); // Paper - block async calls + container.addSlotListener(this.containerListener); + container.setSynchronizer(this.containerSynchronizer); + } @@ -580,6 +_,11 @@ @Override @@ -432,7 +440,7 @@ this.connection .send( new ClientboundPlayerCombatKillPacket(this.getId(), deathMessage), -@@ -903,6 +_,65 @@ +@@ -903,6 +_,66 @@ } ) ); @@ -443,6 +451,7 @@ + // Paper end - Expand PlayerDeathEvent API + @Override + public void die(final DamageSource source) { ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot die async"); // Paper - block async calls + // this.gameEvent(GameEvent.ENTITY_DIE); // Paper - move below event cancellation check + boolean showDeathMessage = this.level().getGameRules().get(GameRules.SHOW_DEATH_MESSAGES); + // CraftBukkit start - fire PlayerDeathEvent @@ -963,7 +972,7 @@ } @Override -@@ -1323,8 +_,9 @@ +@@ -1323,22 +_,51 @@ this.connection.send(new ClientboundShowDialogPacket(dialog)); } @@ -974,7 +983,9 @@ } @Override -@@ -1333,12 +_,39 @@ + public OptionalInt openMenu(final @Nullable MenuProvider provider) { ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot open menu async"); // Paper - block async calls + if (provider == null) { return OptionalInt.empty(); } @@ -1087,7 +1098,7 @@ this.initMenu(this.containerMenu); } -@@ -1409,10 +_,30 @@ +@@ -1409,10 +_,31 @@ @Override public void closeContainer() { @@ -1096,6 +1107,7 @@ + } + @Override + public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot close container async"); // Paper - block async calls + org.bukkit.craftbukkit.event.CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit + // Paper end - Inventory close reason this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId)); diff --git a/paper-server/patches/sources/net/minecraft/stats/ServerRecipeBook.java.patch b/paper-server/patches/sources/net/minecraft/stats/ServerRecipeBook.java.patch index 79fcad6dbccc..c3055072189f 100644 --- a/paper-server/patches/sources/net/minecraft/stats/ServerRecipeBook.java.patch +++ b/paper-server/patches/sources/net/minecraft/stats/ServerRecipeBook.java.patch @@ -1,6 +1,12 @@ --- a/net/minecraft/stats/ServerRecipeBook.java +++ b/net/minecraft/stats/ServerRecipeBook.java -@@ -64,17 +_,21 @@ +@@ -59,22 +_,27 @@ + } + + public int addRecipes(final Collection> recipes, final ServerPlayer player) { ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(player, "Cannot add recipes async"); // Paper - block async calls + List recipesToAdd = new ArrayList<>(); + for (RecipeHolder recipe : recipes) { ResourceKey> id = recipe.id(); if (!this.known.contains(id) && !recipe.value().isSpecial()) { @@ -24,6 +30,14 @@ player.connection.send(new ClientboundRecipeBookAddPacket(recipesToAdd, false)); } +@@ -82,6 +_,7 @@ + } + + public int removeRecipes(final Collection> recipes, final ServerPlayer player) { ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(player, "Cannot remove recipes async"); // Paper - block async calls + List recipesToRemove = Lists.newArrayList(); + + for (RecipeHolder recipe : recipes) { @@ -92,7 +_,7 @@ } } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch index b74db39b6f37..f42b41242e1b 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch @@ -4,7 +4,7 @@ } protected void onPlace(final BlockState state, final Level level, final BlockPos pos, final BlockState oldState, final boolean movedByPiston) { -+ org.spigotmc.AsyncCatcher.catchOp("block onPlace"); // Spigot ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(level, pos, "Cannot place block async"); // Paper - block async calls } protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) { diff --git a/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java b/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java index 83f698af8581..05e06c4f9c10 100644 --- a/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java +++ b/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java @@ -6,6 +6,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; +import ca.spottedleaf.moonrise.common.util.TickThread; import net.minecraft.world.entity.ai.goal.GoalSelector; import net.minecraft.world.entity.ai.goal.WrappedGoal; import org.bukkit.craftbukkit.entity.CraftMob; @@ -18,6 +19,7 @@ public class PaperMobGoals implements MobGoals { @Override public void addGoal(T mob, int priority, Goal goal) { CraftMob craftMob = (CraftMob) mob; + TickThread.ensureTickThread(craftMob.getHandleRaw(), "Cannot add goal async"); net.minecraft.world.entity.ai.goal.Goal mojangGoal; if (goal instanceof PaperGoal paperGoal) { @@ -32,6 +34,7 @@ public void addGoal(T mob, int priority, Goal goal) { @Override public void removeGoal(T mob, Goal goal) { CraftMob craftMob = (CraftMob) mob; + TickThread.ensureTickThread(craftMob.getHandleRaw(), "Cannot remove goal async"); if (goal instanceof PaperCustomGoal) { getHandle(craftMob, goal.getTypes()).removeGoal((net.minecraft.world.entity.ai.goal.Goal) goal); } else if (goal instanceof PaperGoal) { @@ -117,6 +120,7 @@ public Collection> getAllGoals(T mob) { @Override public Collection> getAllGoals(T mob, GoalType type) { CraftMob craftMob = (CraftMob) mob; + TickThread.ensureTickThread(craftMob.getHandleRaw(), "Cannot get all goals async"); Set> goals = new HashSet<>(); for (WrappedGoal item : getHandle(craftMob, type).getAvailableGoals()) { if (!item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type))) { @@ -136,6 +140,7 @@ public Collection> getAllGoals(T mob, GoalType type) { @Override public Collection> getAllGoalsWithout(T mob, GoalType type) { CraftMob craftMob = (CraftMob) mob; + TickThread.ensureTickThread(craftMob.getHandleRaw(), "Cannot get all goals async"); Set> goals = new HashSet<>(); for (GoalType internalType : GoalType.values()) { if (internalType == type) { @@ -169,6 +174,7 @@ public Collection> getRunningGoals(T mob) { @Override public Collection> getRunningGoals(T mob, GoalType type) { CraftMob craftMob = (CraftMob) mob; + TickThread.ensureTickThread(craftMob.getHandleRaw(), "Cannot get running goals async"); Set> goals = new HashSet<>(); getHandle(craftMob, type).getAvailableGoals() .stream().filter(WrappedGoal::isRunning) @@ -187,6 +193,7 @@ public Collection> getRunningGoals(T mob, GoalType type) @Override public Collection> getRunningGoalsWithout(T mob, GoalType type) { CraftMob craftMob = (CraftMob) mob; + TickThread.ensureTickThread(craftMob.getHandleRaw(), "Cannot get running goals async"); Set> goals = new HashSet<>(); for (GoalType internalType : GoalType.values()) { if (internalType == type) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index f3f068011abd..8374855de5cb 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -2,6 +2,7 @@ import ca.spottedleaf.moonrise.common.list.ReferenceList; import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.TickThread; import com.google.common.base.Preconditions; import com.google.common.base.Predicates; import com.google.common.collect.Lists; @@ -1555,7 +1556,7 @@ public void playSound(Location loc, String sound, org.bukkit.SoundCategory categ @Override public void playSound(Location loc, Sound sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) { - org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper + TickThread.ensureTickThread(this.getHandle(), CraftLocation.toBlockPos(loc), "Cannot play sound async"); if (loc == null || sound == null || category == null) return; double x = loc.getX(); @@ -1567,7 +1568,7 @@ public void playSound(Location loc, Sound sound, org.bukkit.SoundCategory catego @Override public void playSound(Location loc, String sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) { - org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper + TickThread.ensureTickThread(this.getHandle(), CraftLocation.toBlockPos(loc), "Cannot play sound async"); if (loc == null || sound == null || category == null) return; double x = loc.getX(); @@ -1590,8 +1591,8 @@ public void playSound(Entity entity, String sound, org.bukkit.SoundCategory cate @Override public void playSound(Entity entity, Sound sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) { - org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper if (!(entity instanceof CraftEntity craftEntity) || entity.getWorld() != this || sound == null || category == null) return; + TickThread.ensureTickThread(craftEntity.getHandleRaw(), "Cannot play sound async"); ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(CraftSound.bukkitToMinecraftHolder(sound), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed); ChunkMap.TrackedEntity entityTracker = this.getHandle().getChunkSource().chunkMap.entityMap.get(entity.getEntityId()); @@ -1611,8 +1612,8 @@ public void playSound(final net.kyori.adventure.sound.Sound sound) { @Override public void playSound(Entity entity, String sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) { - org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper if (!(entity instanceof CraftEntity craftEntity) || entity.getWorld() != this || sound == null || category == null) return; + TickThread.ensureTickThread(craftEntity.getHandleRaw(), "Cannot play sound async"); ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(Holder.direct(SoundEvent.createVariableRangeEvent(Identifier.parse(sound))), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed); ChunkMap.TrackedEntity entityTracker = this.getHandle().getChunkSource().chunkMap.entityMap.get(entity.getEntityId()); @@ -1623,7 +1624,7 @@ public void playSound(Entity entity, String sound, org.bukkit.SoundCategory cate @Override public void playSound(final net.kyori.adventure.sound.Sound sound, final double x, final double y, final double z) { - org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper + TickThread.ensureTickThread(this.getHandle(), Mth.floor(x) >> 4, Mth.floor(z) >> 4, "Cannot play sound async"); io.papermc.paper.adventure.PaperAdventure.asSoundPacket(sound, x, y, z, sound.seed().orElseGet(this.world.getRandom()::nextLong), this.playSound0(x, y, z)); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index e45f9514e4b5..648dc520a0c3 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.entity; +import ca.spottedleaf.moonrise.common.util.TickThread; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.base.Predicates; @@ -371,7 +372,7 @@ public static LookAnchor toApiAnchor(net.minecraft.commands.arguments.EntityAnch @Override public List getNearbyEntities(double x, double y, double z) { Preconditions.checkState(!this.entity.generation, "Cannot get nearby entities during world generation"); - org.spigotmc.AsyncCatcher.catchOp("getNearbyEntities"); // Spigot + TickThread.ensureTickThread(this.entity, "Cannot get nearby entities async"); List entities = this.getHandle().level().getEntities(this.entity, this.entity.getBoundingBox().inflate(x, y, z), Predicates.alwaysTrue()); List result = new java.util.ArrayList<>(entities.size()); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java index 2aea80487ff1..d54deaa9f12d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.entity; +import ca.spottedleaf.moonrise.common.util.TickThread; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; import io.papermc.paper.adventure.PaperAdventure; @@ -326,6 +327,7 @@ public InventoryView getOpenInventory() { @Override public InventoryView openInventory(Inventory inventory) { if (!(this.getHandle() instanceof ServerPlayer)) return null; + TickThread.ensureTickThread(this.entity, "Cannot open inventory async"); ServerPlayer player = (ServerPlayer) this.getHandle(); AbstractContainerMenu formerContainer = this.getHandle().containerMenu; @@ -445,6 +447,7 @@ public void openInventory(InventoryView inventory) { Preconditions.checkArgument(this.equals(inventory.getPlayer()), "InventoryView must belong to the opening player"); if (!(this.getHandle() instanceof ServerPlayer)) return; // TODO: NPC support? if (((ServerPlayer) this.getHandle()).connection == null) return; + TickThread.ensureTickThread(this.entity, "Cannot open inventory view async"); if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) { // fire INVENTORY_CLOSE if one already open ((ServerPlayer) this.getHandle()).connection.handleContainerClose(new ServerboundContainerClosePacket(this.getHandle().containerMenu.containerId), org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper - Inventory close reason @@ -501,6 +504,10 @@ private static int getMountInventoryColumns(final AbstractMountInventoryMenu mou @Override public InventoryView openMerchant(Merchant merchant, boolean force) { Preconditions.checkNotNull(merchant, "merchant cannot be null"); + if (merchant instanceof CraftEntity craftEntity) { + TickThread.ensureTickThread(craftEntity.entity, "Cannot open merchant screen async from merchant"); + } + TickThread.ensureTickThread(this.entity, "Cannot open merchant screen async"); if (!force && merchant.isTrading()) { return null; @@ -562,7 +569,7 @@ public InventoryView openStonecutter(Location location, boolean force) { } private InventoryView openInventory(Location location, boolean force, Material material) { - org.spigotmc.AsyncCatcher.catchOp("open" + material); + TickThread.ensureTickThread(this.entity, "Cannot open " + material + " inventory async"); if (location == null) { location = this.getLocation(); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java index 6b6b0051af41..e558a55086d9 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.entity; +import ca.spottedleaf.moonrise.common.util.TickThread; import com.google.common.base.Preconditions; import com.google.common.collect.Sets; import io.papermc.paper.adventure.PaperAdventure; @@ -505,7 +506,7 @@ public void setKiller(Player killer) { @Override public boolean addPotionEffect(PotionEffect effect) { - org.spigotmc.AsyncCatcher.catchOp("effect add"); // Paper + TickThread.ensureTickThread(this.entity, "Cannot add potion effect async"); return this.getHandle().addEffect(org.bukkit.craftbukkit.potion.CraftPotionUtil.fromBukkit(effect), EntityPotionEffectEvent.Cause.PLUGIN); // Paper - Don't ignore icon } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index ad51146ef274..d5db087f31b7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.entity; +import ca.spottedleaf.moonrise.common.util.TickThread; import com.destroystokyo.paper.event.player.PlayerSetSpawnEvent; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -1339,6 +1340,7 @@ public void setSprinting(boolean sprinting) { @Override public void loadData() { + TickThread.ensureTickThread(this.entity, "Cannot load data async"); this.server.getHandle().playerIo.load(this.getHandle().nameAndId()) .map(tag -> TagValueInput.create(ProblemReporter.DISCARDING, this.server.getServer().registryAccess(), tag)) .ifPresent(this.getHandle()::load); @@ -1346,6 +1348,7 @@ public void loadData() { @Override public void saveData() { + TickThread.ensureTickThread(this.entity, "Cannot save data async"); this.server.getHandle().playerIo.save(this.getHandle()); } @@ -1662,6 +1665,7 @@ public void setGameMode(GameMode mode) { Preconditions.checkArgument(mode != null, "GameMode cannot be null"); if (this.getHandle().connection == null) return; + TickThread.ensureTickThread(this.entity, "Cannot set gamemode async"); this.getHandle().setGameMode(GameType.byId(mode.getValue()), org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.PLUGIN, null); // Paper - Expand PlayerGameModeChangeEvent }