diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 9d0d61a726..e569cfff87 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -881,7 +881,7 @@ return true; } else { -@@ -1147,23 +1604,90 @@ +@@ -1147,23 +1604,91 @@ } public void teleport(double x, double y, double z, float yaw, float pitch) { @@ -933,6 +933,7 @@ + } + + public void internalTeleport(PositionMoveRotation positionmoverotation, Set set) { ++ org.spigotmc.AsyncCatcher.catchOp("teleport"); // Paper + // Paper start - Prevent teleporting dead entities + if (player.isRemoved()) { + LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName()); @@ -975,7 +976,7 @@ if (this.player.hasClientLoaded()) { BlockPos blockposition = packet.getPos(); -@@ -1175,14 +1699,46 @@ +@@ -1175,14 +1700,46 @@ if (!this.player.isSpectator()) { ItemStack itemstack = this.player.getItemInHand(InteractionHand.OFF_HAND); @@ -1024,7 +1025,7 @@ this.player.drop(false); } -@@ -1199,6 +1755,12 @@ +@@ -1199,6 +1756,12 @@ case START_DESTROY_BLOCK: case ABORT_DESTROY_BLOCK: case STOP_DESTROY_BLOCK: @@ -1037,7 +1038,7 @@ this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level().getMaxY(), packet.getSequence()); this.player.connection.ackBlockChangesUpTo(packet.getSequence()); return; -@@ -1218,9 +1780,31 @@ +@@ -1218,9 +1781,31 @@ } } @@ -1069,7 +1070,7 @@ if (this.player.hasClientLoaded()) { this.player.connection.ackBlockChangesUpTo(packet.getSequence()); ServerLevel worldserver = this.player.serverLevel(); -@@ -1230,6 +1814,11 @@ +@@ -1230,6 +1815,11 @@ if (itemstack.isItemEnabled(worldserver.enabledFeatures())) { BlockHitResult movingobjectpositionblock = packet.getHitResult(); Vec3 vec3d = movingobjectpositionblock.getLocation(); @@ -1081,7 +1082,7 @@ BlockPos blockposition = movingobjectpositionblock.getBlockPos(); if (this.player.canInteractWithBlock(blockposition, 1.0D)) { -@@ -1243,7 +1832,8 @@ +@@ -1243,7 +1833,8 @@ int i = this.player.level().getMaxY(); if (blockposition.getY() <= i) { @@ -1091,7 +1092,7 @@ InteractionResult enuminteractionresult = this.player.gameMode.useItemOn(this.player, worldserver, itemstack, enumhand, movingobjectpositionblock); if (enuminteractionresult.consumesAction()) { -@@ -1257,7 +1847,7 @@ +@@ -1257,7 +1848,7 @@ } else if (enuminteractionresult instanceof InteractionResult.Success) { InteractionResult.Success enuminteractionresult_d = (InteractionResult.Success) enuminteractionresult; @@ -1100,7 +1101,7 @@ this.player.swing(enumhand, true); } } -@@ -1281,6 +1871,8 @@ +@@ -1281,6 +1872,8 @@ @Override public void handleUseItem(ServerboundUseItemPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -1109,12 +1110,10 @@ if (this.player.hasClientLoaded()) { this.ackBlockChangesUpTo(packet.getSequence()); ServerLevel worldserver = this.player.serverLevel(); -@@ -1294,8 +1886,49 @@ - - if (f1 != this.player.getXRot() || f != this.player.getYRot()) { +@@ -1296,6 +1889,47 @@ this.player.absRotateTo(f, f1); -+ } -+ + } + + // CraftBukkit start + // Raytrace to look for 'rogue armswings' + double d0 = this.player.getX(); @@ -1145,8 +1144,8 @@ + cancelled = event.useItemInHand() == Event.Result.DENY; + } + this.player.gameMode.firedInteract = false; - } - ++ } ++ + if (cancelled) { + this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524 + return; @@ -1159,7 +1158,7 @@ InteractionResult enuminteractionresult = this.player.gameMode.useItem(this.player, worldserver, itemstack, enumhand); if (enuminteractionresult instanceof InteractionResult.Success) { -@@ -1321,7 +1954,7 @@ +@@ -1321,7 +1955,7 @@ Entity entity = packet.getEntity(worldserver); if (entity != null) { @@ -1168,7 +1167,7 @@ return; } } -@@ -1342,17 +1975,46 @@ +@@ -1342,17 +1976,46 @@ @Override public void onDisconnect(DisconnectionDetails info) { @@ -1219,7 +1218,7 @@ this.player.getTextFilter().leave(); } -@@ -1367,7 +2029,17 @@ +@@ -1367,7 +2030,17 @@ @Override public void handleSetCarriedItem(ServerboundSetCarriedItemPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -1237,7 +1236,7 @@ if (this.player.getInventory().selected != packet.getSlot() && this.player.getUsedItemHand() == InteractionHand.MAIN_HAND) { this.player.stopUsingItem(); } -@@ -1376,11 +2048,18 @@ +@@ -1376,11 +2049,18 @@ this.player.resetLastActionTime(); } else { ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); @@ -1256,7 +1255,7 @@ Optional optional = this.unpackAndApplyLastSeen(packet.lastSeenMessages()); if (!optional.isEmpty()) { -@@ -1394,27 +2073,44 @@ +@@ -1394,27 +2074,44 @@ return; } @@ -1308,7 +1307,7 @@ ParseResults parseresults = this.parseCommand(command); if (this.server.enforceSecureProfile() && SignableCommand.hasSignableArguments(parseresults)) { -@@ -1431,19 +2127,37 @@ +@@ -1431,19 +2128,37 @@ if (!optional.isEmpty()) { this.tryHandleChat(packet.command(), () -> { @@ -1350,7 +1349,7 @@ } catch (SignedMessageChain.DecodeException signedmessagechain_a) { this.handleMessageDecodeFailure(signedmessagechain_a); return; -@@ -1451,10 +2165,10 @@ +@@ -1451,10 +2166,10 @@ CommandSigningContext.SignedArguments commandsigningcontext_a = new CommandSigningContext.SignedArguments(map); @@ -1363,7 +1362,7 @@ } private void handleMessageDecodeFailure(SignedMessageChain.DecodeException exception) { -@@ -1530,14 +2244,20 @@ +@@ -1530,14 +2245,20 @@ return com_mojang_brigadier_commanddispatcher.parse(command, this.player.createCommandSourceStack()); } @@ -1389,7 +1388,7 @@ } } -@@ -1549,7 +2269,7 @@ +@@ -1549,7 +2270,7 @@ if (optional.isEmpty()) { ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); @@ -1398,7 +1397,7 @@ } return optional; -@@ -1566,6 +2286,127 @@ +@@ -1566,6 +2287,127 @@ return false; } @@ -1526,7 +1525,7 @@ private PlayerChatMessage getSignedMessage(ServerboundChatPacket packet, LastSeenMessages lastSeenMessages) throws SignedMessageChain.DecodeException { SignedMessageBody signedmessagebody = new SignedMessageBody(packet.message(), packet.timeStamp(), packet.salt(), lastSeenMessages); -@@ -1573,15 +2414,44 @@ +@@ -1573,15 +2415,44 @@ } private void broadcastChatMessage(PlayerChatMessage message) { @@ -1577,7 +1576,7 @@ } -@@ -1592,7 +2462,7 @@ +@@ -1592,7 +2463,7 @@ synchronized (this.lastSeenMessages) { if (!this.lastSeenMessages.applyOffset(packet.offset())) { ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); @@ -1586,7 +1585,7 @@ } } -@@ -1601,7 +2471,40 @@ +@@ -1601,7 +2472,40 @@ @Override public void handleAnimate(ServerboundSwingPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -1627,7 +1626,7 @@ this.player.swing(packet.getHand()); } -@@ -1609,6 +2512,29 @@ +@@ -1609,6 +2513,29 @@ public void handlePlayerCommand(ServerboundPlayerCommandPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (this.player.hasClientLoaded()) { @@ -1657,7 +1656,7 @@ this.player.resetLastActionTime(); Entity entity; PlayerRideableJumping ijumpable; -@@ -1616,6 +2542,11 @@ +@@ -1616,6 +2543,11 @@ switch (packet.getAction()) { case PRESS_SHIFT_KEY: this.player.setShiftKeyDown(true); @@ -1669,7 +1668,7 @@ break; case RELEASE_SHIFT_KEY: this.player.setShiftKeyDown(false); -@@ -1684,13 +2615,19 @@ +@@ -1684,13 +2616,19 @@ } if (i > 4096) { @@ -1690,7 +1689,7 @@ this.send(new ClientboundPlayerChatPacket(message.link().sender(), message.link().index(), message.signature(), message.signedBody().pack(this.messageSignatureCache), message.unsignedContent(), message.filterMask(), params)); this.addPendingMessage(message); } -@@ -1703,6 +2640,18 @@ +@@ -1703,6 +2641,18 @@ return this.connection.getRemoteAddress(); } @@ -1709,7 +1708,7 @@ public void switchToConfig() { this.waitingForSwitchToConfig = true; this.removePlayerFromWorld(); -@@ -1718,9 +2667,17 @@ +@@ -1718,9 +2668,17 @@ @Override public void handleInteract(ServerboundInteractPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -1727,7 +1726,7 @@ this.player.resetLastActionTime(); this.player.setShiftKeyDown(packet.isUsingSecondaryAction()); -@@ -1733,20 +2690,58 @@ +@@ -1733,20 +2691,58 @@ if (this.player.canInteractWithEntity(axisalignedbb, 3.0D)) { packet.dispatch(new ServerboundInteractPacket.Handler() { @@ -1790,7 +1789,7 @@ } } -@@ -1755,19 +2750,20 @@ +@@ -1755,19 +2751,20 @@ @Override public void onInteraction(InteractionHand hand) { @@ -1814,7 +1813,7 @@ label23: { if (entity instanceof AbstractArrow) { -@@ -1785,17 +2781,41 @@ +@@ -1785,17 +2782,41 @@ } ServerGamePacketListenerImpl.this.player.attack(entity); @@ -1857,7 +1856,7 @@ } } -@@ -1809,7 +2829,7 @@ +@@ -1809,7 +2830,7 @@ case PERFORM_RESPAWN: if (this.player.wonGame) { this.player.wonGame = false; @@ -1866,7 +1865,7 @@ this.resetPosition(); CriteriaTriggers.CHANGED_DIMENSION.trigger(this.player, Level.END, Level.OVERWORLD); } else { -@@ -1817,11 +2837,11 @@ +@@ -1817,11 +2838,11 @@ return; } @@ -1881,7 +1880,7 @@ } } break; -@@ -1833,16 +2853,27 @@ +@@ -1833,16 +2854,27 @@ @Override public void handleContainerClose(ServerboundContainerClosePacket packet) { @@ -1911,7 +1910,7 @@ this.player.containerMenu.sendAllDataToRemote(); } else if (!this.player.containerMenu.stillValid(this.player)) { ServerGamePacketListenerImpl.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu); -@@ -1855,7 +2886,284 @@ +@@ -1855,7 +2887,284 @@ boolean flag = packet.getStateId() != this.player.containerMenu.getStateId(); this.player.containerMenu.suppressRemoteUpdates(); @@ -2197,7 +2196,7 @@ ObjectIterator objectiterator = Int2ObjectMaps.fastIterable(packet.getChangedSlots()).iterator(); while (objectiterator.hasNext()) { -@@ -1879,6 +3187,14 @@ +@@ -1879,6 +3188,14 @@ @Override public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) { @@ -2212,7 +2211,7 @@ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); this.player.resetLastActionTime(); if (!this.player.isSpectator() && this.player.containerMenu.containerId == packet.containerId()) { -@@ -1900,9 +3216,43 @@ +@@ -1900,9 +3217,43 @@ ServerGamePacketListenerImpl.LOGGER.debug("Player {} tried to place impossible recipe {}", this.player, recipeholder.id().location()); return; } @@ -2257,7 +2256,7 @@ if (containerrecipebook_a == RecipeBookMenu.PostPlaceAction.PLACE_GHOST_RECIPE) { this.player.connection.send(new ClientboundPlaceGhostRecipePacket(this.player.containerMenu.containerId, craftingmanager_d.display().display())); } -@@ -1917,6 +3267,7 @@ +@@ -1917,6 +3268,7 @@ @Override public void handleContainerButtonClick(ServerboundContainerButtonClickPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -2265,7 +2264,7 @@ this.player.resetLastActionTime(); if (this.player.containerMenu.containerId == packet.containerId() && !this.player.isSpectator()) { if (!this.player.containerMenu.stillValid(this.player)) { -@@ -1945,7 +3296,44 @@ +@@ -1945,7 +3297,44 @@ boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45; boolean flag2 = itemstack.isEmpty() || itemstack.getCount() <= itemstack.getMaxStackSize(); @@ -2310,7 +2309,7 @@ if (flag1 && flag2) { this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemstack); this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemstack); -@@ -1964,7 +3352,19 @@ +@@ -1964,7 +3353,19 @@ @Override public void handleSignUpdate(ServerboundSignUpdatePacket packet) { @@ -2331,7 +2330,7 @@ this.filterTextPacket(list).thenAcceptAsync((list1) -> { this.updateSignText(packet, list1); -@@ -1972,6 +3372,7 @@ +@@ -1972,6 +3373,7 @@ } private void updateSignText(ServerboundSignUpdatePacket packet, List signText) { @@ -2339,7 +2338,7 @@ this.player.resetLastActionTime(); ServerLevel worldserver = this.player.serverLevel(); BlockPos blockposition = packet.getPos(); -@@ -1993,15 +3394,33 @@ +@@ -1993,15 +3395,33 @@ @Override public void handlePlayerAbilities(ServerboundPlayerAbilitiesPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -2374,7 +2373,7 @@ if (this.player.isModelPartShown(PlayerModelPart.HAT) != flag) { this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT, this.player)); } -@@ -2012,7 +3431,7 @@ +@@ -2012,7 +3432,7 @@ public void handleChangeDifficulty(ServerboundChangeDifficultyPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (this.player.hasPermissions(2) || this.isSingleplayerOwner()) { @@ -2383,7 +2382,7 @@ } } -@@ -2033,7 +3452,7 @@ +@@ -2033,7 +3453,7 @@ if (!Objects.equals(profilepublickey_a, profilepublickey_a1)) { if (profilepublickey_a != null && profilepublickey_a1.expiresAt().isBefore(profilepublickey_a.expiresAt())) { @@ -2392,7 +2391,7 @@ } else { try { SignatureValidator signaturevalidator = this.server.getProfileKeySignatureValidator(); -@@ -2046,7 +3465,7 @@ +@@ -2046,7 +3466,7 @@ this.resetPlayerChatState(remotechatsession_a.validate(this.player.getGameProfile(), signaturevalidator)); } catch (ProfilePublicKey.ValidationException profilepublickey_b) { ServerGamePacketListenerImpl.LOGGER.error("Failed to validate profile key: {}", profilepublickey_b.getMessage()); @@ -2401,7 +2400,7 @@ } } -@@ -2058,7 +3477,7 @@ +@@ -2058,7 +3478,7 @@ if (!this.waitingForSwitchToConfig) { throw new IllegalStateException("Client acknowledged config, but none was requested"); } else { @@ -2410,7 +2409,7 @@ } } -@@ -2083,8 +3502,10 @@ +@@ -2083,8 +3503,10 @@ }); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch index 71db951715..d47e040538 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch @@ -398,7 +398,7 @@ + } + + 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/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch b/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch index 3599ce9b84..68a70b169a 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch @@ -32,10 +32,19 @@ void removeSectionIfEmpty(long sectionPos, EntitySection section) { if (section.isEmpty()) { this.sectionStorage.remove(sectionPos); -@@ -76,6 +91,16 @@ +@@ -63,6 +78,7 @@ + } + + 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; +@@ -76,6 +92,17 @@ } private boolean addEntity(T entity, boolean existing) { ++ org.spigotmc.AsyncCatcher.catchOp("Entity add"); // Paper + // Paper start - chunk system hooks + // I don't want to know why this is a generic type. + Entity entityCasted = (Entity)entity; @@ -49,7 +58,47 @@ if (!this.addEntityUuid(entity)) { return false; } else { -@@ -196,27 +221,35 @@ +@@ -119,19 +146,23 @@ + } + + 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); + } +@@ -143,6 +174,7 @@ + } + + public void updateChunkStatus(ChunkPos chunkPos, Visibility trackingStatus) { ++ org.spigotmc.AsyncCatcher.catchOp("Update chunk status"); // Paper + long i = chunkPos.toLong(); + + if (trackingStatus == Visibility.HIDDEN) { +@@ -187,6 +219,7 @@ + } + + 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) { +@@ -196,33 +229,42 @@ } private boolean storeChunkSections(long chunkPos, Consumer action) { @@ -91,8 +140,18 @@ return true; } } -@@ -238,7 +271,7 @@ + } + + 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); +@@ -236,9 +278,10 @@ + } + 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); - }); @@ -100,7 +159,7 @@ if (!flag) { return false; -@@ -249,24 +282,28 @@ +@@ -249,29 +292,35 @@ } private void unloadEntity(EntityAccess entity) { @@ -118,6 +177,7 @@ private void processPendingLoads() { - ChunkEntities chunkentities; ++ org.spigotmc.AsyncCatcher.catchOp("Entity chunk process pending loads"); // Paper + ChunkEntities chunkentities; // CraftBukkit - decompile error while ((chunkentities = (ChunkEntities) this.loadingInbox.poll()) != null) { @@ -132,16 +192,29 @@ } } -@@ -292,7 +329,7 @@ + + public void tick() { ++ org.spigotmc.AsyncCatcher.catchOp("Entity manager tick"); // Paper + this.processPendingLoads(); + this.processUnloads(); + } +@@ -292,7 +341,8 @@ } public void autoSave() { - this.getAllChunksToSave().forEach((i) -> { ++ 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; if (flag) { -@@ -311,7 +348,7 @@ +@@ -306,12 +356,13 @@ + } + + public void saveAll() { ++ org.spigotmc.AsyncCatcher.catchOp("Entity manager save"); // Paper + LongSet longset = this.getAllChunksToSave(); + while (!longset.isEmpty()) { this.permanentStorage.flush(false); this.processPendingLoads(); @@ -150,7 +223,7 @@ boolean flag = this.chunkVisibility.get(i) == Visibility.HIDDEN; return flag ? this.processChunkUnload(i) : this.storeChunkSections(i, (entityaccess) -> { -@@ -323,7 +360,15 @@ +@@ -323,7 +374,15 @@ } public void close() throws IOException { @@ -167,7 +240,7 @@ this.permanentStorage.close(); } -@@ -350,7 +395,7 @@ +@@ -350,7 +409,7 @@ public void dumpSections(Writer writer) throws IOException { CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("y").addColumn("z").addColumn("visibility").addColumn("load_status").addColumn("entity_count").build(writer); @@ -176,7 +249,7 @@ PersistentEntitySectionManager.ChunkLoadStatus persistententitysectionmanager_b = (PersistentEntitySectionManager.ChunkLoadStatus) this.chunkLoadStatuses.get(i); this.sectionStorage.getExistingSectionPositionsInChunk(i).forEach((j) -> { -@@ -394,7 +439,7 @@ +@@ -394,7 +453,7 @@ private EntitySection currentSection; Callback(final EntityAccess entityaccess, final long i, final EntitySection entitysection) { @@ -185,3 +258,19 @@ this.currentSectionKey = i; this.currentSection = entitysection; } +@@ -405,6 +464,7 @@ + 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)) { +@@ -459,6 +519,7 @@ + + @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/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index d650822155..0ab6a9496e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1755,6 +1755,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @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 if (loc == null || sound == null || category == null) return; double x = loc.getX(); @@ -1766,6 +1767,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @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 if (loc == null || sound == null || category == null) return; double x = loc.getX(); @@ -1798,6 +1800,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @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; ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(CraftSound.bukkitToMinecraftHolder(sound), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed); @@ -1818,6 +1821,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @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; ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(Holder.direct(SoundEvent.createVariableRangeEvent(ResourceLocation.parse(sound))), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed); 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 5d6e4f2aec..10a95c1a40 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 @@ -534,6 +534,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(org.bukkit.craftbukkit.potion.CraftPotionUtil.fromBukkit(effect), EntityPotionEffectEvent.Cause.PLUGIN); // Paper - Don't ignore icon return true; } diff --git a/paper-server/src/main/java/org/spigotmc/AsyncCatcher.java b/paper-server/src/main/java/org/spigotmc/AsyncCatcher.java index bbf0d9d9c4..ef25987604 100644 --- a/paper-server/src/main/java/org/spigotmc/AsyncCatcher.java +++ b/paper-server/src/main/java/org/spigotmc/AsyncCatcher.java @@ -11,6 +11,7 @@ public class AsyncCatcher { if ( AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread ) { + MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); // Paper throw new IllegalStateException( "Asynchronous " + reason + "!" ); } }