From 7b293aba089a1c2d42b51ea960a093d5324706e8 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 11 Mar 2021 03:03:32 -0800 Subject: [PATCH] Do not run close logic for inventories on chunk unload Still call the event and change the active container though. We want to avoid close logic because it's possible to load the chunk through it. This should also be OK from a leak prevention/ state desync POV because the TE is getting unloaded anyways. --- .../server/level/ServerLevel.java.patch | 63 ++++++------ .../server/level/ServerPlayer.java.patch | 99 +++++++++++-------- .../world/entity/player/Player.java.patch | 57 ++++++----- 3 files changed, 123 insertions(+), 96 deletions(-) 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 7472586147..5c003671b3 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 @@ -61,7 +61,7 @@ private int lastSpawnChunkRadius; final EntityTickList entityTickList = new EntityTickList(); public final PersistentEntitySectionManager entityManager; -@@ -214,53 +226,203 @@ +@@ -214,54 +226,204 @@ private final boolean tickTime; private final RandomSequences randomSequences; @@ -278,17 +278,18 @@ return (RandomSequences) this.getDataStorage().computeIfAbsent(RandomSequences.factory(l), "random_sequences"); }); + this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit -+ } -+ + } + + // Paper start + @Override + public boolean hasChunk(int chunkX, int chunkZ) { + return this.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ) != null; - } ++ } + // Paper end - ++ /** @deprecated */ @Deprecated + @VisibleForTesting @@ -273,8 +435,8 @@ this.serverLevelData.setClearWeatherTime(clearDuration); this.serverLevelData.setRainTime(rainDuration); @@ -630,7 +631,7 @@ } } -@@ -939,41 +1192,99 @@ +@@ -939,41 +1192,103 @@ this.entityManager.addNewEntity(player); } @@ -691,9 +692,13 @@ + // Spigot Start + for (net.minecraft.world.level.block.entity.BlockEntity tileentity : chunk.getBlockEntities().values()) { + if (tileentity instanceof net.minecraft.world.Container) { ++ // Paper start - this area looks like it can load chunks, change the behavior ++ // chests for example can apply physics to the world ++ // so instead we just change the active container and call the event + for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((net.minecraft.world.Container) tileentity).getViewers())) { -+ h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - Inventory close reason ++ ((org.bukkit.craftbukkit.entity.CraftHumanEntity) h).getHandle().closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - Inventory close reason + } ++ // Paper end - this area looks like it can load chunks, change the behavior + } + } + // Spigot End @@ -735,7 +740,7 @@ while (iterator.hasNext()) { ServerPlayer entityplayer = (ServerPlayer) iterator.next(); -@@ -982,6 +1293,12 @@ +@@ -982,6 +1297,12 @@ double d1 = (double) pos.getY() - entityplayer.getY(); double d2 = (double) pos.getZ() - entityplayer.getZ(); @@ -748,7 +753,7 @@ if (d0 * d0 + d1 * d1 + d2 * d2 < 1024.0D) { entityplayer.connection.send(new ClientboundBlockDestructionPacket(entityId, pos, progress)); } -@@ -1030,7 +1347,7 @@ +@@ -1030,7 +1351,7 @@ @Override public void levelEvent(@Nullable Player player, int eventId, BlockPos pos, int data) { @@ -757,7 +762,7 @@ } public int getLogicalHeight() { -@@ -1052,6 +1369,7 @@ +@@ -1052,6 +1373,7 @@ this.getChunkSource().blockChanged(pos); this.pathTypesByPosCache.invalidate(pos); @@ -765,7 +770,7 @@ VoxelShape voxelshape = oldState.getCollisionShape(this, pos); VoxelShape voxelshape1 = newState.getCollisionShape(this, pos); -@@ -1060,7 +1378,18 @@ +@@ -1060,7 +1382,18 @@ Iterator iterator = this.navigatingMobs.iterator(); while (iterator.hasNext()) { @@ -785,7 +790,7 @@ PathNavigation navigationabstract = entityinsentient.getNavigation(); if (navigationabstract.shouldRecomputePath(pos)) { -@@ -1082,15 +1411,18 @@ +@@ -1082,15 +1415,18 @@ } } @@ -804,7 +809,7 @@ this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, (Direction) null, orientation); } -@@ -1126,9 +1458,20 @@ +@@ -1126,9 +1462,20 @@ @Override public void explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, ParticleOptions smallParticle, ParticleOptions largeParticle, Holder soundEvent) { @@ -826,7 +831,7 @@ case NONE: explosion_effect = Explosion.BlockInteraction.KEEP; break; -@@ -1144,16 +1487,27 @@ +@@ -1144,16 +1491,27 @@ case TRIGGER: explosion_effect = Explosion.BlockInteraction.TRIGGER_BLOCK; break; @@ -857,7 +862,7 @@ Iterator iterator = this.players.iterator(); while (iterator.hasNext()) { -@@ -1162,10 +1516,11 @@ +@@ -1162,10 +1520,11 @@ if (entityplayer.distanceToSqr(vec3d) < 4096.0D) { Optional optional = Optional.ofNullable((Vec3) serverexplosion.getHitPlayers().get(entityplayer)); @@ -870,7 +875,7 @@ } private Explosion.BlockInteraction getDestroyType(GameRules.Key decayRule) { -@@ -1226,17 +1581,29 @@ +@@ -1226,17 +1585,29 @@ } public int sendParticles(T parameters, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double speed) { @@ -906,7 +911,7 @@ ++j; } } -@@ -1292,7 +1659,7 @@ +@@ -1292,7 +1663,7 @@ @Nullable public BlockPos findNearestMapStructure(TagKey structureTag, BlockPos pos, int radius, boolean skipReferencedStructures) { @@ -915,7 +920,7 @@ return null; } else { Optional> optional = this.registryAccess().lookupOrThrow(Registries.STRUCTURE).get(structureTag); -@@ -1334,11 +1701,22 @@ +@@ -1334,11 +1705,22 @@ @Nullable @Override public MapItemSavedData getMapData(MapId id) { @@ -939,7 +944,7 @@ this.getServer().overworld().getDataStorage().set(id.key(), state); } -@@ -1352,7 +1730,9 @@ +@@ -1352,7 +1734,9 @@ float f1 = this.levelData.getSpawnAngle(); if (!blockposition1.equals(pos) || f1 != angle) { @@ -949,7 +954,7 @@ this.getServer().getPlayerList().broadcastAll(new ClientboundSetDefaultSpawnPositionPacket(pos, angle)); } -@@ -1419,6 +1799,11 @@ +@@ -1419,6 +1803,11 @@ }); optional1.ifPresent((holder) -> { this.getServer().execute(() -> { @@ -961,7 +966,7 @@ this.getPoiManager().add(blockposition1, holder); DebugPackets.sendPoiAddedPacket(this, blockposition1); }); -@@ -1649,6 +2034,11 @@ +@@ -1649,6 +2038,11 @@ @Override public void blockUpdated(BlockPos pos, Block block) { if (!this.isDebug()) { @@ -973,7 +978,7 @@ this.updateNeighborsAt(pos, block); } -@@ -1668,12 +2058,12 @@ +@@ -1668,12 +2062,12 @@ } public boolean isFlat() { @@ -988,7 +993,7 @@ } @Nullable -@@ -1696,7 +2086,7 @@ +@@ -1696,7 +2090,7 @@ private static String getTypeCount(Iterable items, Function classifier) { try { Object2IntOpenHashMap object2intopenhashmap = new Object2IntOpenHashMap(); @@ -997,7 +1002,7 @@ while (iterator.hasNext()) { T t0 = iterator.next(); -@@ -1705,7 +2095,7 @@ +@@ -1705,7 +2099,7 @@ object2intopenhashmap.addTo(s, 1); } @@ -1006,7 +1011,7 @@ String s1 = (String) entry.getKey(); return s1 + ":" + entry.getIntValue(); -@@ -1717,6 +2107,7 @@ +@@ -1717,6 +2111,7 @@ @Override public LevelEntityGetter getEntities() { @@ -1014,7 +1019,7 @@ return this.entityManager.getEntityGetter(); } -@@ -1802,6 +2193,17 @@ +@@ -1802,6 +2197,17 @@ return this.serverLevelData.getGameRules(); } @@ -1032,7 +1037,7 @@ @Override public CrashReportCategory fillReportDetails(CrashReport report) { CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); -@@ -1836,7 +2238,8 @@ +@@ -1836,7 +2242,8 @@ } public void onTrackingStart(Entity entity) { @@ -1042,7 +1047,7 @@ if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.add(entityplayer); ServerLevel.this.updateSleepingPlayerList(); -@@ -1864,9 +2267,53 @@ +@@ -1864,9 +2271,53 @@ } entity.updateDynamicGameEventListener(DynamicGameEventListener::add); @@ -1096,7 +1101,7 @@ ServerLevel.this.getChunkSource().removeEntity(entity); if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.remove(entityplayer); -@@ -1895,6 +2342,15 @@ +@@ -1895,6 +2346,15 @@ } entity.updateDynamicGameEventListener(DynamicGameEventListener::remove); 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 e47e293e3e..f6fc4042ef 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 @@ -114,7 +114,7 @@ @Nullable private Vec3 startingToFallPosition; @Nullable -@@ -258,6 +293,34 @@ +@@ -258,7 +293,35 @@ private final CommandSource commandSource; private int containerCounter; public boolean wonGame; @@ -125,7 +125,7 @@ + public boolean queueHealthUpdatePacket; + public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket; + // Paper end - cancellable death event -+ + + // CraftBukkit start + public CraftPlayer.TransferCookieConnection transferCookieConnection; + public String displayName; @@ -146,9 +146,10 @@ + public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent + public @Nullable String clientBrandName = null; // Paper - Brand support + public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event - ++ public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); + this.chatVisibility = ChatVisiblity.FULL; @@ -266,7 +329,7 @@ this.canChatColor = true; this.lastActionTime = Util.getMillis(); @@ -397,9 +398,12 @@ Logger logger = ServerPlayer.LOGGER; Objects.requireNonNull(logger); -@@ -686,6 +839,29 @@ - - } +@@ -683,8 +836,31 @@ + }); + } + } ++ ++ } + // CraftBukkit start - World fallback code, either respawn location or global spawn + public void spawnIn(Level world) { @@ -421,12 +425,11 @@ + this.setPosRaw(position.x(), position.y(), position.z()); // Paper - don't register to chunks yet + } + this.gameMode.setLevel((ServerLevel) world); -+ } + } + // CraftBukkit end -+ + public void setExperiencePoints(int points) { float f = (float) this.getXpNeededForNextLevel(); - float f1 = (f - 1.0F) / f; @@ -744,6 +920,11 @@ @Override @@ -1196,7 +1199,7 @@ this.initMenu(this.containerMenu); } -@@ -1456,6 +1956,13 @@ +@@ -1456,9 +1956,28 @@ @Override public void closeContainer() { @@ -1210,7 +1213,22 @@ this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId)); this.doCloseContainer(); } -@@ -1485,19 +1992,19 @@ ++ // Paper start - special close for unloaded inventory ++ @Override ++ public void closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { ++ // copied from above ++ CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit ++ // Paper end ++ // copied from below ++ this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId)); ++ this.containerMenu = this.inventoryMenu; ++ // do not run close logic ++ } ++ // Paper end - special close for unloaded inventory + + @Override + public void doCloseContainer() { +@@ -1485,19 +2004,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); @@ -1233,7 +1251,7 @@ } } else if (this.onClimbable()) { if (deltaY > 0.0D) { -@@ -1508,13 +2015,13 @@ +@@ -1508,13 +2027,13 @@ if (i > 0) { if (this.isSprinting()) { this.awardStat(Stats.SPRINT_ONE_CM, i); @@ -1250,7 +1268,7 @@ } } } else if (this.isFallFlying()) { -@@ -1557,7 +2064,7 @@ +@@ -1557,7 +2076,7 @@ @Override public void awardStat(Stat stat, int amount) { this.stats.increment(this, stat, amount); @@ -1259,7 +1277,7 @@ scoreaccess.add(amount); }); } -@@ -1565,7 +2072,7 @@ +@@ -1565,7 +2084,7 @@ @Override public void resetStat(Stat stat) { this.stats.setValue(this, stat, 0); @@ -1268,7 +1286,7 @@ } @Override -@@ -1597,9 +2104,9 @@ +@@ -1597,9 +2116,9 @@ super.jumpFromGround(); this.awardStat(Stats.JUMP); if (this.isSprinting()) { @@ -1280,7 +1298,7 @@ } } -@@ -1613,6 +2120,13 @@ +@@ -1613,6 +2132,13 @@ public void disconnect() { this.disconnected = true; this.ejectPassengers(); @@ -1294,7 +1312,7 @@ if (this.isSleeping()) { this.stopSleepInBed(true, false); } -@@ -1625,6 +2139,7 @@ +@@ -1625,6 +2151,7 @@ public void resetSentInfo() { this.lastSentHealth = -1.0E8F; @@ -1302,7 +1320,7 @@ } @Override -@@ -1661,7 +2176,7 @@ +@@ -1661,7 +2188,7 @@ this.onUpdateAbilities(); if (alive) { this.getAttributes().assignBaseValues(oldPlayer.getAttributes()); @@ -1311,7 +1329,7 @@ this.setHealth(oldPlayer.getHealth()); this.foodData = oldPlayer.foodData; Iterator iterator = oldPlayer.getActiveEffects().iterator(); -@@ -1669,7 +2184,7 @@ +@@ -1669,7 +2196,7 @@ while (iterator.hasNext()) { MobEffectInstance mobeffect = (MobEffectInstance) iterator.next(); @@ -1320,7 +1338,7 @@ } this.getInventory().replaceWith(oldPlayer.getInventory()); -@@ -1680,7 +2195,7 @@ +@@ -1680,7 +2207,7 @@ this.portalProcess = oldPlayer.portalProcess; } else { this.getAttributes().assignBaseValues(oldPlayer.getAttributes()); @@ -1329,7 +1347,7 @@ if (this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || oldPlayer.isSpectator()) { this.getInventory().replaceWith(oldPlayer.getInventory()); this.experienceLevel = oldPlayer.experienceLevel; -@@ -1696,7 +2211,7 @@ +@@ -1696,7 +2223,7 @@ this.lastSentExp = -1; this.lastSentHealth = -1.0F; this.lastSentFood = -1; @@ -1338,7 +1356,7 @@ this.seenCredits = oldPlayer.seenCredits; this.enteredNetherPosition = oldPlayer.enteredNetherPosition; this.chunkTrackingView = oldPlayer.chunkTrackingView; -@@ -1752,19 +2267,19 @@ +@@ -1752,19 +2279,19 @@ } @Override @@ -1362,7 +1380,7 @@ } return flag1; -@@ -1799,10 +2314,18 @@ +@@ -1799,10 +2326,18 @@ } public boolean setGameMode(GameType gameMode) { @@ -1383,7 +1401,7 @@ } else { this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, (float) gameMode.getId())); if (gameMode == GameType.SPECTATOR) { -@@ -1818,7 +2341,7 @@ +@@ -1818,7 +2353,7 @@ this.onUpdateAbilities(); this.updateEffectVisibility(); @@ -1392,7 +1410,7 @@ } } -@@ -1861,8 +2384,13 @@ +@@ -1861,8 +2396,13 @@ } public void sendChatMessage(OutgoingChatMessage message, boolean filterMaskEnabled, ChatType.Bound params) { @@ -1407,7 +1425,7 @@ } } -@@ -1878,7 +2406,36 @@ +@@ -1878,7 +2418,36 @@ } public void updateOptions(ClientInformation clientOptions) { @@ -1444,7 +1462,7 @@ this.requestedViewDistance = clientOptions.viewDistance(); this.chatVisibility = clientOptions.chatVisibility(); this.canChatColor = clientOptions.chatColors(); -@@ -1957,12 +2514,27 @@ +@@ -1957,12 +2526,27 @@ this.camera = (Entity) (entity == null ? this : entity); if (entity1 != this.camera) { @@ -1473,7 +1491,7 @@ } if (entity != null) { -@@ -1999,11 +2571,11 @@ +@@ -1999,11 +2583,11 @@ @Nullable public Component getTabListDisplayName() { @@ -1487,7 +1505,7 @@ } @Override -@@ -2045,12 +2617,44 @@ +@@ -2045,12 +2629,44 @@ this.setRespawnPosition(player.getRespawnDimension(), player.getRespawnPosition(), player.getRespawnAngle(), player.isRespawnForced(), false); } @@ -1534,7 +1552,7 @@ } this.respawnPosition = pos; -@@ -2064,6 +2668,7 @@ +@@ -2064,6 +2680,7 @@ this.respawnForced = false; } @@ -1542,7 +1560,7 @@ } public SectionPos getLastSectionPos() { -@@ -2088,18 +2693,44 @@ +@@ -2088,18 +2705,44 @@ } @Override @@ -1591,7 +1609,7 @@ } this.awardStat(Stats.DROP); -@@ -2115,6 +2746,11 @@ +@@ -2115,6 +2758,11 @@ return null; } else { double d0 = this.getEyeY() - 0.30000001192092896D; @@ -1603,7 +1621,7 @@ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), d0, this.getZ(), stack); entityitem.setPickUpDelay(40); -@@ -2166,6 +2802,16 @@ +@@ -2166,6 +2814,16 @@ } public void loadGameTypes(@Nullable CompoundTag nbt) { @@ -1620,7 +1638,7 @@ this.gameMode.setGameModeForPlayer(this.calculateGameModeForNewPlayer(ServerPlayer.readPlayerMode(nbt, "playerGameType")), ServerPlayer.readPlayerMode(nbt, "previousPlayerGameType")); } -@@ -2275,9 +2921,15 @@ +@@ -2275,9 +2933,15 @@ @Override public void stopRiding() { @@ -1637,7 +1655,7 @@ if (entity instanceof LivingEntity entityliving) { Iterator iterator = entityliving.getActiveEffects().iterator(); -@@ -2375,16 +3027,161 @@ +@@ -2375,10 +3039,12 @@ return TicketType.ENDER_PEARL.timeout(); } @@ -1653,11 +1671,10 @@ } private static float calculateLookAtYaw(Vec3 respawnPos, BlockPos currentPos) { - Vec3 vec3d1 = Vec3.atBottomCenterOf(currentPos).subtract(respawnPos).normalize(); - +@@ -2387,4 +3053,147 @@ return (float) Mth.wrapDegrees(Mth.atan2(vec3d1.z, vec3d1.x) * 57.2957763671875D - 90.0D); -+ } -+ } + } + } + + // CraftBukkit start - Add per-player time and weather. + public long timeOffset = 0; @@ -1682,7 +1699,7 @@ + public void setPlayerWeather(WeatherType type, boolean plugin) { + if (!plugin && this.weather != null) { + return; - } ++ } + + if (plugin) { + this.weather = type; @@ -1693,7 +1710,7 @@ + } else { + this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0)); + } - } ++ } + + private float pluginRainPosition; + private float pluginRainPositionPrevious; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch index 77dab02fd7..d05bb65208 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch @@ -94,7 +94,7 @@ } private boolean isEquipped(Item item) { -@@ -513,6 +541,13 @@ +@@ -513,6 +541,18 @@ } @@ -104,11 +104,16 @@ + this.containerMenu = this.inventoryMenu; + } + // Paper end - Inventory close reason ++ // Paper start - special close for unloaded inventory ++ public void closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { ++ this.containerMenu = this.inventoryMenu; ++ } ++ // Paper end - special close for unloaded inventory + public void closeContainer() { this.containerMenu = this.inventoryMenu; } -@@ -523,8 +558,14 @@ +@@ -523,8 +563,14 @@ public void rideTick() { if (!this.level().isClientSide && this.wantsToStopRiding() && this.isPassenger()) { this.stopRiding(); @@ -125,7 +130,7 @@ super.rideTick(); this.oBob = this.bob; this.bob = 0.0F; -@@ -593,6 +634,7 @@ +@@ -593,6 +639,7 @@ this.playShoulderEntityAmbientSound(this.getShoulderEntityLeft()); this.playShoulderEntityAmbientSound(this.getShoulderEntityRight()); if (!this.level().isClientSide && (this.fallDistance > 0.5F || this.isInWater()) || this.abilities.flying || this.isSleeping() || this.isInPowderSnow) { @@ -133,7 +138,7 @@ this.removeEntitiesOnShoulder(); } -@@ -719,7 +761,14 @@ +@@ -719,7 +766,14 @@ @Nullable public ItemEntity drop(ItemStack stack, boolean throwRandomly, boolean retainOwnership) { @@ -149,7 +154,7 @@ this.swing(InteractionHand.MAIN_HAND); } -@@ -809,7 +858,7 @@ +@@ -809,7 +863,7 @@ } if (nbt.contains("LastDeathLocation", 10)) { @@ -158,7 +163,7 @@ Logger logger = Player.LOGGER; Objects.requireNonNull(logger); -@@ -817,7 +866,7 @@ +@@ -817,7 +871,7 @@ } if (nbt.contains("current_explosion_impact_pos", 9)) { @@ -167,7 +172,7 @@ Logger logger1 = Player.LOGGER; Objects.requireNonNull(logger1); -@@ -854,7 +903,7 @@ +@@ -854,7 +908,7 @@ } this.getLastDeathLocation().flatMap((globalpos) -> { @@ -176,7 +181,7 @@ Logger logger = Player.LOGGER; Objects.requireNonNull(logger); -@@ -886,10 +935,10 @@ +@@ -886,10 +940,10 @@ if (this.isDeadOrDying()) { return false; } else { @@ -189,7 +194,7 @@ } if (world.getDifficulty() == Difficulty.EASY) { -@@ -901,7 +950,13 @@ +@@ -901,7 +955,13 @@ } } @@ -204,7 +209,7 @@ } } } -@@ -923,10 +978,29 @@ +@@ -923,10 +983,29 @@ } public boolean canHarmPlayer(Player player) { @@ -237,7 +242,7 @@ } @Override -@@ -966,32 +1040,38 @@ +@@ -966,32 +1045,38 @@ } } @@ -290,7 +295,7 @@ } public boolean isTextFilteringEnabled() { -@@ -1061,13 +1141,19 @@ +@@ -1061,13 +1146,19 @@ @Override public void removeVehicle() { @@ -312,7 +317,7 @@ } @Override -@@ -1144,10 +1230,15 @@ +@@ -1144,10 +1235,15 @@ f *= 0.2F + f2 * f2 * 0.8F; f1 *= f2; @@ -329,7 +334,7 @@ if (iprojectile.deflect(ProjectileDeflection.AIM_DEFLECT, this, this, true)) { this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_NODAMAGE, this.getSoundSource()); return; -@@ -1159,7 +1250,7 @@ +@@ -1159,7 +1255,7 @@ boolean flag1; if (this.isSprinting() && flag) { @@ -338,7 +343,7 @@ flag1 = true; } else { flag1 = false; -@@ -1168,7 +1259,9 @@ +@@ -1168,7 +1264,9 @@ f += itemstack.getItem().getAttackDamageBonus(target, f, damagesource); boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround() && !this.onClimbable() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && target instanceof LivingEntity && !this.isSprinting(); @@ -348,7 +353,7 @@ f *= 1.5F; } -@@ -1202,13 +1295,17 @@ +@@ -1202,13 +1300,17 @@ if (target instanceof LivingEntity) { LivingEntity entityliving1 = (LivingEntity) target; @@ -368,7 +373,7 @@ } LivingEntity entityliving2; -@@ -1223,8 +1320,13 @@ +@@ -1223,8 +1325,13 @@ if (entityliving2 != this && entityliving2 != target && !this.isAlliedTo((Entity) entityliving2) && (!(entityliving2 instanceof ArmorStand) || !((ArmorStand) entityliving2).isMarker()) && this.distanceToSqr((Entity) entityliving2) < 9.0D) { float f7 = this.getEnchantedDamage(entityliving2, f6, damagesource) * f2; @@ -384,7 +389,7 @@ Level world = this.level(); if (world instanceof ServerLevel) { -@@ -1235,26 +1337,43 @@ +@@ -1235,26 +1342,43 @@ } } @@ -432,7 +437,7 @@ } } -@@ -1308,9 +1427,14 @@ +@@ -1308,9 +1432,14 @@ } } @@ -449,7 +454,7 @@ } } -@@ -1351,7 +1475,14 @@ +@@ -1351,7 +1480,14 @@ @Override public void remove(Entity.RemovalReason reason) { @@ -465,7 +470,7 @@ this.inventoryMenu.removed(this); if (this.containerMenu != null && this.hasContainerOpen()) { this.doCloseContainer(); -@@ -1391,7 +1522,13 @@ +@@ -1391,7 +1527,13 @@ } public Either startSleepInBed(BlockPos pos) { @@ -480,7 +485,7 @@ this.sleepCounter = 0; return Either.right(Unit.INSTANCE); } -@@ -1545,12 +1682,24 @@ +@@ -1545,12 +1687,24 @@ } public void startFallFlying() { @@ -506,7 +511,7 @@ } @Override -@@ -1664,11 +1813,30 @@ +@@ -1664,11 +1818,30 @@ public int getXpNeededForNextLevel() { return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2); } @@ -538,7 +543,7 @@ } } -@@ -1748,13 +1916,20 @@ +@@ -1748,13 +1921,20 @@ @Override public void setItemSlot(EquipmentSlot slot, ItemStack stack) { @@ -566,7 +571,7 @@ } } -@@ -1798,26 +1973,55 @@ +@@ -1798,26 +1978,55 @@ public void removeEntitiesOnShoulder() { if (this.timeEntitySatOnShoulder + 20L < this.level().getGameTime()) { @@ -629,7 +634,7 @@ } @Override -@@ -2003,20 +2207,31 @@ +@@ -2003,20 +2212,31 @@ @Override public ImmutableList getDismountPoses() { return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING);