385
This commit is contained in:
		
					parent
					
						
							
								e07671b7df
							
						
					
				
			
			
				commit
				
					
						7bcc1a4674
					
				
			
		
					 108 changed files with 127 additions and 173 deletions
				
			
		| 
						 | 
					@ -10,28 +10,35 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
 | 
					+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
 | 
					@@ -0,0 +0,0 @@ public abstract class PlayerList {
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
         boolean flag2 = false;
 | 
					             entityplayer1.addTag(s);
 | 
				
			||||||
 
 | 
					         }
 | 
				
			||||||
+        // Paper start - Add PlayerPostRespawnEvent
 | 
					+        // Paper start - Add PlayerPostRespawnEvent
 | 
				
			||||||
+        boolean isBedSpawn = false;
 | 
					+        boolean isBedSpawn = false;
 | 
				
			||||||
+        boolean isRespawn = false;
 | 
					+        boolean isRespawn = false;
 | 
				
			||||||
+        // Paper end - Add PlayerPostRespawnEvent
 | 
					+        // Paper end - Add PlayerPostRespawnEvent
 | 
				
			||||||
+
 | 
					 | 
				
			||||||
         // CraftBukkit start - fire PlayerRespawnEvent
 | 
					 | 
				
			||||||
         if (location == null) {
 | 
					 | 
				
			||||||
-            boolean isBedSpawn = false;
 | 
					 | 
				
			||||||
+            // boolean isBedSpawn = false; // Paper - Add PlayerPostRespawnEvent; moved up
 | 
					 | 
				
			||||||
             ServerLevel worldserver1 = this.server.getLevel(entityplayer.getRespawnDimension());
 | 
					 | 
				
			||||||
             if (worldserver1 != null) {
 | 
					 | 
				
			||||||
                 Optional optional;
 | 
					 | 
				
			||||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
 | 
					 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
             location = respawnEvent.getRespawnLocation();
 | 
					         // CraftBukkit start - fire PlayerRespawnEvent
 | 
				
			||||||
 | 
					         DimensionTransition dimensiontransition;
 | 
				
			||||||
 | 
					@@ -0,0 +0,0 @@ public abstract class PlayerList {
 | 
				
			||||||
 | 
					             dimensiontransition = entityplayer.findRespawnPositionAndUseSpawnBlock(flag, DimensionTransition.DO_NOTHING, reason);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
             if (!flag) entityplayer.reset(); // SPIGOT-4785
 | 
					             if (!flag) entityplayer.reset(); // SPIGOT-4785
 | 
				
			||||||
+            isRespawn = true; // Paper - Add PlayerPostRespawnEvent
 | 
					+            isRespawn = true; // Paper - Add PlayerPostRespawnEvent
 | 
				
			||||||
         } else {
 | 
					         } else {
 | 
				
			||||||
             location.setWorld(worldserver.getWorld());
 | 
					             dimensiontransition = new DimensionTransition(((CraftWorld) location.getWorld()).getHandle(), CraftLocation.toVec3D(location), Vec3.ZERO, location.getYaw(), location.getPitch(), DimensionTransition.DO_NOTHING);
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
 | 
					@@ -0,0 +0,0 @@ public abstract class PlayerList {
 | 
				
			||||||
 | 
					             if (iblockdata.is(Blocks.RESPAWN_ANCHOR)) {
 | 
				
			||||||
 | 
					                 entityplayer1.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 1.0F, 1.0F, worldserver.getRandom().nextLong()));
 | 
				
			||||||
 | 
					             }
 | 
				
			||||||
 | 
					+            // Paper start - Add PlayerPostRespawnEvent
 | 
				
			||||||
 | 
					+            if (iblockdata.is(net.minecraft.tags.BlockTags.BEDS) && !dimensiontransition.missingRespawnBlock()) {
 | 
				
			||||||
 | 
					+                isBedSpawn = true;
 | 
				
			||||||
 | 
					+            }
 | 
				
			||||||
 | 
					+            // Paper end - Add PlayerPostRespawnEvent
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					         // Added from changeDimension
 | 
				
			||||||
 | 
					         this.sendAllPlayerInfo(entityplayer); // Update health, etc...
 | 
				
			||||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
 | 
					@@ -0,0 +0,0 @@ public abstract class PlayerList {
 | 
				
			||||||
         if (entityplayer.connection.isDisconnected()) {
 | 
					         if (entityplayer.connection.isDisconnected()) {
 | 
				
			||||||
             this.save(entityplayer);
 | 
					             this.save(entityplayer);
 | 
				
			||||||
| 
						 | 
					@ -44,5 +51,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
+        // Paper end - Add PlayerPostRespawnEvent
 | 
					+        // Paper end - Add PlayerPostRespawnEvent
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
         // CraftBukkit end
 | 
					         // CraftBukkit end
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
         return entityplayer1;
 | 
					         return entityplayer1;
 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,7 @@ diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.jav
 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
 | 
					--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
 | 
					+++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class NetherPortalBlock extends Block {
 | 
					@@ -0,0 +0,0 @@ public class NetherPortalBlock extends Block implements Portal {
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
                 if (entity != null) {
 | 
					                 if (entity != null) {
 | 
				
			||||||
                     entity.setPortalCooldown();
 | 
					                     entity.setPortalCooldown();
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
 | 
					+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public abstract class Projectile extends Entity implements TraceableEntity {
 | 
					@@ -0,0 +0,0 @@ public abstract class Projectile extends Entity implements TraceableEntity {
 | 
				
			||||||
         this.shoot((double) f5, (double) f6, (double) f7, speed, divergence);
 | 
					         this.shoot((double) f5, (double) f6, (double) f7, speed, divergence);
 | 
				
			||||||
         Vec3 vec3d = shooter.getDeltaMovement();
 | 
					         Vec3 vec3d = shooter.getKnownMovement();
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
-        this.setDeltaMovement(this.getDeltaMovement().add(vec3d.x, shooter.onGround() ? 0.0D : vec3d.y, vec3d.z));
 | 
					-        this.setDeltaMovement(this.getDeltaMovement().add(vec3d.x, shooter.onGround() ? 0.0D : vec3d.y, vec3d.z));
 | 
				
			||||||
+        if (!shooter.level().paperConfig().misc.disableRelativeProjectileVelocity) this.setDeltaMovement(this.getDeltaMovement().add(vec3d.x, shooter.onGround() ? 0.0D : vec3d.y, vec3d.z)); // Paper - allow disabling relative velocity
 | 
					+        if (!shooter.level().paperConfig().misc.disableRelativeProjectileVelocity) this.setDeltaMovement(this.getDeltaMovement().add(vec3d.x, shooter.onGround() ? 0.0D : vec3d.y, vec3d.z)); // Paper - allow disabling relative velocity
 | 
				
			||||||
| 
						 | 
					@ -16,16 +16,16 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
         this.server = server;
 | 
					         this.server = server;
 | 
				
			||||||
         this.stats = server.getPlayerList().getPlayerStats(this);
 | 
					         this.stats = server.getPlayerList().getPlayerStats(this);
 | 
				
			||||||
         this.advancements = server.getPlayerList().getPlayerAdvancements(this);
 | 
					         this.advancements = server.getPlayerList().getPlayerAdvancements(this);
 | 
				
			||||||
-        this.fudgeSpawnLocation(world);
 | 
					-        this.moveTo(this.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F);
 | 
				
			||||||
+        // this.fudgeSpawnLocation(world); // Paper - Don't move existing players to world spawn
 | 
					+        // this.moveTo(this.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); // Paper - Don't move existing players to world spawn
 | 
				
			||||||
         this.updateOptions(clientOptions);
 | 
					         this.updateOptions(clientOptions);
 | 
				
			||||||
         this.object = null;
 | 
					         this.object = null;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
                 position = Vec3.atCenterOf(world.getSharedSpawnPos());
 | 
					                 position = Vec3.atCenterOf(world.getSharedSpawnPos());
 | 
				
			||||||
             }
 | 
					             }
 | 
				
			||||||
             this.setLevel(world);
 | 
					             this.setLevel(world);
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
         // Paper start - Entity#getEntitySpawnReason
 | 
					         // Paper start - Entity#getEntitySpawnReason
 | 
				
			||||||
         if (optional.isEmpty()) {
 | 
					         if (optional.isEmpty()) {
 | 
				
			||||||
             player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login
 | 
					             player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login
 | 
				
			||||||
+            player.fudgeSpawnLocation(worldserver1); // Paper - Don't move existing players to world spawn
 | 
					+            player.moveTo(player.adjustSpawnLocation(worldserver1, worldserver1.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F);
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
         // Paper end - Entity#getEntitySpawnReason
 | 
					         // Paper end - Entity#getEntitySpawnReason
 | 
				
			||||||
         player.setServerLevel(worldserver1);
 | 
					         player.setServerLevel(worldserver1);
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
     public void doTick() {
 | 
					     public void doTick() {
 | 
				
			||||||
         try {
 | 
					         try {
 | 
				
			||||||
| 
						 | 
					@ -32,11 +32,11 @@ But for those who are ok with leaving this inconsistent behavior, you may use WA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It is recommended you regenerate the entities, as these were legit entities, and deserve your love.
 | 
					It is recommended you regenerate the entities, as these were legit entities, and deserve your love.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
 | 
					diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
 | 
					--- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
 | 
					+++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
 | 
					@@ -0,0 +0,0 @@ public class ChunkStatusTasks {
 | 
				
			||||||
                     entity.discard(null); // CraftBukkit - add Bukkit remove cause
 | 
					                     entity.discard(null); // CraftBukkit - add Bukkit remove cause
 | 
				
			||||||
                     needsRemoval = true;
 | 
					                     needsRemoval = true;
 | 
				
			||||||
                 }
 | 
					                 }
 | 
				
			||||||
| 
						 | 
					@ -44,20 +44,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
                 return !needsRemoval;
 | 
					                 return !needsRemoval;
 | 
				
			||||||
             }));
 | 
					             }));
 | 
				
			||||||
             // CraftBukkit end
 | 
					             // CraftBukkit end
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
 | 
					         }
 | 
				
			||||||
         });
 | 
					 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
+    // Paper start - duplicate uuid resolving
 | 
					+    // Paper start - duplicate uuid resolving
 | 
				
			||||||
+    // rets true if to prevent the entity from being added
 | 
					+    // rets true if to prevent the entity from being added
 | 
				
			||||||
+    public static boolean checkDupeUUID(ServerLevel level, Entity entity) {
 | 
					+    public static boolean checkDupeUUID(ServerLevel level, net.minecraft.world.entity.Entity entity) {
 | 
				
			||||||
+        io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode mode = level.paperConfig().entities.spawning.duplicateUuid.mode;
 | 
					+        io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode mode = level.paperConfig().entities.spawning.duplicateUuid.mode;
 | 
				
			||||||
+        if (mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.WARN
 | 
					+        if (mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.WARN
 | 
				
			||||||
+            && mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.DELETE
 | 
					+            && mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.DELETE
 | 
				
			||||||
+            && mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.SAFE_REGEN) {
 | 
					+            && mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.SAFE_REGEN) {
 | 
				
			||||||
+            return false;
 | 
					+            return false;
 | 
				
			||||||
+        }
 | 
					+        }
 | 
				
			||||||
+        Entity other = level.getEntity(entity.getUUID());
 | 
					+        net.minecraft.world.entity.Entity other = level.getEntity(entity.getUUID());
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
+        if (other == null || other == entity) {
 | 
					+        if (other == null || other == entity) {
 | 
				
			||||||
+            return false;
 | 
					+            return false;
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
+        return false;
 | 
					+        return false;
 | 
				
			||||||
+    }
 | 
					+    }
 | 
				
			||||||
+    // Paper end - duplicate uuid resolving
 | 
					+    // Paper end - duplicate uuid resolving
 | 
				
			||||||
+
 | 
					 }
 | 
				
			||||||
     public CompletableFuture<ChunkResult<LevelChunk>> prepareTickingChunk(ChunkHolder holder) {
 | 
					 | 
				
			||||||
         CompletableFuture<ChunkResult<List<ChunkAccess>>> completablefuture = this.getChunkRangeFuture(holder, 1, (i) -> {
 | 
					 | 
				
			||||||
             return ChunkStatus.FULL;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -45,14 +45,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
         this.age = Math.min(this.age, other.age);
 | 
					         this.age = Math.min(this.age, other.age);
 | 
				
			||||||
         other.discard(EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause
 | 
					         other.discard(EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
 | 
					@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
 | 
				
			||||||
 | 
					                 int l = amount - k * amount / j;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
             itemstack.setDamageValue(itemstack.getDamageValue() - j);
 | 
					                 if (l > 0) {
 | 
				
			||||||
             int k = amount - this.durabilityToXp(j);
 | 
					-                    this.value = l; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls
 | 
				
			||||||
-            this.value = k; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls
 | 
					+                    // this.value = l; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls // Paper - the value field should not be mutated here because it doesn't take "count" into account
 | 
				
			||||||
+            // this.value = k; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls // Paper - the value field should not be mutated here because it doesn't take "count" into account
 | 
					                     return this.repairPlayerItems(player, l);
 | 
				
			||||||
 
 | 
					                 }
 | 
				
			||||||
             return k > 0 ? this.repairPlayerItems(player, k) : 0;
 | 
					             }
 | 
				
			||||||
         } else {
 | 
					 | 
				
			||||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
 | 
					diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
 | 
					--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
     public double maxHealthCache;
 | 
					     public double maxHealthCache;
 | 
				
			||||||
     public boolean joining = true;
 | 
					     public boolean joining = true;
 | 
				
			||||||
     public boolean sentListPacket = false;
 | 
					     public boolean sentListPacket = false;
 | 
				
			||||||
| 
						 | 
					@ -81,10 +81,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
         player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn
 | 
					         player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn
 | 
				
			||||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
 | 
					@@ -0,0 +0,0 @@ public abstract class PlayerList {
 | 
				
			||||||
 
 | 
					         worldserver1 = player.serverLevel(); // CraftBukkit - Update in case join event changed it
 | 
				
			||||||
             playerconnection.send(new ClientboundUpdateMobEffectPacket(player.getId(), mobeffect, false));
 | 
					         // CraftBukkit end
 | 
				
			||||||
         }
 | 
					         this.sendActivePlayerEffects(player);
 | 
				
			||||||
-
 | 
					 | 
				
			||||||
+        // Paper start - Fire PlayerJoinEvent when Player is actually ready; move vehicle into method so it can be called above - short circuit around that code
 | 
					+        // Paper start - Fire PlayerJoinEvent when Player is actually ready; move vehicle into method so it can be called above - short circuit around that code
 | 
				
			||||||
+        this.onPlayerJoinFinish(player, worldserver1, s1);
 | 
					+        this.onPlayerJoinFinish(player, worldserver1, s1);
 | 
				
			||||||
+    }
 | 
					+    }
 | 
				
			||||||
| 
						 | 
					@ -75,19 +75,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
     @Override
 | 
					     @Override
 | 
				
			||||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					 | 
				
			||||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					 | 
				
			||||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					 | 
				
			||||||
                 this.isChangingDimension = true; // CraftBukkit - Set teleport invulnerability only if player changing worlds
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
                 this.connection.send(new ClientboundRespawnPacket(this.createCommonSpawnInfo(worldserver), (byte) 3));
 | 
					 | 
				
			||||||
-                this.connection.send(new ClientboundChangeDifficultyPacket(this.level().getDifficulty(), this.level().getLevelData().isDifficultyLocked()));
 | 
					 | 
				
			||||||
+                this.connection.send(new ClientboundChangeDifficultyPacket(worldserver.getDifficulty(), this.level().getLevelData().isDifficultyLocked())); // Paper - per level difficulty
 | 
					 | 
				
			||||||
                 PlayerList playerlist = this.server.getPlayerList();
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
                 playerlist.sendPlayerPermissionLevel(this);
 | 
					 | 
				
			||||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
 | 
					diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
 | 
					--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
 | 
				
			||||||
| 
						 | 
					@ -35,47 +35,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
             entityitem.setDefaultPickUpDelay();
 | 
					             entityitem.setDefaultPickUpDelay();
 | 
				
			||||||
             // CraftBukkit start
 | 
					             // CraftBukkit start
 | 
				
			||||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
 | 
					@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
 | 
				
			||||||
     @Nullable
 | 
					     public Entity changeDimension(DimensionTransition teleportTarget) {
 | 
				
			||||||
     public Entity teleportTo(ServerLevel worldserver, Vec3 location) {
 | 
					         Level world = this.level();
 | 
				
			||||||
         // CraftBukkit end
 | 
					 
 | 
				
			||||||
+        // Paper start - Fix item duplication and teleport issues
 | 
					+        // Paper start - Fix item duplication and teleport issues
 | 
				
			||||||
+        if (!this.isAlive() || !this.valid) {
 | 
					+        if (!this.isAlive() || !this.valid) {
 | 
				
			||||||
+            LOGGER.warn("Illegal Entity Teleport " + this + " to " + worldserver + ":" + location, new Throwable());
 | 
					+            LOGGER.warn("Illegal Entity Teleport " + this + " to " + teleportTarget.newLevel() + ":" + teleportTarget.pos(), new Throwable());
 | 
				
			||||||
+            return null;
 | 
					+            return null;
 | 
				
			||||||
+        }
 | 
					+        }
 | 
				
			||||||
+        // Paper end - Fix item duplication and teleport issues
 | 
					+        // Paper end - Fix item duplication and teleport issues
 | 
				
			||||||
         if (this.level() instanceof ServerLevel && !this.isRemoved()) {
 | 
					         if (world instanceof ServerLevel worldserver) {
 | 
				
			||||||
             this.level().getProfiler().push("changeDimension");
 | 
					             if (!this.isRemoved()) {
 | 
				
			||||||
             // CraftBukkit start
 | 
					                 // CraftBukkit start
 | 
				
			||||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
 | 
					@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
 | 
				
			||||||
                 // CraftBukkit end
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
                 this.level().getProfiler().popPush("reloading");
 | 
					 | 
				
			||||||
+                // Paper start - Fix item duplication and teleport issues
 | 
					 | 
				
			||||||
+                if (this instanceof Mob) {
 | 
					 | 
				
			||||||
+                    ((Mob) this).dropLeash(true, true); // Paper drop lead
 | 
					 | 
				
			||||||
+                }
 | 
					 | 
				
			||||||
+                // Paper end - Fix item duplication and teleport issues
 | 
					 | 
				
			||||||
                 Entity entity = this.getType().create(worldserver);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
                 if (entity != null) {
 | 
					 | 
				
			||||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
 | 
					 | 
				
			||||||
                     // CraftBukkit start - Forward the CraftEntity to the new entity
 | 
					 | 
				
			||||||
                     this.getBukkitEntity().setHandle(entity);
 | 
					 | 
				
			||||||
                     entity.bukkitEntity = this.getBukkitEntity();
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-                    if (this instanceof Mob) {
 | 
					 | 
				
			||||||
-                        ((Mob) this).dropLeash(true, false); // Unleash to prevent duping of leads.
 | 
					 | 
				
			||||||
-                    }
 | 
					 | 
				
			||||||
                     // CraftBukkit end
 | 
					 | 
				
			||||||
                 }
 | 
					 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 | 
					                 if (entity2 != null) {
 | 
				
			||||||
 | 
					                     if (this != entity2) {
 | 
				
			||||||
 | 
					+                        // Paper start - Fix item duplication and teleport issues
 | 
				
			||||||
 | 
					+                        if (this instanceof Mob) {
 | 
				
			||||||
 | 
					+                            ((Mob) this).dropLeash(true, true); // Paper drop lead
 | 
				
			||||||
 | 
					+                        }
 | 
				
			||||||
 | 
					+                        // Paper end - Fix item duplication and teleport issues
 | 
				
			||||||
 | 
					                         entity2.restoreFrom(this);
 | 
				
			||||||
 | 
					                         this.removeAfterChangingDimensions();
 | 
				
			||||||
 | 
					                         // CraftBukkit start - Forward the CraftEntity to the new entity
 | 
				
			||||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
 | 
					@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
     public boolean canChangeDimensions() {
 | 
					     public boolean canChangeDimensions(Level from, Level to) {
 | 
				
			||||||
-        return !this.isPassenger() && !this.isVehicle();
 | 
					-        return true;
 | 
				
			||||||
+        return !this.isPassenger() && !this.isVehicle() && isAlive() && valid; // Paper - Fix item duplication and teleport issues
 | 
					+        return this.isAlive() && this.valid; // Paper - Fix item duplication and teleport issues
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
     public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) {
 | 
					     public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) {
 | 
				
			||||||
| 
						 | 
					@ -85,7 +74,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
 | 
					+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
 | 
					@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
 | 
				
			||||||
                 // Paper start
 | 
					                 // Paper start
 | 
				
			||||||
                 org.bukkit.event.entity.EntityDeathEvent deathEvent = this.dropAllDeathLoot(damageSource);
 | 
					                 org.bukkit.event.entity.EntityDeathEvent deathEvent = this.dropAllDeathLoot(worldserver, damageSource);
 | 
				
			||||||
                 if (deathEvent == null || !deathEvent.isCancelled()) {
 | 
					                 if (deathEvent == null || !deathEvent.isCancelled()) {
 | 
				
			||||||
-                    if (this.deathScore >= 0 && entityliving != null) {
 | 
					-                    if (this.deathScore >= 0 && entityliving != null) {
 | 
				
			||||||
-                        entityliving.awardKillScore(this, this.deathScore, damageSource);
 | 
					-                        entityliving.awardKillScore(this, this.deathScore, damageSource);
 | 
				
			||||||
| 
						 | 
					@ -97,16 +86,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
                     if (this instanceof Mob) {
 | 
					                     if (this instanceof Mob) {
 | 
				
			||||||
                         for (EquipmentSlot slot : this.clearedEquipmentSlots) {
 | 
					                         for (EquipmentSlot slot : this.clearedEquipmentSlots) {
 | 
				
			||||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
 | 
					@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
 | 
				
			||||||
             this.dropCustomDeathLoot(source, i, flag);
 | 
					             this.dropCustomDeathLoot(world, damageSource, flag);
 | 
				
			||||||
             this.clearEquipmentSlots = prev; // Paper
 | 
					             this.clearEquipmentSlots = prev; // Paper
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
-        // CraftBukkit start - Call death event
 | 
					-        // CraftBukkit start - Call death event
 | 
				
			||||||
-        org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, source, this.drops); // Paper
 | 
					-        org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, damageSource, this.drops); // Paper
 | 
				
			||||||
+        // CraftBukkit start - Call death event // Paper start - call advancement triggers with correct entity equipment
 | 
					+        // CraftBukkit start - Call death event // Paper start - call advancement triggers with correct entity equipment
 | 
				
			||||||
+        org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, source, this.drops, () -> {
 | 
					+        org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, damageSource, this.drops, () -> {
 | 
				
			||||||
+            final LivingEntity entityliving = this.getKillCredit();
 | 
					+            final LivingEntity entityliving = this.getKillCredit();
 | 
				
			||||||
+            if (this.deathScore >= 0 && entityliving != null) {
 | 
					+            if (this.deathScore >= 0 && entityliving != null) {
 | 
				
			||||||
+                entityliving.awardKillScore(this, this.deathScore, source);
 | 
					+                entityliving.awardKillScore(this, this.deathScore, damageSource);
 | 
				
			||||||
+            }
 | 
					+            }
 | 
				
			||||||
+        }); // Paper end
 | 
					+        }); // Paper end
 | 
				
			||||||
         this.postDeathDropItems(deathEvent); // Paper
 | 
					         this.postDeathDropItems(deathEvent); // Paper
 | 
				
			||||||
| 
						 | 
					@ -149,7 +138,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
+        // Paper end
 | 
					+        // Paper end
 | 
				
			||||||
         CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
 | 
					         CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
 | 
				
			||||||
         CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
 | 
					         CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
 | 
				
			||||||
         EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward());
 | 
					         EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity()));
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
 | 
					@@ -0,0 +0,0 @@ public class CraftEventFactory {
 | 
				
			||||||
         playDeathSound(victim, event);
 | 
					         playDeathSound(victim, event);
 | 
				
			||||||
         // Paper end
 | 
					         // Paper end
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
+        }
 | 
					+        }
 | 
				
			||||||
+    }
 | 
					+    }
 | 
				
			||||||
+    // Paper end - guard against serializing mismatching coordinates
 | 
					+    // Paper end - guard against serializing mismatching coordinates
 | 
				
			||||||
     public static ProtoChunk read(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt) {
 | 
					+
 | 
				
			||||||
 | 
					     public static ProtoChunk read(ServerLevel world, PoiManager poiStorage, RegionStorageInfo key, ChunkPos chunkPos, CompoundTag nbt) {
 | 
				
			||||||
-        ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos"));
 | 
					-        ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos"));
 | 
				
			||||||
+        ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); // Paper - guard against serializing mismatching coordinates; diff on change, see ChunkSerializer#getChunkCoordinate
 | 
					+        ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); // Paper - guard against serializing mismatching coordinates; diff on change, see ChunkSerializer#getChunkCoordinate
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
| 
						 | 
					@ -90,16 +90,16 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
         this.stats = server.getPlayerList().getPlayerStats(this);
 | 
					         this.stats = server.getPlayerList().getPlayerStats(this);
 | 
				
			||||||
         this.advancements = server.getPlayerList().getPlayerAdvancements(this);
 | 
					         this.advancements = server.getPlayerList().getPlayerAdvancements(this);
 | 
				
			||||||
         // this.fudgeSpawnLocation(world); // Paper - Don't move existing players to world spawn
 | 
					         // this.moveTo(this.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); // Paper - Don't move existing players to world spawn
 | 
				
			||||||
-        this.updateOptions(clientOptions);
 | 
					-        this.updateOptions(clientOptions);
 | 
				
			||||||
+        this.updateOptionsNoEvents(clientOptions); // Paper - don't call options events on login
 | 
					+        this.updateOptionsNoEvents(clientOptions); // Paper - don't call options events on login
 | 
				
			||||||
         this.object = null;
 | 
					         this.object = null;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
         this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper
 | 
					         this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
| 
						 | 
					@ -123,12 +123,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
         // CraftBukkit start
 | 
					         // CraftBukkit start
 | 
				
			||||||
         if (this.getMainArm() != clientOptions.mainHand()) {
 | 
					         if (this.getMainArm() != clientOptions.mainHand()) {
 | 
				
			||||||
             PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), this.getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
 | 
					             PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), this.getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
             this.server.server.getPluginManager().callEvent(new com.destroystokyo.paper.event.player.PlayerLocaleChangeEvent(this.getBukkitEntity(), this.language, clientOptions.language())); // Paper
 | 
					             this.server.server.getPluginManager().callEvent(new com.destroystokyo.paper.event.player.PlayerLocaleChangeEvent(this.getBukkitEntity(), this.language, clientOptions.language())); // Paper
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
         // CraftBukkit end
 | 
					         // CraftBukkit end
 | 
				
			||||||
+        // Paper start - don't call options events on login
 | 
					+        // Paper start - don't call options events on login
 | 
				
			||||||
+        updateOptionsNoEvents(clientOptions);
 | 
					+        this.updateOptionsNoEvents(clientOptions);
 | 
				
			||||||
+    }
 | 
					+    }
 | 
				
			||||||
+    public void updateOptionsNoEvents(ClientInformation clientOptions) {
 | 
					+    public void updateOptionsNoEvents(ClientInformation clientOptions) {
 | 
				
			||||||
+        // Paper end
 | 
					+        // Paper end
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
+    }
 | 
					+    }
 | 
				
			||||||
+    public void afterDestroy(Level world, BlockPos pos, ItemStack tool) {
 | 
					+    public void afterDestroy(Level world, BlockPos pos, ItemStack tool) {
 | 
				
			||||||
+        // Paper end - Improve Block#breakNaturally API
 | 
					+        // Paper end - Improve Block#breakNaturally API
 | 
				
			||||||
         if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) == 0) {
 | 
					         if (!EnchantmentHelper.hasTag(tool, EnchantmentTags.PREVENTS_ICE_MELTING)) {
 | 
				
			||||||
             if (world.dimensionType().ultraWarm()) {
 | 
					             if (world.dimensionType().ultraWarm()) {
 | 
				
			||||||
                 world.removeBlock(pos, false);
 | 
					                 world.removeBlock(pos, false);
 | 
				
			||||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
 | 
					diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
 | 
				
			||||||
| 
						 | 
					@ -80,7 +80,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
+        }
 | 
					+        }
 | 
				
			||||||
+        if (optional.isEmpty() || invalidPlayerWorld[0]) {
 | 
					+        if (optional.isEmpty() || invalidPlayerWorld[0]) {
 | 
				
			||||||
+            // Paper end - reset to main world spawn if first spawn or invalid world
 | 
					+            // Paper end - reset to main world spawn if first spawn or invalid world
 | 
				
			||||||
             player.fudgeSpawnLocation(worldserver1); // Paper - Don't move existing players to world spawn
 | 
					             player.moveTo(player.adjustSpawnLocation(worldserver1, worldserver1.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F);
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
         // Paper end - Entity#getEntitySpawnReason
 | 
					         // Paper end - Entity#getEntitySpawnReason
 | 
				
			||||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
 | 
					diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
 | 
				
			||||||
| 
						 | 
					@ -30,10 +30,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
-            this.level.getProfiler().incrementCounter("getChunkNow");
 | 
					-            this.level.getProfiler().incrementCounter("getChunkNow");
 | 
				
			||||||
-            long k = ChunkPos.asLong(chunkX, chunkZ);
 | 
					-            long k = ChunkPos.asLong(chunkX, chunkZ);
 | 
				
			||||||
-
 | 
					-
 | 
				
			||||||
 | 
					-            ChunkAccess ichunkaccess;
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
-            for (int l = 0; l < 4; ++l) {
 | 
					-            for (int l = 0; l < 4; ++l) {
 | 
				
			||||||
-                if (k == this.lastChunkPos[l] && this.lastChunkStatus[l] == ChunkStatus.FULL) {
 | 
					-                if (k == this.lastChunkPos[l] && this.lastChunkStatus[l] == ChunkStatus.FULL) {
 | 
				
			||||||
-                    ChunkAccess ichunkaccess = this.lastChunk[l];
 | 
					-                    ichunkaccess = this.lastChunk[l];
 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-                    return ichunkaccess instanceof LevelChunk ? (LevelChunk) ichunkaccess : null;
 | 
					-                    return ichunkaccess instanceof LevelChunk ? (LevelChunk) ichunkaccess : null;
 | 
				
			||||||
-                }
 | 
					-                }
 | 
				
			||||||
-            }
 | 
					-            }
 | 
				
			||||||
| 
						 | 
					@ -43,22 +44,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
-            if (playerchunk == null) {
 | 
					-            if (playerchunk == null) {
 | 
				
			||||||
-                return null;
 | 
					-                return null;
 | 
				
			||||||
-            } else {
 | 
					-            } else {
 | 
				
			||||||
-                ChunkResult<ChunkAccess> chunkresult = (ChunkResult) playerchunk.getFutureIfPresent(ChunkStatus.FULL).getNow(null); // CraftBukkit - decompile error
 | 
					-                ichunkaccess = playerchunk.getChunkIfPresent(ChunkStatus.FULL);
 | 
				
			||||||
-
 | 
					-                if (ichunkaccess != null) {
 | 
				
			||||||
-                if (chunkresult == null) {
 | 
					-                    this.storeInCache(k, ichunkaccess, ChunkStatus.FULL);
 | 
				
			||||||
-                    return null;
 | 
					-                    if (ichunkaccess instanceof LevelChunk) {
 | 
				
			||||||
-                } else {
 | 
					-                        return (LevelChunk) ichunkaccess;
 | 
				
			||||||
-                    ChunkAccess ichunkaccess1 = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-                    if (ichunkaccess1 != null) {
 | 
					 | 
				
			||||||
-                        this.storeInCache(k, ichunkaccess1, ChunkStatus.FULL);
 | 
					 | 
				
			||||||
-                        if (ichunkaccess1 instanceof LevelChunk) {
 | 
					 | 
				
			||||||
-                            return (LevelChunk) ichunkaccess1;
 | 
					 | 
				
			||||||
-                        }
 | 
					 | 
				
			||||||
-                    }
 | 
					-                    }
 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-                    return null;
 | 
					 | 
				
			||||||
-                }
 | 
					-                }
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-                return null;
 | 
				
			||||||
-            }
 | 
					-            }
 | 
				
			||||||
+            return this.getChunkAtIfLoadedMainThread(chunkX, chunkZ); // Paper - Perf: Optimise getChunkAt calls for loaded chunks
 | 
					+            return this.getChunkAtIfLoadedMainThread(chunkX, chunkZ); // Paper - Perf: Optimise getChunkAt calls for loaded chunks
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
     public boolean wonGame;
 | 
					     public boolean wonGame;
 | 
				
			||||||
     private int containerUpdateDelay; // Paper - Configurable container update tick rate
 | 
					     private int containerUpdateDelay; // Paper - Configurable container update tick rate
 | 
				
			||||||
     public long loginTime; // Paper - Replace OfflinePlayer#getLastPlayed
 | 
					     public long loginTime; // Paper - Replace OfflinePlayer#getLastPlayed
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
         });
 | 
					         });
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
| 
						 | 
					@ -61,8 +61,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
     @Override
 | 
					     @Override
 | 
				
			||||||
     public void die(DamageSource damageSource) {
 | 
					     public void die(DamageSource damageSource) {
 | 
				
			||||||
         // this.gameEvent(GameEvent.ENTITY_DIE); // Paper - move below event cancellation check
 | 
					         // this.gameEvent(GameEvent.ENTITY_DIE); // Paper - move below event cancellation check
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
         this.dropExperience();
 | 
					         this.dropExperience(damageSource.getEntity());
 | 
				
			||||||
         // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory.
 | 
					         // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory.
 | 
				
			||||||
         if (!event.getKeepInventory()) {
 | 
					         if (!event.getKeepInventory()) {
 | 
				
			||||||
-            this.getInventory().clearContent();
 | 
					-            this.getInventory().clearContent();
 | 
				
			||||||
| 
						 | 
					@ -8,12 +8,12 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
             this.tellNeutralMobsThatIDied();
 | 
					             this.tellNeutralMobsThatIDied();
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
         // SPIGOT-5478 must be called manually now
 | 
					         // SPIGOT-5478 must be called manually now
 | 
				
			||||||
-        this.dropExperience();
 | 
					-        this.dropExperience(damageSource.getEntity());
 | 
				
			||||||
+        if (event.shouldDropExperience()) this.dropExperience(); // Paper - tie to event
 | 
					+        if (event.shouldDropExperience()) this.dropExperience(damageSource.getEntity()); // Paper - tie to event
 | 
				
			||||||
         // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory.
 | 
					         // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory.
 | 
				
			||||||
         if (!event.getKeepInventory()) {
 | 
					         if (!event.getKeepInventory()) {
 | 
				
			||||||
             // Paper start - PlayerDeathEvent#getItemsToKeep
 | 
					             // Paper start - PlayerDeathEvent#getItemsToKeep
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
-        if (!itemstack.isEmpty() && !this.isUsingItem()) {
 | 
					-        if (!itemstack.isEmpty() && !this.isUsingItem()) {
 | 
				
			||||||
+        if (!itemstack.isEmpty() && !this.isUsingItem() || forceUpdate) { // Paper - Prevent consuming the wrong itemstack
 | 
					+        if (!itemstack.isEmpty() && !this.isUsingItem() || forceUpdate) { // Paper - Prevent consuming the wrong itemstack
 | 
				
			||||||
             this.useItem = itemstack;
 | 
					             this.useItem = itemstack;
 | 
				
			||||||
             this.useItemRemaining = itemstack.getUseDuration();
 | 
					             this.useItemRemaining = itemstack.getUseDuration(this);
 | 
				
			||||||
             if (!this.level().isClientSide) {
 | 
					             if (!this.level().isClientSide) {
 | 
				
			||||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
 | 
					@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
 | 
				
			||||||
                 this.releaseUsingItem();
 | 
					                 this.releaseUsingItem();
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
 | 
				
			||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
					+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
             containerUpdateDelay = this.level().paperConfig().tickRates.containerUpdate;
 | 
					             containerUpdateDelay = this.level().paperConfig().tickRates.containerUpdate;
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
         // Paper end - Configurable container update tick rate
 | 
					         // Paper end - Configurable container update tick rate
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
             this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper - Inventory close reason
 | 
					             this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper - Inventory close reason
 | 
				
			||||||
             this.containerMenu = this.inventoryMenu;
 | 
					             this.containerMenu = this.inventoryMenu;
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 | 
					@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
 | 
				
			||||||
             } else {
 | 
					             } else {
 | 
				
			||||||
                 // CraftBukkit start
 | 
					                 // CraftBukkit start
 | 
				
			||||||
                 this.containerMenu = container;
 | 
					                 this.containerMenu = container;
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue