From 7dcff24771de86d2db8fa0e8caf86b319ad1e4c9 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Wed, 23 Aug 2023 13:22:09 -0700 Subject: [PATCH] Fix slot desync General patch fixing slot desyncs between the server and client that result from cancelled events/paper introduced logic. Co-authored-by: Minecrell Co-authored-by: Newwind --- .../server/level/ServerPlayer.java.patch | 147 +++++++++--------- .../ServerGamePacketListenerImpl.java.patch | 56 +++---- .../minecraft/world/entity/Entity.java.patch | 87 ++++++----- .../world/entity/animal/Cow.java.patch | 3 +- .../world/entity/animal/goat/Goat.java.patch | 7 +- .../world/item/ArmorStandItem.java.patch | 3 +- .../minecraft/world/item/BlockItem.java.patch | 2 +- .../world/item/EndCrystalItem.java.patch | 3 +- .../world/item/MinecartItem.java.patch | 3 +- 9 files changed, 159 insertions(+), 152 deletions(-) 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 b9501d8e28..fcd76b0f15 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 @@ -214,7 +214,7 @@ }; this.textFilter = server.createTextFilterForPlayer(this); this.gameMode = server.createGameModeForPlayer(this); -@@ -349,17 +445,71 @@ +@@ -349,17 +445,72 @@ this.server = server; this.stats = server.getPlayerList().getPlayerStats(this); this.advancements = server.getPlayerList().getPlayerAdvancements(this); @@ -233,6 +233,7 @@ + // Use method to resend items in hands in case of client desync, because the item use got cancelled. + // For example, when cancelling the leash event ++ @Deprecated // Paper - this shouldn't be used, use the regular sendAllDataToRemote call to resync all + public void resendItemInHands() { + this.containerMenu.findSlot(this.getInventory(), this.getInventory().selected).ifPresent(s -> { + this.containerSynchronizer.sendSlotChange(this.containerMenu, s, this.getMainHandItem()); @@ -289,7 +290,7 @@ int i = Math.max(0, this.server.getSpawnRadius(world)); int j = Mth.floor(world.getWorldBorder().getDistanceToBorder((double) basePos.getX(), (double) basePos.getZ())); -@@ -395,14 +545,20 @@ +@@ -395,14 +546,20 @@ Objects.requireNonNull(basePos); crashreportsystemdetails.setDetail("Origin", basePos::toString); @@ -312,7 +313,7 @@ }); throw new ReportedException(crashreport); } -@@ -440,7 +596,7 @@ +@@ -440,7 +597,7 @@ dataresult = WardenSpawnTracker.CODEC.parse(new Dynamic(NbtOps.INSTANCE, nbt.get("warden_spawn_tracker"))); logger = ServerPlayer.LOGGER; Objects.requireNonNull(logger); @@ -321,7 +322,7 @@ this.wardenSpawnTracker = wardenspawntracker; }); } -@@ -457,17 +613,26 @@ +@@ -457,17 +614,26 @@ return this.server.getRecipeManager().byKey(resourcekey).isPresent(); }); } @@ -349,7 +350,7 @@ Logger logger1 = ServerPlayer.LOGGER; Objects.requireNonNull(logger1); -@@ -482,7 +647,7 @@ +@@ -482,7 +648,7 @@ dataresult = BlockPos.CODEC.parse(NbtOps.INSTANCE, nbtbase); logger = ServerPlayer.LOGGER; Objects.requireNonNull(logger); @@ -358,7 +359,7 @@ this.raidOmenPosition = blockposition; }); } -@@ -492,7 +657,7 @@ +@@ -492,7 +658,7 @@ @Override public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); @@ -367,7 +368,7 @@ Logger logger = ServerPlayer.LOGGER; Objects.requireNonNull(logger); -@@ -526,6 +691,7 @@ +@@ -526,6 +692,7 @@ nbt.put("SpawnDimension", nbtbase); }); } @@ -375,7 +376,7 @@ nbt.putBoolean("spawn_extra_particles_on_fall", this.spawnExtraParticlesOnFall); if (this.raidOmenPosition != null) { -@@ -544,7 +710,20 @@ +@@ -544,7 +711,20 @@ Entity entity = this.getRootVehicle(); Entity entity1 = this.getVehicle(); @@ -397,7 +398,7 @@ CompoundTag nbttagcompound1 = new CompoundTag(); CompoundTag nbttagcompound2 = new CompoundTag(); -@@ -564,7 +743,7 @@ +@@ -564,7 +744,7 @@ ServerLevel worldserver = (ServerLevel) world; CompoundTag nbttagcompound = ((CompoundTag) nbt.get()).getCompound("RootVehicle"); Entity entity = EntityType.loadEntityRecursive(nbttagcompound.getCompound("Entity"), worldserver, EntitySpawnReason.LOAD, (entity1) -> { @@ -406,7 +407,7 @@ }); if (entity == null) { -@@ -598,12 +777,12 @@ +@@ -598,12 +778,12 @@ if (!this.isPassenger()) { ServerPlayer.LOGGER.warn("Couldn't reattach entity to player"); @@ -421,7 +422,7 @@ } } } -@@ -625,7 +804,7 @@ +@@ -625,7 +805,7 @@ CompoundTag nbttagcompound1 = new CompoundTag(); entityenderpearl.save(nbttagcompound1); @@ -430,7 +431,7 @@ Logger logger = ServerPlayer.LOGGER; Objects.requireNonNull(logger); -@@ -651,7 +830,7 @@ +@@ -651,7 +831,7 @@ nbttaglist.forEach((nbtbase1) -> { if (nbtbase1 instanceof CompoundTag nbttagcompound) { if (nbttagcompound.contains("ender_pearl_dimension")) { @@ -439,7 +440,7 @@ Logger logger = ServerPlayer.LOGGER; Objects.requireNonNull(logger); -@@ -684,7 +863,30 @@ +@@ -684,7 +864,30 @@ } } @@ -470,7 +471,7 @@ public void setExperiencePoints(int points) { float f = (float) this.getXpNeededForNextLevel(); -@@ -744,6 +946,11 @@ +@@ -744,6 +947,11 @@ @Override public void tick() { @@ -482,7 +483,7 @@ this.tickClientLoadTimeout(); this.gameMode.tick(); this.wardenSpawnTracker.tick(); -@@ -751,9 +958,13 @@ +@@ -751,9 +959,13 @@ --this.invulnerableTime; } @@ -499,7 +500,7 @@ this.containerMenu = this.inventoryMenu; } -@@ -807,7 +1018,7 @@ +@@ -807,7 +1019,7 @@ public void doTick() { try { @@ -508,7 +509,7 @@ super.tick(); } -@@ -820,7 +1031,7 @@ +@@ -820,7 +1032,7 @@ } if (this.getHealth() != this.lastSentHealth || this.lastSentFood != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0F != this.lastFoodSaturationZero) { @@ -517,7 +518,7 @@ this.lastSentHealth = this.getHealth(); this.lastSentFood = this.foodData.getFoodLevel(); this.lastFoodSaturationZero = this.foodData.getSaturationLevel() == 0.0F; -@@ -851,6 +1062,12 @@ +@@ -851,6 +1063,12 @@ this.updateScoreForCriteria(ObjectiveCriteria.EXPERIENCE, Mth.ceil((float) this.lastRecordedExperience)); } @@ -530,17 +531,15 @@ if (this.experienceLevel != this.lastRecordedLevel) { this.lastRecordedLevel = this.experienceLevel; this.updateScoreForCriteria(ObjectiveCriteria.LEVEL, Mth.ceil((float) this.lastRecordedLevel)); -@@ -863,8 +1080,22 @@ - - if (this.tickCount % 20 == 0) { +@@ -865,6 +1083,20 @@ CriteriaTriggers.LOCATION.trigger(this); -+ } -+ + } + + // CraftBukkit start - initialize oldLevel, fire PlayerLevelChangeEvent, and tick client-sided world border + if (this.oldLevel == -1) { + this.oldLevel = this.experienceLevel; - } - ++ } ++ + if (this.oldLevel != this.experienceLevel) { + CraftEventFactory.callPlayerLevelChangeEvent(this.getBukkitEntity(), this.oldLevel, this.experienceLevel); + this.oldLevel = this.experienceLevel; @@ -553,7 +552,7 @@ } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking player"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Player being ticked"); -@@ -893,7 +1124,7 @@ +@@ -893,7 +1125,7 @@ if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.serverLevel().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION)) { if (this.tickCount % 20 == 0) { if (this.getHealth() < this.getMaxHealth()) { @@ -562,7 +561,7 @@ } float f = this.foodData.getSaturationLevel(); -@@ -946,19 +1177,105 @@ +@@ -946,19 +1178,105 @@ } private void updateScoreForCriteria(ObjectiveCriteria criterion, int score) { @@ -672,7 +671,7 @@ this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), ichatbasecomponent), PacketSendListener.exceptionallySend(() -> { boolean flag1 = true; String s = ichatbasecomponent.getString(256); -@@ -988,12 +1305,23 @@ +@@ -988,12 +1306,23 @@ if (this.serverLevel().getGameRules().getBoolean(GameRules.RULE_FORGIVE_DEAD_PLAYERS)) { this.tellNeutralMobsThatIDied(); } @@ -700,7 +699,7 @@ LivingEntity entityliving = this.getKillCredit(); if (entityliving != null) { -@@ -1028,10 +1356,12 @@ +@@ -1028,10 +1357,12 @@ public void awardKillScore(Entity entityKilled, DamageSource damageSource) { if (entityKilled != this) { super.awardKillScore(entityKilled, damageSource); @@ -716,7 +715,7 @@ } else { this.awardStat(Stats.MOB_KILLS); } -@@ -1049,7 +1379,8 @@ +@@ -1049,7 +1380,8 @@ int i = scoreboardteam.getColor().getId(); if (i >= 0 && i < criterions.length) { @@ -726,7 +725,7 @@ } } -@@ -1062,8 +1393,8 @@ +@@ -1062,8 +1394,8 @@ } else { Entity entity = source.getEntity(); @@ -737,7 +736,7 @@ if (!this.canHarmPlayer(entityhuman)) { return false; -@@ -1074,8 +1405,8 @@ +@@ -1074,8 +1406,8 @@ AbstractArrow entityarrow = (AbstractArrow) entity; Entity entity1 = entityarrow.getOwner(); @@ -748,7 +747,7 @@ if (!this.canHarmPlayer(entityhuman1)) { return false; -@@ -1083,38 +1414,84 @@ +@@ -1083,38 +1415,84 @@ } } @@ -841,7 +840,7 @@ } public static Optional findRespawnAndUseSpawnBlock(ServerLevel world, BlockPos pos, float spawnAngle, boolean spawnForced, boolean alive) { -@@ -1129,11 +1506,11 @@ +@@ -1129,11 +1507,11 @@ } return optional.map((vec3d) -> { @@ -855,7 +854,7 @@ }); } else if (!spawnForced) { return Optional.empty(); -@@ -1142,7 +1519,7 @@ +@@ -1142,7 +1520,7 @@ BlockState iblockdata1 = world.getBlockState(pos.above()); boolean flag3 = iblockdata1.getBlock().isPossibleToRespawnInThis(iblockdata1); @@ -864,7 +863,7 @@ } } -@@ -1160,6 +1537,7 @@ +@@ -1160,6 +1538,7 @@ @Nullable @Override public ServerPlayer teleport(TeleportTransition teleportTarget) { @@ -872,7 +871,7 @@ if (this.isRemoved()) { return null; } else { -@@ -1169,39 +1547,78 @@ +@@ -1169,39 +1548,78 @@ ServerLevel worldserver = teleportTarget.newLevel(); ServerLevel worldserver1 = this.serverLevel(); @@ -959,7 +958,7 @@ this.connection.resetPosition(); worldserver.addDuringTeleport(this); gameprofilerfiller.pop(); -@@ -1215,12 +1632,35 @@ +@@ -1215,12 +1633,35 @@ this.lastSentExp = -1; this.lastSentHealth = -1.0F; this.lastSentFood = -1; @@ -995,7 +994,7 @@ public void forceSetRotation(float yaw, float pitch) { this.connection.send(new ClientboundPlayerRotationPacket(yaw, pitch)); } -@@ -1228,13 +1668,27 @@ +@@ -1228,13 +1669,27 @@ public void triggerDimensionChangeTriggers(ServerLevel origin) { ResourceKey resourcekey = origin.dimension(); ResourceKey resourcekey1 = this.level().dimension(); @@ -1026,7 +1025,7 @@ this.enteredNetherPosition = null; } -@@ -1251,36 +1705,63 @@ +@@ -1251,36 +1706,63 @@ this.containerMenu.broadcastChanges(); } @@ -1105,7 +1104,7 @@ this.awardStat(Stats.SLEEP_IN_BED); CriteriaTriggers.SLEPT_IN_BED.trigger(this); }); -@@ -1293,9 +1774,8 @@ +@@ -1293,9 +1775,8 @@ return either; } } @@ -1116,7 +1115,7 @@ } @Override -@@ -1322,13 +1802,31 @@ +@@ -1322,13 +1803,31 @@ @Override public void stopSleepInBed(boolean skipSleepTimer, boolean updateSleepingPlayers) { @@ -1149,7 +1148,7 @@ } } -@@ -1341,7 +1839,7 @@ +@@ -1341,7 +1840,7 @@ @Override public boolean isInvulnerableTo(ServerLevel world, DamageSource source) { @@ -1158,7 +1157,7 @@ } @Override -@@ -1387,8 +1885,9 @@ +@@ -1387,8 +1886,9 @@ this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos(), front)); } @@ -1169,7 +1168,7 @@ } @Override -@@ -1396,13 +1895,35 @@ +@@ -1396,13 +1896,35 @@ if (factory == null) { return OptionalInt.empty(); } else { @@ -1205,7 +1204,7 @@ if (container == null) { if (this.isSpectator()) { this.displayClientMessage(Component.translatable("container.spectatorCantOpen").withStyle(ChatFormatting.RED), true); -@@ -1410,9 +1931,11 @@ +@@ -1410,9 +1932,11 @@ return OptionalInt.empty(); } else { @@ -1219,7 +1218,7 @@ return OptionalInt.of(this.containerCounter); } } -@@ -1425,15 +1948,26 @@ +@@ -1425,15 +1949,26 @@ @Override public void openHorseInventory(AbstractHorse horse, Container inventory) { @@ -1249,7 +1248,7 @@ this.initMenu(this.containerMenu); } -@@ -1456,9 +1990,28 @@ +@@ -1456,9 +1991,28 @@ @Override public void closeContainer() { @@ -1278,7 +1277,7 @@ @Override public void doCloseContainer() { -@@ -1485,19 +2038,19 @@ +@@ -1485,19 +2039,19 @@ i = Math.round((float) Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) * 100.0F); if (i > 0) { this.awardStat(Stats.SWIM_ONE_CM, i); @@ -1301,7 +1300,7 @@ } } else if (this.onClimbable()) { if (deltaY > 0.0D) { -@@ -1508,13 +2061,13 @@ +@@ -1508,13 +2062,13 @@ if (i > 0) { if (this.isSprinting()) { this.awardStat(Stats.SPRINT_ONE_CM, i); @@ -1318,7 +1317,7 @@ } } } else if (this.isFallFlying()) { -@@ -1557,7 +2110,7 @@ +@@ -1557,7 +2111,7 @@ @Override public void awardStat(Stat stat, int amount) { this.stats.increment(this, stat, amount); @@ -1327,7 +1326,7 @@ scoreaccess.add(amount); }); } -@@ -1565,7 +2118,7 @@ +@@ -1565,7 +2119,7 @@ @Override public void resetStat(Stat stat) { this.stats.setValue(this, stat, 0); @@ -1336,7 +1335,7 @@ } @Override -@@ -1597,9 +2150,9 @@ +@@ -1597,9 +2151,9 @@ super.jumpFromGround(); this.awardStat(Stats.JUMP); if (this.isSprinting()) { @@ -1348,7 +1347,7 @@ } } -@@ -1613,6 +2166,13 @@ +@@ -1613,6 +2167,13 @@ public void disconnect() { this.disconnected = true; this.ejectPassengers(); @@ -1362,7 +1361,7 @@ if (this.isSleeping()) { this.stopSleepInBed(true, false); } -@@ -1625,6 +2185,7 @@ +@@ -1625,6 +2186,7 @@ public void resetSentInfo() { this.lastSentHealth = -1.0E8F; @@ -1370,7 +1369,7 @@ } @Override -@@ -1661,7 +2222,7 @@ +@@ -1661,7 +2223,7 @@ this.onUpdateAbilities(); if (alive) { this.getAttributes().assignBaseValues(oldPlayer.getAttributes()); @@ -1379,7 +1378,7 @@ this.setHealth(oldPlayer.getHealth()); this.foodData = oldPlayer.foodData; Iterator iterator = oldPlayer.getActiveEffects().iterator(); -@@ -1669,7 +2230,7 @@ +@@ -1669,7 +2231,7 @@ while (iterator.hasNext()) { MobEffectInstance mobeffect = (MobEffectInstance) iterator.next(); @@ -1388,7 +1387,7 @@ } this.getInventory().replaceWith(oldPlayer.getInventory()); -@@ -1680,7 +2241,7 @@ +@@ -1680,7 +2242,7 @@ this.portalProcess = oldPlayer.portalProcess; } else { this.getAttributes().assignBaseValues(oldPlayer.getAttributes()); @@ -1397,7 +1396,7 @@ if (this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || oldPlayer.isSpectator()) { this.getInventory().replaceWith(oldPlayer.getInventory()); this.experienceLevel = oldPlayer.experienceLevel; -@@ -1696,7 +2257,7 @@ +@@ -1696,7 +2258,7 @@ this.lastSentExp = -1; this.lastSentHealth = -1.0F; this.lastSentFood = -1; @@ -1406,7 +1405,7 @@ this.seenCredits = oldPlayer.seenCredits; this.enteredNetherPosition = oldPlayer.enteredNetherPosition; this.chunkTrackingView = oldPlayer.chunkTrackingView; -@@ -1752,19 +2313,19 @@ +@@ -1752,19 +2314,19 @@ } @Override @@ -1430,7 +1429,7 @@ } return flag1; -@@ -1799,10 +2360,18 @@ +@@ -1799,10 +2361,18 @@ } public boolean setGameMode(GameType gameMode) { @@ -1451,7 +1450,7 @@ } else { this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, (float) gameMode.getId())); if (gameMode == GameType.SPECTATOR) { -@@ -1818,7 +2387,7 @@ +@@ -1818,7 +2388,7 @@ this.onUpdateAbilities(); this.updateEffectVisibility(); @@ -1460,7 +1459,7 @@ } } -@@ -1861,8 +2430,13 @@ +@@ -1861,8 +2431,13 @@ } public void sendChatMessage(OutgoingChatMessage message, boolean filterMaskEnabled, ChatType.Bound params) { @@ -1475,7 +1474,7 @@ } } -@@ -1878,7 +2452,36 @@ +@@ -1878,7 +2453,36 @@ } public void updateOptions(ClientInformation clientOptions) { @@ -1512,7 +1511,7 @@ this.requestedViewDistance = clientOptions.viewDistance(); this.chatVisibility = clientOptions.chatVisibility(); this.canChatColor = clientOptions.chatColors(); -@@ -1957,12 +2560,27 @@ +@@ -1957,12 +2561,27 @@ this.camera = (Entity) (entity == null ? this : entity); if (entity1 != this.camera) { @@ -1541,7 +1540,7 @@ } if (entity != null) { -@@ -1999,11 +2617,11 @@ +@@ -1999,11 +2618,11 @@ @Nullable public Component getTabListDisplayName() { @@ -1555,7 +1554,7 @@ } @Override -@@ -2045,12 +2663,44 @@ +@@ -2045,12 +2664,44 @@ this.setRespawnPosition(player.getRespawnDimension(), player.getRespawnPosition(), player.getRespawnAngle(), player.isRespawnForced(), false); } @@ -1602,7 +1601,7 @@ } this.respawnPosition = pos; -@@ -2064,6 +2714,7 @@ +@@ -2064,6 +2715,7 @@ this.respawnForced = false; } @@ -1610,7 +1609,7 @@ } public SectionPos getLastSectionPos() { -@@ -2088,18 +2739,44 @@ +@@ -2088,18 +2740,44 @@ } @Override @@ -1659,7 +1658,7 @@ } this.awardStat(Stats.DROP); -@@ -2115,6 +2792,11 @@ +@@ -2115,6 +2793,11 @@ return null; } else { double d0 = this.getEyeY() - 0.30000001192092896D; @@ -1671,7 +1670,7 @@ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), d0, this.getZ(), stack); entityitem.setPickUpDelay(40); -@@ -2166,6 +2848,16 @@ +@@ -2166,6 +2849,16 @@ } public void loadGameTypes(@Nullable CompoundTag nbt) { @@ -1688,7 +1687,7 @@ this.gameMode.setGameModeForPlayer(this.calculateGameModeForNewPlayer(ServerPlayer.readPlayerMode(nbt, "playerGameType")), ServerPlayer.readPlayerMode(nbt, "previousPlayerGameType")); } -@@ -2275,9 +2967,15 @@ +@@ -2275,9 +2968,15 @@ @Override public void stopRiding() { @@ -1705,7 +1704,7 @@ if (entity instanceof LivingEntity entityliving) { Iterator iterator = entityliving.getActiveEffects().iterator(); -@@ -2375,10 +3073,12 @@ +@@ -2375,10 +3074,12 @@ return TicketType.ENDER_PEARL.timeout(); } @@ -1721,7 +1720,7 @@ } private static float calculateLookAtYaw(Vec3 respawnPos, BlockPos currentPos) { -@@ -2387,4 +3087,147 @@ +@@ -2387,4 +3088,147 @@ return (float) Mth.wrapDegrees(Mth.atan2(vec3d1.z, vec3d1.x) * 57.2957763671875D - 90.0D); } } 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 f2b5c76e79..2e0eb6eb0a 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 @@ -338,7 +338,7 @@ boolean flag1 = entity.verticalCollisionBelow; if (entity instanceof LivingEntity) { -@@ -449,19 +607,72 @@ +@@ -449,20 +607,73 @@ d10 = d6 * d6 + d7 * d7 + d8 * d8; boolean flag2 = false; @@ -357,8 +357,8 @@ + this.player.absMoveTo(d0, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit this.send(ClientboundMoveVehiclePacket.fromEntity(entity)); return; -+ } -+ + } + + // CraftBukkit start - fire PlayerMoveEvent + Player player = this.getCraftPlayer(); + if (!this.hasMoved) { @@ -407,11 +407,12 @@ + this.justTeleported = false; + return; + } - } ++ } + // CraftBukkit end - ++ this.player.serverLevel().getChunkSource().move(this.player); entity.recordMovementThroughBlocks(new Vec3(d0, d1, d2), entity.position()); + Vec3 vec3d = new Vec3(entity.getX() - d0, entity.getY() - d1, entity.getZ() - d2); @@ -489,16 +700,17 @@ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (packet.getId() == this.awaitingTeleport) { @@ -1872,7 +1873,7 @@ this.player.resetLastActionTime(); this.player.setShiftKeyDown(packet.isUsingSecondaryAction()); -@@ -1733,20 +2786,58 @@ +@@ -1733,20 +2786,59 @@ if (this.player.canInteractWithEntity(axisalignedbb, 3.0D)) { packet.dispatch(new ServerboundInteractPacket.Handler() { @@ -1906,10 +1907,11 @@ + // Refresh the current entity metadata + entity.refreshEntityData(ServerGamePacketListenerImpl.this.player); + // SPIGOT-7136 - Allays -+ if (entity instanceof Allay) { ++ if (entity instanceof Allay || entity instanceof net.minecraft.world.entity.animal.horse.AbstractHorse) { // Paper - Fix horse armor desync + ServerGamePacketListenerImpl.this.send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.values()).map((slot) -> Pair.of(slot, ((LivingEntity) entity).getItemBySlot(slot).copy())).collect(Collectors.toList()))); -+ ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); + } ++ ++ ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - fix slot desync - always refresh player inventory + } + + if (event.isCancelled()) { @@ -1935,7 +1937,7 @@ } } -@@ -1755,19 +2846,20 @@ +@@ -1755,19 +2847,20 @@ @Override public void onInteraction(InteractionHand hand) { @@ -1959,7 +1961,7 @@ label23: { if (entity instanceof AbstractArrow) { -@@ -1785,17 +2877,41 @@ +@@ -1785,17 +2878,41 @@ } ServerGamePacketListenerImpl.this.player.attack(entity); @@ -2002,7 +2004,7 @@ } } -@@ -1809,7 +2925,7 @@ +@@ -1809,7 +2926,7 @@ case PERFORM_RESPAWN: if (this.player.wonGame) { this.player.wonGame = false; @@ -2011,7 +2013,7 @@ this.resetPosition(); CriteriaTriggers.CHANGED_DIMENSION.trigger(this.player, Level.END, Level.OVERWORLD); } else { -@@ -1817,11 +2933,11 @@ +@@ -1817,11 +2934,11 @@ return; } @@ -2026,7 +2028,7 @@ } } break; -@@ -1833,16 +2949,27 @@ +@@ -1833,16 +2950,27 @@ @Override public void handleContainerClose(ServerboundContainerClosePacket packet) { @@ -2056,7 +2058,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 +2982,284 @@ +@@ -1855,7 +2983,284 @@ boolean flag = packet.getStateId() != this.player.containerMenu.getStateId(); this.player.containerMenu.suppressRemoteUpdates(); @@ -2342,7 +2344,7 @@ ObjectIterator objectiterator = Int2ObjectMaps.fastIterable(packet.getChangedSlots()).iterator(); while (objectiterator.hasNext()) { -@@ -1879,6 +3283,14 @@ +@@ -1879,6 +3284,14 @@ @Override public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) { @@ -2357,7 +2359,7 @@ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); this.player.resetLastActionTime(); if (!this.player.isSpectator() && this.player.containerMenu.containerId == packet.containerId()) { -@@ -1900,9 +3312,43 @@ +@@ -1900,9 +3313,43 @@ ServerGamePacketListenerImpl.LOGGER.debug("Player {} tried to place impossible recipe {}", this.player, recipeholder.id().location()); return; } @@ -2402,7 +2404,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 +3363,7 @@ +@@ -1917,6 +3364,7 @@ @Override public void handleContainerButtonClick(ServerboundContainerButtonClickPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -2410,7 +2412,7 @@ this.player.resetLastActionTime(); if (this.player.containerMenu.containerId == packet.containerId() && !this.player.isSpectator()) { if (!this.player.containerMenu.stillValid(this.player)) { -@@ -1945,7 +3392,44 @@ +@@ -1945,7 +3393,44 @@ boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45; boolean flag2 = itemstack.isEmpty() || itemstack.getCount() <= itemstack.getMaxStackSize(); @@ -2455,7 +2457,7 @@ if (flag1 && flag2) { this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemstack); this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemstack); -@@ -1964,7 +3448,19 @@ +@@ -1964,7 +3449,19 @@ @Override public void handleSignUpdate(ServerboundSignUpdatePacket packet) { @@ -2476,7 +2478,7 @@ this.filterTextPacket(list).thenAcceptAsync((list1) -> { this.updateSignText(packet, list1); -@@ -1972,6 +3468,7 @@ +@@ -1972,6 +3469,7 @@ } private void updateSignText(ServerboundSignUpdatePacket packet, List signText) { @@ -2484,7 +2486,7 @@ this.player.resetLastActionTime(); ServerLevel worldserver = this.player.serverLevel(); BlockPos blockposition = packet.getPos(); -@@ -1993,15 +3490,33 @@ +@@ -1993,15 +3491,33 @@ @Override public void handlePlayerAbilities(ServerboundPlayerAbilitiesPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -2519,7 +2521,7 @@ if (this.player.isModelPartShown(PlayerModelPart.HAT) != flag) { this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT, this.player)); } -@@ -2012,7 +3527,7 @@ +@@ -2012,7 +3528,7 @@ public void handleChangeDifficulty(ServerboundChangeDifficultyPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (this.player.hasPermissions(2) || this.isSingleplayerOwner()) { @@ -2528,7 +2530,7 @@ } } -@@ -2033,7 +3548,7 @@ +@@ -2033,7 +3549,7 @@ if (!Objects.equals(profilepublickey_a, profilepublickey_a1)) { if (profilepublickey_a != null && profilepublickey_a1.expiresAt().isBefore(profilepublickey_a.expiresAt())) { @@ -2537,7 +2539,7 @@ } else { try { SignatureValidator signaturevalidator = this.server.getProfileKeySignatureValidator(); -@@ -2045,8 +3560,8 @@ +@@ -2045,8 +3561,8 @@ this.resetPlayerChatState(remotechatsession_a.validate(this.player.getGameProfile(), signaturevalidator)); } catch (ProfilePublicKey.ValidationException profilepublickey_b) { @@ -2548,7 +2550,7 @@ } } -@@ -2058,7 +3573,7 @@ +@@ -2058,7 +3574,7 @@ if (!this.waitingForSwitchToConfig) { throw new IllegalStateException("Client acknowledged config, but none was requested"); } else { @@ -2557,7 +2559,7 @@ } } -@@ -2076,15 +3591,18 @@ +@@ -2076,15 +3592,18 @@ private void resetPlayerChatState(RemoteChatSession session) { this.chatSession = session; @@ -2579,7 +2581,7 @@ @Override public void handleClientTickEnd(ServerboundClientTickEndPacket packet) { -@@ -2115,4 +3633,17 @@ +@@ -2115,4 +3634,17 @@ InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch index ce4756de0a..a2e61caaab 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -1063,21 +1063,22 @@ leashable.removeLeash(); } else { leashable.dropLeash(); -@@ -2200,6 +2781,13 @@ +@@ -2200,6 +2781,14 @@ if (itemstack.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) { if (!this.level().isClientSide()) { + // CraftBukkit start - fire PlayerLeashEntityEvent + if (CraftEventFactory.callPlayerLeashEntityEvent(this, player, player, hand).isCancelled()) { -+ ((ServerPlayer) player).resendItemInHands(); // SPIGOT-7615: Resend to fix client desync with used item ++ // ((ServerPlayer) player).resendItemInHands(); // SPIGOT-7615: Resend to fix client desync with used item // Paper - Fix inventory desync + ((ServerPlayer) player).connection.send(new ClientboundSetEntityLinkPacket(this, leashable.getLeashHolder())); ++ player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync + return InteractionResult.PASS; + } + // CraftBukkit end leashable.setLeashedTo(player, true); } -@@ -2265,15 +2853,15 @@ +@@ -2265,15 +2854,15 @@ } public boolean showVehicleHealth() { @@ -1096,7 +1097,7 @@ return false; } else { for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) { -@@ -2285,11 +2873,32 @@ +@@ -2285,11 +2874,32 @@ if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) { return false; } else { @@ -1130,7 +1131,7 @@ this.vehicle = entity; this.vehicle.addPassenger(this); entity.getIndirectPassengersStream().filter((entity2) -> { -@@ -2314,19 +2923,30 @@ +@@ -2314,19 +2924,30 @@ } public void removeVehicle() { @@ -1163,7 +1164,7 @@ protected void addPassenger(Entity passenger) { if (passenger.getVehicle() != this) { throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)"); -@@ -2349,21 +2969,53 @@ +@@ -2349,21 +2970,53 @@ } } @@ -1223,7 +1224,7 @@ } protected boolean canAddPassenger(Entity passenger) { -@@ -2464,7 +3116,7 @@ +@@ -2464,7 +3117,7 @@ if (teleporttransition != null) { ServerLevel worldserver1 = teleporttransition.newLevel(); @@ -1232,7 +1233,7 @@ this.teleport(teleporttransition); } } -@@ -2547,7 +3199,7 @@ +@@ -2547,7 +3200,7 @@ } public boolean isCrouching() { @@ -1241,7 +1242,7 @@ } public boolean isSprinting() { -@@ -2563,7 +3215,7 @@ +@@ -2563,7 +3216,7 @@ } public boolean isVisuallySwimming() { @@ -1250,7 +1251,7 @@ } public boolean isVisuallyCrawling() { -@@ -2571,6 +3223,13 @@ +@@ -2571,6 +3224,13 @@ } public void setSwimming(boolean swimming) { @@ -1264,7 +1265,7 @@ this.setSharedFlag(4, swimming); } -@@ -2609,6 +3268,7 @@ +@@ -2609,6 +3269,7 @@ @Nullable public PlayerTeam getTeam() { @@ -1272,7 +1273,7 @@ return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName()); } -@@ -2624,8 +3284,12 @@ +@@ -2624,8 +3285,12 @@ return this.getTeam() != null ? this.getTeam().isAlliedTo(team) : false; } @@ -1286,7 +1287,7 @@ } public boolean getSharedFlag(int index) { -@@ -2644,7 +3308,7 @@ +@@ -2644,7 +3309,7 @@ } public int getMaxAirSupply() { @@ -1295,7 +1296,7 @@ } public int getAirSupply() { -@@ -2652,7 +3316,18 @@ +@@ -2652,7 +3317,18 @@ } public void setAirSupply(int air) { @@ -1315,7 +1316,7 @@ } public int getTicksFrozen() { -@@ -2679,11 +3354,44 @@ +@@ -2679,11 +3355,44 @@ public void thunderHit(ServerLevel world, LightningBolt lightning) { this.setRemainingFireTicks(this.remainingFireTicks + 1); @@ -1362,7 +1363,7 @@ } public void onAboveBubbleCol(boolean drag) { -@@ -2713,7 +3421,7 @@ +@@ -2713,7 +3422,7 @@ this.resetFallDistance(); } @@ -1371,7 +1372,7 @@ return true; } -@@ -2818,7 +3526,7 @@ +@@ -2818,7 +3527,7 @@ public String toString() { String s = this.level() == null ? "~NULL~" : this.level().toString(); @@ -1380,7 +1381,7 @@ } public final boolean isInvulnerableToBase(DamageSource damageSource) { -@@ -2838,6 +3546,13 @@ +@@ -2838,6 +3547,13 @@ } public void restoreFrom(Entity original) { @@ -1394,7 +1395,7 @@ CompoundTag nbttagcompound = original.saveWithoutId(new CompoundTag()); nbttagcompound.remove("Dimension"); -@@ -2850,8 +3565,57 @@ +@@ -2850,8 +3566,57 @@ public Entity teleport(TeleportTransition teleportTarget) { Level world = this.level(); @@ -1452,7 +1453,7 @@ ServerLevel worldserver1 = teleportTarget.newLevel(); boolean flag = worldserver1.dimension() != worldserver.dimension(); -@@ -2918,10 +3682,19 @@ +@@ -2918,10 +3683,19 @@ gameprofilerfiller.pop(); return null; } else { @@ -1473,7 +1474,7 @@ Iterator iterator1 = list1.iterator(); while (iterator1.hasNext()) { -@@ -2947,7 +3720,7 @@ +@@ -2947,7 +3721,7 @@ } private void sendTeleportTransitionToRidingPlayers(TeleportTransition teleportTarget) { @@ -1482,7 +1483,7 @@ Iterator iterator = this.getIndirectPassengers().iterator(); while (iterator.hasNext()) { -@@ -2995,9 +3768,17 @@ +@@ -2995,9 +3769,17 @@ } protected void removeAfterChangingDimensions() { @@ -1503,7 +1504,7 @@ } } -@@ -3006,11 +3787,34 @@ +@@ -3006,11 +3788,34 @@ return PortalShape.getRelativePosition(portalRect, portalAxis, this.position(), this.getDimensions(this.getPose())); } @@ -1538,7 +1539,7 @@ if (from.dimension() == Level.END && to.dimension() == Level.OVERWORLD) { Iterator iterator = this.getPassengers().iterator(); -@@ -3134,10 +3938,16 @@ +@@ -3134,10 +3939,16 @@ return (Boolean) this.entityData.get(Entity.DATA_CUSTOM_NAME_VISIBLE); } @@ -1558,7 +1559,7 @@ return entity != null; } -@@ -3187,7 +3997,7 @@ +@@ -3187,7 +3998,7 @@ /** @deprecated */ @Deprecated protected void fixupDimensions() { @@ -1567,7 +1568,7 @@ EntityDimensions entitysize = this.getDimensions(entitypose); this.dimensions = entitysize; -@@ -3196,7 +4006,7 @@ +@@ -3196,7 +4007,7 @@ public void refreshDimensions() { EntityDimensions entitysize = this.dimensions; @@ -1576,7 +1577,7 @@ EntityDimensions entitysize1 = this.getDimensions(entitypose); this.dimensions = entitysize1; -@@ -3258,10 +4068,29 @@ +@@ -3258,10 +4069,29 @@ } public final void setBoundingBox(AABB boundingBox) { @@ -1608,7 +1609,7 @@ return this.getDimensions(pose).eyeHeight(); } -@@ -3300,7 +4129,14 @@ +@@ -3300,7 +4130,14 @@ public void startSeenByPlayer(ServerPlayer player) {} @@ -1624,7 +1625,7 @@ public float rotate(Rotation rotation) { float f = Mth.wrapDegrees(this.getYRot()); -@@ -3335,7 +4171,7 @@ +@@ -3335,7 +4172,7 @@ } @Nullable @@ -1633,7 +1634,7 @@ return null; } -@@ -3373,20 +4209,34 @@ +@@ -3373,20 +4210,34 @@ } private Stream getIndirectPassengersStream() { @@ -1668,7 +1669,7 @@ return () -> { return this.getIndirectPassengersStream().iterator(); }; -@@ -3399,6 +4249,7 @@ +@@ -3399,6 +4250,7 @@ } public boolean hasExactlyOnePlayerPassenger() { @@ -1676,7 +1677,7 @@ return this.countPlayerPassengers() == 1; } -@@ -3435,7 +4286,7 @@ +@@ -3435,7 +4287,7 @@ } public boolean isControlledByLocalInstance() { @@ -1685,7 +1686,7 @@ if (entityliving instanceof Player entityhuman) { return entityhuman.isLocalPlayer(); -@@ -3445,7 +4296,7 @@ +@@ -3445,7 +4297,7 @@ } public boolean isControlledByClient() { @@ -1694,7 +1695,7 @@ return entityliving != null && entityliving.isControlledByClient(); } -@@ -3463,7 +4314,7 @@ +@@ -3463,7 +4315,7 @@ return new Vec3((double) f1 * d2 / (double) f3, 0.0D, (double) f2 * d2 / (double) f3); } @@ -1703,7 +1704,7 @@ return new Vec3(this.getX(), this.getBoundingBox().maxY, this.getZ()); } -@@ -3489,8 +4340,37 @@ +@@ -3489,8 +4341,37 @@ return 1; } @@ -1742,7 +1743,7 @@ } public void lookAt(EntityAnchorArgument.Anchor anchorPoint, Vec3 target) { -@@ -3551,6 +4431,11 @@ +@@ -3551,6 +4432,11 @@ vec3d = vec3d.add(vec3d1); ++k1; } @@ -1754,7 +1755,7 @@ } } } -@@ -3613,7 +4498,7 @@ +@@ -3613,7 +4499,7 @@ return new ClientboundAddEntityPacket(this, entityTrackerEntry); } @@ -1763,7 +1764,7 @@ return this.type.getDimensions(); } -@@ -3714,7 +4599,39 @@ +@@ -3714,7 +4600,39 @@ return this.getZ((2.0D * this.random.nextDouble() - 1.0D) * widthScale); } @@ -1803,7 +1804,7 @@ if (this.position.x != x || this.position.y != y || this.position.z != z) { this.position = new Vec3(x, y, z); int i = Mth.floor(x); -@@ -3732,6 +4649,12 @@ +@@ -3732,6 +4650,12 @@ this.levelCallback.onMove(); } @@ -1816,7 +1817,7 @@ } public void checkDespawn() {} -@@ -3818,8 +4741,17 @@ +@@ -3818,8 +4742,17 @@ @Override public final void setRemoved(Entity.RemovalReason reason) { @@ -1835,7 +1836,7 @@ } if (this.removalReason.shouldDestroy()) { -@@ -3827,14 +4759,30 @@ +@@ -3827,14 +4760,30 @@ } this.getPassengers().forEach(Entity::stopRiding); @@ -1868,7 +1869,7 @@ @Override public void setLevelCallback(EntityInLevelCallback changeListener) { this.levelCallback = changeListener; -@@ -3887,7 +4835,7 @@ +@@ -3887,7 +4836,7 @@ } public Vec3 getKnownMovement() { @@ -1877,7 +1878,7 @@ if (entityliving instanceof Player entityhuman) { if (this.isAlive()) { -@@ -3962,4 +4910,14 @@ +@@ -3962,4 +4911,14 @@ void accept(Entity entity, double x, double y, double z); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Cow.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Cow.java.patch index e09b07cd04..4e23f7179b 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Cow.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Cow.java.patch @@ -12,7 +12,7 @@ public class Cow extends Animal { -@@ -92,8 +97,16 @@ +@@ -92,8 +97,17 @@ ItemStack itemstack = player.getItemInHand(hand); if (itemstack.is(Items.BUCKET) && !this.isBaby()) { @@ -20,6 +20,7 @@ + PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); + + if (event.isCancelled()) { ++ player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync + return InteractionResult.PASS; + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch index 3084a4832d..44290161de 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch @@ -21,7 +21,7 @@ } @Override -@@ -229,15 +234,23 @@ +@@ -229,15 +234,24 @@ ItemStack itemstack = player.getItemInHand(hand); if (itemstack.is(Items.BUCKET) && !this.isBaby()) { @@ -29,6 +29,7 @@ + PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); + + if (event.isCancelled()) { ++ player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync + return InteractionResult.PASS; + } + // CraftBukkit end @@ -47,7 +48,7 @@ this.playEatingSound(); } -@@ -353,8 +366,7 @@ +@@ -353,8 +367,7 @@ double d2 = (double) Mth.randomBetween(this.random, -0.2F, 0.2F); ItemEntity entityitem = new ItemEntity(this.level(), vec3d.x(), vec3d.y(), vec3d.z(), itemstack, d0, d1, d2); @@ -57,7 +58,7 @@ } } -@@ -383,4 +395,15 @@ +@@ -383,4 +396,15 @@ public static boolean checkGoatSpawnRules(EntityType entityType, LevelAccessor world, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random) { return world.getBlockState(pos.below()).is(BlockTags.GOATS_SPAWNABLE_ON) && isBrightEnoughToSpawn(world, pos); } diff --git a/paper-server/patches/sources/net/minecraft/world/item/ArmorStandItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ArmorStandItem.java.patch index e54a0d54ab..5be546c2b6 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/ArmorStandItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/ArmorStandItem.java.patch @@ -1,11 +1,12 @@ --- a/net/minecraft/world/item/ArmorStandItem.java +++ b/net/minecraft/world/item/ArmorStandItem.java -@@ -53,6 +53,11 @@ +@@ -53,6 +53,12 @@ float f = (float) Mth.floor((Mth.wrapDegrees(context.getRotation() - 180.0F) + 22.5F) / 45.0F) * 45.0F; entityarmorstand.moveTo(entityarmorstand.getX(), entityarmorstand.getY(), entityarmorstand.getZ(), f, 0.0F); + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityarmorstand).isCancelled()) { ++ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync + return InteractionResult.FAIL; + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch index 75987699a4..52e43aa9e4 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch @@ -61,7 +61,7 @@ + if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { + blockstate.update(true, false); + -+ if (this instanceof SolidBucketItem) { ++ if (true) { // Paper - if the event is called here, the inventory should be updated + ((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541 + } + return InteractionResult.FAIL; diff --git a/paper-server/patches/sources/net/minecraft/world/item/EndCrystalItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/EndCrystalItem.java.patch index d9f548e749..ba84da3813 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/EndCrystalItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/EndCrystalItem.java.patch @@ -1,11 +1,12 @@ --- a/net/minecraft/world/item/EndCrystalItem.java +++ b/net/minecraft/world/item/EndCrystalItem.java -@@ -47,6 +47,11 @@ +@@ -47,6 +47,12 @@ EndCrystal entityendercrystal = new EndCrystal(world, d0 + 0.5D, d1, d2 + 0.5D); entityendercrystal.setShowBottom(false); + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityendercrystal).isCancelled()) { ++ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync + return InteractionResult.FAIL; + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/item/MinecartItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/MinecartItem.java.patch index e04ca4357f..f97004f5f9 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/MinecartItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/MinecartItem.java.patch @@ -1,12 +1,13 @@ --- a/net/minecraft/world/item/MinecartItem.java +++ b/net/minecraft/world/item/MinecartItem.java -@@ -67,7 +67,12 @@ +@@ -67,7 +67,13 @@ if (world instanceof ServerLevel) { ServerLevel worldserver = (ServerLevel) world; - worldserver.addFreshEntity(entityminecartabstract); + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityminecartabstract).isCancelled()) { ++ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync + return InteractionResult.FAIL; + } + // CraftBukkit end