diff --git a/SHIT_TO_CHECK.md b/SHIT_TO_CHECK.md new file mode 100644 index 0000000000..6077d66cd2 --- /dev/null +++ b/SHIT_TO_CHECK.md @@ -0,0 +1,6 @@ +# Shit to check + +* Mini: "Allow disabling armour stand ticking": Not sure if the equipment update actually works, vanilla shifted a bunch of shit +* Mini: "Optimize World Server Map": Figure out how to fill PaperWorldMap, it needs a dim key which doesnt exist anymore? +* Mini: "MC-50319": fix if still works +* Mini: I definetly dropped a patch I didnt want to drop, we need to go thru in the end and see if all patches are still in, lol diff --git a/Spigot-Server-Patches/Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch b/Spigot-Server-Patches/Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch index 25ff9cc73a..20c6b35293 100644 --- a/Spigot-Server-Patches/Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch +++ b/Spigot-Server-Patches/Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch @@ -23,13 +23,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } else { - PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = new PlayerChunkMap.EntityTracker(entity, i, j, entitytypes.isDeltaTracking()); + } else { + PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = new PlayerChunkMap.EntityTracker(entity, i, j, entitytypes.isDeltaTracking()); -+ entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker - this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker); - playerchunkmap_entitytracker.track(this.world.getPlayers()); - if (entity instanceof EntityPlayer) { ++ entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker + this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker); + playerchunkmap_entitytracker.track(this.world.getPlayers()); + if (entity instanceof EntityPlayer) { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { if (playerchunkmap_entitytracker1 != null) { playerchunkmap_entitytracker1.a(); @@ -55,17 +55,17 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { - // CraftBukkit start - private int tickPosition; +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { + public final UUID uuid; + boolean hasPhysicsEvent = true; // Paper + private static Throwable getAddToWorldStackTrace(Entity entity) { + return new Throwable(entity + " Added to world at " + new java.util.Date()); + } - // Add env and gen to constructor - public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { -@@ -0,0 +0,0 @@ public class WorldServer extends World { + public Chunk getChunkIfLoaded(int x, int z) { + return this.chunkProvider.getChunkAt(x, z, false); +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { // CraftBukkit start private boolean addEntity0(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) { org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot @@ -95,7 +95,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getName(entity.getEntityType())); // CraftBukkit return false; } else if (this.isUUIDTaken(entity)) { -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { } } diff --git a/Spigot-Server-Patches/Add-LivingEntity-getTargetEntity.patch b/Spigot-Server-Patches/Add-LivingEntity-getTargetEntity.patch index 2cc27e09fc..5654137fe9 100644 --- a/Spigot-Server-Patches/Add-LivingEntity-getTargetEntity.patch +++ b/Spigot-Server-Patches/Add-LivingEntity-getTargetEntity.patch @@ -33,8 +33,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return this.minX < d3 && this.maxX > d0 && this.minY < d4 && this.maxY > d1 && this.minZ < d5 && this.maxZ > d2; } -+ public final boolean contains(Vec3D vec3d) { return c(vec3d); } // Paper - OBFHELPER - public boolean c(Vec3D vec3d) { ++ public final boolean contains(Vec3D vec3d) { return d(vec3d); } // Paper - OBFHELPER + public boolean d(Vec3D vec3d) { return this.e(vec3d.x, vec3d.y, vec3d.z); } @@ -0,0 +0,0 @@ public class AxisAlignedBB { @@ -61,8 +61,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return this.getPassengers().size() < 1; } -+ public final float getCollisionBorderSize() { return aV(); } // Paper - OBFHELPER - public float aV() { ++ public final float getCollisionBorderSize() { return bc(); } // Paper - OBFHELPER + public float bc() { return 0.0F; } diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java @@ -117,7 +117,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 }; + public static Predicate notSpectator() { return f; } // Paper - OBFHELPER public static final Predicate f = (entity) -> { - return !entity.isSpectator(); + return !(entity instanceof EntityHuman) || !entity.isSpectator() && !((EntityHuman) entity).isCreative() && entity.world.getDifficulty() != EnumDifficulty.PEACEFUL; }; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/Add-More-Creeper-API.patch b/Spigot-Server-Patches/Add-More-Creeper-API.patch index 3db233fd66..b715d9b89e 100644 --- a/Spigot-Server-Patches/Add-More-Creeper-API.patch +++ b/Spigot-Server-Patches/Add-More-Creeper-API.patch @@ -11,12 +11,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class EntityCreeper extends EntityMonster { private static final DataWatcherObject POWERED = DataWatcher.a(EntityCreeper.class, DataWatcherRegistry.i); private static final DataWatcherObject d = DataWatcher.a(EntityCreeper.class, DataWatcherRegistry.i); private static final DataWatcherObject isIgnitedDW = d; // Paper OBFHELPER - private int bw; + private int bv; - private int fuseTicks; + public int fuseTicks; // Paper - public public int maxFuseTicks = 30; public int explosionRadius = 3; - private int bA; + private int bz; @@ -0,0 +0,0 @@ public class EntityCreeper extends EntityMonster { } diff --git a/Spigot-Server-Patches/Add-PhantomPreSpawnEvent.patch b/Spigot-Server-Patches/Add-PhantomPreSpawnEvent.patch index 4edf1de8c2..c936637787 100644 --- a/Spigot-Server-Patches/Add-PhantomPreSpawnEvent.patch +++ b/Spigot-Server-Patches/Add-PhantomPreSpawnEvent.patch @@ -51,7 +51,7 @@ diff --git a/src/main/java/net/minecraft/server/MobSpawnerPhantom.java b/src/mai index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/MobSpawnerPhantom.java +++ b/src/main/java/net/minecraft/server/MobSpawnerPhantom.java -@@ -0,0 +0,0 @@ public class MobSpawnerPhantom { +@@ -0,0 +0,0 @@ public class MobSpawnerPhantom implements MobSpawner { int k = 1 + random.nextInt(difficultydamagescaler.a().a() + 1); for (int l = 0; l < k; ++l) { diff --git a/Spigot-Server-Patches/Add-PlayerConnectionCloseEvent.patch b/Spigot-Server-Patches/Add-PlayerConnectionCloseEvent.patch index 2fa43e13ce..a06a43a143 100644 --- a/Spigot-Server-Patches/Add-PlayerConnectionCloseEvent.patch +++ b/Spigot-Server-Patches/Add-PlayerConnectionCloseEvent.patch @@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/NetworkManager.java +++ b/src/main/java/net/minecraft/server/NetworkManager.java @@ -0,0 +0,0 @@ public class NetworkManager extends SimpleChannelInboundHandler> { - this.i().a(new ChatMessage("multiplayer.disconnect.generic", new Object[0])); + this.i().a(new ChatMessage("multiplayer.disconnect.generic")); } this.packetQueue.clear(); // Free up packet queue. + // Paper start - Add PlayerConnectionCloseEvent diff --git a/Spigot-Server-Patches/Add-TNTPrimeEvent.patch b/Spigot-Server-Patches/Add-TNTPrimeEvent.patch index dfa1303149..e070a1b9cb 100644 --- a/Spigot-Server-Patches/Add-TNTPrimeEvent.patch +++ b/Spigot-Server-Patches/Add-TNTPrimeEvent.patch @@ -15,17 +15,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import com.destroystokyo.paper.event.block.TNTPrimeEvent; // Paper - TNTPrimeEvent import java.util.Map; import java.util.Random; - import java.util.Map.Entry; -@@ -0,0 +0,0 @@ public class BlockFire extends Block { - world.setTypeAndData(blockposition, (IBlockData) this.a((IBlockAccess) world, blockposition).set(BlockFire.AGE, l), 3); +@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { + + world.setTypeAndData(blockposition, this.a(world, blockposition, l), 3); } else { - world.a(blockposition, false); + if(iblockdata.getBlock() != Blocks.TNT) world.a(blockposition, false); // Paper - TNTPrimeEvent - We might be cancelling it below, move the setAir down } Block block = iblockdata.getBlock(); -@@ -0,0 +0,0 @@ public class BlockFire extends Block { +@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { if (block instanceof BlockTNT) { BlockTNT blocktnt = (BlockTNT) block; @@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class BlockTNT extends Block { public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { - if (iblockdata1.getBlock() != iblockdata.getBlock()) { + if (!iblockdata1.a(iblockdata.getBlock())) { if (world.isBlockIndirectlyPowered(blockposition)) { + // Paper start - TNTPrimeEvent + org.bukkit.block.Block tntBlock = MCUtil.toBukkitBlock(world, blockposition);; @@ -80,12 +80,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void wasExploded(World world, BlockPosition blockposition, Explosion explosion) { if (!world.isClientSide) { + // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = MCUtil.toBukkitBlock(world, blockposition);; ++ org.bukkit.block.Block tntBlock = MCUtil.toBukkitBlock(world, blockposition); + org.bukkit.entity.Entity source = explosion.source != null ? explosion.source.getBukkitEntity() : null; + if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent()) + return; + // Paper end - EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) blockposition.getX() + 0.5F), (double) blockposition.getY(), (double) ((float) blockposition.getZ() + 0.5F), explosion.getSource()); + EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, explosion.getSource()); entitytntprimed.setFuseTicks((short) (world.random.nextInt(entitytntprimed.getFuseTicks() / 4) + entitytntprimed.getFuseTicks() / 8)); @@ -0,0 +0,0 @@ public class BlockTNT extends Block { @@ -106,12 +106,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - TNTPrimeEvent + org.bukkit.block.Block tntBlock = MCUtil.toBukkitBlock(world, blockposition); -+ if (!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.PROJECTILE, entityarrow.getBukkitEntity()).callEvent()) { ++ if (!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.PROJECTILE, iprojectile.getBukkitEntity()).callEvent()) { + return; + } + // Paper end + - a(world, blockposition, entity1 instanceof EntityLiving ? (EntityLiving) entity1 : null); + a(world, blockposition, entity instanceof EntityLiving ? (EntityLiving) entity : null); world.a(blockposition, false); } diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java @@ -128,7 +128,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public class EntityEnderDragon extends EntityInsentient implements IMonster { @@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { }); - craftBlock.getNMS().dropNaturally(world, blockposition, ItemStack.a); + craftBlock.getNMS().dropNaturally(world, blockposition, ItemStack.b); } + // Paper start - TNTPrimeEvent + org.bukkit.block.Block tntBlock = world.getWorld().getBlockAt(blockposition.x, blockposition.y, blockposition.z); diff --git a/Spigot-Server-Patches/Add-Velocity-IP-Forwarding-Support.patch b/Spigot-Server-Patches/Add-Velocity-IP-Forwarding-Support.patch index 5783f3dcf8..34707dec93 100644 --- a/Spigot-Server-Patches/Add-Velocity-IP-Forwarding-Support.patch +++ b/Spigot-Server-Patches/Add-Velocity-IP-Forwarding-Support.patch @@ -35,8 +35,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public static int packetInSpamThreshold = 300; @@ -0,0 +0,0 @@ public class PaperConfig { - } } + tabSpamLimit = getInt("settings.spam-limiter.tab-spam-limit", tabSpamLimit); } + + public static boolean velocitySupport; @@ -202,7 +202,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return; + } + // Paper end - this.disconnect(new ChatMessage("multiplayer.disconnect.unexpected_query_response", new Object[0])); + this.disconnect(new ChatMessage("multiplayer.disconnect.unexpected_query_response")); } diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java diff --git a/Spigot-Server-Patches/Add-config-to-disable-ender-dragon-legacy-check.patch b/Spigot-Server-Patches/Add-config-to-disable-ender-dragon-legacy-check.patch index 60c8380507..db52112c64 100644 --- a/Spigot-Server-Patches/Add-config-to-disable-ender-dragon-legacy-check.patch +++ b/Spigot-Server-Patches/Add-config-to-disable-ender-dragon-legacy-check.patch @@ -26,23 +26,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private int h; private int i; private int j; -- private boolean k; -+ private boolean k; private void setDragonKilled(boolean dragonKilled) { this.k = dragonKilled; } // Paper - OBFHELPER - private boolean l; - public UUID m; // CraftBukkit PAIL private -> public, rename dragonUUID +- private boolean dragonKilled; ++ private boolean dragonKilled; private void setDragonKilled(boolean dragonKilled) { this.dragonKilled = dragonKilled; } // Paper - OBFHELPER + private boolean previouslyKilled; + public UUID dragonUUID; - private boolean n; + private boolean n; private void setScanForLegacyFight(boolean scanForLegacyFight) { this.n = scanForLegacyFight; } private boolean scanForLegacyFight() { return this.n; } // Paper - OBFHELPER - public BlockPosition o; // CraftBukkit PAIL private -> public, rename portalLocation - public EnumDragonRespawn p; // CraftBukkit PAIL private -> public, rename respawnPhase + public BlockPosition exitPortalLocation; + public EnumDragonRespawn respawnPhase; private int q; @@ -0,0 +0,0 @@ public class EnderDragonBattle { - this.bossBattle = (BossBattleServer) (new BossBattleServer(new ChatMessage("entity.minecraft.ender_dragon", new Object[0]), BossBattle.BarColor.PINK, BossBattle.BarStyle.PROGRESS)).setPlayMusic(true).c(true); - this.e = Lists.newArrayList(); + this.bossBattle = (BossBattleServer) (new BossBattleServer(new ChatMessage("entity.minecraft.ender_dragon"), BossBattle.BarColor.PINK, BossBattle.BarStyle.PROGRESS)).setPlayMusic(true).c(true); + this.gateways = Lists.newArrayList(); this.n = true; + // Paper start + setScanForLegacyFight(worldserver.paperConfig.scanForLegacyEnderDragon); + if (!scanForLegacyFight()) setDragonKilled(true); + // Paper end - this.d = worldserver; + this.world = worldserver; if (nbttagcompound.hasKeyOfType("DragonKilled", 99)) { - if (nbttagcompound.b("DragonUUID")) { + if (nbttagcompound.b("Dragon")) { diff --git a/Spigot-Server-Patches/Add-hand-to-bucket-events.patch b/Spigot-Server-Patches/Add-hand-to-bucket-events.patch index 9f697c91a1..fbcc5aba57 100644 --- a/Spigot-Server-Patches/Add-hand-to-bucket-events.patch +++ b/Spigot-Server-Patches/Add-hand-to-bucket-events.patch @@ -10,13 +10,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/EntityCow.java @@ -0,0 +0,0 @@ public class EntityCow extends EntityAnimal { - if (itemstack.getItem() == Items.BUCKET && !entityhuman.abilities.canInstantlyBuild && !this.isBaby()) { + if (itemstack.getItem() == Items.BUCKET && !this.isBaby()) { // CraftBukkit start - Got milk? -- org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(entityhuman.world, entityhuman, this.getChunkCoordinates(), this.getChunkCoordinates(), null, itemstack, Items.MILK_BUCKET); -+ org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(entityhuman.world, entityhuman, this.getChunkCoordinates(), this.getChunkCoordinates(), null, itemstack, Items.MILK_BUCKET, enumhand); // Paper - add enumHand +- org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((WorldServer) entityhuman.world, entityhuman, this.getChunkCoordinates(), this.getChunkCoordinates(), null, itemstack, Items.MILK_BUCKET); ++ org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((WorldServer) entityhuman.world, entityhuman, this.getChunkCoordinates(), this.getChunkCoordinates(), null, itemstack, Items.MILK_BUCKET, enumhand); // Paper - add enumHand if (event.isCancelled()) { - return false; + return EnumInteractionResult.PASS; diff --git a/src/main/java/net/minecraft/server/ItemBucket.java b/src/main/java/net/minecraft/server/ItemBucket.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ItemBucket.java @@ -25,8 +25,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (iblockdata.getBlock() instanceof IFluidSource) { // CraftBukkit start FluidType dummyFluid = ((IFluidSource) iblockdata.getBlock()).removeFluid(DummyGeneratorAccess.INSTANCE, blockposition, iblockdata); -- PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(world, entityhuman, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.a()); -+ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(world, entityhuman, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.a(), enumhand); +- PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((WorldServer) world, entityhuman, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.a()); ++ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((WorldServer) world, entityhuman, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.a(), enumhand); // Paper - add enumhand if (event.isCancelled()) { ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutBlockChange(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager) @@ -34,14 +34,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 iblockdata = world.getType(blockposition); BlockPosition blockposition2 = iblockdata.getBlock() instanceof IFluidContainer && this.fluidType == FluidTypes.WATER ? blockposition : blockposition1; -- if (this.a(entityhuman, world, blockposition2, movingobjectpositionblock, movingobjectpositionblock.getDirection(), blockposition, itemstack)) { // CraftBukkit -+ if (this.a(entityhuman, world, blockposition2, movingobjectpositionblock, movingobjectpositionblock.getDirection(), blockposition, itemstack, enumhand)) { // CraftBukkit // Paper - add enumhand +- if (this.a(entityhuman, world, blockposition2, movingobjectpositionblock1, movingobjectpositionblock1.getDirection(), blockposition, itemstack)) { // CraftBukkit ++ if (this.a(entityhuman, world, blockposition2, movingobjectpositionblock1, movingobjectpositionblock1.getDirection(), blockposition, itemstack, enumhand)) { // CraftBukkit // Paper - add enumhand this.a(world, itemstack, blockposition2); if (entityhuman instanceof EntityPlayer) { CriterionTriggers.y.a((EntityPlayer) entityhuman, blockposition2, itemstack); @@ -0,0 +0,0 @@ public class ItemBucket extends Item { + public void a(World world, ItemStack itemstack, BlockPosition blockposition) {} - // CraftBukkit start public boolean a(@Nullable EntityHuman entityhuman, World world, BlockPosition blockposition, @Nullable MovingObjectPositionBlock movingobjectpositionblock) { - return a(entityhuman, world, blockposition, movingobjectpositionblock, null, null, null); + // Paper start - add enumHand @@ -55,27 +55,84 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!(this.fluidType instanceof FluidTypeFlowing)) { return false; @@ -0,0 +0,0 @@ public class ItemBucket extends Item { - boolean flag = iblockdata.a(this.fluidType); - if (!iblockdata.isAir() && !flag && (!(iblockdata.getBlock() instanceof IFluidContainer) || !((IFluidContainer) iblockdata.getBlock()).canPlace(world, blockposition, iblockdata, this.fluidType))) { -- return movingobjectpositionblock == null ? false : this.a(entityhuman, world, movingobjectpositionblock.getBlockPosition().shift(movingobjectpositionblock.getDirection()), (MovingObjectPositionBlock) null, enumdirection, clicked, itemstack); // CraftBukkit -+ return movingobjectpositionblock == null ? false : this.a(entityhuman, world, movingobjectpositionblock.getBlockPosition().shift(movingobjectpositionblock.getDirection()), (MovingObjectPositionBlock) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit - } else { - // CraftBukkit start - if (entityhuman != null) { -- PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent(world, entityhuman, blockposition, clicked, enumdirection, itemstack); -+ PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent(world, entityhuman, blockposition, clicked, enumdirection, itemstack, enumhand); - if (event.isCancelled()) { - ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutBlockChange(world, blockposition)); // SPIGOT-4238: needed when looking through entity - ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541 + // CraftBukkit start + if (flag1 && entityhuman != null) { +- PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((WorldServer) world, entityhuman, blockposition, clicked, enumdirection, itemstack); ++ PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((WorldServer) world, entityhuman, blockposition, clicked, enumdirection, itemstack, enumhand); // Paper - add enumhand + if (event.isCancelled()) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutBlockChange(world, blockposition)); // SPIGOT-4238: needed when looking through entity + ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541 +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + } + // Paper end + ++ // Paper start - moved up from WorldServer ++ public BlockPosition getSpawn() { ++ BlockPosition blockposition = new BlockPosition(this.worldData.a(), this.worldData.b(), this.worldData.c()); ++ ++ if (!this.getWorldBorder().a(blockposition)) { ++ blockposition = this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, new BlockPosition(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ())); ++ } ++ ++ return blockposition; ++ } ++ // Paper end + @Override + public boolean s_() { + return this.isClientSide; +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { + this.getMinecraftServer().getPlayerList().sendAll(new PacketPlayOutSpawnPosition(blockposition)); + } + +- public BlockPosition getSpawn() { +- BlockPosition blockposition = new BlockPosition(this.worldData.a(), this.worldData.b(), this.worldData.c()); +- +- if (!this.getWorldBorder().a(blockposition)) { +- blockposition = this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, new BlockPosition(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ())); +- } +- +- return blockposition; +- } ++ // Paper - moved up to World ++ //public BlockPosition getSpawn() { ++ // BlockPosition blockposition = new BlockPosition(this.worldData.a(), this.worldData.b(), this.worldData.c()); ++ // ++ // if (!this.getWorldBorder().a(blockposition)) { ++ // blockposition = this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, new BlockPosition(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ())); ++ // } ++ // ++ // return blockposition; ++ //} ++ // Paper end + + public LongSet getForceLoadedChunks() { + ForcedChunk forcedchunk = (ForcedChunk) this.getWorldPersistentData().b(ForcedChunk::new, "chunks"); diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +@@ -0,0 +0,0 @@ public class CraftEventFactory { + public static Entity entityDamage; // For use in EntityDamageByEntityEvent + + // helper methods +- private static boolean canBuild(WorldServer world, Player player, int x, int z) { ++ private static boolean canBuild(World world, Player player, int x, int z) { + int spawnSize = Bukkit.getServer().getSpawnRadius(); + + if (world.getDimensionKey() != World.OVERWORLD) return true; @@ -0,0 +0,0 @@ public class CraftEventFactory { } - private static PlayerEvent getPlayerBucketEvent(boolean isFilling, World world, EntityHuman who, BlockPosition changed, BlockPosition clicked, EnumDirection clickedFace, ItemStack itemstack, net.minecraft.server.Item item) { + private static PlayerEvent getPlayerBucketEvent(boolean isFilling, WorldServer world, EntityHuman who, BlockPosition changed, BlockPosition clicked, EnumDirection clickedFace, ItemStack itemstack, net.minecraft.server.Item item) { + // Paper start - add enumHand + return getPlayerBucketEvent(isFilling, world, who, changed, clicked, clickedFace, itemstack, item, null); + } diff --git a/Spigot-Server-Patches/Add-more-Witch-API.patch b/Spigot-Server-Patches/Add-more-Witch-API.patch index beea3400f0..44ef5dc6a1 100644 --- a/Spigot-Server-Patches/Add-more-Witch-API.patch +++ b/Spigot-Server-Patches/Add-more-Witch-API.patch @@ -24,26 +24,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public class EntityWitch extends EntityRaider implements IRangedEntity { private static final UUID b = UUID.fromString("5CD17E52-A79A-43D3-A529-90FDE04B181E"); -- private static final AttributeModifier bw = (new AttributeModifier(EntityWitch.b, "Drinking speed penalty", -0.25D, AttributeModifier.Operation.ADDITION)).a(false); -+ private static final AttributeModifier bw = (new AttributeModifier(EntityWitch.b, "Drinking speed penalty", -0.25D, AttributeModifier.Operation.ADDITION)).a(false); private static final AttributeModifier DRINKING_SPEED = bw; // Paper - OBFHELPER - private static final DataWatcherObject bx = DataWatcher.a(EntityWitch.class, DataWatcherRegistry.i); -- private int by; -+ private int by; public int getPotionUseTimeLeft() { return by; } public void setPotionUseTimeLeft(int timeLeft) { by = timeLeft; } // Paper - OBFHELPER - private PathfinderGoalNearestHealableRaider bz; - private PathfinderGoalNearestAttackableTargetWitch bA; +- private static final AttributeModifier bv = new AttributeModifier(EntityWitch.b, "Drinking speed penalty", -0.25D, AttributeModifier.Operation.ADDITION); ++ private static final AttributeModifier bv = new AttributeModifier(EntityWitch.b, "Drinking speed penalty", -0.25D, AttributeModifier.Operation.ADDITION); private static final AttributeModifier DRINKING_SPEED = bv; // Paper - OBFHELPER + private static final DataWatcherObject bw = DataWatcher.a(EntityWitch.class, DataWatcherRegistry.i); +- private int bx; ++ private int bx; public int getPotionUseTimeLeft() { return bx; } public void setPotionUseTimeLeft(int timeLeft) { bx = timeLeft; } // Paper - OBFHELPER + private PathfinderGoalNearestHealableRaider by; + private PathfinderGoalNearestAttackableTargetWitch bz; @@ -0,0 +0,0 @@ public class EntityWitch extends EntityRaider implements IRangedEntity { return SoundEffects.ENTITY_WITCH_DEATH; } -+ public void setDrinkingPotion(boolean drinkingPotion) { t(drinkingPotion); } // Paper - OBFHELPER - public void t(boolean flag) { - this.getDataWatcher().set(EntityWitch.bx, flag); ++ public void setDrinkingPotion(boolean drinkingPotion) { v(drinkingPotion); } // Paper - OBFHELPER + public void v(boolean flag) { + this.getDataWatcher().set(EntityWitch.bw, flag); } -+ public boolean isDrinkingPotion() { return l(); } // Paper - OBFHELPER - public boolean l() { - return (Boolean) this.getDataWatcher().get(EntityWitch.bx); ++ public boolean isDrinkingPotion() { return m(); } // Paper - OBFHELPER + public boolean m() { + return (Boolean) this.getDataWatcher().get(EntityWitch.bw); } @@ -0,0 +0,0 @@ public class EntityWitch extends EntityRaider implements IRangedEntity { } @@ -53,27 +53,33 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - ItemStack potion = PotionUtil.a(new ItemStack(Items.POTION), potionregistry); - org.bukkit.inventory.ItemStack bukkitStack = com.destroystokyo.paper.event.entity.WitchReadyPotionEvent.process((org.bukkit.entity.Witch) this.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(potion)); - this.setSlot(EnumItemSlot.MAINHAND, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(bukkitStack)); -+ // Paper start - move all this down into its own method -+// ItemStack potion = PotionUtil.a(new ItemStack(Items.POTION), potionregistry); -+// org.bukkit.inventory.ItemStack bukkitStack = com.destroystokyo.paper.event.entity.WitchReadyPotionEvent.process((org.bukkit.entity.Witch) this.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(potion)); -+// this.setSlot(EnumItemSlot.MAINHAND, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(bukkitStack)); -+// // Paper end -+// this.bB = this.getItemInMainHand().k(); -+// this.s(true); -+// this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_WITCH_DRINK, this.getSoundCategory(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F); -+// AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); -+// -+// attributeinstance.removeModifier(EntityWitch.bz); -+// attributeinstance.addModifier(EntityWitch.bz); -+ this.setDrinkingPotion(PotionUtil.addPotionToItemStack(new ItemStack(Items.POTION), potionregistry)); - // Paper end -- this.by = this.getItemInMainHand().k(); -- this.t(true); -- this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_WITCH_DRINK, this.getSoundCategory(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F); -- AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); +- // Paper end +- this.bx = this.getItemInMainHand().k(); +- this.v(true); +- if (!this.isSilent()) { +- this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_WITCH_DRINK, this.getSoundCategory(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F); +- } - -- attributeinstance.removeModifier(EntityWitch.bw); -- attributeinstance.addModifier(EntityWitch.bw); +- AttributeModifiable attributemodifiable = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); +- +- attributemodifiable.removeModifier(EntityWitch.bv); +- attributemodifiable.b(EntityWitch.bv); ++ //// Paper start ++ //ItemStack potion = PotionUtil.a(new ItemStack(Items.POTION), potionregistry); ++ //org.bukkit.inventory.ItemStack bukkitStack = com.destroystokyo.paper.event.entity.WitchReadyPotionEvent.process((org.bukkit.entity.Witch) this.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(potion)); ++ //this.setSlot(EnumItemSlot.MAINHAND, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(bukkitStack)); ++ //// Paper end ++ //this.bx = this.getItemInMainHand().k(); ++ //this.v(true); ++ //if (!this.isSilent()) { ++ // this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_WITCH_DRINK, this.getSoundCategory(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F); ++ //} ++ // ++ //AttributeModifiable attributemodifiable = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); ++ // ++ //attributemodifiable.removeModifier(EntityWitch.bv); ++ //attributemodifiable.b(EntityWitch.bv); ++ this.setDrinkingPotion(PotionUtil.addPotionToItemStack(new ItemStack(Items.POTION), potionregistry)); } } @@ -81,20 +87,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 super.movementTick(); } -+ // Paper start ++ // Paper start - moved to its own method + public void setDrinkingPotion(ItemStack potion) { + setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(WitchReadyPotionEvent.process((Witch) getBukkitEntity(), CraftItemStack.asCraftMirror(potion)))); + setPotionUseTimeLeft(getItemInMainHand().getItemUseMaxDuration()); + setDrinkingPotion(true); -+ world.sendSoundEffect(null, locX(), locY(), locZ(), SoundEffects.ENTITY_WITCH_DRINK, getSoundCategory(), 1.0F, 0.8F + random.nextFloat() * 0.4F); -+ AttributeInstance attributeinstance = getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); -+ attributeinstance.removeModifier(EntityWitch.DRINKING_SPEED); -+ attributeinstance.addModifier(EntityWitch.DRINKING_SPEED); ++ if (!this.isSilent()) { ++ this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_WITCH_DRINK, this.getSoundCategory(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F); ++ } ++ AttributeModifiable attributemodifiable = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); ++ attributemodifiable.removeModifier(EntityWitch.bv); ++ attributemodifiable.b(EntityWitch.bv); + } + // Paper end + @Override - public SoundEffect eq() { + public SoundEffect eM() { return SoundEffects.ENTITY_WITCH_CELEBRATE; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/Add-more-Zombie-API.patch b/Spigot-Server-Patches/Add-more-Zombie-API.patch index d204cbb428..2b4eadb144 100644 --- a/Spigot-Server-Patches/Add-more-Zombie-API.patch +++ b/Spigot-Server-Patches/Add-more-Zombie-API.patch @@ -13,8 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + public boolean isArmsRaisedZombie() { return (this.datawatcher.get(EntityInsentient.b) & 4) != 0; } // Paper - OBFHELPER -+ public void setArmsRaisedZombie(boolean flag) { this.q(flag); } // Paper - OBFHELPER - public void q(boolean flag) { ++ public void setArmsRaisedZombie(boolean flag) { this.setAggressive(flag); } // Paper - OBFHELPER + public void setAggressive(boolean flag) { byte b0 = (Byte) this.datawatcher.get(EntityInsentient.b); diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java @@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityZombie.java +++ b/src/main/java/net/minecraft/server/EntityZombie.java @@ -0,0 +0,0 @@ public class EntityZombie extends EntityMonster { - private int bC; + private int bA; public int drownedConversionTime; private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field + private boolean shouldBurnInDay = true; // Paper @@ -48,15 +48,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end + - protected void ev() { - this.b(EntityTypes.DROWNED); - this.world.a((EntityHuman) null, 1040, new BlockPosition(this), 0); + protected void eQ() { + this.c(EntityTypes.DROWNED); + if (!this.isSilent()) { @@ -0,0 +0,0 @@ public class EntityZombie extends EntityMonster { - } + } -+ public boolean shouldBurnInDay() { return K_(); } // Paper - OBFHELPER - protected boolean K_() { ++ public boolean shouldBurnInDay() { return U_(); } // Paper - OBFHELPER + protected boolean U_() { - return true; + return shouldBurnInDay; } @@ -71,8 +71,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public boolean damageEntity(DamageSource damagesource, float f) { if (super.damageEntity(damagesource, f)) { @@ -0,0 +0,0 @@ public class EntityZombie extends EntityMonster { - nbttagcompound.setBoolean("CanBreakDoors", this.ey()); - nbttagcompound.setInt("InWaterTime", this.isInWater() ? this.bC : -1); + nbttagcompound.setBoolean("CanBreakDoors", this.eV()); + nbttagcompound.setInt("InWaterTime", this.isInWater() ? this.bA : -1); nbttagcompound.setInt("DrownedConversionTime", this.isDrownConverting() ? this.drownedConversionTime : -1); + nbttagcompound.setBoolean("Paper.ShouldBurnInDay", shouldBurnInDay); // Paper } diff --git a/Spigot-Server-Patches/Add-sun-related-API.patch b/Spigot-Server-Patches/Add-sun-related-API.patch index ec035bfd43..7ff0ea595c 100644 --- a/Spigot-Server-Patches/Add-sun-related-API.patch +++ b/Spigot-Server-Patches/Add-sun-related-API.patch @@ -9,13 +9,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -0,0 +0,0 @@ public abstract class EntityInsentient extends EntityLiving { - return flag; + } -+ public boolean isInDaylight() { return this.en(); } // Paper - OBFHELPER - protected boolean en() { ++ public boolean isInDaylight() { return this.eH(); } // Paper - OBFHELPER + protected boolean eH() { if (this.world.isDay() && !this.world.isClientSide) { - float f = this.aI(); + float f = this.aO(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java diff --git a/Spigot-Server-Patches/Allow-Saving-of-Oversized-Chunks.patch b/Spigot-Server-Patches/Allow-Saving-of-Oversized-Chunks.patch index 10d8c58f9d..eaf70ed6f8 100644 --- a/Spigot-Server-Patches/Allow-Saving-of-Oversized-Chunks.patch +++ b/Spigot-Server-Patches/Allow-Saving-of-Oversized-Chunks.patch @@ -69,11 +69,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private final RegionFileBitSet freeSectors; + public final File file; - public RegionFile(File file, File file1) throws IOException { - this(file.toPath(), file1.toPath(), RegionFileCompression.b); + public RegionFile(File file, File file1, boolean flag) throws IOException { + this(file.toPath(), file1.toPath(), RegionFileCompression.b, flag); } - public RegionFile(java.nio.file.Path java_nio_file_path, java.nio.file.Path java_nio_file_path1, RegionFileCompression regionfilecompression) throws IOException { + public RegionFile(java.nio.file.Path java_nio_file_path, java.nio.file.Path java_nio_file_path1, RegionFileCompression regionfilecompression, boolean flag) throws IOException { + this.file = java_nio_file_path.toFile(); // Paper this.f = ByteBuffer.allocateDirect(8192); + initOversizedState(); diff --git a/Spigot-Server-Patches/Allow-disabling-armour-stand-ticking.patch b/Spigot-Server-Patches/Allow-disabling-armour-stand-ticking.patch index 5738cb10e0..dd8f1d9a7d 100644 --- a/Spigot-Server-Patches/Allow-disabling-armour-stand-ticking.patch +++ b/Spigot-Server-Patches/Allow-disabling-armour-stand-ticking.patch @@ -37,11 +37,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public EntityArmorStand(EntityTypes entitytypes, World world) { super(entitytypes, world); @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - this.rightArmPose = EntityArmorStand.bu; - this.leftLegPose = EntityArmorStand.bv; - this.rightLegPose = EntityArmorStand.bw; + this.rightArmPose = EntityArmorStand.bt; + this.leftLegPose = EntityArmorStand.bu; + this.rightLegPose = EntityArmorStand.bv; + if (world != null) this.canTick = world.paperConfig.armorStandTick; // Paper - armour stand ticking - this.H = 0.0F; + this.G = 0.0F; } @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { @@ -136,125 +136,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void setRightLegPose(Vector3f vector3f) { this.rightLegPose = vector3f; - this.datawatcher.set(EntityArmorStand.bp, vector3f); + this.datawatcher.set(EntityArmorStand.bo, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public Vector3f r() { -diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/EntityLiving.java -+++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { - } - } - -- EnumItemSlot[] aenumitemslot = EnumItemSlot.values(); -- int k = aenumitemslot.length; -- -- for (int l = 0; l < k; ++l) { -- EnumItemSlot enumitemslot = aenumitemslot[l]; -- ItemStack itemstack; -- -- switch (enumitemslot.a()) { -- case HAND: -- itemstack = (ItemStack) this.bu.get(enumitemslot.b()); -- break; -- case ARMOR: -- itemstack = (ItemStack) this.bv.get(enumitemslot.b()); -- break; -- default: -- continue; -- } -- -- ItemStack itemstack1 = this.getEquipment(enumitemslot); -- -- if (!ItemStack.matches(itemstack1, itemstack)) { -- // Paper start - PlayerArmorChangeEvent -- if (this instanceof EntityPlayer && enumitemslot.getType() == EnumItemSlot.Function.ARMOR) { -- final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack); -- final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemstack1); -- new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent(); -- } -- // Paper end -- ((WorldServer) this.world).getChunkProvider().broadcast(this, new PacketPlayOutEntityEquipment(this.getId(), enumitemslot, itemstack1)); -- if (!itemstack.isEmpty()) { -- this.getAttributeMap().a(itemstack.a(enumitemslot)); -- } -- -- if (!itemstack1.isEmpty()) { -- this.getAttributeMap().b(itemstack1.a(enumitemslot)); -- } -- -- switch (enumitemslot.a()) { -- case HAND: -- this.bu.set(enumitemslot.b(), itemstack1.cloneItemStack()); -- break; -- case ARMOR: -- this.bv.set(enumitemslot.b(), itemstack1.cloneItemStack()); -- } -- } -- } -+ updateEntityEquipment(); // Paper - split into own method - - if (this.ticksLived % 20 == 0) { - this.getCombatTracker().g(); -@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { - } - } - -+ // Paper start - split into own method from above -+ public void updateEntityEquipment() { -+ EnumItemSlot[] aenumitemslot = EnumItemSlot.values(); -+ int k = aenumitemslot.length; -+ for (int l = 0; l < k; ++l) { -+ EnumItemSlot enumitemslot = aenumitemslot[l]; -+ ItemStack itemstack; -+ -+ switch (enumitemslot.a()) { -+ case HAND: -+ itemstack = (ItemStack) this.bu.get(enumitemslot.b()); -+ break; -+ case ARMOR: -+ itemstack = (ItemStack) this.bv.get(enumitemslot.b()); -+ break; -+ default: -+ continue; -+ } -+ -+ ItemStack itemstack1 = this.getEquipment(enumitemslot); -+ -+ if (!ItemStack.matches(itemstack1, itemstack)) { -+ // Paper start - PlayerArmorChangeEvent -+ if (this instanceof EntityPlayer && enumitemslot.getType() == EnumItemSlot.Function.ARMOR) { -+ final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack); -+ final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemstack1); -+ new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent(); -+ } -+ // Paper end -+ ((WorldServer) this.world).getChunkProvider().broadcast(this, new PacketPlayOutEntityEquipment(this.getId(), enumitemslot, itemstack1)); -+ if (!itemstack.isEmpty()) { -+ this.getAttributeMap().a(itemstack.a(enumitemslot)); -+ } -+ -+ if (!itemstack1.isEmpty()) { -+ this.getAttributeMap().b(itemstack1.a(enumitemslot)); -+ } -+ -+ switch (enumitemslot.a()) { -+ case HAND: -+ this.bu.set(enumitemslot.b(), itemstack1.cloneItemStack()); -+ break; -+ case ARMOR: -+ this.bv.set(enumitemslot.b(), itemstack1.cloneItemStack()); -+ } -+ } -+ } -+ } -+ - protected float f(float f, float f1) { - float f2 = MathHelper.g(f - this.aI); - diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java diff --git a/Spigot-Server-Patches/AnvilDamageEvent.patch b/Spigot-Server-Patches/AnvilDamageEvent.patch index 427be22550..68fe5cac77 100644 --- a/Spigot-Server-Patches/AnvilDamageEvent.patch +++ b/Spigot-Server-Patches/AnvilDamageEvent.patch @@ -8,20 +8,21 @@ diff --git a/src/main/java/net/minecraft/server/ContainerAnvil.java b/src/main/j index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ContainerAnvil.java +++ b/src/main/java/net/minecraft/server/ContainerAnvil.java -@@ -0,0 +0,0 @@ public class ContainerAnvil extends Container { +@@ -0,0 +0,0 @@ public class ContainerAnvil extends ContainerAnvilAbstract { - if (!entityhuman.abilities.canInstantlyBuild && iblockdata.a(TagsBlock.ANVIL) && entityhuman.getRandom().nextFloat() < 0.12F) { - IBlockData iblockdata1 = BlockAnvil.e(iblockdata); -+ // Paper start -+ com.destroystokyo.paper.event.block.AnvilDamagedEvent event = new com.destroystokyo.paper.event.block.AnvilDamagedEvent(getBukkitView(), iblockdata1 != null ? org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(iblockdata1) : null); -+ if (!event.callEvent()) { -+ return; -+ } else if (event.getDamageState() == com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState.BROKEN) { -+ iblockdata1 = null; -+ } else { -+ iblockdata1 = ((org.bukkit.craftbukkit.block.data.CraftBlockData) event.getDamageState().getMaterial().createBlockData()).getState().set(BlockAnvil.FACING, iblockdata.get(BlockAnvil.FACING)); -+ } -+ // Paper end - - if (iblockdata1 == null) { - world.a(blockposition, false); + if (!entityhuman.abilities.canInstantlyBuild && iblockdata.a((Tag) TagsBlock.ANVIL) && entityhuman.getRandom().nextFloat() < 0.12F) { + IBlockData iblockdata1 = BlockAnvil.c(iblockdata); +- ++ // Paper start ++ com.destroystokyo.paper.event.block.AnvilDamagedEvent event = new com.destroystokyo.paper.event.block.AnvilDamagedEvent(getBukkitView(), iblockdata1 != null ? org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(iblockdata1) : null); ++ if (!event.callEvent()) { ++ return; ++ } else if (event.getDamageState() == com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState.BROKEN) { ++ iblockdata1 = null; ++ } else { ++ iblockdata1 = ((org.bukkit.craftbukkit.block.data.CraftBlockData) event.getDamageState().getMaterial().createBlockData()).getState().set(BlockAnvil.FACING, iblockdata.get(BlockAnvil.FACING)); ++ } ++ // Paper end + if (iblockdata1 == null) { + world.a(blockposition, false); + world.triggerEffect(1029, blockposition, 0); diff --git a/Spigot-Server-Patches/Avoid-dimension-id-collisions.patch b/Spigot-Server-Patches/Avoid-dimension-id-collisions.patch deleted file mode 100644 index 18e88d2c62..0000000000 --- a/Spigot-Server-Patches/Avoid-dimension-id-collisions.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Brokkonaut -Date: Tue, 25 Sep 2018 06:53:43 +0200 -Subject: [PATCH] Avoid dimension id collisions - -getDimensionId() returns the dimension id - 1. So without this patch -we would reuse an existing dimension id, if some other dimension was -unloaded before. - -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -0,0 +0,0 @@ public final class CraftServer implements Server { - boolean used = false; - do { - for (WorldServer server : console.getWorlds()) { -- used = server.getWorldProvider().getDimensionManager().getDimensionID() == dimension; -+ used = server.getWorldProvider().getDimensionManager().getDimensionID() + 1 == dimension; // Paper - getDimensionID returns the dimension - 1, so we have to add 1 - if (used) { - dimension++; - break; diff --git a/Spigot-Server-Patches/Avoid-item-merge-if-stack-size-above-max-stack-size.patch b/Spigot-Server-Patches/Avoid-item-merge-if-stack-size-above-max-stack-size.patch index dce92699cd..ccf361b5a0 100644 --- a/Spigot-Server-Patches/Avoid-item-merge-if-stack-size-above-max-stack-size.patch +++ b/Spigot-Server-Patches/Avoid-item-merge-if-stack-size-above-max-stack-size.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class EntityItem extends Entity { private void mergeNearby() { - if (this.w()) { + if (this.z()) { + // Paper start - avoid item merge if stack size above max stack size + ItemStack stack = getItemStack(); + if (stack.getCount() >= stack.getMaxStackSize()) return; diff --git a/Spigot-Server-Patches/Block-Enderpearl-Travel-Exploit.patch b/Spigot-Server-Patches/Block-Enderpearl-Travel-Exploit.patch index fd2ce53dd0..dba4656a0b 100644 --- a/Spigot-Server-Patches/Block-Enderpearl-Travel-Exploit.patch +++ b/Spigot-Server-Patches/Block-Enderpearl-Travel-Exploit.patch @@ -26,15 +26,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + log("Disable Unloaded Chunk Enderpearl Exploit: " + (disableEnderpearlExploit ? "enabled" : "disabled")); + } } -diff --git a/src/main/java/net/minecraft/server/EntityProjectile.java b/src/main/java/net/minecraft/server/EntityProjectile.java +diff --git a/src/main/java/net/minecraft/server/IProjectile.java b/src/main/java/net/minecraft/server/IProjectile.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/EntityProjectile.java -+++ b/src/main/java/net/minecraft/server/EntityProjectile.java -@@ -0,0 +0,0 @@ public abstract class EntityProjectile extends Entity implements IProjectile { - if (nbttagcompound.hasKeyOfType("owner", 10)) { - this.shooterId = GameProfileSerializer.b(nbttagcompound.getCompound("owner")); +--- a/src/main/java/net/minecraft/server/IProjectile.java ++++ b/src/main/java/net/minecraft/server/IProjectile.java +@@ -0,0 +0,0 @@ public abstract class IProjectile extends Entity { + protected void loadData(NBTTagCompound nbttagcompound) { + if (nbttagcompound.b("Owner")) { + this.shooter = nbttagcompound.a("Owner"); ++ if (this instanceof EntityEnderPearl && this.world != null && this.world.paperConfig.disableEnderpearlExploit) { this.shooter = null; } // Paper - Don't store shooter name for pearls to block enderpearl travel exploit } -+ if (this instanceof EntityEnderPearl && this.world != null && this.world.paperConfig.disableEnderpearlExploit) { this.shooterId = null; } // Paper - Don't store shooter name for pearls to block enderpearl travel exploit - - } + this.d = nbttagcompound.getBoolean("LeftOwner"); diff --git a/Spigot-Server-Patches/BlockDestroyEvent.patch b/Spigot-Server-Patches/BlockDestroyEvent.patch index be3b8c16ce..a73e5da21e 100644 --- a/Spigot-Server-Patches/BlockDestroyEvent.patch +++ b/Spigot-Server-Patches/BlockDestroyEvent.patch @@ -31,8 +31,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end -- this.triggerEffect(2001, blockposition, Block.getCombinedId(iblockdata)); -+ if (playEffect) this.triggerEffect(2001, blockposition, Block.getCombinedId(iblockdata)); // Paper - if (flag) { - TileEntity tileentity = iblockdata.getBlock().isTileEntity() ? this.getTileEntity(blockposition) : null; +- if (!(iblockdata.getBlock() instanceof BlockFireAbstract)) { ++ if (playEffect && !(iblockdata.getBlock() instanceof BlockFireAbstract)) { // Paper + this.triggerEffect(2001, blockposition, Block.getCombinedId(iblockdata)); + } diff --git a/Spigot-Server-Patches/Book-Size-Limits.patch b/Spigot-Server-Patches/Book-Size-Limits.patch index 17e6bc3ebd..4c54df95b6 100644 --- a/Spigot-Server-Patches/Book-Size-Limits.patch +++ b/Spigot-Server-Patches/Book-Size-Limits.patch @@ -25,9 +25,9 @@ diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -0,0 +0,0 @@ import java.util.Iterator; - import java.util.Optional; +@@ -0,0 +0,0 @@ import java.util.Optional; import java.util.Set; + import java.util.stream.Stream; import javax.annotation.Nullable; +import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; diff --git a/Spigot-Server-Patches/Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch b/Spigot-Server-Patches/Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch index b169dff76a..986b453714 100644 --- a/Spigot-Server-Patches/Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch +++ b/Spigot-Server-Patches/Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch @@ -13,6 +13,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void setHasWhitelist(boolean flag) { + new com.destroystokyo.paper.event.server.WhitelistToggleEvent(flag).callEvent(); - this.whitelist.setEnabled(flag); // Paper + this.hasWhitelist = flag; } diff --git a/Spigot-Server-Patches/Catch-JsonParseException-in-Entity-and-TE-names.patch b/Spigot-Server-Patches/Catch-JsonParseException-in-Entity-and-TE-names.patch index 8a82dbaf1e..7e9c2b1d8d 100644 --- a/Spigot-Server-Patches/Catch-JsonParseException-in-Entity-and-TE-names.patch +++ b/Spigot-Server-Patches/Catch-JsonParseException-in-Entity-and-TE-names.patch @@ -25,19 +25,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } if (nbttagcompound.hasKeyOfType("TrackOutput", 1)) { -diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/Entity.java -+++ b/src/main/java/net/minecraft/server/Entity.java -@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - this.Z(); - this.setYawPitch(this.yaw, this.pitch); - if (nbttagcompound.hasKeyOfType("CustomName", 8)) { -- this.setCustomName(IChatBaseComponent.ChatSerializer.a(nbttagcompound.getString("CustomName"))); -+ this.setCustomName(MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound)); // Paper - Catch ParseException - } - - this.setCustomNameVisible(nbttagcompound.getBoolean("CustomNameVisible")); diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/MCUtil.java @@ -67,8 +54,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/TileEntityBanner.java +++ b/src/main/java/net/minecraft/server/TileEntityBanner.java @@ -0,0 +0,0 @@ public class TileEntityBanner extends TileEntity implements INamableTileEntity { - public void load(NBTTagCompound nbttagcompound) { - super.load(nbttagcompound); + public void load(IBlockData iblockdata, NBTTagCompound nbttagcompound) { + super.load(iblockdata, nbttagcompound); if (nbttagcompound.hasKeyOfType("CustomName", 8)) { - this.a = IChatBaseComponent.ChatSerializer.a(nbttagcompound.getString("CustomName")); + this.a = MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound); // Paper - Catch ParseException @@ -80,7 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/TileEntityContainer.java +++ b/src/main/java/net/minecraft/server/TileEntityContainer.java @@ -0,0 +0,0 @@ public abstract class TileEntityContainer extends TileEntity implements IInvento - super.load(nbttagcompound); + super.load(iblockdata, nbttagcompound); this.chestLock = ChestLock.b(nbttagcompound); if (nbttagcompound.hasKeyOfType("CustomName", 8)) { - this.customName = IChatBaseComponent.ChatSerializer.a(nbttagcompound.getString("CustomName")); diff --git a/Spigot-Server-Patches/Check-Drowned-for-Villager-Aggression-Config.patch b/Spigot-Server-Patches/Check-Drowned-for-Villager-Aggression-Config.patch deleted file mode 100644 index ca8a4a851c..0000000000 --- a/Spigot-Server-Patches/Check-Drowned-for-Villager-Aggression-Config.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: BillyGalbreath -Date: Wed, 10 Oct 2018 21:22:44 -0500 -Subject: [PATCH] Check Drowned for Villager Aggression Config - - -diff --git a/src/main/java/net/minecraft/server/EntityDrowned.java b/src/main/java/net/minecraft/server/EntityDrowned.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/EntityDrowned.java -+++ b/src/main/java/net/minecraft/server/EntityDrowned.java -@@ -0,0 +0,0 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { - this.goalSelector.a(7, new PathfinderGoalRandomStroll(this, 1.0D)); - this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityDrowned.class})).a(EntityPigZombie.class)); - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, this::i)); -- this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)); -+ if ( world.spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)); // Paper - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); - this.targetSelector.a(5, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, 10, true, false, EntityTurtle.bw)); - } diff --git a/Spigot-Server-Patches/Chunk-debug-command.patch b/Spigot-Server-Patches/Chunk-debug-command.patch index 843227c30d..02fd77ff94 100644 --- a/Spigot-Server-Patches/Chunk-debug-command.patch +++ b/Spigot-Server-Patches/Chunk-debug-command.patch @@ -189,13 +189,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -0,0 +0,0 @@ import org.apache.logging.log4j.Logger; + public class ChunkProviderServer extends IChunkProvider { - private static final int b = (int) Math.pow(17.0D, 2.0D); -- private static final List c = ChunkStatus.a(); -+ private static final List c = ChunkStatus.a(); static final List getPossibleChunkStatuses() { return ChunkProviderServer.c; } // Paper - OBFHELPER +- private static final List b = ChunkStatus.a(); ++ private static final List b = ChunkStatus.a(); static final List getPossibleChunkStatuses() { return ChunkProviderServer.b; } // Paper - OBFHELPER private final ChunkMapDistance chunkMapDistance; - public final ChunkGenerator chunkGenerator; + public final ChunkGenerator chunkGenerator; private final WorldServer world; diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/ChunkMapDistance-CME.patch b/Spigot-Server-Patches/ChunkMapDistance-CME.patch index 47ed536e5b..6360b000c5 100644 --- a/Spigot-Server-Patches/ChunkMapDistance-CME.patch +++ b/Spigot-Server-Patches/ChunkMapDistance-CME.patch @@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/ChunkMapDistance.java +++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { - private final ChunkMapDistance.a e = new ChunkMapDistance.a(); + private final ChunkMapDistance.a ticketLevelTracker = new ChunkMapDistance.a(); private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); private final ChunkMapDistance.c g = new ChunkMapDistance.c(33); - private final Set pendingChunkUpdates = Sets.newHashSet(); diff --git a/Spigot-Server-Patches/Configurable-Alternative-LootPool-Luck-Formula.patch b/Spigot-Server-Patches/Configurable-Alternative-LootPool-Luck-Formula.patch index d14abfcd1f..b30d7488df 100644 --- a/Spigot-Server-Patches/Configurable-Alternative-LootPool-Luck-Formula.patch +++ b/Spigot-Server-Patches/Configurable-Alternative-LootPool-Luck-Formula.patch @@ -60,12 +60,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public abstract class LootSelectorEntry extends LootEntryAbstract { +- protected final int c; - protected final int e; -- protected final int f; -+ protected final int e; public int getWeight() { return e; } // Paper - OBFHELPER -+ protected final int f; public int getQuality() { return f; } // Paper - OBFHELPER - protected final LootItemFunction[] g; - private final BiFunction c; ++ protected final int c; public int getWeight() { return c; } // Paper - OBFHELPER ++ protected final int e; public int getQuality() { return e; } // Paper - OBFHELPER + protected final LootItemFunction[] f; + private final BiFunction g; private final LootEntry h = new LootSelectorEntry.c() { @@ -0,0 +0,0 @@ public abstract class LootSelectorEntry extends LootEntryAbstract { @@ -77,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public int a(float f) { -- return Math.max(MathHelper.d((float) LootSelectorEntry.this.e + (float) LootSelectorEntry.this.f * f), 0); +- return Math.max(MathHelper.d((float) LootSelectorEntry.this.c + (float) LootSelectorEntry.this.e * f), 0); + // Paper start - Offer an alternative loot formula to refactor how luck bonus applies + // SEE: https://luckformula.emc.gs for details and data + if (lastLuck != null && lastLuck == f) { @@ -104,7 +104,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return lastWeight; } } -+ private Float lastLuck = null; -+ private int lastWeight = 0; -+ // Paper end ++ private Float lastLuck = null; ++ private int lastWeight = 0; ++ // Paper end } diff --git a/Spigot-Server-Patches/Configurable-Bed-Search-Radius.patch b/Spigot-Server-Patches/Configurable-Bed-Search-Radius.patch index 8eda2f5aab..103cea0352 100644 --- a/Spigot-Server-Patches/Configurable-Bed-Search-Radius.patch +++ b/Spigot-Server-Patches/Configurable-Bed-Search-Radius.patch @@ -39,7 +39,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 EnumDirection enumdirection = (EnumDirection) iworldreader.getType(blockposition).get(BlockBed.FACING); + // Paper start - configurable bed search radius + if (entitytypes == EntityTypes.PLAYER) return findSafePosition(entitytypes, (World) iworldreader, enumdirection, blockposition); -+ int j = blockposition.getX(); int k = blockposition.getY(); int l = blockposition.getZ(); @@ -47,7 +46,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return Optional.empty(); } -- protected static Optional a(EntityTypes entitytypes, IWorldReader iworldreader, BlockPosition blockposition) { +- public static Optional a(EntityTypes entitytypes, IWorldReader iworldreader, BlockPosition blockposition) { + private static Optional findSafePosition(EntityTypes entitytypes, World world, EnumDirection updirection, BlockPosition blockposition){ + int radius = world.paperConfig.bedSearchRadius; + double angle = Math.PI / 2; @@ -143,15 +142,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end + + // Paper start -- add maxBelow param -+ protected static Optional a(EntityTypes entitytypes, IWorldReader iworldreader, BlockPosition blockposition) { return isSafeRespawn(entitytypes, iworldreader, blockposition, 2); } -+ protected static Optional isSafeRespawn(EntityTypes entitytypes, IWorldReader iworldreader, BlockPosition blockposition, int maxBelow) { ++ public static Optional a(EntityTypes entitytypes, IWorldReader iworldreader, BlockPosition blockposition) { return isSafeRespawn(entitytypes, iworldreader, blockposition, 2); } ++ public static Optional isSafeRespawn(EntityTypes entitytypes, IWorldReader iworldreader, BlockPosition blockposition, int maxBelow) { + // Paper end VoxelShape voxelshape = iworldreader.getType(blockposition).getCollisionShape(iworldreader, blockposition); if (voxelshape.c(EnumDirection.EnumAxis.Y) > 0.4375D) { @@ -0,0 +0,0 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity { } else { - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(blockposition); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = blockposition.i(); - while (blockposition_mutableblockposition.getY() >= 0 && blockposition.getY() - blockposition_mutableblockposition.getY() <= 2 && iworldreader.getType(blockposition_mutableblockposition).getCollisionShape(iworldreader, blockposition_mutableblockposition).isEmpty()) { + while (blockposition_mutableblockposition.getY() >= 0 && blockposition.getY() - blockposition_mutableblockposition.getY() <= maxBelow && iworldreader.getType(blockposition_mutableblockposition).getCollisionShape(iworldreader, blockposition_mutableblockposition).isEmpty()) { // Paper -- configurable max distance to search below diff --git a/Spigot-Server-Patches/Configurable-Keep-Spawn-Loaded-range-per-world.patch b/Spigot-Server-Patches/Configurable-Keep-Spawn-Loaded-range-per-world.patch index b8cb8a135f..c24cf6cc84 100644 --- a/Spigot-Server-Patches/Configurable-Keep-Spawn-Loaded-range-per-world.patch +++ b/Spigot-Server-Patches/Configurable-Keep-Spawn-Loaded-range-per-world.patch @@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + worldloadlistener.setChunkRadius(radiusBlocks / 16); + // Paper end + - MinecraftServer.LOGGER.info("Preparing start region for dimension '{}'/{}", worldserver.getWorldData().getName(), DimensionManager.a(worldserver.worldProvider.getDimensionManager().getType())); // CraftBukkit + MinecraftServer.LOGGER.info("Preparing start region for dimension {}", worldserver.getDimensionKey().a()); BlockPosition blockposition = worldserver.getSpawn(); @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant= this.bA + 600) { - float f = this.aI(); +@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { + if (this.world.isDay() && this.ticksLived >= this.bz + 600) { + float f = this.aO(); -- if (f > 0.5F && this.world.f(new BlockPosition(this)) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) { -+ if (f > 0.5F && this.world.f(new BlockPosition(this)) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper +- if (f > 0.5F && this.world.f(this.getChunkCoordinates()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) { ++ if (f > 0.5F && this.world.f(this.getChunkCoordinates()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper this.setGoalTarget((EntityLiving) null); - this.eq(); + this.eM(); } -@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster { - } else if (!(damagesource instanceof EntityDamageSourceIndirect) && damagesource != DamageSource.FIREWORKS) { - boolean flag = super.damageEntity(damagesource, f); - -- if (!this.world.p_() && damagesource.ignoresArmor() && this.random.nextInt(10) != 0) { -+ if (!this.world.p_() && damagesource.ignoresArmor() && this.random.nextInt(10) != 0 && this.tryEscape(damagesource == DamageSource.DROWN ? EndermanEscapeEvent.Reason.DROWN : EndermanEscapeEvent.Reason.CRITICAL_HIT)) { // Paper - this.eq(); - } - - return flag; - } else { +@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { + if (this.isInvulnerable(damagesource)) { + return false; + } else if (damagesource instanceof EntityDamageSourceIndirect) { + if (this.tryEscape(EndermanEscapeEvent.Reason.INDIRECT)) { // Paper start for (int i = 0; i < 64; ++i) { - if (this.eq()) { + if (this.eM()) { return true; } } + } // Paper end return false; - } -@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster { + } else { + boolean flag = super.damageEntity(damagesource, f); + +- if (!this.world.s_() && this.random.nextInt(10) != 0) { ++ if (!this.world.s_() && this.random.nextInt(10) != 0 && this.tryEscape(damagesource == DamageSource.DROWN ? EndermanEscapeEvent.Reason.DROWN : EndermanEscapeEvent.Reason.CRITICAL_HIT)) { // Paper + this.eM(); + } + +@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { static class PathfinderGoalPlayerWhoLookedAtTarget extends PathfinderGoalNearestAttackableTarget { @@ -71,12 +71,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private EntityHuman j; private int k; private int l; -@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster { +@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { } else { if (this.c != null && !this.i.isPassenger()) { - if (this.i.f((EntityHuman) this.c)) { + if (this.i.g((EntityHuman) this.c)) { - if (this.c.h((Entity) this.i) < 16.0D) { + if (this.c.h((Entity) this.i) < 16.0D && this.getEnderman().tryEscape(EndermanEscapeEvent.Reason.STARE)) { - this.i.eq(); + this.i.eM(); } diff --git a/Spigot-Server-Patches/Entity-getEntitySpawnReason.patch b/Spigot-Server-Patches/Entity-getEntitySpawnReason.patch index b5ba67c705..1aa9b01187 100644 --- a/Spigot-Server-Patches/Entity-getEntitySpawnReason.patch +++ b/Spigot-Server-Patches/Entity-getEntitySpawnReason.patch @@ -64,7 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -0,0 +0,0 @@ public abstract class PlayerList { // CraftBukkit start - WorldServer finalWorldServer = worldserver; + WorldServer finalWorldServer = worldserver1; Entity entity = EntityTypes.a(nbttagcompound1.getCompound("Entity"), finalWorldServer, (entity1) -> { - return !finalWorldServer.addEntitySerialized(entity1) ? null : entity1; + return !finalWorldServer.addEntitySerialized(entity1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity1; // Paper @@ -75,7 +75,7 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { // CraftBukkit start private boolean addEntity0(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) { org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot diff --git a/Spigot-Server-Patches/EntityShootBowEvent-consumeArrow-and-getArrowItem-AP.patch b/Spigot-Server-Patches/EntityShootBowEvent-consumeArrow-and-getArrowItem-AP.patch index 8288857fae..89ac9db8d9 100644 --- a/Spigot-Server-Patches/EntityShootBowEvent-consumeArrow-and-getArrowItem-AP.patch +++ b/Spigot-Server-Patches/EntityShootBowEvent-consumeArrow-and-getArrowItem-AP.patch @@ -22,7 +22,7 @@ diff --git a/src/main/java/net/minecraft/server/ItemBow.java b/src/main/java/net index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ItemBow.java +++ b/src/main/java/net/minecraft/server/ItemBow.java -@@ -0,0 +0,0 @@ public class ItemBow extends ItemProjectileWeapon { +@@ -0,0 +0,0 @@ public class ItemBow extends ItemProjectileWeapon implements ItemVanishable { if ((double) f >= 0.1D) { boolean flag1 = flag && itemstack1.getItem() == Items.ARROW; @@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!world.isClientSide) { ItemArrow itemarrow = (ItemArrow) ((ItemArrow) (itemstack1.getItem() instanceof ItemArrow ? itemstack1.getItem() : Items.ARROW)); EntityArrow entityarrow = itemarrow.a(world, itemstack1, (EntityLiving) entityhuman); -@@ -0,0 +0,0 @@ public class ItemBow extends ItemProjectileWeapon { +@@ -0,0 +0,0 @@ public class ItemBow extends ItemProjectileWeapon implements ItemVanishable { entityarrow.setOnFire(100); } // CraftBukkit start @@ -39,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (event.isCancelled()) { event.getProjectile().remove(); return; -@@ -0,0 +0,0 @@ public class ItemBow extends ItemProjectileWeapon { +@@ -0,0 +0,0 @@ public class ItemBow extends ItemProjectileWeapon implements ItemVanishable { itemstack.damage(1, entityhuman, (entityhuman1) -> { entityhuman1.broadcastItemBreak(entityhuman.getRaisedHand()); }); @@ -49,10 +49,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 entityarrow.fromPlayer = EntityArrow.PickupStatus.CREATIVE_ONLY; } -@@ -0,0 +0,0 @@ public class ItemBow extends ItemProjectileWeapon { +@@ -0,0 +0,0 @@ public class ItemBow extends ItemProjectileWeapon implements ItemVanishable { } - world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ARROW_SHOOT, SoundCategory.PLAYERS, 1.0F, 1.0F / (ItemBow.i.nextFloat() * 0.4F + 1.2F) + f * 0.5F); + world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ARROW_SHOOT, SoundCategory.PLAYERS, 1.0F, 1.0F / (ItemBow.RANDOM.nextFloat() * 0.4F + 1.2F) + f * 0.5F); - if (!flag1 && !entityhuman.abilities.canInstantlyBuild) { + if (!flag1 && !entityhuman.abilities.canInstantlyBuild && consumeArrow) { // Paper itemstack1.subtract(1); @@ -62,7 +62,7 @@ diff --git a/src/main/java/net/minecraft/server/ItemCrossbow.java b/src/main/jav index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ItemCrossbow.java +++ b/src/main/java/net/minecraft/server/ItemCrossbow.java -@@ -0,0 +0,0 @@ public class ItemCrossbow extends ItemProjectileWeapon { +@@ -0,0 +0,0 @@ public class ItemCrossbow extends ItemProjectileWeapon implements ItemVanishable ((IProjectile) object).shoot((double) vector3fa.a(), (double) vector3fa.b(), (double) vector3fa.c(), f1, f2); } // CraftBukkit start diff --git a/Spigot-Server-Patches/EntityTransformedEvent.patch b/Spigot-Server-Patches/EntityTransformedEvent.patch index 0b0ac6e3af..0d5fbe354f 100644 --- a/Spigot-Server-Patches/EntityTransformedEvent.patch +++ b/Spigot-Server-Patches/EntityTransformedEvent.patch @@ -4,42 +4,46 @@ Date: Thu, 26 Jul 2018 15:30:03 -0400 Subject: [PATCH] EntityTransformedEvent +diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/EntityInsentient.java ++++ b/src/main/java/net/minecraft/server/EntityInsentient.java +@@ -0,0 +0,0 @@ public abstract class EntityInsentient extends EntityLiving { + if (CraftEventFactory.callEntityTransformEvent(this, t0, EntityTransformEvent.TransformReason.DROWNED).isCancelled()) { + return null; + } ++ if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), t0.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.DROWNED).callEvent()) return null; // Paper + this.world.addEntity(t0, CreatureSpawnEvent.SpawnReason.DROWNED); + // CraftBukkit end + this.die(); diff --git a/src/main/java/net/minecraft/server/EntityMushroomCow.java b/src/main/java/net/minecraft/server/EntityMushroomCow.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityMushroomCow.java +++ b/src/main/java/net/minecraft/server/EntityMushroomCow.java -@@ -0,0 +0,0 @@ public class EntityMushroomCow extends EntityCow { - if (CraftEventFactory.callEntityTransformEvent(this, entitycow, EntityTransformEvent.TransformReason.SHEARED).isCancelled()) { - return false; - } -+ if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), entitycow.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.SHEARED).callEvent()) return false; // Paper - this.world.addEntity(entitycow, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHEARED); +@@ -0,0 +0,0 @@ public class EntityMushroomCow extends EntityCow implements IShearable { + if (CraftEventFactory.callEntityTransformEvent(this, entitycow, EntityTransformEvent.TransformReason.SHEARED).isCancelled()) { + return; + } ++ if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), entitycow.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.SHEARED).callEvent()) return; // Paper + this.world.addEntity(entitycow, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHEARED); - this.die(); // CraftBukkit - from above + this.die(); // CraftBukkit - from above diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityVillager.java +++ b/src/main/java/net/minecraft/server/EntityVillager.java @@ -0,0 +0,0 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - if (CraftEventFactory.callEntityTransformEvent(this, entitywitch, EntityTransformEvent.TransformReason.LIGHTNING).isCancelled()) { - return; - } -+ if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), entitywitch.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.LIGHTNING).callEvent()) return; // Paper - this.world.addEntity(entitywitch, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); - // CraftBukkit end - this.die(); + if (CraftEventFactory.callEntityTransformEvent(this, entitywitch, EntityTransformEvent.TransformReason.LIGHTNING).isCancelled()) { + return; + } ++ if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), entitywitch.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.LIGHTNING).callEvent()) return; // Paper + this.world.addEntity(entitywitch, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); + // CraftBukkit end + this.die(); diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityZombie.java +++ b/src/main/java/net/minecraft/server/EntityZombie.java -@@ -0,0 +0,0 @@ public class EntityZombie extends EntityMonster { - return; - } - // CraftBukkit end -+ if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), entityzombie.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.DROWNED).callEvent()) return; // Paper - this.world.addEntity(entityzombie, CreatureSpawnEvent.SpawnReason.DROWNED); // CraftBukkit - added spawn reason - this.die(); - } @@ -0,0 +0,0 @@ public class EntityZombie extends EntityMonster { if (CraftEventFactory.callEntityTransformEvent(this, entityzombievillager, EntityTransformEvent.TransformReason.INFECTION).isCancelled()) { return; diff --git a/Spigot-Server-Patches/Expand-World.spawnParticle-API-and-add-Builder.patch b/Spigot-Server-Patches/Expand-World.spawnParticle-API-and-add-Builder.patch index 87a8eae32e..9543ff2949 100644 --- a/Spigot-Server-Patches/Expand-World.spawnParticle-API-and-add-Builder.patch +++ b/Spigot-Server-Patches/Expand-World.spawnParticle-API-and-add-Builder.patch @@ -13,16 +13,16 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { public final Int2ObjectMap entitiesById = new Int2ObjectLinkedOpenHashMap(); private final Map entitiesByUUID = Maps.newHashMap(); private final Queue entitiesToAdd = Queues.newArrayDeque(); - private final List players = Lists.newArrayList(); + public final List players = Lists.newArrayList(); // Paper - private -> public + public final ChunkProviderServer chunkProvider; // Paper - public boolean tickingEntities; private final MinecraftServer server; - private final WorldNBTStorage dataManager; -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { } public int sendParticles(EntityPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) { diff --git a/Spigot-Server-Patches/ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch b/Spigot-Server-Patches/ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch index 6fcf7f9971..0d0006482c 100644 --- a/Spigot-Server-Patches/ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch +++ b/Spigot-Server-Patches/ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch @@ -289,7 +289,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + entity = new EntityExperienceOrb(world, x, y, z, 0, org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM, null, null); // Paper } else if (LightningStrike.class.isAssignableFrom(clazz)) { entity = EntityTypes.LIGHTNING_BOLT.a(world); - } else if (Firework.class.isAssignableFrom(clazz)) { + } else if (AreaEffectCloud.class.isAssignableFrom(clazz)) { 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 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java diff --git a/Spigot-Server-Patches/Expose-attack-cooldown-methods-for-Player.patch b/Spigot-Server-Patches/Expose-attack-cooldown-methods-for-Player.patch index bc8dcbcd31..23f8a5b681 100644 --- a/Spigot-Server-Patches/Expose-attack-cooldown-methods-for-Player.patch +++ b/Spigot-Server-Patches/Expose-attack-cooldown-methods-for-Player.patch @@ -9,22 +9,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java @@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving { - this.datawatcher.set(EntityHuman.bt, nbttagcompound); + this.datawatcher.set(EntityHuman.bs, nbttagcompound); } -+ public float getCooldownPeriod() { return this.ex(); } // Paper - OBFHELPER - public float ex() { - return (float) (1.0D / this.getAttributeInstance(GenericAttributes.ATTACK_SPEED).getValue() * 20.0D); ++ public float getCooldownPeriod() { return this.eR(); } // Paper - OBFHELPER + public float eR() { + return (float) (1.0D / this.b(GenericAttributes.ATTACK_SPEED) * 20.0D); } -+ public float getCooledAttackStrength(float adjustTicks) { return s(adjustTicks); } // Paper - OBFHELPER - public float s(float f) { - return MathHelper.a(((float) this.aB + f) / this.ex(), 0.0F, 1.0F); ++ public float getCooledAttackStrength(float adjustTicks) { return getAttackCooldown(adjustTicks); } // Paper - OBFHELPER + public float getAttackCooldown(float f) { + return MathHelper.a(((float) this.aA + f) / this.eR(), 0.0F, 1.0F); } + public void resetCooldown() { this.ey(); } // Paper - OBFHELPER - public void ey() { - this.aB = 0; + public void resetAttackCooldown() { + this.aA = 0; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/Fire-BlockPistonRetractEvent-for-all-empty-pistons.patch b/Spigot-Server-Patches/Fire-BlockPistonRetractEvent-for-all-empty-pistons.patch index 91ea6ace63..264f712801 100644 --- a/Spigot-Server-Patches/Fire-BlockPistonRetractEvent-for-all-empty-pistons.patch +++ b/Spigot-Server-Patches/Fire-BlockPistonRetractEvent-for-all-empty-pistons.patch @@ -44,4 +44,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + //} // Paper // PAIL: checkME - what happened to setTypeAndData? // CraftBukkit end - world.playBlockAction(blockposition, this, b0, enumdirection.b()); + world.playBlockAction(blockposition, this, b0, enumdirection.c()); diff --git a/Spigot-Server-Patches/Fire-EntityShootBowEvent-for-Illusioner.patch b/Spigot-Server-Patches/Fire-EntityShootBowEvent-for-Illusioner.patch index c8bb8b887f..6fa50679fd 100644 --- a/Spigot-Server-Patches/Fire-EntityShootBowEvent-for-Illusioner.patch +++ b/Spigot-Server-Patches/Fire-EntityShootBowEvent-for-Illusioner.patch @@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (event.getProjectile() == entityarrow.getBukkitEntity()) { + this.world.addEntity(entityarrow); + } - this.a(SoundEffects.ENTITY_SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F)); + this.playSound(SoundEffects.ENTITY_SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F)); - this.world.addEntity(entityarrow); + // Paper end } diff --git a/Spigot-Server-Patches/Fire-event-on-GS4-query.patch b/Spigot-Server-Patches/Fire-event-on-GS4-query.patch deleted file mode 100644 index 33a76f6f69..0000000000 --- a/Spigot-Server-Patches/Fire-event-on-GS4-query.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mark Vainomaa -Date: Sun, 17 Mar 2019 21:46:56 +0200 -Subject: [PATCH] Fire event on GS4 query - - -diff --git a/src/main/java/net/minecraft/server/RemoteConnectionThread.java b/src/main/java/net/minecraft/server/RemoteConnectionThread.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/RemoteConnectionThread.java -+++ b/src/main/java/net/minecraft/server/RemoteConnectionThread.java -@@ -0,0 +0,0 @@ public abstract class RemoteConnectionThread implements Runnable { - private static final Logger LOGGER = LogManager.getLogger(); - private static final AtomicInteger i = new AtomicInteger(0); - protected boolean a; -- protected final IMinecraftServer b; -+ protected final IMinecraftServer b; protected IMinecraftServer getServer() { return this.b; } // Paper - OBFHELPER - protected final String c; - protected Thread d; - protected final int e = 5; -@@ -0,0 +0,0 @@ public abstract class RemoteConnectionThread implements Runnable { - this.b.g(s); - } - -+ protected int getPlayerCount() { return this.d(); } // Paper - OBFHELPER - protected int d() { - return this.b.getPlayerCount(); - } -diff --git a/src/main/java/net/minecraft/server/RemoteStatusListener.java b/src/main/java/net/minecraft/server/RemoteStatusListener.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/RemoteStatusListener.java -+++ b/src/main/java/net/minecraft/server/RemoteStatusListener.java -@@ -0,0 +0,0 @@ public class RemoteStatusListener extends RemoteConnectionThread { - - private long h; - private final int i; -- private final int j; -- private final int k; -- private final String l; -- private final String m; -+ private final int j; private int getServerPort() { return this.j; } // Paper - OBFHELPER -+ private final int k; private int getMaxPlayers() { return this.k; } // Paper - OBFHELPER -+ private final String l; private String getMotd() { return this.l; } // Paper - OBFHELPER -+ private final String m; private String getWorldName() { return this.m; } // Paper - OBFHELPER - private DatagramSocket n; - private final byte[] o = new byte[1460]; - private DatagramPacket p; - private final Map q; -- private String r; -+ private String r; private String getServerHost() { return this.r; } // Paper - OBFHELPER - private String s; - private final Map t; - private final long u; -- private final RemoteStatusReply v; -+ private final RemoteStatusReply v; private RemoteStatusReply getCachedFullResponse() { return this.v; } // Paper - OBFHELPER - private long w; - - public RemoteStatusListener(IMinecraftServer iminecraftserver) { -@@ -0,0 +0,0 @@ public class RemoteStatusListener extends RemoteConnectionThread { - - remotestatusreply.a((int) 0); - remotestatusreply.a(this.a(datagrampacket.getSocketAddress())); -+ /* Paper start - GS4 Query event - remotestatusreply.a(this.l); - remotestatusreply.a("SMP"); - remotestatusreply.a(this.m); -@@ -0,0 +0,0 @@ public class RemoteStatusListener extends RemoteConnectionThread { - remotestatusreply.a(Integer.toString(this.k)); - remotestatusreply.a((short) this.j); - remotestatusreply.a(this.r); -+ */ -+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType queryType = -+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType.BASIC; -+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse queryResponse = com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.builder() -+ .motd(this.getMotd()) -+ .map(this.getWorldName()) -+ .currentPlayers(this.getPlayerCount()) -+ .maxPlayers(this.getMaxPlayers()) -+ .port(this.getServerPort()) -+ .hostname(this.getServerHost()) -+ .gameVersion(this.getServer().getVersion()) -+ .serverVersion(org.bukkit.Bukkit.getServer().getName() + " on " + org.bukkit.Bukkit.getServer().getBukkitVersion()) -+ .build(); -+ com.destroystokyo.paper.event.server.GS4QueryEvent queryEvent = -+ new com.destroystokyo.paper.event.server.GS4QueryEvent(queryType, datagrampacket.getAddress(), queryResponse); -+ queryEvent.callEvent(); -+ queryResponse = queryEvent.getResponse(); -+ remotestatusreply.writeString(queryResponse.getMotd()); -+ remotestatusreply.writeString("SMP"); -+ remotestatusreply.writeString(queryResponse.getMap()); -+ remotestatusreply.writeString(Integer.toString(queryResponse.getCurrentPlayers())); -+ remotestatusreply.writeString(Integer.toString(queryResponse.getMaxPlayers())); -+ remotestatusreply.writeShort((short) queryResponse.getPort()); -+ remotestatusreply.writeString(queryResponse.getHostname()); -+ // Paper end - this.a(remotestatusreply.a(), datagrampacket); - this.a("Status [" + socketaddress + "]"); - } -@@ -0,0 +0,0 @@ public class RemoteStatusListener extends RemoteConnectionThread { - this.v.a("splitnum"); - this.v.a((int) 128); - this.v.a((int) 0); -+ /* Paper start - GS4 Query event - this.v.a("hostname"); - this.v.a(this.l); - this.v.a("gametype"); -@@ -0,0 +0,0 @@ public class RemoteStatusListener extends RemoteConnectionThread { - } - - this.v.a((int) 0); -+ */ -+ // Pack plugins -+ java.util.List plugins = java.util.Collections.emptyList(); -+ org.bukkit.plugin.Plugin[] bukkitPlugins; -+ if(((DedicatedServer) this.getServer()).server.getQueryPlugins() && (bukkitPlugins = org.bukkit.Bukkit.getPluginManager().getPlugins()).length > 0) { -+ plugins = java.util.stream.Stream.of(bukkitPlugins) -+ .map(plugin -> com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation.of(plugin.getName(), plugin.getDescription().getVersion())) -+ .collect(java.util.stream.Collectors.toList()); -+ } -+ -+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse queryResponse = com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.builder() -+ .motd(this.getMotd()) -+ .map(this.getWorldName()) -+ .currentPlayers(this.getPlayerCount()) -+ .maxPlayers(this.getMaxPlayers()) -+ .port(this.getServerPort()) -+ .hostname(this.getServerHost()) -+ .plugins(plugins) -+ .players(this.getServer().getPlayers()) -+ .gameVersion(this.getServer().getVersion()) -+ .serverVersion(org.bukkit.Bukkit.getServer().getName() + " on " + org.bukkit.Bukkit.getServer().getBukkitVersion()) -+ .build(); -+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType queryType = -+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType.FULL; -+ com.destroystokyo.paper.event.server.GS4QueryEvent queryEvent = -+ new com.destroystokyo.paper.event.server.GS4QueryEvent(queryType, datagrampacket.getAddress(), queryResponse); -+ queryEvent.callEvent(); -+ queryResponse = queryEvent.getResponse(); -+ this.getCachedFullResponse().writeString("hostname"); -+ this.getCachedFullResponse().writeString(queryResponse.getMotd()); -+ this.getCachedFullResponse().writeString("gametype"); -+ this.getCachedFullResponse().writeString("SMP"); -+ this.getCachedFullResponse().writeString("game_id"); -+ this.getCachedFullResponse().writeString("MINECRAFT"); -+ this.getCachedFullResponse().writeString("version"); -+ this.getCachedFullResponse().writeString(queryResponse.getGameVersion()); -+ this.getCachedFullResponse().writeString("plugins"); -+ java.lang.StringBuilder pluginsString = new java.lang.StringBuilder(); -+ pluginsString.append(queryResponse.getServerVersion()); -+ if(!queryResponse.getPlugins().isEmpty()) { -+ pluginsString.append(": "); -+ Iterator iter = queryResponse.getPlugins().iterator(); -+ while(iter.hasNext()) { -+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation info = iter.next(); -+ pluginsString.append(info.getName()); -+ if (info.getVersion() != null) { -+ pluginsString.append(' ').append(info.getVersion().replaceAll(";", ",")); -+ } -+ if (iter.hasNext()) { -+ pluginsString.append(';').append(' '); -+ } -+ } -+ } -+ this.getCachedFullResponse().writeString(pluginsString.toString()); -+ this.getCachedFullResponse().writeString("map"); -+ this.getCachedFullResponse().writeString(queryResponse.getMap()); -+ this.getCachedFullResponse().writeString("numplayers"); -+ this.getCachedFullResponse().writeString(Integer.toString(queryResponse.getCurrentPlayers())); -+ this.getCachedFullResponse().writeString("maxplayers"); -+ this.getCachedFullResponse().writeString(Integer.toString(queryResponse.getMaxPlayers())); -+ this.getCachedFullResponse().writeString("hostport"); -+ this.getCachedFullResponse().writeString(Integer.toString(queryResponse.getPort())); -+ this.getCachedFullResponse().writeString("hostip"); -+ this.getCachedFullResponse().writeString(queryResponse.getHostname()); -+ // The "meaningless data" start, copied from above -+ this.getCachedFullResponse().writeInt(0); -+ this.getCachedFullResponse().writeInt(1); -+ this.getCachedFullResponse().writeString("player_"); -+ this.getCachedFullResponse().writeInt(0); -+ // "Meaningless data" end -+ queryResponse.getPlayers().forEach(this.getCachedFullResponse()::writeStringUnchecked); -+ this.getCachedFullResponse().writeInt(0); -+ // Paper end - return this.v.a(); - } - } -diff --git a/src/main/java/net/minecraft/server/RemoteStatusReply.java b/src/main/java/net/minecraft/server/RemoteStatusReply.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/RemoteStatusReply.java -+++ b/src/main/java/net/minecraft/server/RemoteStatusReply.java -@@ -0,0 +0,0 @@ public class RemoteStatusReply { - this.b.write(abyte, 0, abyte.length); - } - -+ public void writeString(String string) throws IOException { this.a(string); } // Paper - OBFHELPER - public void a(String s) throws IOException { - this.b.writeBytes(s); - this.b.write(0); - } -+ // Paper start - unchecked exception variant to use in Stream API -+ public void writeStringUnchecked(String string) { -+ try { -+ writeString(string); -+ } catch (IOException e) { -+ com.destroystokyo.paper.util.SneakyThrow.sneaky(e); -+ } -+ } -+ // Paper end - -+ public void writeInt(int i) throws IOException { this.a(i); } // Paper - OBFHELPER - public void a(int i) throws IOException { - this.b.write(i); - } - -+ public void writeShort(short i) throws IOException { this.a(i); } // Paper - OBFHELPER - public void a(short short0) throws IOException { - this.b.writeShort(Short.reverseBytes(short0)); - } diff --git a/Spigot-Server-Patches/Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch b/Spigot-Server-Patches/Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch index 91aae7ed4c..73c15fe4cc 100644 --- a/Spigot-Server-Patches/Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch +++ b/Spigot-Server-Patches/Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch @@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return super.isMainThread() /*|| this.isStopped()*/; // CraftBukkit - MC-142590 // Paper - causes issues elsewhere } - @Deprecated + public boolean isDebugging() { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/Spigot-Server-Patches/Fix-MC-124320.patch b/Spigot-Server-Patches/Fix-MC-124320.patch index bf287bfd13..c8c060d0d6 100644 --- a/Spigot-Server-Patches/Fix-MC-124320.patch +++ b/Spigot-Server-Patches/Fix-MC-124320.patch @@ -8,8 +8,8 @@ diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/m index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/Block.java +++ b/src/main/java/net/minecraft/server/Block.java -@@ -0,0 +0,0 @@ public class Block implements IMaterial { - return tag.isTagged(this); +@@ -0,0 +0,0 @@ public class Block extends BlockBase implements IMaterial { + return this == block; } + public static IBlockData getValidBlockForPosition(IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition) { return Block.b(iblockdata, generatoraccess, blockposition); } // Paper - OBFHELPER @@ -20,8 +20,8 @@ diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/j index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityEnderman.java +++ b/src/main/java/net/minecraft/server/EntityEnderman.java -@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster { - if (block.a(TagsBlock.ENDERMAN_HOLDABLE) && flag) { +@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { + if (block.a((Tag) TagsBlock.ENDERMAN_HOLDABLE) && flag) { // CraftBukkit start - Pickup event if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.enderman, blockposition, Blocks.AIR.getBlockData()).isCancelled()) { - this.enderman.setCarried(iblockdata); @@ -31,7 +31,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // CraftBukkit end } -@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster { +@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { static class PathfinderGoalEndermanPlaceBlock extends PathfinderGoal { @@ -39,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private final EntityEnderman a; public PathfinderGoalEndermanPlaceBlock(EntityEnderman entityenderman) { -@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster { +@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { IBlockData iblockdata = world.getType(blockposition); BlockPosition blockposition1 = blockposition.down(); IBlockData iblockdata1 = world.getType(blockposition1); diff --git a/Spigot-Server-Patches/Fix-SpongeAbsortEvent-handling.patch b/Spigot-Server-Patches/Fix-SpongeAbsortEvent-handling.patch index b09e6ab7f3..22dbbed314 100644 --- a/Spigot-Server-Patches/Fix-SpongeAbsortEvent-handling.patch +++ b/Spigot-Server-Patches/Fix-SpongeAbsortEvent-handling.patch @@ -9,9 +9,9 @@ diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/m index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/Block.java +++ b/src/main/java/net/minecraft/server/Block.java -@@ -0,0 +0,0 @@ public class Block implements IMaterial { +@@ -0,0 +0,0 @@ public class Block extends BlockBase implements IMaterial { - iblockdata.dropNaturally(world, blockposition, ItemStack.a); + iblockdata.dropNaturally(world, blockposition, ItemStack.b); } - + public static void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, @Nullable TileEntity tileentity) { a(iblockdata, world, blockposition, tileentity); } diff --git a/Spigot-Server-Patches/Fix-client-rendering-skulls-from-same-user.patch b/Spigot-Server-Patches/Fix-client-rendering-skulls-from-same-user.patch index f5c519bfbb..1041163eb7 100644 --- a/Spigot-Server-Patches/Fix-client-rendering-skulls-from-same-user.patch +++ b/Spigot-Server-Patches/Fix-client-rendering-skulls-from-same-user.patch @@ -16,20 +16,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java @@ -0,0 +0,0 @@ public final class ItemStack { - // Paper end + private int g; @Deprecated private Item item; - private NBTTagCompound tag; + NBTTagCompound tag; // Paper -> package private - private boolean h; - private EntityItemFrame i; - private ShapeDetectorBlock j; + private boolean j; + private Entity k; + private ShapeDetectorBlock l; diff --git a/src/main/java/net/minecraft/server/PacketDataSerializer.java b/src/main/java/net/minecraft/server/PacketDataSerializer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PacketDataSerializer.java +++ b/src/main/java/net/minecraft/server/PacketDataSerializer.java @@ -0,0 +0,0 @@ public class PacketDataSerializer extends ByteBuf { - if (item.usesDurability() || item.o()) { + if (item.usesDurability() || item.n()) { // Spigot start - filter itemstack = itemstack.cloneItemStack(); - CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); diff --git a/Spigot-Server-Patches/Fix-exploit-that-allowed-colored-signs-to-be-created.patch b/Spigot-Server-Patches/Fix-exploit-that-allowed-colored-signs-to-be-created.patch index 08d9d50c19..d656a63d27 100644 --- a/Spigot-Server-Patches/Fix-exploit-that-allowed-colored-signs-to-be-created.patch +++ b/Spigot-Server-Patches/Fix-exploit-that-allowed-colored-signs-to-be-created.patch @@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 String[] lines = new String[4]; for (int i = 0; i < astring.length; ++i) { -- lines[i] = EnumChatFormat.b(new ChatComponentText(EnumChatFormat.b(astring[i])).getString()); +- lines[i] = EnumChatFormat.a(new ChatComponentText(EnumChatFormat.a(astring[i])).getString()); + lines[i] = SharedConstants.a(astring[i]); //Paper - Replaced with anvil color stripping method to stop exploits that allow colored signs to be created. } SignChangeEvent event = new SignChangeEvent((org.bukkit.craftbukkit.block.CraftBlock) player.getWorld().getBlockAt(x, y, z), this.server.getPlayer(this.player), lines); diff --git a/Spigot-Server-Patches/Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch b/Spigot-Server-Patches/Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch index 35b7e708a5..5ef6019ee1 100644 --- a/Spigot-Server-Patches/Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch +++ b/Spigot-Server-Patches/Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch @@ -22,25 +22,27 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { - int k = MathHelper.floor(entity.locZ() / 16.0D); +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { + int k = MathHelper.floor(entity.locZ() / 16.0D); - if (!entity.inChunk || entity.chunkX != i || entity.chunkY != j || entity.chunkZ != k) { -- if (entity.inChunk && this.isChunkLoaded(entity.chunkX, entity.chunkZ)) { -- this.getChunkAt(entity.chunkX, entity.chunkZ).a(entity, entity.chunkY); -+ // Paper start - remove entity if its in a chunk more correctly. -+ Chunk currentChunk = entity.getCurrentChunk(); -+ if (currentChunk != null) { -+ currentChunk.removeEntity(entity); - } -+ // Paper end + if (!entity.inChunk || entity.chunkX != i || entity.chunkY != j || entity.chunkZ != k) { ++ // Paper start - remove entity if its in a chunk more correctly. ++ Chunk currentChunk = entity.getCurrentChunk(); ++ if (currentChunk != null) { ++ currentChunk.removeEntity(entity); ++ } ++ // Paper end ++ + if (entity.inChunk && this.isChunkLoaded(entity.chunkX, entity.chunkZ)) { + this.getChunkAt(entity.chunkX, entity.chunkZ).a(entity, entity.chunkY); + } -- if (!entity.cc() && !this.isChunkLoaded(i, k)) { -+ if (!entity.valid && !entity.cc() && !this.isChunkLoaded(i, k)) { // Paper - always load chunks to register valid entities location - entity.inChunk = false; - } else { - this.getChunkAt(i, k).a(entity); -@@ -0,0 +0,0 @@ public class WorldServer extends World { +- if (!entity.cj() && !this.isChunkLoaded(i, k)) { ++ if (!entity.valid && !entity.cj() && !this.isChunkLoaded(i, k)) { // Paper - always load chunks to register valid entities location + if (entity.inChunk) { + WorldServer.LOGGER.warn("Entity {} left loaded chunk area", entity); + } +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { return false; } // CraftBukkit end diff --git a/Spigot-Server-Patches/Fix-sign-edit-memory-leak.patch b/Spigot-Server-Patches/Fix-sign-edit-memory-leak.patch index 281877f6b2..3fb3a8a859 100644 --- a/Spigot-Server-Patches/Fix-sign-edit-memory-leak.patch +++ b/Spigot-Server-Patches/Fix-sign-edit-memory-leak.patch @@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - if (!tileentitysign.d() || tileentitysign.f() != this.player) { + if (!tileentitysign.d() || tileentitysign.signEditor == null || !tileentitysign.signEditor.equals(this.player.getUniqueID())) { - this.minecraftServer.warning("Player " + this.player.getDisplayName().getString() + " just tried to change non-editable sign"); + PlayerConnection.LOGGER.warn("Player {} just tried to change non-editable sign", this.player.getDisplayName().getString()); this.sendPacket(tileentity.getUpdatePacket()); // CraftBukkit return; diff --git a/src/main/java/net/minecraft/server/TileEntitySign.java b/src/main/java/net/minecraft/server/TileEntitySign.java @@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/TileEntitySign.java @@ -0,0 +0,0 @@ public class TileEntitySign extends TileEntity implements ICommandListener { // private EntityHuman c; - private final String[] g = new String[4]; + private final IChatFormatted[] g; private EnumColor color; + public java.util.UUID signEditor; // Paper diff --git a/Spigot-Server-Patches/Fix-some-generation-concurrency-issues.patch b/Spigot-Server-Patches/Fix-some-generation-concurrency-issues.patch deleted file mode 100644 index b5df741edb..0000000000 --- a/Spigot-Server-Patches/Fix-some-generation-concurrency-issues.patch +++ /dev/null @@ -1,223 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Shane Freeder -Date: Fri, 24 May 2019 07:53:16 +0100 -Subject: [PATCH] Fix some generation concurrency issues - - -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - private int tileTickPosition; - public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions - public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here -+ // Paper start - yes this is hacky as shit -+ RegionLimitedWorldAccess regionLimited; -+ World originalWorld; -+ public World regionLimited(RegionLimitedWorldAccess limitedWorldAccess) { -+ try { -+ World clone = (World) super.clone(); -+ clone.regionLimited = limitedWorldAccess; -+ clone.originalWorld = this; -+ return clone; -+ } catch (CloneNotSupportedException e1) { -+ } -+ return null; -+ } -+ ChunkCoordIntPair[] strongholdCoords; -+ List strongholdStuctures = Lists.newArrayList(); -+ final java.lang.Object stuctureLock = new Object(); -+ // Paper end - - public CraftWorld getWorld() { - return this.world; -diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureStateProviderWeighted.java b/src/main/java/net/minecraft/server/WorldGenFeatureStateProviderWeighted.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/WorldGenFeatureStateProviderWeighted.java -+++ b/src/main/java/net/minecraft/server/WorldGenFeatureStateProviderWeighted.java -@@ -0,0 +0,0 @@ public class WorldGenFeatureStateProviderWeighted extends WorldGenFeatureStatePr - this(new WeightedList<>(dynamic.get("entries").orElseEmptyList(), IBlockData::a)); - } - -- public WorldGenFeatureStateProviderWeighted a(IBlockData iblockdata, int i) { -+ public synchronized WorldGenFeatureStateProviderWeighted a(IBlockData iblockdata, int i) { // Paper - this.b.a(iblockdata, i); - return this; - } - - @Override -- public IBlockData a(Random random, BlockPosition blockposition) { -+ public synchronized IBlockData a(Random random, BlockPosition blockposition) { // Paper - return (IBlockData) this.b.b(random); - } - - @Override -- public T a(DynamicOps dynamicops) { -+ public synchronized T a(DynamicOps dynamicops) { // Paper - Builder builder = ImmutableMap.builder(); - - builder.put(dynamicops.createString("type"), dynamicops.createString(IRegistry.t.getKey(this.a).toString())).put(dynamicops.createString("entries"), this.b.a(dynamicops, (iblockdata) -> { -diff --git a/src/main/java/net/minecraft/server/WorldGenStronghold.java b/src/main/java/net/minecraft/server/WorldGenStronghold.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/WorldGenStronghold.java -+++ b/src/main/java/net/minecraft/server/WorldGenStronghold.java -@@ -0,0 +0,0 @@ import javax.annotation.Nullable; - - public class WorldGenStronghold extends StructureGenerator { - -+ /* // Paper start - no shared state - private boolean a; - private ChunkCoordIntPair[] aq; - private final List ar = Lists.newArrayList(); - private long as; -+ */ - - public WorldGenStronghold(Function, ? extends WorldGenFeatureEmptyConfiguration> function) { - super(function); -@@ -0,0 +0,0 @@ public class WorldGenStronghold extends StructureGenerator chunkgenerator, Random random, int i, int j, BiomeBase biomebase) { -+ // Paper start -+ /* - if (this.as != chunkgenerator.getSeed()) { - this.d(); - } -+ */ -+ final World world = chunkgenerator.getWorld(); - -- if (!this.a) { -+ synchronized (world.stuctureLock) { -+ if ( world.strongholdCoords == null) { - this.a(chunkgenerator); -- this.a = true; -- } -+ // this.a = true; -+ }} -+ // Paper end - -- ChunkCoordIntPair[] achunkcoordintpair = this.aq; -+ ChunkCoordIntPair[] achunkcoordintpair = world.strongholdCoords; // Paper - int k = achunkcoordintpair.length; - - for (int l = 0; l < k; ++l) { -@@ -0,0 +0,0 @@ public class WorldGenStronghold extends StructureGenerator chunkgenerator, BlockPosition blockposition, int i, boolean flag) { - if (!chunkgenerator.getWorldChunkManager().a(this)) { - return null; - } else { -+ // Paper start - no shared state -+ /* - if (this.as != world.getSeed()) { - this.d(); - } -+ */ - -- if (!this.a) { -- this.a(chunkgenerator); -- this.a = true; -+ synchronized (world.stuctureLock) { -+ if ( world.strongholdCoords == null) { -+ this.a(chunkgenerator); -+ //this.a = true; -+ } - } -+ // Paper end - - BlockPosition blockposition1 = null; - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - double d0 = Double.MAX_VALUE; -- ChunkCoordIntPair[] achunkcoordintpair = this.aq; -+ ChunkCoordIntPair[] achunkcoordintpair = world.strongholdCoords; // Paper - int j = achunkcoordintpair.length; - - for (int k = 0; k < j; ++k) { -@@ -0,0 +0,0 @@ public class WorldGenStronghold extends StructureGenerator chunkgenerator) { -- this.as = chunkgenerator.getSeed(); -+ //this.as = chunkgenerator.getSeed(); // Paper - List list = Lists.newArrayList(); - Iterator iterator = IRegistry.BIOME.iterator(); - -@@ -0,0 +0,0 @@ public class WorldGenStronghold extends StructureGenerator= i1) { -- this.aq[l1] = new ChunkCoordIntPair(i2, j2); -+ strongholdCoords[l1] = new ChunkCoordIntPair(i2, j2); // Paper - } - - d0 += 6.283185307179586D / (double) k; -@@ -0,0 +0,0 @@ public class WorldGenStronghold extends StructureGenerator { - this.c = this.a(new PacketDataSerializer(this.j()), chunk, i); + this.c = this.a(new PacketDataSerializer(this.k()), chunk, i); this.g = Lists.newArrayList(); iterator = chunk.getTileEntities().entrySet().iterator(); + int totalTileEntities = 0; // Paper diff --git a/Spigot-Server-Patches/Here-s-Johnny.patch b/Spigot-Server-Patches/Here-s-Johnny.patch deleted file mode 100644 index a6c684a390..0000000000 --- a/Spigot-Server-Patches/Here-s-Johnny.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: BillyGalbreath -Date: Fri, 12 Oct 2018 01:37:22 -0500 -Subject: [PATCH] Here's Johnny! - - -diff --git a/src/main/java/net/minecraft/server/EntityVindicator.java b/src/main/java/net/minecraft/server/EntityVindicator.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/EntityVindicator.java -+++ b/src/main/java/net/minecraft/server/EntityVindicator.java -@@ -0,0 +0,0 @@ public class EntityVindicator extends EntityIllagerAbstract { - private static final Predicate b = (enumdifficulty) -> { - return enumdifficulty == EnumDifficulty.NORMAL || enumdifficulty == EnumDifficulty.HARD; - }; -- private boolean bw; -+ private boolean bw; public boolean isJohnny() { return bw; } public void setJohnny(boolean johnny) { bw = johnny; } // Paper - OBFHELPER - - public EntityVindicator(EntityTypes entitytypes, World world) { - super(entitytypes, world); -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVindicator.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVindicator.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVindicator.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVindicator.java -@@ -0,0 +0,0 @@ public class CraftVindicator extends CraftIllager implements Vindicator { - public EntityType getType() { - return EntityType.VINDICATOR; - } -+ -+ // Paper start -+ public boolean isJohnny() { -+ return getHandle().isJohnny(); -+ } -+ -+ public void setJohnny(boolean johnny) { -+ getHandle().setJohnny(johnny); -+ } -+ // Paper end - } diff --git a/Spigot-Server-Patches/Hook-into-CB-plugin-rewrites.patch b/Spigot-Server-Patches/Hook-into-CB-plugin-rewrites.patch index 6431b24064..6bc040443a 100644 --- a/Spigot-Server-Patches/Hook-into-CB-plugin-rewrites.patch +++ b/Spigot-Server-Patches/Hook-into-CB-plugin-rewrites.patch @@ -7,19 +7,6 @@ Allows us to do fun stuff like rewrite the OBC util fastutil location to our own relocation. Also lets us rewrite NMS calls for when we're debugging in an IDE pre-relocate. -diff --git a/pom.xml b/pom.xml -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/pom.xml -+++ b/pom.xml -@@ -0,0 +0,0 @@ - - org.ow2.asm - asm -- 7.3.1 -+ 8.0.1 - compile - - diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java @@ -94,11 +81,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 { OptionParser parser = new OptionParser(); @@ -0,0 +0,0 @@ public class Commodore - ClassReader cr = new ClassReader( b ); - ClassWriter cw = new ClassWriter( cr, 0 ); -- cr.accept( new ClassVisitor( Opcodes.ASM7, cw ) -+ cr.accept( new ClassVisitor( Opcodes.ASM8, cw) // Paper + cr.accept( new ClassVisitor( Opcodes.ASM8, cw ) { + // Paper start - Rewrite plugins + @Override @@ -160,8 +144,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + super.visitFrame( type, nLocal, local, nStack, stack ); + } + -+ -+ + @Override + public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) + { @@ -170,8 +152,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + super.visitLocalVariable( name, descriptor, signature, start, end, index ); + } + // Paper end -+ -+ @Override public void visitFieldInsn(int opcode, String owner, String name, String desc) @@ -184,9 +164,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end + - if ( modern ) + if ( owner.equals( "org/bukkit/block/Biome" ) ) { - if ( owner.equals( "org/bukkit/Material" ) ) + switch ( name ) @@ -0,0 +0,0 @@ public class Commodore return; } diff --git a/Spigot-Server-Patches/Ignore-Dead-Entities-in-entityList-iteration.patch b/Spigot-Server-Patches/Ignore-Dead-Entities-in-entityList-iteration.patch index 9ebba48da9..4781665029 100644 --- a/Spigot-Server-Patches/Ignore-Dead-Entities-in-entityList-iteration.patch +++ b/Spigot-Server-Patches/Ignore-Dead-Entities-in-entityList-iteration.patch @@ -28,12 +28,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { - while (iterator.hasNext()) { - Entity entity1 = (Entity) iterator.next(); -+ if (entity1.shouldBeRemoved) continue; // Paper + for (int i1 = 0; i1 < l; ++i1) { + Entity entity1 = (Entity) list1.get(i1); ++ if (entity1.shouldBeRemoved) continue; // Paper - if (entity1.getBoundingBox().c(axisalignedbb) && entity1 != entity) { - if (predicate == null || predicate.test(entity1)) { + if (entity1.getBoundingBox().c(axisalignedbb) && entity1 != entity) { + if (predicate == null || predicate.test(entity1)) { @@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { while (iterator.hasNext()) { @@ -66,16 +66,7 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { - - while (objectiterator.hasNext()) { - Entity entity = (Entity) objectiterator.next(); -- -+ if (entity.shouldBeRemoved) continue; // Paper - if (entity instanceof EntityInsentient) { - EntityInsentient entityinsentient = (EntityInsentient) entity; - -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { entity.origin = entity.getBukkitEntity().getLocation(); } // Paper end @@ -83,7 +74,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 new com.destroystokyo.paper.event.entity.EntityAddToWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid } -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.removeEntityFromChunk(entity); this.entitiesById.remove(entity.getId()); this.unregisterEntity(entity); diff --git a/Spigot-Server-Patches/Implement-CraftBlockSoundGroup.patch b/Spigot-Server-Patches/Implement-CraftBlockSoundGroup.patch index 5bc4fbec57..1f2a54c4bf 100644 --- a/Spigot-Server-Patches/Implement-CraftBlockSoundGroup.patch +++ b/Spigot-Server-Patches/Implement-CraftBlockSoundGroup.patch @@ -48,52 +48,40 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return CraftSound.getSoundByEffect(soundEffectType.getFallSound()); + } +} -diff --git a/src/main/java/net/minecraft/server/IBlockData.java b/src/main/java/net/minecraft/server/IBlockData.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/IBlockData.java -+++ b/src/main/java/net/minecraft/server/IBlockData.java -@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements - return this.getBlock().isTicking(this); - } - -+ public final SoundEffectType getStepSound() { return this.r(); } // Paper - OBFHELPER - public SoundEffectType r() { - return this.getBlock().getStepSound(this); - } diff --git a/src/main/java/net/minecraft/server/SoundEffectType.java b/src/main/java/net/minecraft/server/SoundEffectType.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/SoundEffectType.java +++ b/src/main/java/net/minecraft/server/SoundEffectType.java @@ -0,0 +0,0 @@ public class SoundEffectType { - public static final SoundEffectType w = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_LANTERN_BREAK, SoundEffects.BLOCK_LANTERN_STEP, SoundEffects.BLOCK_LANTERN_PLACE, SoundEffects.BLOCK_LANTERN_HIT, SoundEffects.BLOCK_LANTERN_FALL); - public final float x; - public final float y; -- private final SoundEffect z; -+ private final SoundEffect z; public final SoundEffect getBreakSound() { return this.z; } // Paper - OBFHELPER - private final SoundEffect A; - private final SoundEffect B; -- private final SoundEffect C; -+ private final SoundEffect C; public final SoundEffect getHitSound() { return this.C; } // Paper - OBFHELPER - private final SoundEffect D; + public static final SoundEffectType U = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_GILDED_BLACKSTONE_BREAK, SoundEffects.BLOCK_GILDED_BLACKSTONE_STEP, SoundEffects.BLOCK_GILDED_BLACKSTONE_PLACE, SoundEffects.BLOCK_GILDED_BLACKSTONE_HIT, SoundEffects.BLOCK_GILDED_BLACKSTONE_FALL); + public final float V; + public final float W; +- private final SoundEffect X; ++ private final SoundEffect X; public final SoundEffect getBreakSound() { return this.X; } // Paper - OBFHELPER + private final SoundEffect Y; + private final SoundEffect Z; +- private final SoundEffect aa; ++ private final SoundEffect aa; public final SoundEffect getHitSound() { return this.aa; } // Paper - OBFHELPER + private final SoundEffect ab; public SoundEffectType(float f, float f1, SoundEffect soundeffect, SoundEffect soundeffect1, SoundEffect soundeffect2, SoundEffect soundeffect3, SoundEffect soundeffect4) { @@ -0,0 +0,0 @@ public class SoundEffectType { - return this.y; + return this.W; } + public final SoundEffect getStepSound() { return this.d(); } // Paper - OBFHELPER public SoundEffect d() { - return this.A; + return this.Y; } + public final SoundEffect getPlaceSound() { return this.e(); } // Paper - OBFHELPER public SoundEffect e() { - return this.B; + return this.Z; } + public final SoundEffect getFallSound() { return this.g(); } // Paper - OBFHELPER public SoundEffect g() { - return this.D; + return this.ab; } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/Implement-EntityTeleportEndGatewayEvent.patch b/Spigot-Server-Patches/Implement-EntityTeleportEndGatewayEvent.patch index de3ce504ad..6cae15a8b4 100644 --- a/Spigot-Server-Patches/Implement-EntityTeleportEndGatewayEvent.patch +++ b/Spigot-Server-Patches/Implement-EntityTeleportEndGatewayEvent.patch @@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return; + } -- entity.enderTeleportAndLoad((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D); +- entity1.enderTeleportAndLoad((double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D); + entity.enderTeleportAndLoad(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); + // Paper end - EntityTeleportEndGatewayEvent } diff --git a/Spigot-Server-Patches/Implement-Expanded-ArmorStand-API.patch b/Spigot-Server-Patches/Implement-Expanded-ArmorStand-API.patch index 0334987c83..866ca714ba 100644 --- a/Spigot-Server-Patches/Implement-Expanded-ArmorStand-API.patch +++ b/Spigot-Server-Patches/Implement-Expanded-ArmorStand-API.patch @@ -14,9 +14,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { private final NonNullList armorItems; private boolean armorStandInvisible; - public long bq; -- private int bB; -+ private int bB; public void setDisabledSlots(int i) { bB = i; } public int getDisabledSlots() { return bB; } // Paper - OBFHELPER + public long bp; +- private int bA; ++ private int bA; public void setDisabledSlots(int i) { bA = i; } public int getDisabledSlots() { return bA; } // Paper - OBFHELPER public Vector3f headPose; public Vector3f bodyPose; public Vector3f leftArmPose; @@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public boolean isSlotDisabled(EnumItemSlot slot) { return this.d(slot); } // Paper - OBFHELPER private boolean d(EnumItemSlot enumitemslot) { - return (this.bB & 1 << enumitemslot.c()) != 0 || enumitemslot.a() == EnumItemSlot.Function.HAND && !this.hasArms(); + return (this.bA & 1 << enumitemslot.c()) != 0 || enumitemslot.a() == EnumItemSlot.Function.HAND && !this.hasArms(); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/Implement-PlayerPostRespawnEvent.patch b/Spigot-Server-Patches/Implement-PlayerPostRespawnEvent.patch index 3ded4ff618..88df875693 100644 --- a/Spigot-Server-Patches/Implement-PlayerPostRespawnEvent.patch +++ b/Spigot-Server-Patches/Implement-PlayerPostRespawnEvent.patch @@ -9,8 +9,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -0,0 +0,0 @@ public abstract class PlayerList { - - // this.a(entityplayer1, entityplayer, worldserver); // CraftBukkit - removed + // this.a(entityplayer1, entityplayer, worldserver1); // CraftBukkit - removed + boolean flag2 = false; + // Paper start + boolean isBedSpawn = false; @@ -20,17 +20,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit start - fire PlayerRespawnEvent if (location == null) { - boolean isBedSpawn = false; -+ //boolean isBedSpawn = false; Paper - moved up - CraftWorld cworld = (CraftWorld) this.server.server.getWorld(entityplayer.spawnWorld); - if (cworld != null && blockposition != null) { - Optional optional = EntityHuman.getBed(cworld.getHandle(), blockposition, flag1); ++ // boolean isBedSpawn = false; // Paper - moved up + WorldServer worldserver1 = this.server.getWorldServer(entityplayer.getSpawnDimension()); + if (worldserver1 != null) { + Optional optional; @@ -0,0 +0,0 @@ public abstract class PlayerList { location = respawnEvent.getRespawnLocation(); if (!flag) entityplayer.reset(); // SPIGOT-4785 + isRespawn = true; // Paper } else { - location.setWorld(server.getWorldServer(dimensionmanager).getWorld()); + location.setWorld(worldserver.getWorld()); } @@ -0,0 +0,0 @@ public abstract class PlayerList { if (entityplayer.playerConnection.isDisconnected()) { diff --git a/Spigot-Server-Patches/Implement-furnace-cook-speed-multiplier-API.patch b/Spigot-Server-Patches/Implement-furnace-cook-speed-multiplier-API.patch index beab8b3d1f..f39ce0fc52 100644 --- a/Spigot-Server-Patches/Implement-furnace-cook-speed-multiplier-API.patch +++ b/Spigot-Server-Patches/Implement-furnace-cook-speed-multiplier-API.patch @@ -9,8 +9,8 @@ diff --git a/src/main/java/net/minecraft/server/TileEntityFurnace.java b/src/mai index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/TileEntityFurnace.java +++ b/src/main/java/net/minecraft/server/TileEntityFurnace.java -@@ -0,0 +0,0 @@ import java.util.Map; - import java.util.Map.Entry; +@@ -0,0 +0,0 @@ import java.util.List; + import java.util.Map; import javax.annotation.Nullable; // CraftBukkit start +import java.util.List; @@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public int cookTimeTotal; protected final IContainerProperties b; @@ -0,0 +0,0 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I - this.n.put(minecraftkey, j); + this.n.put(new MinecraftKey(s), nbttagcompound1.getInt(s)); } + // Paper start - cook speed API @@ -43,8 +43,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 nbttagcompound.setShort("CookTimeTotal", (short) this.cookTimeTotal); + nbttagcompound.setDouble("Paper.CookSpeedMultiplier", this.cookSpeedMultiplier); // Paper - cook speed multiplier API ContainerUtil.a(nbttagcompound, this.items); - nbttagcompound.setShort("RecipesUsedSize", (short) this.n.size()); - int i = 0; + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + @@ -0,0 +0,0 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I } diff --git a/Spigot-Server-Patches/Improve-BlockPosition-inlining.patch b/Spigot-Server-Patches/Improve-BlockPosition-inlining.patch index 58706a92fa..5561d27712 100644 --- a/Spigot-Server-Patches/Improve-BlockPosition-inlining.patch +++ b/Spigot-Server-Patches/Improve-BlockPosition-inlining.patch @@ -24,43 +24,7 @@ diff --git a/src/main/java/net/minecraft/server/BaseBlockPosition.java b/src/mai index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BaseBlockPosition.java +++ b/src/main/java/net/minecraft/server/BaseBlockPosition.java -@@ -0,0 +0,0 @@ import javax.annotation.concurrent.Immutable; - public class BaseBlockPosition implements Comparable { - - public static final BaseBlockPosition ZERO = new BaseBlockPosition(0, 0, 0); -- @Deprecated -- private final int a; -- @Deprecated -- private final int b; -- @Deprecated -- private final int c; - // Paper start -- public boolean isValidLocation() { -- return a >= -30000000 && c >= -30000000 && a < 30000000 && c < 30000000 && b >= 0 && b < 256; -+ protected int x; -+ protected int y; -+ protected int z; -+ -+ public final boolean isValidLocation() { -+ return x >= -30000000 && z >= -30000000 && x < 30000000 && z < 30000000 && y >= 0 && y < 256; - } -- public boolean isInvalidYLocation() { -- return b < 0 || b >= 256; -+ public final boolean isInvalidYLocation() { -+ return y < 0 || y >= 256; - } - // Paper end - - public BaseBlockPosition(int i, int j, int k) { -- this.a = i; -- this.b = j; -- this.c = k; -+ this.x = i; -+ this.y = j; -+ this.z = k; - } - - public BaseBlockPosition(double d0, double d1, double d2) { +@@ -0,0 +0,0 @@ public class BaseBlockPosition implements Comparable { this(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); } @@ -70,188 +34,42 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return true; } else if (!(object instanceof BaseBlockPosition)) { @@ -0,0 +0,0 @@ public class BaseBlockPosition implements Comparable { - } else { - BaseBlockPosition baseblockposition = (BaseBlockPosition) object; - -- return this.getX() != baseblockposition.getX() ? false : (this.getY() != baseblockposition.getY() ? false : this.getZ() == baseblockposition.getZ()); -+ return x == baseblockposition.x && z == baseblockposition.z && y == baseblockposition.y; // Paper } } - public int hashCode() { -- return (this.getY() + this.getZ() * 31) * 31 + this.getX(); + public final int hashCode() { // Paper -+ return (this.y + this.z * 31) * 31 + this.x; // Paper + return (this.getY() + this.getZ() * 31) * 31 + this.getX(); } - public int compareTo(BaseBlockPosition baseblockposition) { +@@ -0,0 +0,0 @@ public class BaseBlockPosition implements Comparable { return this.getY() == baseblockposition.getY() ? (this.getZ() == baseblockposition.getZ() ? this.getX() - baseblockposition.getX() : this.getZ() - baseblockposition.getZ()) : this.getY() - baseblockposition.getY(); } - public int getX() { -- return this.a; -+ // Paper start -+ public final int getX() { -+ return this.x; ++ public final int getX() { // Paper + return this.a; } - public int getY() { -- return this.b; -+ public final int getY() { -+ return this.y; ++ public final int getY() { // Paper + return this.b; } - public int getZ() { -- return this.c; -+ public final int getZ() { -+ return this.z; - } -+ // Paper end - - public BaseBlockPosition down() { - return this.down(1); -@@ -0,0 +0,0 @@ public class BaseBlockPosition implements Comparable { - public BaseBlockPosition shift(EnumDirection enumdirection, int i) { - return i == 0 ? this : new BaseBlockPosition(this.getX() + enumdirection.getAdjacentX() * i, this.getY() + enumdirection.getAdjacentY() * i, this.getZ() + enumdirection.getAdjacentZ() * i); - } -+ // Paper end - - public BaseBlockPosition d(BaseBlockPosition baseblockposition) { - return new BaseBlockPosition(this.getY() * baseblockposition.getZ() - this.getZ() * baseblockposition.getY(), this.getZ() * baseblockposition.getX() - this.getX() * baseblockposition.getZ(), this.getX() * baseblockposition.getY() - this.getY() * baseblockposition.getX()); ++ public final int getZ() { // Paper + return this.e; } - public boolean a(BaseBlockPosition baseblockposition, double d0) { -- return this.distanceSquared((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ(), false) < d0 * d0; -+ return this.distanceSquared((double) baseblockposition.x, (double) baseblockposition.y, (double) baseblockposition.z, false) < d0 * d0; // Paper - } - - public boolean a(IPosition iposition, double d0) { -@@ -0,0 +0,0 @@ public class BaseBlockPosition implements Comparable { - } - - public int n(BaseBlockPosition baseblockposition) { -- float f = (float) Math.abs(baseblockposition.getX() - this.getX()); -- float f1 = (float) Math.abs(baseblockposition.getY() - this.getY()); -- float f2 = (float) Math.abs(baseblockposition.getZ() - this.getZ()); -+ float f = (float) Math.abs(baseblockposition.getX() - this.x); // Paper -+ float f1 = (float) Math.abs(baseblockposition.getY() - this.y); // Paper -+ float f2 = (float) Math.abs(baseblockposition.getZ() - this.z); // Paper - - return (int) (f + f1 + f2); - } diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockPosition.java +++ b/src/main/java/net/minecraft/server/BlockPosition.java -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali - return new BlockPosition(b(i), c(i), d(i)); +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { + return a(this.getX(), this.getY(), this.getZ()); } + public static long asLong(int x, int y, int z) { return a(x, y, z); } // Paper - OBFHELPER public static long a(int i, int j, int k) { long l = 0L; -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali - } - - public long asLong() { -- return a(this.getX(), this.getY(), this.getZ()); -+ return a(this.x, this.y, this.z); // Paper - } - - public BlockPosition a(double d0, double d1, double d2) { -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali - } - - public static class MutableBlockPosition extends BlockPosition { -- -+ // Paper start - comment out -+ /* - protected int b; - protected int c; - protected int d; -- -+ */ -+ // Paper end - public MutableBlockPosition() { - this(0, 0, 0); - } -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali - } - - public MutableBlockPosition(int i, int j, int k) { -- super(0, 0, 0); -+ // Paper start -+ super(i, j, k); -+ /* - this.b = i; - this.c = j; -- this.d = k; -+ this.d = k;*/ -+ // Paper end - } - - public MutableBlockPosition(double d0, double d1, double d2) { -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali - return super.a(enumblockrotation).immutableCopy(); - } - -+ -+ /* -+ // Paper start - use parent getters - @Override - public int getX() { - return this.b; -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali - @Override - public int getZ() { - return this.d; -- } -+ }*/ -+ // Paper end - - public BlockPosition.MutableBlockPosition setValues(int i, int j, int k) { return d(i, j, k);} // Paper - OBFHELPER - public BlockPosition.MutableBlockPosition d(int i, int j, int k) { -- this.b = i; -- this.c = j; -- this.d = k; -+ // Paper start - use xyz -+ this.x = i; -+ this.y = j; -+ this.z = k; -+ // Paper end - return this; - } - -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali - } - - public BlockPosition.MutableBlockPosition c(EnumDirection enumdirection, int i) { -- return this.d(this.b + enumdirection.getAdjacentX() * i, this.c + enumdirection.getAdjacentY() * i, this.d + enumdirection.getAdjacentZ() * i); -+ return this.d(this.x + enumdirection.getAdjacentX() * i, this.y + enumdirection.getAdjacentY() * i, this.z + enumdirection.getAdjacentZ() * i); - } - - public BlockPosition.MutableBlockPosition e(int i, int j, int k) { -- return this.d(this.b + i, this.c + j, this.d + k); -+ return this.d(this.x + i, this.y + j, this.z + k); - } - - public final void setX(final int x) { this.o(x); } // Paper - OBFHELPER - public void o(int i) { -- this.b = i; -+ this.x = i; // Paper change to x - } - - public final void setY(final int y) { this.p(y); } // Paper - OBFHELPER - public void p(int i) { -- this.c = i; -+ this.y = i; // Paper change to y - } - - public final void setZ(final int z) { this.q(z); } // Paper - OBFHELPER - public void q(int i) { -- this.d = i; -+ this.z = i; // Paper change to z - } - - @Override diff --git a/Spigot-Server-Patches/Improve-Server-Thread-Pool-and-Thread-Priorities.patch b/Spigot-Server-Patches/Improve-Server-Thread-Pool-and-Thread-Priorities.patch index 29d53e3fb5..363735867f 100644 --- a/Spigot-Server-Patches/Improve-Server-Thread-Pool-and-Thread-Priorities.patch +++ b/Spigot-Server-Patches/Improve-Server-Thread-Pool-and-Thread-Priorities.patch @@ -16,13 +16,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant collidableExemptions = new HashSet<>(); public boolean canPickUpLoot; public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper + public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event @@ -140,18 +140,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public float getBukkitYaw() { @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { - - if (this.getHealth() <= 0.0F) { + if (knockbackCancelled) this.world.broadcastEntityEffect(this, (byte) 2); // Paper - Disable explosion knockback + if (this.dk()) { if (!this.f(damagesource)) { - SoundEffect soundeffect = this.getSoundDeath(); + // Paper start - moved into CraftEventFactory event caller for cancellable death event + //SoundEffect soundeffect = this.getSoundDeath(); - if (flag1 && soundeffect != null) { -- this.a(soundeffect, this.getSoundVolume(), this.dn()); +- this.playSound(soundeffect, this.getSoundVolume(), this.dG()); - } +// if (flag1 && soundeffect != null) { -+// this.a(soundeffect, this.getSoundVolume(), this.dn()); ++// this.playSound(soundeffect, this.getSoundVolume(), this.dG()); +// } + this.silentDeath = !flag1; // mark entity as dying silently + // Paper end @@ -166,8 +166,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 EntityLiving entityliving = this.getKillingEntity(); + /* // Paper - move down to make death event cancellable - if (this.aW >= 0 && entityliving != null) { - entityliving.a(this, this.aW, damagesource); + if (this.aV >= 0 && entityliving != null) { + entityliving.a(this, this.aV, damagesource); } @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { if (this.isSleeping()) { @@ -177,7 +177,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.killed = true; - this.getCombatTracker().g(); -+ //this.getCombatTracker().g(); ++ //this.getCombatTracker().g(); // Paper if (!this.world.isClientSide) { - this.d(damagesource); + org.bukkit.event.entity.EntityDeathEvent deathEvent = this.d(damagesource); @@ -198,7 +198,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end + - this.f(entityliving); + this.g(entityliving); } + if (this.killed) { // Paper @@ -215,7 +215,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - if (entityliving instanceof EntityWither) { + if (this.killed && entityliving instanceof EntityWither) { // Paper if (this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { - BlockPosition blockposition = new BlockPosition(this); + BlockPosition blockposition = this.getChunkCoordinates(); IBlockData iblockdata = Blocks.WITHER_ROSE.getBlockData(); @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { } @@ -232,7 +232,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.dropInventory(); // CraftBukkit - from below + org.bukkit.event.entity.EntityDeathEvent deathEvent; // Paper - if (this.isDropExperience() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { + if (this.cV() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { this.a(damagesource, flag); this.dropDeathLoot(damagesource, i, flag); // CraftBukkit start - Call death event @@ -274,8 +274,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return 1.0F; } -+ public float getSoundPitch() { return dn();} // Paper - OBFHELPER - protected float dn() { ++ public float getSoundPitch() { return dG();} // Paper - OBFHELPER + protected float dG() { return this.isBaby() ? (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.5F : (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F; } diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -376,7 +376,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end } - public void injectScaledMaxHealth(Collection collection, boolean force) { + public void injectScaledMaxHealth(Collection collection, boolean force) { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java diff --git a/Spigot-Server-Patches/InventoryCloseEvent-Reason-API.patch b/Spigot-Server-Patches/InventoryCloseEvent-Reason-API.patch index 33c16f5258..bd98ded920 100644 --- a/Spigot-Server-Patches/InventoryCloseEvent-Reason-API.patch +++ b/Spigot-Server-Patches/InventoryCloseEvent-Reason-API.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java @@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving { - this.dW(); + this.es(); super.tick(); if (!this.world.isClientSide && this.activeContainer != null && !this.activeContainer.canUse(this)) { - this.closeInventory(); @@ -85,7 +85,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit + // Paper end this.playerConnection.sendPacket(new PacketPlayOutCloseWindow(this.activeContainer.windowId)); - this.m(); + this.o(); } diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -98,7 +98,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit + CraftEventFactory.handleInventoryCloseEvent(this.player, org.bukkit.event.inventory.InventoryCloseEvent.Reason.PLAYER); // CraftBukkit // Paper - this.player.m(); + this.player.o(); } diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -117,7 +117,7 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { for (TileEntity tileentity : chunk.getTileEntities().values()) { if (tileentity instanceof IInventory) { for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((IInventory) tileentity).getViewers())) { @@ -126,7 +126,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } } -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { // Spigot Start if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder) { for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((org.bukkit.inventory.InventoryHolder) entity.getBukkitEntity()).getInventory().getViewers())) { diff --git a/Spigot-Server-Patches/ItemStack-getMaxItemUseDuration.patch b/Spigot-Server-Patches/ItemStack-getMaxItemUseDuration.patch index b80ac05822..c06e7fc429 100644 --- a/Spigot-Server-Patches/ItemStack-getMaxItemUseDuration.patch +++ b/Spigot-Server-Patches/ItemStack-getMaxItemUseDuration.patch @@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public int getItemUseMaxDuration() { return k(); } // Paper - OBFHELPER public int k() { - return this.getItem().f_(this); + return this.getItem().e_(this); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/Lazy-init-world-storage-in-CraftOfflinePlayer.patch b/Spigot-Server-Patches/Lazy-init-world-storage-in-CraftOfflinePlayer.patch deleted file mode 100644 index c1d50fa72a..0000000000 --- a/Spigot-Server-Patches/Lazy-init-world-storage-in-CraftOfflinePlayer.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zach Brown <1254957+zachbr@users.noreply.github.com> -Date: Tue, 11 Dec 2018 22:25:07 -0500 -Subject: [PATCH] Lazy init world storage in CraftOfflinePlayer - -Allows access to some offline player properties even when there are no -worlds loaded. This is typically a rare occurrence but probably one that -should be covered as best we can. - -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java -@@ -0,0 +0,0 @@ import org.bukkit.plugin.Plugin; - public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializable { - private final GameProfile profile; - private final CraftServer server; -- private final WorldNBTStorage storage; -+ private WorldNBTStorage storage; // Paper - lazy init - - protected CraftOfflinePlayer(CraftServer server, GameProfile profile) { - this.server = server; - this.profile = profile; -- this.storage = (WorldNBTStorage) (server.console.getWorldServer(DimensionManager.OVERWORLD).getDataManager()); -+ //this.storage = (WorldNBTStorage) (server.console.getWorldServer(DimensionManager.OVERWORLD).getDataManager()); // Paper - lazy init - - } - -@@ -0,0 +0,0 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa - return hash; - } - -+ // Paper - lazy -+ private WorldNBTStorage getStorageLazy() { -+ if (this.storage == null) { -+ net.minecraft.server.WorldServer worldServer = server.console.getWorldServer(DimensionManager.OVERWORLD); -+ if (worldServer == null) { -+ throw new IllegalStateException("Cannot get world storage when there are no worlds loaded!"); -+ } else { -+ this.storage = (WorldNBTStorage) worldServer.getDataManager(); -+ } -+ } -+ -+ return this.storage; -+ } -+ // Paper end -+ - private NBTTagCompound getData() { -- return storage.getPlayerData(getUniqueId().toString()); -+ return getStorageLazy().getPlayerData(getUniqueId().toString()); - } - - private NBTTagCompound getBukkitData() { -@@ -0,0 +0,0 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa - } - - private File getDataFile() { -- return new File(storage.getPlayerDir(), getUniqueId() + ".dat"); -+ return new File(getStorageLazy().getPlayerDir(), getUniqueId() + ".dat"); - } - - @Override diff --git a/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch b/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch deleted file mode 100644 index 8c3e2decd0..0000000000 --- a/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Trigary -Date: Fri, 14 Sep 2018 17:42:08 +0200 -Subject: [PATCH] Limit lightning strike effect distance - - -diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -0,0 +0,0 @@ public class PaperWorldConfig { - } - } - -+ public double sqrMaxThunderDistance; -+ public double sqrMaxLightningImpactSoundDistance; -+ public double maxLightningFlashDistance; -+ private void lightningStrikeDistanceLimit() { -+ sqrMaxThunderDistance = getInt("lightning-strike-distance-limit.sound", -1); -+ if (sqrMaxThunderDistance > 0) { -+ sqrMaxThunderDistance *= sqrMaxThunderDistance; -+ } -+ -+ sqrMaxLightningImpactSoundDistance = getInt("lightning-strike-distance-limit.impact-sound", -1); -+ if (sqrMaxLightningImpactSoundDistance < 0) { -+ sqrMaxLightningImpactSoundDistance = 32 * 32; //Vanilla value -+ } else { -+ sqrMaxLightningImpactSoundDistance *= sqrMaxLightningImpactSoundDistance; -+ } -+ -+ maxLightningFlashDistance = getInt("lightning-strike-distance-limit.flash", -1); -+ if (maxLightningFlashDistance < 0) { -+ maxLightningFlashDistance = 512; // Vanilla value -+ } -+ } -+ - public int fixedInhabitedTime; - private void fixedInhabitedTime() { - if (PaperConfig.version < 16) { -diff --git a/src/main/java/net/minecraft/server/EntityLightning.java b/src/main/java/net/minecraft/server/EntityLightning.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/EntityLightning.java -+++ b/src/main/java/net/minecraft/server/EntityLightning.java -@@ -0,0 +0,0 @@ public class EntityLightning extends Entity { - double deltaX = this.locX() - player.locX(); - double deltaZ = this.locZ() - player.locZ(); - double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; -+ // Paper start - Limit lightning strike effect distance -+ if (distanceSquared <= this.world.paperConfig.sqrMaxLightningImpactSoundDistance) { -+ player.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(SoundEffects.ENTITY_LIGHTNING_BOLT_IMPACT, -+ SoundCategory.WEATHER, this.locX(), this.locY(), this.locZ(), 2.0f, 0.5F + this.random.nextFloat() * 0.2F)); -+ } -+ -+ if (world.paperConfig.sqrMaxThunderDistance != -1 && distanceSquared >= world.paperConfig.sqrMaxThunderDistance) { -+ continue; -+ } -+ -+ // Paper end - if (distanceSquared > viewDistance * viewDistance) { - double deltaLength = Math.sqrt(distanceSquared); - double relativeX = player.locX() + (deltaX / deltaLength) * viewDistance; -@@ -0,0 +0,0 @@ public class EntityLightning extends Entity { - } - } - // CraftBukkit end -- this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_LIGHTNING_BOLT_IMPACT, SoundCategory.WEATHER, 2.0F, 0.5F + this.random.nextFloat() * 0.2F); -+ //this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_LIGHTNING_BOLT_IMPACT, SoundCategory.WEATHER, 2.0F, 0.5F + this.random.nextFloat() * 0.2F); // Paper - Limit lightning strike effect distance (the packet is now sent from inside the loop) - } - - --this.lifeTicks; -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { - } - // CraftBukkit end - this.globalEntityList.add(entitylightning); -- this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entitylightning.locX(), entitylightning.locY(), entitylightning.locZ(), 512.0D, this, new PacketPlayOutSpawnEntityWeather(entitylightning)); // Paper - use world instead of dimension -+ this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entitylightning.locX(), entitylightning.locY(), entitylightning.locZ(), paperConfig.maxLightningFlashDistance, this, new PacketPlayOutSpawnEntityWeather(entitylightning)); // Paper - use world instead of dimension, limit lightning strike effect distance - } - - @Override diff --git a/Spigot-Server-Patches/LivingEntity-Hand-Raised-Item-Use-API.patch b/Spigot-Server-Patches/LivingEntity-Hand-Raised-Item-Use-API.patch index 425694ecc9..9e9a69abfb 100644 --- a/Spigot-Server-Patches/LivingEntity-Hand-Raised-Item-Use-API.patch +++ b/Spigot-Server-Patches/LivingEntity-Hand-Raised-Item-Use-API.patch @@ -15,21 +15,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private float bD; - protected ItemStack activeItem; + public ItemStack activeItem; // Paper - public + protected int bk; protected int bl; - protected int bm; private BlockPosition bE; @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { return this.activeItem; } -+ public int getItemUseRemainingTime() { return this.dE(); } // Paper - OBFHELPER - public int dE() { - return this.bl; ++ public int getItemUseRemainingTime() { return this.dY(); } // Paper - OBFHELPER + public int dY() { + return this.bk; } -+ public int getHandRaisedTime() { return this.dF(); } // Paper - OBFHELPER - public int dF() { - return this.isHandRaised() ? this.activeItem.k() - this.dE() : 0; ++ public int getHandRaisedTime() { return this.dZ(); } // Paper - OBFHELPER + public int dZ() { + return this.isHandRaised() ? this.activeItem.k() - this.dY() : 0; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/MC-114618-Fix-EntityAreaEffectCloud-from-going-negat.patch b/Spigot-Server-Patches/MC-114618-Fix-EntityAreaEffectCloud-from-going-negat.patch index 17e364f1cc..16487401c2 100644 --- a/Spigot-Server-Patches/MC-114618-Fix-EntityAreaEffectCloud-from-going-negat.patch +++ b/Spigot-Server-Patches/MC-114618-Fix-EntityAreaEffectCloud-from-going-negat.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/EntityAreaEffectCloud.java @@ -0,0 +0,0 @@ public class EntityAreaEffectCloud extends Entity { super.tick(); - boolean flag = this.l(); + boolean flag = this.k(); float f = this.getRadius(); + // Paper start - fix MC-114618 + if (f < 0.0F) { diff --git a/Spigot-Server-Patches/MC-135506-Experience-should-save-as-Integers.patch b/Spigot-Server-Patches/MC-135506-Experience-should-save-as-Integers.patch index b5a140c999..13380aac18 100644 --- a/Spigot-Server-Patches/MC-135506-Experience-should-save-as-Integers.patch +++ b/Spigot-Server-Patches/MC-135506-Experience-should-save-as-Integers.patch @@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java +++ b/src/main/java/net/minecraft/server/EntityExperienceOrb.java @@ -0,0 +0,0 @@ public class EntityExperienceOrb extends Entity { - public void b(NBTTagCompound nbttagcompound) { + public void saveData(NBTTagCompound nbttagcompound) { nbttagcompound.setShort("Health", (short) this.e); nbttagcompound.setShort("Age", (short) this.c); - nbttagcompound.setShort("Value", (short) this.value); @@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } @@ -0,0 +0,0 @@ public class EntityExperienceOrb extends Entity { - public void a(NBTTagCompound nbttagcompound) { + public void loadData(NBTTagCompound nbttagcompound) { this.e = nbttagcompound.getShort("Health"); this.c = nbttagcompound.getShort("Age"); - this.value = nbttagcompound.getShort("Value"); diff --git a/Spigot-Server-Patches/MC-145260-Fix-Whitelist-On-Off-inconsistency.patch b/Spigot-Server-Patches/MC-145260-Fix-Whitelist-On-Off-inconsistency.patch index fa794f1650..a8888d55f8 100644 --- a/Spigot-Server-Patches/MC-145260-Fix-Whitelist-On-Off-inconsistency.patch +++ b/Spigot-Server-Patches/MC-145260-Fix-Whitelist-On-Off-inconsistency.patch @@ -10,31 +10,10 @@ everything to the Whitelist object. https://github.com/PaperMC/Paper/issues/1880 -diff --git a/src/main/java/net/minecraft/server/JsonList.java b/src/main/java/net/minecraft/server/JsonList.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/JsonList.java -+++ b/src/main/java/net/minecraft/server/JsonList.java -@@ -0,0 +0,0 @@ public class JsonList> { - return this.e; - } - -+ public void setEnabled(boolean flag) { this.a(flag); } // Paper - OBFHeLPER - public void a(boolean flag) { - this.e = flag; - } diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java -@@ -0,0 +0,0 @@ public abstract class PlayerList { - // private final Map p; - // CraftBukkit end - public IPlayerFileData playerFileData; -- private boolean hasWhitelist; -+ //private boolean hasWhitelist; - protected final int maxPlayers; - private int viewDistance; - private EnumGamemode t; @@ -0,0 +0,0 @@ public abstract class PlayerList { } public boolean isWhitelisted(GameProfile gameprofile, org.bukkit.event.player.PlayerLoginEvent loginEvent) { @@ -47,17 +26,3 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 event.callEvent(); if (!event.isWhitelisted()) { if (loginEvent != null) { -@@ -0,0 +0,0 @@ public abstract class PlayerList { - } - - public boolean getHasWhitelist() { -- return this.hasWhitelist; -+ return this.whitelist.isEnabled(); // Paper - } - - public void setHasWhitelist(boolean flag) { -- this.hasWhitelist = flag; -+ this.whitelist.setEnabled(flag); // Paper - } - - public List b(String s) { diff --git a/Spigot-Server-Patches/MC-50319-Check-other-worlds-for-shooter-of-projectil.patch b/Spigot-Server-Patches/MC-50319-Check-other-worlds-for-shooter-of-projectil.patch index 7ac8cb0e55..f0d6b6a720 100644 --- a/Spigot-Server-Patches/MC-50319-Check-other-worlds-for-shooter-of-projectil.patch +++ b/Spigot-Server-Patches/MC-50319-Check-other-worlds-for-shooter-of-projectil.patch @@ -10,24 +10,27 @@ because the entity is in another world. If the projectile fails to find the shooter in the current world, check other worlds. -diff --git a/src/main/java/net/minecraft/server/EntityProjectile.java b/src/main/java/net/minecraft/server/EntityProjectile.java +diff --git a/src/main/java/net/minecraft/server/IProjectile.java b/src/main/java/net/minecraft/server/IProjectile.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/EntityProjectile.java -+++ b/src/main/java/net/minecraft/server/EntityProjectile.java -@@ -0,0 +0,0 @@ public abstract class EntityProjectile extends Entity implements IProjectile { - public EntityLiving getShooter() { - if ((this.shooter == null || this.shooter.dead) && this.shooterId != null && this.world instanceof WorldServer) { - Entity entity = ((WorldServer) this.world).getEntity(this.shooterId); -+ // Paper start - MC-50319 - shooter might be in another world (arrows through portals) -+ if (entity == null) { -+ for (WorldServer world : world.getMinecraftServer().getWorlds()) { -+ entity = world.getEntity(this.shooterId); -+ if (entity != null) { -+ break; -+ } +--- a/src/main/java/net/minecraft/server/IProjectile.java ++++ b/src/main/java/net/minecraft/server/IProjectile.java +@@ -0,0 +0,0 @@ public abstract class IProjectile extends Entity { + + @Nullable + public Entity getShooter() { +- return this.shooter != null && this.world instanceof WorldServer ? ((WorldServer) this.world).getEntity(this.shooter) : (this.c != 0 ? this.world.getEntity(this.c) : null); ++ // Paper start - MC-50319 - shooter might be in another world (arrows through portals) ++ Entity entity = this.shooter != null && this.world instanceof WorldServer ? ((WorldServer) this.world).getEntity(this.shooter) : (this.c != 0 ? this.world.getEntity(this.c) : null); ++ if (entity == null) { ++ for (WorldServer world : world.getMinecraftServer().getWorlds()) { ++ entity = world.getEntity(this.shooter); ++ if (entity != null) { ++ break; + } + } -+ // Paper end ++ } ++ return entity; ++ // Paper end + } - if (entity instanceof EntityLiving) { - this.shooter = (EntityLiving) entity; + @Override diff --git a/Spigot-Server-Patches/Make-player-data-saving-configurable.patch b/Spigot-Server-Patches/Make-player-data-saving-configurable.patch index 7eb8539431..2db25b2cc5 100644 --- a/Spigot-Server-Patches/Make-player-data-saving-configurable.patch +++ b/Spigot-Server-Patches/Make-player-data-saving-configurable.patch @@ -26,11 +26,11 @@ diff --git a/src/main/java/net/minecraft/server/WorldNBTStorage.java b/src/main/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldNBTStorage.java +++ b/src/main/java/net/minecraft/server/WorldNBTStorage.java -@@ -0,0 +0,0 @@ public class WorldNBTStorage implements IPlayerFileData { +@@ -0,0 +0,0 @@ public class WorldNBTStorage { + } - @Override public void save(EntityHuman entityhuman) { + if(!com.destroystokyo.paper.PaperConfig.savePlayerData) return; // Paper - Make player data saving configurable try { NBTTagCompound nbttagcompound = entityhuman.save(new NBTTagCompound()); - File file = new File(this.playerDir, entityhuman.getUniqueIDString() + ".dat.tmp"); + File file = File.createTempFile(entityhuman.getUniqueIDString() + "-", ".dat", this.playerDir); diff --git a/Spigot-Server-Patches/Make-shield-blocking-delay-configurable.patch b/Spigot-Server-Patches/Make-shield-blocking-delay-configurable.patch index 71e644ea51..d1eb5d785d 100644 --- a/Spigot-Server-Patches/Make-shield-blocking-delay-configurable.patch +++ b/Spigot-Server-Patches/Make-shield-blocking-delay-configurable.patch @@ -26,8 +26,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.isHandRaised() && !this.activeItem.isEmpty()) { Item item = this.activeItem.getItem(); -- return item.e_(this.activeItem) != EnumAnimation.BLOCK ? false : item.f_(this.activeItem) - this.bl >= 5; -+ return item.e_(this.activeItem) != EnumAnimation.BLOCK ? false : item.f_(this.activeItem) - this.bl >= getShieldBlockingDelay(); // Paper - shieldBlockingDelay +- return item.d_(this.activeItem) != EnumAnimation.BLOCK ? false : item.e_(this.activeItem) - this.bk >= 5; ++ return item.d_(this.activeItem) != EnumAnimation.BLOCK ? false : item.e_(this.activeItem) - this.bk >= getShieldBlockingDelay(); // Paper - shieldBlockingDelay } else { return false; } diff --git a/Spigot-Server-Patches/Make-the-default-permission-message-configurable.patch b/Spigot-Server-Patches/Make-the-default-permission-message-configurable.patch index 2b34660d3a..caa6fe2b3f 100644 --- a/Spigot-Server-Patches/Make-the-default-permission-message-configurable.patch +++ b/Spigot-Server-Patches/Make-the-default-permission-message-configurable.patch @@ -14,8 +14,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.command.Command; - import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; + import org.bukkit.configuration.file.YamlConfiguration; @@ -0,0 +0,0 @@ public class PaperConfig { connectionThrottleKickMessage = getString("messages.kick.connection-throttle", connectionThrottleKickMessage); } diff --git a/Spigot-Server-Patches/Mob-Pathfinding-API.patch b/Spigot-Server-Patches/Mob-Pathfinding-API.patch index 8d4e03eeff..1da6849bca 100644 --- a/Spigot-Server-Patches/Mob-Pathfinding-API.patch +++ b/Spigot-Server-Patches/Mob-Pathfinding-API.patch @@ -171,7 +171,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable - public PathEntity a(Entity entity, int i) { + public final PathEntity calculateDestination(Entity entity) { return a(entity, 0); } public PathEntity a(Entity entity, int i) { - return this.a(ImmutableSet.of(new BlockPosition(entity)), entity, 16, true, i); // Paper + return this.a(ImmutableSet.of(entity.getChunkCoordinates()), entity, 16, true, i); // Paper } @@ -0,0 +0,0 @@ public abstract class NavigationAbstract { @@ -234,11 +234,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return this.a(entity, this.e); } -- public Vec3D g() { -+ public Vec3D getNext() { return g(); } public Vec3D g() { // Paper - OBFHELPER - PathPoint pathpoint = (PathPoint) this.a.get(this.e); +- public BaseBlockPosition g() { ++ public BaseBlockPosition getNext() { return g(); } public BaseBlockPosition g() { // Paper - OBFHELPER + PathPoint pathpoint = this.h(); - return new Vec3D((double) pathpoint.a, (double) pathpoint.b, (double) pathpoint.c); + return new BaseBlockPosition(pathpoint.a, pathpoint.b, pathpoint.c); diff --git a/src/main/java/net/minecraft/server/PathPoint.java b/src/main/java/net/minecraft/server/PathPoint.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PathPoint.java diff --git a/Spigot-Server-Patches/Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch b/Spigot-Server-Patches/Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch index 4ccce0ebb9..86b6e5b476 100644 --- a/Spigot-Server-Patches/Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch +++ b/Spigot-Server-Patches/Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch @@ -9,16 +9,16 @@ diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/n index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BiomeBase.java +++ b/src/main/java/net/minecraft/server/BiomeBase.java -@@ -0,0 +0,0 @@ public abstract class BiomeBase { - protected final Map>> r = Maps.newHashMap(); +@@ -0,0 +0,0 @@ public class BiomeBase { + protected final Map>> r; protected final List> s = Lists.newArrayList(); - protected final Map, WorldGenFeatureConfiguration> t = Maps.newHashMap(); -- private final Map> v = Maps.newHashMap(); -+ private final java.util.EnumMap> v = Maps.newEnumMap(EnumCreatureType.class); // Paper - private final ThreadLocal w = ThreadLocal.withInitial(() -> { - return (Long2FloatLinkedOpenHashMap) SystemUtils.a(() -> { - Long2FloatLinkedOpenHashMap long2floatlinkedopenhashmap = new Long2FloatLinkedOpenHashMap(1024, 0.25F) { -@@ -0,0 +0,0 @@ public abstract class BiomeBase { + private final Map, StructureFeature> u; +- private final Map> v; ++ private final Map> v = Maps.newEnumMap(EnumCreatureType.class); // Paper + private final Map, BiomeBase.e> w = Maps.newHashMap(); + private final List x; + private final ThreadLocal y = ThreadLocal.withInitial(() -> { +@@ -0,0 +0,0 @@ public class BiomeBase { for (j = 0; j < i; ++j) { EnumCreatureType enumcreaturetype = aenumcreaturetype[j]; @@ -27,8 +27,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } else { -@@ -0,0 +0,0 @@ public abstract class BiomeBase { - return this.m; +@@ -0,0 +0,0 @@ public class BiomeBase { + return this.l; } + // Paper start - keep track of data in a pair set to give O(1) contains calls - we have to hook removals incase plugins mess with it @@ -63,6 +63,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end + - public static class a { + public static class d { - @Nullable + public static final Codec a = RecordCodecBuilder.create((instance) -> { diff --git a/Spigot-Server-Patches/Optimize-BlockPosition-helper-methods.patch b/Spigot-Server-Patches/Optimize-BlockPosition-helper-methods.patch index 0b029eb22c..8b41511ab7 100644 --- a/Spigot-Server-Patches/Optimize-BlockPosition-helper-methods.patch +++ b/Spigot-Server-Patches/Optimize-BlockPosition-helper-methods.patch @@ -9,7 +9,7 @@ diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/ja index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockPosition.java +++ b/src/main/java/net/minecraft/server/BlockPosition.java -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { } public BlockPosition up() { diff --git a/Spigot-Server-Patches/Optimize-Captured-TileEntity-Lookup.patch b/Spigot-Server-Patches/Optimize-Captured-TileEntity-Lookup.patch index fa92989644..b966bc8c6e 100644 --- a/Spigot-Server-Patches/Optimize-Captured-TileEntity-Lookup.patch +++ b/Spigot-Server-Patches/Optimize-Captured-TileEntity-Lookup.patch @@ -29,4 +29,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + //TileEntity tileentity = null; // Paper - move up if (this.tickingTileEntities) { - tileentity = this.e(blockposition); + tileentity = this.D(blockposition); diff --git a/Spigot-Server-Patches/Optimize-CraftBlockData-Creation.patch b/Spigot-Server-Patches/Optimize-CraftBlockData-Creation.patch deleted file mode 100644 index 3f1a8a6095..0000000000 --- a/Spigot-Server-Patches/Optimize-CraftBlockData-Creation.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: miclebrick -Date: Thu, 23 Aug 2018 11:45:32 -0400 -Subject: [PATCH] Optimize CraftBlockData Creation - -Avoids a hashmap lookup by cacheing a reference to the CraftBlockData -and cloning it when one is needed. - -diff --git a/src/main/java/net/minecraft/server/IBlockData.java b/src/main/java/net/minecraft/server/IBlockData.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/IBlockData.java -+++ b/src/main/java/net/minecraft/server/IBlockData.java -@@ -0,0 +0,0 @@ import com.google.common.collect.ImmutableMap; - import com.mojang.datafixers.Dynamic; - import com.mojang.datafixers.types.DynamicOps; - import com.mojang.datafixers.util.Pair; -+import org.bukkit.craftbukkit.block.data.CraftBlockData; -+ - import java.util.Arrays; - import java.util.Iterator; - import java.util.List; -@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements - return (Block) this.a; - } - -+ // Paper start - impl cached craft block data, lazy load to fix issue with loading at the wrong time -+ private CraftBlockData cachedCraftBlockData; -+ -+ public CraftBlockData createCraftBlockData() { -+ if(cachedCraftBlockData == null) cachedCraftBlockData = CraftBlockData.createData(this); -+ return (CraftBlockData) cachedCraftBlockData.clone(); -+ } -+ // Paper end -+ - public Material getMaterial() { - return this.getBlock().k(this); - } -diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -@@ -0,0 +0,0 @@ public class CraftBlockData implements BlockData { - return craft; - } - -+ // Paper start - optimize creating BlockData to not need a map lookup -+ static { -+ // Initialize cached data for all IBlockData instances after registration -+ Block.REGISTRY_ID.iterator().forEachRemaining(IBlockData::createCraftBlockData); -+ } - public static CraftBlockData fromData(IBlockData data) { -+ return data.createCraftBlockData(); -+ } -+ -+ public static CraftBlockData createData(IBlockData data) { -+ // Paper end - return MAP.getOrDefault(data.getBlock().getClass(), CraftBlockData::new).apply(data); - } - } diff --git a/Spigot-Server-Patches/Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/Spigot-Server-Patches/Optimize-Network-Manager-and-add-advanced-packet-sup.patch index 89c236f34e..10a915a758 100644 --- a/Spigot-Server-Patches/Optimize-Network-Manager-and-add-advanced-packet-sup.patch +++ b/Spigot-Server-Patches/Optimize-Network-Manager-and-add-advanced-packet-sup.patch @@ -51,7 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.channel.config().setAutoRead(true); NetworkManager.LOGGER.debug("Enabled auto read"); @@ -0,0 +0,0 @@ public class NetworkManager extends SimpleChannelInboundHandler> { - NetworkManager.LOGGER.debug("Set listener of {} to {}", this, packetlistener); + Validate.notNull(packetlistener, "packetListener", new Object[0]); this.packetListener = packetlistener; } + // Paper start @@ -298,7 +298,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.j() != null) { @@ -0,0 +0,0 @@ public class NetworkManager extends SimpleChannelInboundHandler> { } else if (this.i() != null) { - this.i().a(new ChatMessage("multiplayer.disconnect.generic", new Object[0])); + this.i().a(new ChatMessage("multiplayer.disconnect.generic")); } - this.packetQueue.clear(); // Free up packet queue. + clearPacketQueue(); // Paper @@ -335,11 +335,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -0,0 +0,0 @@ public abstract class PlayerList { + boolean flag1 = gamerules.getBoolean(GameRules.REDUCED_DEBUG_INFO); - // CraftBukkit - getType() // Spigot - view distance + networkmanager.queueImmunity = true; // Paper - playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), WorldData.c(worlddata.getSeed()), worlddata.isHardcore(), worldserver.worldProvider.getDimensionManager().getType(), this.getMaxPlayers(), worlddata.getType(), worldserver.spigotConfig.viewDistance, flag1, !flag)); + playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), entityplayer.playerInteractManager.c(), BiomeManager.a(worldserver1.getSeed()), worlddata.isHardcore(), this.server.E(), this.s, worldserver1.getTypeKey(), worldserver1.getDimensionKey(), this.getMaxPlayers(), worldserver.spigotConfig.viewDistance, flag1, !flag, worldserver1.isDebugWorld(), worldserver1.isFlatWorld())); entityplayer.getBukkitEntity().sendSupportedChannels(); // CraftBukkit playerconnection.sendPacket(new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.a, (new PacketDataSerializer(Unpooled.buffer())).a(this.getServer().getServerModName()))); @@ -0,0 +0,0 @@ public abstract class PlayerList { diff --git a/Spigot-Server-Patches/Optimize-RegistryMaterials.patch b/Spigot-Server-Patches/Optimize-RegistryMaterials.patch index 472458eeab..631d0e862f 100644 --- a/Spigot-Server-Patches/Optimize-RegistryMaterials.patch +++ b/Spigot-Server-Patches/Optimize-RegistryMaterials.patch @@ -17,16 +17,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected static final Logger LOGGER = LogManager.getLogger(); - protected final RegistryID b = new RegistryID<>(256); - protected final BiMap c = HashBiMap.create(); +- private final BiMap, T> bb = HashBiMap.create(); + protected final RegistryID b = new RegistryID<>(2048); // Paper - use bigger expected size to reduce collisions + protected final BiMap c = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions ++ private final BiMap, T> bb = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions + private final Set> bc = Sets.newIdentityHashSet(); protected Object[] d; - private int V; - + private int bd; @@ -0,0 +0,0 @@ public class RegistryMaterials extends IRegistryWritable { this.d = collection.toArray(new Object[collection.size()]); } -- return this.d[random.nextInt(this.d.length)]; -+ return (T) this.d[random.nextInt(this.d.length)]; // Paper - Decompile fix +- return SystemUtils.a(this.d, random); ++ return (T) SystemUtils.a(this.d, random); // Paper - Decompile fix } - } + + @Override +@@ -0,0 +0,0 @@ public class RegistryMaterials extends IRegistryWritable { + Iterator iterator = registrymaterials.b.iterator(); + + while (iterator.hasNext()) { +- T t0 = iterator.next(); ++ T t0 = (T) iterator.next(); // Paper - Decompile fix + + builder.add(Pair.of(registrymaterials.c(t0).get(), t0)); + } diff --git a/Spigot-Server-Patches/Optimize-Server-World-Map.patch b/Spigot-Server-Patches/Optimize-Server-World-Map.patch index f70b6a1158..9a52f6dc4e 100644 --- a/Spigot-Server-Patches/Optimize-Server-World-Map.patch +++ b/Spigot-Server-Patches/Optimize-Server-World-Map.patch @@ -28,6 +28,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +package com.destroystokyo.paper; + +import net.minecraft.server.DimensionManager; ++import net.minecraft.server.ResourceKey; ++import net.minecraft.server.World; +import net.minecraft.server.WorldServer; + +import javax.annotation.Nonnull; @@ -40,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import java.util.Map; +import java.util.Set; + -+public class PaperWorldMap extends HashMap { ++public class PaperWorldMap extends HashMap, WorldServer> { + private final List worlds = new ArrayList<>(); + private final List worldsIterable = new ArrayList() { + @Override @@ -80,10 +82,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override + public WorldServer get(Object key) { + // Will hit the below method -+ return key instanceof DimensionManager ? get((DimensionManager) key) : null; ++ return key instanceof ResourceKey ? get((ResourceKey) key) : null; + } -+ -+ public WorldServer get(DimensionManager key) { ++ // TODO figure out what to do with dimension ids ++ public WorldServer get(ResourceKey key) { + int id = key.getDimensionID()+1; + return worlds.size() > id ? worlds.get(id) : null; + } @@ -98,7 +100,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ public WorldServer put(DimensionManager key, WorldServer value) { ++ public WorldServer put(ResourceKey key, WorldServer value) { + while (worlds.size() <= key.getDimensionID()+1) { + worlds.add(null); + } @@ -111,8 +113,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ public void putAll(Map m) { -+ for (Entry e : m.entrySet()) { ++ public void putAll(Map, ? extends WorldServer> m) { ++ for (Entry, ? extends WorldServer> e : m.entrySet()) { + put(e.getKey(), e.getValue()); + } + } @@ -142,17 +144,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + @Override + public boolean containsValue(Object value) { -+ return value instanceof WorldServer && get(((WorldServer) value).worldProvider.getDimensionManager()) != null; ++ return value instanceof WorldServer && get(((WorldServer) value).getDimensionKey()) != null; + } + + @Nonnull + @Override -+ public Set keySet() { -+ return new AbstractSet() { ++ public Set> keySet() { ++ return new AbstractSet>() { + @Override -+ public Iterator iterator() { ++ public Iterator> iterator() { + Iterator iterator = worldsIterable.iterator(); -+ return new Iterator() { ++ return new Iterator>() { + + @Override + public boolean hasNext() { @@ -160,8 +162,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ public DimensionManager next() { -+ return iterator.next().worldProvider.getDimensionManager(); ++ public ResourceKey next() { ++ return iterator.next().getDimensionKey(); + } + + @Override @@ -184,12 +186,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ public Set> entrySet() { -+ return new AbstractSet>() { ++ public Set, WorldServer>> entrySet() { ++ return new AbstractSet, WorldServer>>() { + @Override -+ public Iterator> iterator() { ++ public Iterator, WorldServer>> iterator() { + Iterator iterator = worldsIterable.iterator(); -+ return new Iterator>() { ++ return new Iterator, WorldServer>>() { + + @Override + public boolean hasNext() { @@ -197,9 +199,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ public Entry next() { ++ public Entry, WorldServer> next() { + WorldServer entry = iterator.next(); -+ return new SimpleEntry<>(entry.worldProvider.getDimensionManager(), entry); ++ return new SimpleEntry<>(entry.getDimensionKey(), entry); + } + + @Override @@ -221,28 +223,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant worldServer = Maps.newLinkedHashMap(); // CraftBukkit - keep order, k+v already use identity methods -+ public final Map worldServer = new com.destroystokyo.paper.PaperWorldMap(); // Paper; + private int serverPort; + public final IRegistryCustom.Dimension f; +- public final Map, WorldServer> worldServer; ++ public final Map, WorldServer> worldServer = new com.destroystokyo.paper.PaperWorldMap(); // Paper; private PlayerList playerList; - private volatile boolean isRunning = true; + private volatile boolean isRunning; private volatile boolean isRestarting = false; // Paper - flag to signify we're attempting to restart @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant -Date: Thu, 27 Sep 2018 01:43:35 -0600 -Subject: [PATCH] Optimize redstone algorithm - -Author: theosib -Co-authored-by: egg82 - -Original license: MIT - -This patch implements theosib's redstone algorithms to completely overhaul the way redstone works. -The new algorithms should be many times faster than current vanilla ones. -From the original author's comments, it looks like it shouldn't interfere with any redstone save for very extreme edge-cases. - -Surprisingly, not a lot was touched aside from a few obfuscation helpers and BlockRedstoneWire. -A lot of this code is self-contained in a helper class. - -Aside from making the obvious class/function renames and obfhelpers I didn't need to modify much. -Just added Bukkit's event system and took a few liberties with dead code and comment misspellings. - -diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -0,0 +0,0 @@ public class PaperWorldConfig { - private void preventMovingIntoUnloadedChunks() { - preventMovingIntoUnloadedChunks = getBoolean("prevent-moving-into-unloaded-chunks", false); - } -+ -+ public boolean useEigencraftRedstone = false; -+ private void useEigencraftRedstone() { -+ useEigencraftRedstone = this.getBoolean("use-faster-eigencraft-redstone", false); -+ if (useEigencraftRedstone) { -+ log("Using Eigencraft redstone algorithm by theosib."); -+ } else { -+ log("Using vanilla redstone algorithm."); -+ } -+ } - } -diff --git a/src/main/java/com/destroystokyo/paper/util/RedstoneWireTurbo.java b/src/main/java/com/destroystokyo/paper/util/RedstoneWireTurbo.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/RedstoneWireTurbo.java -@@ -0,0 +0,0 @@ -+package com.destroystokyo.paper.util; -+ -+import java.util.List; -+import java.util.Map; -+import java.util.concurrent.ThreadLocalRandom; -+ -+import org.bukkit.event.block.BlockRedstoneEvent; -+ -+import com.google.common.collect.Lists; -+import com.google.common.collect.Maps; -+ -+import net.minecraft.server.Block; -+import net.minecraft.server.BlockPosition; -+import net.minecraft.server.BlockRedstoneWire; -+import net.minecraft.server.IBlockData; -+import net.minecraft.server.Items; -+import net.minecraft.server.ItemStack; -+import net.minecraft.server.World; -+ -+/** -+ * Used for the faster redstone algorithm. -+ * Original author: theosib -+ * Original license: MIT -+ * -+ * Ported to Paper and updated to 1.13 by egg82 -+ */ -+public class RedstoneWireTurbo { -+ /* -+ * This is Helper class for BlockRedstoneWire. It implements a minimally-invasive -+ * bolt-on accelerator that performs a breadth-first search through redstone wire blocks -+ * in order to more efficiently and deterministically compute new redstone wire power levels -+ * and determine the order in which other blocks should be updated. -+ * -+ * Features: -+ * - Changes to BlockRedstoneWire are very limited, no other classes are affected, and the -+ * choice between old and new redstone wire update algorithms is switchable on-line. -+ * - The vanilla implementation relied on World.notifyNeighborsOfStateChange for redstone -+ * wire blocks to communicate power level changes to each other, generating 36 block -+ * updates per call. This improved implementation propagates power level changes directly -+ * between redstone wire blocks. Redstone wire power levels are therefore computed more quickly, -+ * and block updates are sent only to non-redstone blocks, many of which may perform an -+ * action when informed of a change in redstone power level. (Note: Block updates are not -+ * the same as state changes to redstone wire. Wire block states are updated as soon -+ * as they are computed.) -+ * - Of the 36 block updates generated by a call to World.notifyNeighborsOfStateChange, -+ * 12 of them are obviously redundant (e.g. the west neighbor of the east neighbor). -+ * These are eliminated. -+ * - Updates to redstone wire and other connected blocks are propagated in a breath-first -+ * manner, radiating out from the initial trigger (a block update to a redstone wire -+ * from something other than redstone wire). -+ * - Updates are scheduled both deterministically and in an intuitive order, addressing bug -+ * MC-11193. -+ * - All redstone behavior that used to be locational now works the same in all locations. -+ * - All behaviors of redstone wire that used to be orientational now work the same in all -+ * orientations, as long as orientation can be determined; random otherwise. Some other -+ * redstone components still update directionally (e.g. switches), and this code can't -+ * compensate for that. -+ * - Information that is otherwise computed over and over again or which is expensive to -+ * to compute is cached for faster lookup. This includes coordinates of block position -+ * neighbors and block states that won't change behind our backs during the execution of -+ * this search algorithm. -+ * - Redundant block updates (both to redstone wire and to other blocks) are heavily -+ * consolidated. For worst-case scenarios (depowering of redstone wire) this results -+ * in a reduction of block updates by as much as 95% (factor of 1/21). Due to overheads, -+ * empirical testing shows a speedup better than 10x. This addresses bug MC-81098. -+ * -+ * Extensive testing has been performed to ensure that existing redstone contraptions still -+ * behave as expected. Results of early testing that identified undesirable behavior changes -+ * were addressed. Additionally, real-time performance testing revealed compute inefficiencies -+ * With earlier implementations of this accelerator. Some compatibility adjustments and -+ * performance optimizations resulted in harmless increases in block updates above the -+ * theoretical minimum. -+ * -+ * Only a single redstone machine was found to break: An instant dropper line hack that -+ * relies on powered rails and quasi-connectivity but doesn't work in all directions. The -+ * replacement is to lay redstone wire directly on top of the dropper line, which now works -+ * reliably in any direction. -+ * -+ * There are numerous other optimization that can be made, but those will be provided later in -+ * separate updates. This version is designed to be minimalistic. -+ * -+ * Many thanks to the following individuals for their help in testing this functionality: -+ * - pokechu22, _MethodZz_, WARBEN, NarcolepticFrog, CommandHelper (nessie), ilmango, -+ * OreoLamp, Xcom6000, tryashtar, RedCMD, Smokey95Dog, EDDxample, Rays Works, -+ * Nodnam, BlockyPlays, Grumm, NeunEinser, HelVince. -+ */ -+ -+ /* Reference to BlockRedstoneWire object, which uses this accelerator */ -+ private final BlockRedstoneWire wire; -+ -+ /* -+ * Implementation: -+ * -+ * RedstoneWire Blocks are updated in concentric rings or "layers" radiating out from the -+ * initial block update that came from a call to BlockRedstoneWire.neighborChanged(). -+ * All nodes put in Layer N are those with Manhattan distance N from the trigger -+ * position, reachable through connected redstone wire blocks. -+ * -+ * Layer 0 represents the trigger block position that was input to neighborChanged. -+ * Layer 1 contains the immediate neighbors of that position. -+ * Layer N contains the neighbors of blocks in layer N-1, not including -+ * those in previous layers. -+ * -+ * Layers enforce an update order that is a function of Manhattan distance -+ * from the initial coordinates input to neighborChanged. The same -+ * coordinates may appear in multiple layers, but redundant updates are minimized. -+ * Block updates are sent layer-by-layer. If multiple of a block's neighbors experience -+ * redstone wire changes before its layer is processed, then those updates will be merged. -+ * If a block's update has been sent, but its neighboring redstone changes -+ * after that, then another update will be sent. This preserves compatibility with -+ * machines that rely on zero-tick behavior, except that the new functionality is non- -+ * locational. -+ * -+ * Within each layer, updates are ordered left-to-right relative to the direction of -+ * information flow. This makes the implementation non-orientational. Only when -+ * this direction is ambiguous is randomness applied (intentionally). -+ */ -+ private List updateQueue0 = Lists.newArrayList(); -+ private List updateQueue1 = Lists.newArrayList(); -+ private List updateQueue2 = Lists.newArrayList(); -+ -+ public RedstoneWireTurbo(BlockRedstoneWire wire) { -+ this.wire = wire; -+ } -+ -+ /* -+ * Compute neighbors of a block. When a redstone wire value changes, previously it called -+ * World.notifyNeighborsOfStateChange. That lists immediately neighboring blocks in -+ * west, east, down, up, north, south order. For each of those neighbors, their own -+ * neighbors are updated in the same order. This generates 36 updates, but 12 of them are -+ * redundant; for instance the west neighbor of a block's east neighbor. -+ * -+ * Note that this ordering is only used to create the initial list of neighbors. Once -+ * the direction of signal flow is identified, the ordering of updates is completely -+ * reorganized. -+ */ -+ public static BlockPosition[] computeAllNeighbors(final BlockPosition pos) { -+ final int x = pos.getX(); -+ final int y = pos.getY(); -+ final int z = pos.getZ(); -+ final BlockPosition[] n = new BlockPosition[24]; -+ -+ // Immediate neighbors, in the same order as -+ // World.notifyNeighborsOfStateChange, etc.: -+ // west, east, down, up, north, south -+ n[0] = new BlockPosition(x - 1, y, z); -+ n[1] = new BlockPosition(x + 1, y, z); -+ n[2] = new BlockPosition(x, y - 1, z); -+ n[3] = new BlockPosition(x, y + 1, z); -+ n[4] = new BlockPosition(x, y, z - 1); -+ n[5] = new BlockPosition(x, y, z + 1); -+ -+ // Neighbors of neighbors, in the same order, -+ // except that duplicates are not included -+ n[6] = new BlockPosition(x - 2, y, z); -+ n[7] = new BlockPosition(x - 1, y - 1, z); -+ n[8] = new BlockPosition(x - 1, y + 1, z); -+ n[9] = new BlockPosition(x - 1, y, z - 1); -+ n[10] = new BlockPosition(x - 1, y, z + 1); -+ n[11] = new BlockPosition(x + 2, y, z); -+ n[12] = new BlockPosition(x + 1, y - 1, z); -+ n[13] = new BlockPosition(x + 1, y + 1, z); -+ n[14] = new BlockPosition(x + 1, y, z - 1); -+ n[15] = new BlockPosition(x + 1, y, z + 1); -+ n[16] = new BlockPosition(x, y - 2, z); -+ n[17] = new BlockPosition(x, y - 1, z - 1); -+ n[18] = new BlockPosition(x, y - 1, z + 1); -+ n[19] = new BlockPosition(x, y + 2, z); -+ n[20] = new BlockPosition(x, y + 1, z - 1); -+ n[21] = new BlockPosition(x, y + 1, z + 1); -+ n[22] = new BlockPosition(x, y, z - 2); -+ n[23] = new BlockPosition(x, y, z + 2); -+ return n; -+ } -+ -+ /* -+ * We only want redstone wires to update redstone wires that are -+ * immediately adjacent. Some more distant updates can result -+ * in cross-talk that (a) wastes time and (b) can make the update -+ * order unintuitive. Therefore (relative to the neighbor order -+ * computed by computeAllNeighbors), updates are not scheduled -+ * for redstone wire in those non-connecting positions. On the -+ * other hand, updates will always be sent to *other* types of blocks -+ * in any of the 24 neighboring positions. -+ */ -+ private static final boolean[] update_redstone = { -+ true, true, false, false, true, true, // 0 to 5 -+ false, true, true, false, false, false, // 6 to 11 -+ true, true, false, false, false, true, // 12 to 17 -+ true, false, true, true, false, false // 18 to 23 -+ }; -+ -+ // Internal numbering for cardinal directions -+ private static final int North = 0; -+ private static final int East = 1; -+ private static final int South = 2; -+ private static final int West = 3; -+ -+ /* -+ * These lookup tables completely remap neighbor positions into a left-to-right -+ * ordering, based on the cardinal direction that is determined to be forward. -+ * See below for more explanation. -+ */ -+ private static final int[] forward_is_north = {2, 3, 16, 19, 0, 4, 1, 5, 7, 8, 17, 20, 12, 13, 18, 21, 6, 9, 22, 14, 11, 10, 23, 15}; -+ private static final int[] forward_is_east = {2, 3, 16, 19, 4, 1, 5, 0, 17, 20, 12, 13, 18, 21, 7, 8, 22, 14, 11, 15, 23, 9, 6, 10}; -+ private static final int[] forward_is_south = {2, 3, 16, 19, 1, 5, 0, 4, 12, 13, 18, 21, 7, 8, 17, 20, 11, 15, 23, 10, 6, 14, 22, 9}; -+ private static final int[] forward_is_west = {2, 3, 16, 19, 5, 0, 4, 1, 18, 21, 7, 8, 17, 20, 12, 13, 23, 10, 6, 9, 22, 15, 11, 14}; -+ -+ /* For any orientation, we end up with the update order defined below. This order is relative to any redstone wire block -+ * that is itself having an update computed, and this center position is marked with C. -+ * - The update position marked 0 is computed first, and the one marked 23 is last. -+ * - Forward is determined by the local direction of information flow into position C from prior updates. -+ * - The first updates are scheduled for the four positions below and above C. -+ * - Then updates are scheduled for the four horizontal neighbors of C, followed by the positions below and above those neighbors. -+ * - Finally, updates are scheduled for the remaining positions with Manhattan distance 2 from C (at the same Y coordinate). -+ * - For a given horizontal distance from C, updates are scheduled starting from directly left and stepping clockwise to directly -+ * right. The remaining positions behind C are scheduled counterclockwise so as to maintain the left-to-right ordering. -+ * - If C is in layer N of the update schedule, then all 24 positions may be scheduled for layer N+1. For redstone wire, no -+ * updates are scheduled for positions that cannot directly connect. Additionally, the four positions above and below C -+ * are ALSO scheduled for layer N+2. -+ * - This update order was selected after experimenting with a number of alternative schedules, based on its compatibility -+ * with existing redstone designs and behaviors that were considered to be intuitive by various testers. WARBEN in particular -+ * made some of the most challenging test cases, but the 3-tick clocks (made by RedCMD) were also challenging to fix, -+ * along with the rail-based instant dropper line built by ilmango. Numerous others made test cases as well, including -+ * NarcolepticFrog, nessie, and Pokechu22. -+ * -+ * - The forward direction is determined locally. So when there are branches in the redstone wire, the left one will get updated -+ * before the right one. Each branch can have its own relative forward direction, resulting in the left side of a left branch -+ * having priority over the right branch of a left branch, which has priority over the left branch of a right branch, followed -+ * by the right branch of a right branch. And so forth. Since redstone power reduces to zero after a path distance of 15, -+ * that imposes a practical limit on the branching. Note that the branching is not tracked explicitly -- relative forward -+ * directions dictate relative sort order, which maintains the proper global ordering. This also makes it unnecessary to be -+ * concerned about branches meeting up with each other. -+ * -+ * ^ -+ * | -+ * Forward -+ * <-- Left Right --> -+ * -+ * 18 -+ * 10 17 5 19 11 -+ * 2 8 0 12 16 4 C 6 20 9 1 13 3 -+ * 14 21 7 23 15 -+ * Further 22 Further -+ * Down Down Up Up -+ * -+ * Backward -+ * | -+ * V -+ */ -+ -+ // This allows the above remapping tables to be looked up by cardial direction index -+ private static final int[][] reordering = { forward_is_north, forward_is_east, forward_is_south, forward_is_west }; -+ -+ /* -+ * Input: Array of UpdateNode objects in an order corresponding to the positions -+ * computed by computeAllNeighbors above. -+ * Output: Array of UpdateNode objects oriented using the above remapping tables -+ * corresponding to the identified heading (direction of information flow). -+ */ -+ private static void orientNeighbors(final UpdateNode[] src, final UpdateNode[] dst, final int heading) { -+ final int[] re = reordering[heading]; -+ for (int i = 0; i < 24; i++) { -+ dst[i] = src[re[i]]; -+ } -+ } -+ -+ /* -+ * Structure to keep track of redstone wire blocks and -+ * neighbors that will receive updates. -+ */ -+ private static class UpdateNode { -+ public static enum Type { -+ UNKNOWN, REDSTONE, OTHER -+ } -+ -+ IBlockData currentState; // Keep track of redstone wire value -+ UpdateNode[] neighbor_nodes; // References to neighbors (directed graph edges) -+ BlockPosition self; // UpdateNode's own position -+ BlockPosition parent; // Which block pos spawned/updated this node -+ Type type = Type.UNKNOWN; // unknown, redstone wire, other type of block -+ int layer; // Highest layer this node is scheduled in -+ boolean visited; // To keep track of information flow direction, visited restone wire is marked -+ int xbias, zbias; // Remembers directionality of ancestor nodes; helps eliminate directional ambiguities. -+ } -+ -+ /* -+ * Keep track of all block positions discovered during search and their current states. -+ * We want to remember one entry for each position. -+ */ -+ private final Map nodeCache = Maps.newHashMap(); -+ -+ /* -+ * For a newly created UpdateNode object, determine what type of block it is. -+ */ -+ private void identifyNode(final World worldIn, final UpdateNode upd1) { -+ final BlockPosition pos = upd1.self; -+ final IBlockData oldState = worldIn.getType(pos); -+ upd1.currentState = oldState; -+ -+ // Some neighbors of redstone wire are other kinds of blocks. -+ // These need to receive block updates to inform them that -+ // redstone wire values have changed. -+ final Block block = oldState.getBlock(); -+ if (block != wire) { -+ // Mark this block as not redstone wire and therefore -+ // requiring updates -+ upd1.type = UpdateNode.Type.OTHER; -+ -+ // Non-redstone blocks may propagate updates, but those updates -+ // are not handled by this accelerator. Therefore, we do not -+ // expand this position's neighbors. -+ return; -+ } -+ -+ // One job of BlockRedstoneWire.neighborChanged is to convert -+ // redstone wires to items if the block beneath was removed. -+ // With this accelerator, BlockRedstoneWire.neighborChanged -+ // is only typically called for a single wire block, while -+ // others are processed internally by the breadth first search -+ // algorithm. To preserve this game behavior, this check must -+ // be replicated here. -+ if (!wire.canPlace(null, worldIn, pos)) { -+ // Pop off the redstone dust -+ Block.a(worldIn, pos, new ItemStack(Items.REDSTONE)); // TODO -+ worldIn.setAir(pos); -+ -+ // Mark this position as not being redstone wire -+ upd1.type = UpdateNode.Type.OTHER; -+ -+ // Note: Sending updates to air blocks leads to an empty method. -+ // Testing shows this to be faster than explicitly avoiding updates to -+ // air blocks. -+ return; -+ } -+ -+ // If the above conditions fail, then this is a redstone wire block. -+ upd1.type = UpdateNode.Type.REDSTONE; -+ } -+ -+ /* -+ * Given which redstone wire blocks have been visited and not visited -+ * around the position currently being updated, compute the cardinal -+ * direction that is "forward." -+ * -+ * rx is the forward direction along the West/East axis -+ * rz is the forward direction along the North/South axis -+ */ -+ static private int computeHeading(final int rx, final int rz) { -+ // rx and rz can only take on values -1, 0, and 1, so we can -+ // compute a code number that allows us to use a single switch -+ // to determine the heading. -+ final int code = (rx + 1) + 3 * (rz + 1); -+ switch (code) { -+ case 0: { -+ // Both rx and rz are -1 (northwest) -+ // Randomly choose one to be forward. -+ final int j = ThreadLocalRandom.current().nextInt(0, 1); -+ return (j == 0) ? North : West; -+ } -+ case 1: { -+ // rx=0, rz=-1 -+ // Definitively North -+ return North; -+ } -+ case 2: { -+ // rx=1, rz=-1 (northeast) -+ // Choose randomly between north and east -+ final int j = ThreadLocalRandom.current().nextInt(0, 1); -+ return (j == 0) ? North : East; -+ } -+ case 3: { -+ // rx=-1, rz=0 -+ // Definitively West -+ return West; -+ } -+ case 4: { -+ // rx=0, rz=0 -+ // Heading is completely ambiguous. Choose -+ // randomly among the four cardinal directions. -+ return ThreadLocalRandom.current().nextInt(0, 4); -+ } -+ case 5: { -+ // rx=1, rz=0 -+ // Definitively East -+ return East; -+ } -+ case 6: { -+ // rx=-1, rz=1 (southwest) -+ // Choose randomly between south and west -+ final int j = ThreadLocalRandom.current().nextInt(0, 1); -+ return (j == 0) ? South : West; -+ } -+ case 7: { -+ // rx=0, rz=1 -+ // Definitively South -+ return South; -+ } -+ case 8: { -+ // rx=1, rz=1 (southeast) -+ // Choose randomly between south and east -+ final int j = ThreadLocalRandom.current().nextInt(0, 1); -+ return (j == 0) ? South : East; -+ } -+ } -+ -+ // We should never get here -+ return ThreadLocalRandom.current().nextInt(0, 4); -+ } -+ -+ // Select whether to use updateSurroundingRedstone from BlockRedstoneWire (old) -+ // or this helper class (new) -+ private static final boolean old_current_change = false; -+ -+ /* -+ * Process a node whose neighboring redstone wire has experienced value changes. -+ */ -+ private void updateNode(final World worldIn, final UpdateNode upd1, final int layer) { -+ final BlockPosition pos = upd1.self; -+ -+ // Mark this redstone wire as having been visited so that it can be used -+ // to calculate direction of information flow. -+ upd1.visited = true; -+ -+ // Look up the last known state. -+ // Due to the way other redstone components are updated, we do not -+ // have to worry about a state changing behind our backs. The rare -+ // exception is handled by scheduleReentrantNeighborChanged. -+ final IBlockData oldState = upd1.currentState; -+ -+ // Ask the wire block to compute its power level from its neighbors. -+ // This will also update the wire's power level and return a new -+ // state if it has changed. When a wire power level is changed, -+ // calculateCurrentChanges will immediately update the block state in the world -+ // and return the same value here to be cached in the corresponding -+ // UpdateNode object. -+ IBlockData newState; -+ if (old_current_change) { -+ newState = wire.calculateCurrentChanges(worldIn, pos, pos, oldState); -+ } else { -+ // Looking up block state is slow. This accelerator includes a version of -+ // calculateCurrentChanges that uses cahed wire values for a -+ // significant performance boost. -+ newState = this.calculateCurrentChanges(worldIn, upd1); -+ } -+ -+ // Only inform neighbors if the state has changed -+ if (newState != oldState) { -+ // Store the new state -+ upd1.currentState = newState; -+ -+ // Inform neighbors of the change -+ propagateChanges(worldIn, upd1, layer); -+ } -+ } -+ -+ /* -+ * This identifies the neighboring positions of a new UpdateNode object, -+ * determines their types, and links those to into the graph. Then based on -+ * what nodes in the redstone wire graph have been visited, the neighbors -+ * are reordered left-to-right relative to the direction of information flow. -+ */ -+ private void findNeighbors(final World worldIn, final UpdateNode upd1) { -+ final BlockPosition pos = upd1.self; -+ -+ // Get the list of neighbor coordinates -+ final BlockPosition[] neighbors = computeAllNeighbors(pos); -+ -+ // Temporary array of neighbors in cardinal ordering -+ final UpdateNode[] neighbor_nodes = new UpdateNode[24]; -+ -+ // Target array of neighbors sorted left-to-right -+ upd1.neighbor_nodes = new UpdateNode[24]; -+ -+ for (int i=0; i<24; i++) { -+ // Look up each neighbor in the node cache -+ final BlockPosition pos2 = neighbors[i]; -+ UpdateNode upd2 = nodeCache.get(pos2); -+ if (upd2 == null) { -+ // If this is a previously unreached position, create -+ // a new update node, add it to the cache, and identify what it is. -+ upd2 = new UpdateNode(); -+ upd2.self = pos2; -+ upd2.parent = pos; -+ nodeCache.put(pos2, upd2); -+ identifyNode(worldIn, upd2); -+ } -+ -+ // For non-redstone blocks, any of the 24 neighboring positions -+ // should receive a block update. However, some block coordinates -+ // may contain a redstone wire that does not directly connect to the -+ // one being expanded. To avoid redundant calculations and confusing -+ // cross-talk, those neighboring positions are not included. -+ if (update_redstone[i] || upd2.type != UpdateNode.Type.REDSTONE) { -+ neighbor_nodes[i] = upd2; -+ } -+ } -+ -+ // Determine the directions from which the redstone signal may have come from. This -+ // checks for redstone wire at the same Y level and also Y+1 and Y-1, relative to the -+ // block being expanded. -+ final boolean fromWest = (neighbor_nodes[0].visited || neighbor_nodes[7].visited || neighbor_nodes[8].visited); -+ final boolean fromEast = (neighbor_nodes[1].visited || neighbor_nodes[12].visited || neighbor_nodes[13].visited); -+ final boolean fromNorth = (neighbor_nodes[4].visited || neighbor_nodes[17].visited || neighbor_nodes[20].visited); -+ final boolean fromSouth = (neighbor_nodes[5].visited || neighbor_nodes[18].visited || neighbor_nodes[21].visited); -+ -+ int cx = 0, cz = 0; -+ if (fromWest) cx += 1; -+ if (fromEast) cx -= 1; -+ if (fromNorth) cz += 1; -+ if (fromSouth) cz -= 1; -+ -+ int heading; -+ if (cx==0 && cz==0) { -+ // If there is no clear direction, try to inherit the heading from ancestor nodes. -+ heading = computeHeading(upd1.xbias, upd1.zbias); -+ -+ // Propagate that heading to descendant nodes. -+ for (int i=0; i<24; i++) { -+ final UpdateNode nn = neighbor_nodes[i]; -+ if (nn != null) { -+ nn.xbias = upd1.xbias; -+ nn.zbias = upd1.zbias; -+ } -+ } -+ } else { -+ if (cx != 0 && cz != 0) { -+ // If the heading is somewhat ambiguous, try to disambiguate based on -+ // ancestor nodes. -+ if (upd1.xbias != 0) cz = 0; -+ if (upd1.zbias != 0) cx = 0; -+ } -+ heading = computeHeading(cx, cz); -+ -+ // Propagate that heading to descendant nodes. -+ for (int i=0; i<24; i++) { -+ final UpdateNode nn = neighbor_nodes[i]; -+ if (nn != null) { -+ nn.xbias = cx; -+ nn.zbias = cz; -+ } -+ } -+ } -+ -+ // Reorder neighboring UpdateNode objects according to the forward direction -+ // determined above. -+ orientNeighbors(neighbor_nodes, upd1.neighbor_nodes, heading); -+ } -+ -+ /* -+ * For any redstone wire block in layer N, inform neighbors to recompute their states -+ * in layers N+1 and N+2; -+ */ -+ private void propagateChanges(final World worldIn, final UpdateNode upd1, final int layer) { -+ if (upd1.neighbor_nodes == null) { -+ // If this node has not been expanded yet, find its neighbors -+ findNeighbors(worldIn, upd1); -+ } -+ -+ final BlockPosition pos = upd1.self; -+ -+ // All neighbors may be scheduled for layer N+1 -+ final int layer1 = layer + 1; -+ -+ // If the node being updated (upd1) has already been expanded, then merely -+ // schedule updates to its neighbors. -+ for (int i = 0; i < 24; i++) { -+ final UpdateNode upd2 = upd1.neighbor_nodes[i]; -+ -+ // This test ensures that an UpdateNode is never scheduled to the same layer -+ // more than once. Also, skip non-connecting redstone wire blocks -+ if (upd2 != null && layer1 > upd2.layer) { -+ upd2.layer = layer1; -+ updateQueue1.add(upd2); -+ -+ // Keep track of which block updated this neighbor -+ upd2.parent = pos; -+ } -+ } -+ -+ // Nodes above and below are scheduled ALSO for layer N+2 -+ final int layer2 = layer + 2; -+ -+ // Repeat of the loop above, but only for the first four (above and below) neighbors -+ // and for layer N+2; -+ for (int i = 0; i < 4; i++) { -+ final UpdateNode upd2 = upd1.neighbor_nodes[i]; -+ if (upd2 != null && layer2 > upd2.layer) { -+ upd2.layer = layer2; -+ updateQueue2.add(upd2); -+ upd2.parent = pos; -+ } -+ } -+ } -+ -+ // The breadth-first search below will send block updates to blocks -+ // that are not redstone wire. If one of those updates results in -+ // a distant redstone wire getting an update, then this.neighborChanged -+ // will get called. This would be a reentrant call, and -+ // it is necessary to properly integrate those updates into the -+ // on-going search through redstone wire. Thus, we make the layer -+ // currently being processed visible at the object level. -+ -+ // The current layer being processed by the breadth-first search -+ private int currentWalkLayer = 0; -+ -+ private void shiftQueue() { -+ final List t = updateQueue0; -+ t.clear(); -+ updateQueue0 = updateQueue1; -+ updateQueue1 = updateQueue2; -+ updateQueue2 = t; -+ } -+ -+ /* -+ * Perform a breadth-first (layer by layer) traversal through redstone -+ * wire blocks, propagating value changes to neighbors in an order -+ * that is a function of distance from the initial call to -+ * this.neighborChanged. -+ */ -+ private void breadthFirstWalk(final World worldIn) { -+ shiftQueue(); -+ currentWalkLayer = 1; -+ -+ // Loop over all layers -+ while (updateQueue0.size()>0 || updateQueue1.size()>0) { -+ // Get the set of blocks in this layer -+ final List thisLayer = updateQueue0; -+ -+ // Loop over all blocks in the layer. Recall that -+ // this is a List, preserving the insertion order of -+ // left-to-right based on direction of information flow. -+ for (UpdateNode upd : thisLayer) { -+ if (upd.type == UpdateNode.Type.REDSTONE) { -+ // If the node is is redstone wire, -+ // schedule updates to neighbors if its value -+ // has changed. -+ updateNode(worldIn, upd, currentWalkLayer); -+ } else { -+ // If this block is not redstone wire, send a block update. -+ // Redstone wire blocks get state updates, but they don't -+ // need block updates. Only non-redstone neighbors need updates. -+ -+ // World.neighborChanged is called from -+ // World.notifyNeighborsOfStateChange, and -+ // notifyNeighborsOfStateExcept. We don't use -+ // World.notifyNeighborsOfStateChange here, since we are -+ // already keeping track of all of the neighbor positions -+ // that need to be updated. All on its own, handling neighbors -+ // this way reduces block updates by 1/3 (24 instead of 36). -+ worldIn.neighborChanged(upd.self, wire, upd.parent); -+ } -+ } -+ -+ // Move on to the next layer -+ shiftQueue(); -+ currentWalkLayer++; -+ } -+ -+ currentWalkLayer = 0; -+ } -+ -+ /* -+ * Normally, when Minecraft is computing redstone wire power changes, and a wire power level -+ * change sends a block update to a neighboring functional component (e.g. piston, repeater, etc.), -+ * those updates are queued. Only once all redstone wire updates are complete will any component -+ * action generate any further block updates to redstone wire. Instant repeater lines, for instance, -+ * will process all wire updates for one redstone line, after which the pistons will zero-tick, -+ * after which the next redstone line performs all of its updates. Thus, each wire is processed in its -+ * own discrete wave. -+ * -+ * However, there are some corner cases where this pattern breaks, with a proof of concept discovered -+ * by Rays Works, which works the same in vanilla. The scenario is as follows: -+ * (1) A redstone wire is conducting a signal. -+ * (2) Part-way through that wave of updates, a neighbor is updated that causes an update to a completely -+ * separate redstone wire. -+ * (3) This results in a call to BlockRedstoneWire.neighborChanged for that other wire, in the middle of -+ * an already on-going propagation through the first wire. -+ * -+ * The vanilla code, being depth-first, would end up fully processing the second wire before going back -+ * to finish processing the first one. (Although technically, vanilla has no special concept of "being -+ * in the middle" of processing updates to a wire.) For the breadth-first algorithm, we give this -+ * situation special handling, where the updates for the second wire are incorporated into the schedule -+ * for the first wire, and then the callstack is allowed to unwind back to the on-going search loop in -+ * order to continue processing both the first and second wire in the order of distance from the initial -+ * trigger. -+ */ -+ private IBlockData scheduleReentrantNeighborChanged(final World worldIn, final BlockPosition pos, final IBlockData newState, final BlockPosition source) { -+ if (source != null) { -+ // If the cause of the redstone wire update is known, we can use that to help determine -+ // direction of information flow. -+ UpdateNode src = nodeCache.get(source); -+ if (src == null) { -+ src = new UpdateNode(); -+ src.self = source; -+ src.parent = source; -+ src.visited = true; -+ identifyNode(worldIn, src); -+ nodeCache.put(source, src); -+ } -+ } -+ -+ // Find or generate a node for the redstone block position receiving the update -+ UpdateNode upd = nodeCache.get(pos); -+ if (upd == null) { -+ upd = new UpdateNode(); -+ upd.self = pos; -+ upd.parent = pos; -+ upd.visited = true; -+ identifyNode(worldIn, upd); -+ nodeCache.put(pos, upd); -+ } -+ upd.currentState = newState; -+ -+ // Receiving this block update may mean something in the world changed. -+ // Therefore we clear the cached block info about all neighbors of -+ // the position receiving the update and then re-identify what they are. -+ if (upd.neighbor_nodes != null) { -+ for (int i=0; i<24; i++) { -+ final UpdateNode upd2 = upd.neighbor_nodes[i]; -+ if (upd2 == null) continue; -+ upd2.type = UpdateNode.Type.UNKNOWN; -+ upd2.currentState = null; -+ identifyNode(worldIn, upd2); -+ } -+ } -+ -+ // The block at 'pos' is a redstone wire and has been updated already by calling -+ // wire.calculateCurrentChanges, so we don't schedule that. However, we do need -+ // to schedule its neighbors. By passing the current value of 'currentWalkLayer' to -+ // propagateChanges, the neighbors of 'pos' are scheduled for layers currentWalkLayer+1 -+ // and currentWalkLayer+2. -+ propagateChanges(worldIn, upd, currentWalkLayer); -+ -+ // Return here. The call stack will unwind back to the first call to -+ // updateSurroundingRedstone, whereupon the new updates just scheduled will -+ // be propagated. This also facilitates elimination of superfluous and -+ // redundant block updates. -+ return newState; -+ } -+ -+ /* -+ * New version of pre-existing updateSurroundingRedstone, which is called from -+ * wire.updateSurroundingRedstone, which is called from wire.neighborChanged and a -+ * few other methods in BlockRedstoneWire. This sets off the breadth-first -+ * walk through all redstone dust connected to the initial position triggered. -+ */ -+ public IBlockData updateSurroundingRedstone(final World worldIn, final BlockPosition pos, final IBlockData state, final BlockPosition source) { -+ // Check this block's neighbors and see if its power level needs to change -+ // Use the calculateCurrentChanges method in BlockRedstoneWire since we have no -+ // cached block states at this point. -+ final IBlockData newState = wire.calculateCurrentChanges(worldIn, pos, pos, state); -+ -+ // If no change, exit -+ if (newState == state) { -+ return state; -+ } -+ -+ // Check to see if this update was received during an on-going breadth first search -+ if (currentWalkLayer > 0 || nodeCache.size() > 0) { -+ // As breadthFirstWalk progresses, it sends block updates to neighbors. Some of those -+ // neighbors may affect the world so as to cause yet another redstone wire block to receive -+ // an update. If that happens, we need to integrate those redstone wire updates into the -+ // already on-going graph walk being performed by breadthFirstWalk. -+ return scheduleReentrantNeighborChanged(worldIn, pos, newState, source); -+ } -+ // If there are no on-going walks through redstone wire, then start a new walk. -+ -+ // If the source of the block update to the redstone wire at 'pos' is known, we can use -+ // that to help determine the direction of information flow. -+ if (source != null) { -+ final UpdateNode src = new UpdateNode(); -+ src.self = source; -+ src.parent = source; -+ src.visited = true; -+ nodeCache.put(source, src); -+ identifyNode(worldIn, src); -+ } -+ -+ // Create a node representing the block at 'pos', and then propagate updates -+ // to its neighbors. As stated above, the call to wire.calculateCurrentChanges -+ // already performs the update to the block at 'pos', so it is not added to the schedule. -+ final UpdateNode upd = new UpdateNode(); -+ upd.self = pos; -+ upd.parent = source!=null ? source : pos; -+ upd.currentState = newState; -+ upd.type = UpdateNode.Type.REDSTONE; -+ upd.visited = true; -+ nodeCache.put(pos, upd); -+ propagateChanges(worldIn, upd, 0); -+ -+ // Perform the walk over all directly reachable redstone wire blocks, propagating wire value -+ // updates in a breadth first order out from the initial update received for the block at 'pos'. -+ breadthFirstWalk(worldIn); -+ -+ // With the whole search completed, clear the list of all known blocks. -+ // We do not want to keep around state information that may be changed by other code. -+ // In theory, we could cache the neighbor block positions, but that is a separate -+ // optimization. -+ nodeCache.clear(); -+ -+ return newState; -+ } -+ -+ // For any array of neighbors in an UpdateNode object, these are always -+ // the indices of the four immediate neighbors at the same Y coordinate. -+ private static final int[] rs_neighbors = {4, 5, 6, 7}; -+ private static final int[] rs_neighbors_up = {9, 11, 13, 15}; -+ private static final int[] rs_neighbors_dn = {8, 10, 12, 14}; -+ -+ /* -+ * Updated calculateCurrentChanges that is optimized for speed and uses -+ * the UpdateNode's neighbor array to find the redstone states of neighbors -+ * that might power it. -+ */ -+ private IBlockData calculateCurrentChanges(final World worldIn, final UpdateNode upd) { -+ IBlockData state = upd.currentState; -+ final int i = state.get(BlockRedstoneWire.POWER).intValue(); -+ int j = 0; -+ j = getMaxCurrentStrength(upd, j); -+ int l = 0; -+ -+ wire.setCanProvidePower(false); -+ // Unfortunately, World.isBlockIndirectlyGettingPowered is complicated, -+ // and I'm not ready to try to replicate even more functionality from -+ // elsewhere in Minecraft into this accelerator. So sadly, we must -+ // suffer the performance hit of this very expensive call. If there -+ // is consistency to what this call returns, we may be able to cache it. -+ final int k = worldIn.isBlockIndirectlyGettingPowered(upd.self); -+ wire.setCanProvidePower(true); -+ -+ // The variable 'k' holds the maximum redstone power value of any adjacent blocks. -+ // If 'k' has the highest level of all neighbors, then the power level of this -+ // redstone wire will be set to 'k'. If 'k' is already 15, then nothing inside the -+ // following loop can affect the power level of the wire. Therefore, the loop is -+ // skipped if k is already 15. -+ if (k < 15) { -+ if (upd.neighbor_nodes == null) { -+ // If this node's neighbors are not known, expand the node -+ findNeighbors(worldIn, upd); -+ } -+ -+ // These remain constant, so pull them out of the loop. -+ // Regardless of which direction is forward, the UpdateNode for the -+ // position directly above the node being calculated is always -+ // at index 1. -+ UpdateNode center_up = upd.neighbor_nodes[1]; -+ boolean center_up_is_cube = center_up.currentState.isOccluding(worldIn, center_up.self); // TODO -+ -+ for (int m = 0; m < 4; m++) { -+ // Get the neighbor array index of each of the four cardinal -+ // neighbors. -+ int n = rs_neighbors[m]; -+ -+ // Get the max redstone power level of each of the cardinal -+ // neighbors -+ UpdateNode neighbor = upd.neighbor_nodes[n]; -+ l = getMaxCurrentStrength(neighbor, l); -+ -+ // Also check the positions above and below the cardinal -+ // neighbors -+ boolean neighbor_is_cube = neighbor.currentState.isOccluding(worldIn, neighbor.self); // TODO -+ if (!neighbor_is_cube) { -+ UpdateNode neighbor_down = upd.neighbor_nodes[rs_neighbors_dn[m]]; -+ l = getMaxCurrentStrength(neighbor_down, l); -+ } else -+ if (!center_up_is_cube) { -+ UpdateNode neighbor_up = upd.neighbor_nodes[rs_neighbors_up[m]]; -+ l = getMaxCurrentStrength(neighbor_up, l); -+ } -+ } -+ } -+ -+ // The new code sets this RedstoneWire block's power level to the highest neighbor -+ // minus 1. This usually results in wire power levels dropping by 2 at a time. -+ // This optimization alone has no impact on update order, only the number of updates. -+ j = l - 1; -+ -+ // If 'l' turns out to be zero, then j will be set to -1, but then since 'k' will -+ // always be in the range of 0 to 15, the following if will correct that. -+ if (k > j) j = k; -+ -+ // egg82's amendment -+ // Adding Bukkit's BlockRedstoneEvent - er.. event. -+ if (i != j) { -+ BlockRedstoneEvent event = new BlockRedstoneEvent(worldIn.getWorld().getBlockAt(upd.self.getX(), upd.self.getY(), upd.self.getZ()), i, j); -+ worldIn.getServer().getPluginManager().callEvent(event); -+ j = event.getNewCurrent(); -+ } -+ -+ if (i != j) { -+ // If the power level has changed from its previous value, compute a new state -+ // and set it in the world. -+ // Possible optimization: Don't commit state changes to the world until they -+ // need to be known by some nearby non-redstone-wire block. -+ BlockPosition pos = new BlockPosition(upd.self.getX(), upd.self.getY(), upd.self.getZ()); -+ if (wire.canPlace(null, worldIn, pos)) { -+ state = state.set(BlockRedstoneWire.POWER, Integer.valueOf(j)); -+ worldIn.setTypeAndData(upd.self, state, 2); -+ } -+ } -+ -+ return state; -+ } -+ -+ /* -+ * Optimized function to compute a redstone wire's power level based on cached -+ * state. -+ */ -+ private static int getMaxCurrentStrength(final UpdateNode upd, final int strength) { -+ if (upd.type != UpdateNode.Type.REDSTONE) return strength; -+ final int i = upd.currentState.get(BlockRedstoneWire.POWER).intValue(); -+ return i > strength ? i : strength; -+ } -+} -diff --git a/src/main/java/net/minecraft/server/BlockRedstoneWire.java b/src/main/java/net/minecraft/server/BlockRedstoneWire.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BlockRedstoneWire.java -+++ b/src/main/java/net/minecraft/server/BlockRedstoneWire.java -@@ -0,0 +0,0 @@ - package net.minecraft.server; - -+import com.destroystokyo.paper.PaperConfig; -+import com.destroystokyo.paper.util.RedstoneWireTurbo; - import com.google.common.collect.ImmutableMap; - import com.google.common.collect.Lists; - import com.google.common.collect.Maps; -@@ -0,0 +0,0 @@ public class BlockRedstoneWire extends Block { - public static final BlockStateInteger POWER = BlockProperties.at; - public static final Map> f = Maps.newEnumMap(ImmutableMap.of(EnumDirection.NORTH, BlockRedstoneWire.NORTH, EnumDirection.EAST, BlockRedstoneWire.EAST, EnumDirection.SOUTH, BlockRedstoneWire.SOUTH, EnumDirection.WEST, BlockRedstoneWire.WEST)); - protected static final VoxelShape[] g = new VoxelShape[]{Block.a(3.0D, 0.0D, 3.0D, 13.0D, 1.0D, 13.0D), Block.a(3.0D, 0.0D, 3.0D, 13.0D, 1.0D, 16.0D), Block.a(0.0D, 0.0D, 3.0D, 13.0D, 1.0D, 13.0D), Block.a(0.0D, 0.0D, 3.0D, 13.0D, 1.0D, 16.0D), Block.a(3.0D, 0.0D, 0.0D, 13.0D, 1.0D, 13.0D), Block.a(3.0D, 0.0D, 0.0D, 13.0D, 1.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 13.0D, 1.0D, 13.0D), Block.a(0.0D, 0.0D, 0.0D, 13.0D, 1.0D, 16.0D), Block.a(3.0D, 0.0D, 3.0D, 16.0D, 1.0D, 13.0D), Block.a(3.0D, 0.0D, 3.0D, 16.0D, 1.0D, 16.0D), Block.a(0.0D, 0.0D, 3.0D, 16.0D, 1.0D, 13.0D), Block.a(0.0D, 0.0D, 3.0D, 16.0D, 1.0D, 16.0D), Block.a(3.0D, 0.0D, 0.0D, 16.0D, 1.0D, 13.0D), Block.a(3.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 13.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D)}; -- private boolean h = true; -- private final Set i = Sets.newHashSet(); -+ private boolean h = true; public final boolean canProvidePower() { return this.h; } public final void setCanProvidePower(boolean value) { this.h = value; } // Paper - OBFHELPER -+ private final Set i = Sets.newHashSet(); private Set getBlocksNeedingUpdate() { return this.i; } // Paper - OBFHELPER - - public BlockRedstoneWire(Block.Info block_info) { - super(block_info); -@@ -0,0 +0,0 @@ public class BlockRedstoneWire extends Block { - return iblockdata1.d(iworldreader, blockposition1, EnumDirection.UP) || iblockdata1.getBlock() == Blocks.HOPPER; - } - -+ // Paper start - Optimize redstone -+ // The bulk of the new functionality is found in RedstoneWireTurbo.java -+ RedstoneWireTurbo turbo = new RedstoneWireTurbo(this); -+ -+ /* -+ * Modified version of pre-existing updateSurroundingRedstone, which is called from -+ * this.neighborChanged and a few other methods in this class. -+ * Note: Added 'source' argument so as to help determine direction of information flow -+ */ -+ private IBlockData updateSurroundingRedstone(World worldIn, BlockPosition pos, IBlockData state, BlockPosition source) { -+ if (worldIn.paperConfig.useEigencraftRedstone) { -+ return turbo.updateSurroundingRedstone(worldIn, pos, state, source); -+ } -+ return a(worldIn, pos, state); -+ } -+ -+ /* -+ * Slightly modified method to compute redstone wire power levels from neighboring blocks. -+ * Modifications cut the number of power level changes by about 45% from vanilla, and this -+ * optimization synergizes well with the breadth-first search implemented in -+ * RedstoneWireTurbo. -+ * Note: RedstoneWireTurbo contains a faster version of this code. -+ * Note: Made this public so that RedstoneWireTurbo can access it. -+ */ -+ public IBlockData calculateCurrentChanges(World worldIn, BlockPosition pos1, BlockPosition pos2, IBlockData state) { -+ IBlockData iblockstate = state; -+ int i = state.get(POWER).intValue(); -+ int j = 0; -+ j = this.getPower(j, worldIn.getType(pos2)); -+ this.setCanProvidePower(false); -+ int k = worldIn.isBlockIndirectlyGettingPowered(pos1); -+ this.setCanProvidePower(true); -+ -+ if (!worldIn.paperConfig.useEigencraftRedstone) { -+ // This code is totally redundant to if statements just below the loop. -+ if (k > 0 && k > j - 1) { -+ j = k; -+ } -+ } -+ -+ int l = 0; -+ -+ // The variable 'k' holds the maximum redstone power value of any adjacent blocks. -+ // If 'k' has the highest level of all neighbors, then the power level of this -+ // redstone wire will be set to 'k'. If 'k' is already 15, then nothing inside the -+ // following loop can affect the power level of the wire. Therefore, the loop is -+ // skipped if k is already 15. -+ if (!worldIn.paperConfig.useEigencraftRedstone || k < 15) { -+ for (EnumDirection enumfacing : EnumDirection.EnumDirectionLimit.HORIZONTAL) { -+ BlockPosition blockpos = pos1.shift(enumfacing); -+ boolean flag = blockpos.getX() != pos2.getX() || blockpos.getZ() != pos2.getZ(); -+ -+ if (flag) { -+ l = this.getPower(l, worldIn.getType(blockpos)); -+ } -+ -+ if (worldIn.getType(blockpos).isOccluding(worldIn, blockpos) && !worldIn.getType(pos1.up()).isOccluding(worldIn, pos1)) { -+ if (flag && pos1.getY() >= pos2.getY()) { -+ l = this.getPower(l, worldIn.getType(blockpos.up())); -+ } -+ } else if (!worldIn.getType(blockpos).isOccluding(worldIn, blockpos) && flag && pos1.getY() <= pos2.getY()) { -+ l = this.getPower(l, worldIn.getType(blockpos.down())); -+ } -+ } -+ } -+ -+ if (!worldIn.paperConfig.useEigencraftRedstone) { -+ // The old code would decrement the wire value only by 1 at a time. -+ if (l > j) { -+ j = l - 1; -+ } else if (j > 0) { -+ --j; -+ } else { -+ j = 0; -+ } -+ -+ if (k > j - 1) { -+ j = k; -+ } -+ } else { -+ // The new code sets this RedstoneWire block's power level to the highest neighbor -+ // minus 1. This usually results in wire power levels dropping by 2 at a time. -+ // This optimization alone has no impact on update order, only the number of updates. -+ j = l - 1; -+ -+ // If 'l' turns out to be zero, then j will be set to -1, but then since 'k' will -+ // always be in the range of 0 to 15, the following if will correct that. -+ if (k > j) j = k; -+ } -+ -+ if (i != j) { -+ state = state.set(POWER, Integer.valueOf(j)); -+ -+ if (worldIn.getType(pos1) == iblockstate) { -+ worldIn.setTypeAndData(pos1, state, 2); -+ } -+ -+ if (!worldIn.paperConfig.useEigencraftRedstone) { -+ // The new search algorithm keeps track of blocks needing updates in its own data structures, -+ // so only add anything to blocksNeedingUpdate if we're using the vanilla update algorithm. -+ this.getBlocksNeedingUpdate().add(pos1); -+ -+ for (EnumDirection enumfacing1 : EnumDirection.values()) { -+ this.getBlocksNeedingUpdate().add(pos1.shift(enumfacing1)); -+ } -+ } -+ } -+ -+ return state; -+ } -+ // Paper end - private IBlockData a(World world, BlockPosition blockposition, IBlockData iblockdata) { - iblockdata = this.b(world, blockposition, iblockdata); - List list = Lists.newArrayList(this.i); -@@ -0,0 +0,0 @@ public class BlockRedstoneWire extends Block { - @Override - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { - if (iblockdata1.getBlock() != iblockdata.getBlock() && !world.isClientSide) { -- this.a(world, blockposition, iblockdata); -+ this.updateSurroundingRedstone(world, blockposition, iblockdata, null); // Paper - Optimize redstone - Iterator iterator = EnumDirection.EnumDirectionLimit.VERTICAL.iterator(); - - EnumDirection enumdirection; -@@ -0,0 +0,0 @@ public class BlockRedstoneWire extends Block { - world.applyPhysics(blockposition.shift(enumdirection), this); - } - -- this.a(world, blockposition, iblockdata); -+ this.updateSurroundingRedstone(world, blockposition, iblockdata, null); // Paper - Optimize redstone - Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); - - EnumDirection enumdirection1; -@@ -0,0 +0,0 @@ public class BlockRedstoneWire extends Block { - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { - if (!world.isClientSide) { - if (iblockdata.canPlace(world, blockposition)) { -- this.a(world, blockposition, iblockdata); -+ this.updateSurroundingRedstone(world, blockposition, iblockdata, blockposition1); // Paper - Optimize redstone - } else { - c(iblockdata, world, blockposition); - world.a(blockposition, false); -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - - } - -+ public void neighborChanged(BlockPosition pos, Block blockIn, BlockPosition fromPos) { a(pos, blockIn, fromPos); } // Paper - OBFHELPER - public void a(BlockPosition blockposition, Block block, BlockPosition blockposition1) { - if (!this.isClientSide) { - IBlockData iblockdata = this.getType(blockposition); -@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - return this.getBlockFacePower(blockposition.down(), EnumDirection.DOWN) > 0 ? true : (this.getBlockFacePower(blockposition.up(), EnumDirection.UP) > 0 ? true : (this.getBlockFacePower(blockposition.north(), EnumDirection.NORTH) > 0 ? true : (this.getBlockFacePower(blockposition.south(), EnumDirection.SOUTH) > 0 ? true : (this.getBlockFacePower(blockposition.west(), EnumDirection.WEST) > 0 ? true : this.getBlockFacePower(blockposition.east(), EnumDirection.EAST) > 0)))); - } - -+ public int isBlockIndirectlyGettingPowered(BlockPosition pos) { return this.q(pos); } // Paper - OBFHELPER - public int q(BlockPosition blockposition) { - int i = 0; - EnumDirection[] aenumdirection = World.a; diff --git a/Spigot-Server-Patches/Option-to-prevent-armor-stands-from-doing-entity-loo.patch b/Spigot-Server-Patches/Option-to-prevent-armor-stands-from-doing-entity-loo.patch index 582695f230..f56ab24534 100644 --- a/Spigot-Server-Patches/Option-to-prevent-armor-stands-from-doing-entity-loo.patch +++ b/Spigot-Server-Patches/Option-to-prevent-armor-stands-from-doing-entity-loo.patch @@ -23,9 +23,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + // Paper end } } - + // Paper start - Prevent armor stands from doing entity lookups + @Override + public boolean getCubes(@Nullable Entity entity, AxisAlignedBB axisAlignedBB) { @@ -33,7 +33,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return GeneratorAccess.super.getCubes(entity, axisAlignedBB); + } + // Paper end -+ - public boolean b(AxisAlignedBB axisalignedbb) { - int i = MathHelper.floor(axisalignedbb.minX); - int j = MathHelper.f(axisalignedbb.maxX); + + public Explosion explode(@Nullable Entity entity, double d0, double d1, double d2, float f, Explosion.Effect explosion_effect) { + return this.createExplosion(entity, (DamageSource) null, (ExplosionDamageCalculator) null, d0, d1, d2, f, false, explosion_effect); diff --git a/Spigot-Server-Patches/Per-Player-View-Distance-API-placeholders.patch b/Spigot-Server-Patches/Per-Player-View-Distance-API-placeholders.patch index a8a3b4bf35..c045464602 100644 --- a/Spigot-Server-Patches/Per-Player-View-Distance-API-placeholders.patch +++ b/Spigot-Server-Patches/Per-Player-View-Distance-API-placeholders.patch @@ -11,33 +11,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityEnderDragon.java +++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java @@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { + if (this.deathAnimationTicks == 1 && !this.isSilent()) { // CraftBukkit start - Use relative location for far away sounds - // this.world.b(1028, new BlockPosition(this), 0); - // Paper start -- //int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API -+ int viewDistance = this.world.getWorld().getViewDistance() * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API - for (EntityPlayer player : ((WorldServer)world).getPlayers()) { + // this.world.b(1028, this.getChunkCoordinates(), 0); +- //int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API ++ int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API + for (EntityPlayer player : (List) ((WorldServer)world).getPlayers()) { - final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch -+ //final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch - // Paper end ++ // final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch ++ // Paper end double deltaX = this.locX() - player.locX(); double deltaZ = this.locZ() - player.locZ(); + double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; diff --git a/src/main/java/net/minecraft/server/EntityWither.java b/src/main/java/net/minecraft/server/EntityWither.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityWither.java +++ b/src/main/java/net/minecraft/server/EntityWither.java @@ -0,0 +0,0 @@ public class EntityWither extends EntityMonster implements IRangedEntity { - // CraftBukkit start - Use relative location for far away sounds - // this.world.b(1023, new BlockPosition(this), 0); - // Paper start -- //int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API -+ int viewDistance = this.world.getWorld().getViewDistance() * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API - for (EntityPlayer player : ((WorldServer)world).getPlayers()) { -- final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch -+ //final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch - // Paper end - double deltaX = this.locX() - player.locX(); - double deltaZ = this.locZ() - player.locZ(); + if (!this.isSilent()) { + // CraftBukkit start - Use relative location for far away sounds + // this.world.b(1023, new BlockPosition(this), 0); +- //int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API ++ int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API + for (EntityPlayer player : (List)this.world.getPlayers()) { +- final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch ++ // final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch + double deltaX = this.locX() - player.locX(); + double deltaZ = this.locZ() - player.locZ(); + double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java diff --git a/Spigot-Server-Patches/Player.setPlayerProfile-API.patch b/Spigot-Server-Patches/Player.setPlayerProfile-API.patch index 6fff4b3cda..7162fb48fe 100644 --- a/Spigot-Server-Patches/Player.setPlayerProfile-API.patch +++ b/Spigot-Server-Patches/Player.setPlayerProfile-API.patch @@ -10,13 +10,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java @@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving { - protected int bO; - protected final float bP = 0.02F; - private int bS; -- private final GameProfile bT; -+ private GameProfile bT; public final void setProfile(final GameProfile profile) { this.bT = profile; } // Paper - OBFHELPER - private ItemStack bV; - private final ItemCooldown bW; + protected int bN; + protected final float bO = 0.02F; + private int g; +- private final GameProfile bQ; ++ private final GameProfile bQ; public final void setProfile(final GameProfile profile) { this.bQ = profile; } // Paper - OBFHELPER + private ItemStack bS; + private final ItemCooldown bT; @Nullable diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/java/net/minecraft/server/LoginListener.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/PlayerElytraBoostEvent.patch b/Spigot-Server-Patches/PlayerElytraBoostEvent.patch index a09fa45660..a0401a6ec3 100644 --- a/Spigot-Server-Patches/PlayerElytraBoostEvent.patch +++ b/Spigot-Server-Patches/PlayerElytraBoostEvent.patch @@ -28,4 +28,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end } - return InteractionResultWrapper.success(entityhuman.b(enumhand)); + return InteractionResultWrapper.a(entityhuman.b(enumhand), world.s_()); diff --git a/Spigot-Server-Patches/PlayerReadyArrowEvent.patch b/Spigot-Server-Patches/PlayerReadyArrowEvent.patch index 54a4bb478a..4ad7b23b19 100644 --- a/Spigot-Server-Patches/PlayerReadyArrowEvent.patch +++ b/Spigot-Server-Patches/PlayerReadyArrowEvent.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java @@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving { - return (EntitySize) EntityHuman.b.getOrDefault(entitypose, EntityHuman.bp); + return ImmutableList.of(EntityPose.STANDING, EntityPose.CROUCHING, EntityPose.SWIMMING); } + // Paper start diff --git a/Spigot-Server-Patches/Prevent-Enderman-from-loading-chunks.patch b/Spigot-Server-Patches/Prevent-Enderman-from-loading-chunks.patch index 701d2e459c..892390ef1e 100644 --- a/Spigot-Server-Patches/Prevent-Enderman-from-loading-chunks.patch +++ b/Spigot-Server-Patches/Prevent-Enderman-from-loading-chunks.patch @@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/j index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityEnderman.java +++ b/src/main/java/net/minecraft/server/EntityEnderman.java -@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster { +@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { int j = MathHelper.floor(this.enderman.locY() + random.nextDouble() * 3.0D); int k = MathHelper.floor(this.enderman.locZ() - 2.0D + random.nextDouble() * 4.0D); BlockPosition blockposition = new BlockPosition(i, j, k); @@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Block block = iblockdata.getBlock(); Vec3D vec3d = new Vec3D((double) MathHelper.floor(this.enderman.locX()) + 0.5D, (double) j + 0.5D, (double) MathHelper.floor(this.enderman.locZ()) + 0.5D); Vec3D vec3d1 = new Vec3D((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D); -@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster { +@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { int j = MathHelper.floor(this.a.locY() + random.nextDouble() * 2.0D); int k = MathHelper.floor(this.a.locZ() - 1.0D + random.nextDouble() * 2.0D); BlockPosition blockposition = new BlockPosition(i, j, k); diff --git a/Spigot-Server-Patches/Prevent-Mob-AI-Rules-from-Loading-Chunks.patch b/Spigot-Server-Patches/Prevent-Mob-AI-Rules-from-Loading-Chunks.patch index 61b8584225..aaff23aa35 100644 --- a/Spigot-Server-Patches/Prevent-Mob-AI-Rules-from-Loading-Chunks.patch +++ b/Spigot-Server-Patches/Prevent-Mob-AI-Rules-from-Loading-Chunks.patch @@ -26,10 +26,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable private BlockPosition a(BlockPosition blockposition, IBlockAccess iblockaccess) { -- if (iblockaccess.getType(blockposition).getBlock() == this.g) { +- if (iblockaccess.getType(blockposition).a(this.g)) { + Block block = world.getBlockIfLoaded(blockposition); // Paper + if (block == null) return null; // Paper -+ if (block == this.g) { // Paper ++ if (block.a(this.g)) { // Paper return blockposition; } else { BlockPosition[] ablockposition = new BlockPosition[]{blockposition.down(), blockposition.west(), blockposition.east(), blockposition.north(), blockposition.south(), blockposition.down().down()}; @@ -37,8 +37,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 for (int j = 0; j < i; ++j) { BlockPosition blockposition1 = ablockposition1[j]; -- if (iblockaccess.getType(blockposition1).getBlock() == this.g) { -+ if (world.getBlockIfLoaded(blockposition1) == this.g) { // Paper +- if (iblockaccess.getType(blockposition1).a(this.g)) { ++ if (iblockaccess.getBlockIfLoaded(blockposition1).a(this.g)) { // Paper return blockposition1; } } @@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - IChunkAccess ichunkaccess = iworldreader.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4, ChunkStatus.FULL, false); + IChunkAccess ichunkaccess = iworldreader.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); // Paper - return ichunkaccess == null ? false : ichunkaccess.getType(blockposition).getBlock() == this.g && ichunkaccess.getType(blockposition.up()).isAir() && ichunkaccess.getType(blockposition.up(2)).isAir(); + return ichunkaccess == null ? false : ichunkaccess.getType(blockposition).a(this.g) && ichunkaccess.getType(blockposition.up()).isAir() && ichunkaccess.getType(blockposition.up(2)).isAir(); } diff --git a/src/main/java/net/minecraft/server/RandomPositionGenerator.java b/src/main/java/net/minecraft/server/RandomPositionGenerator.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -67,9 +67,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 }); } -- if (flag || !entitycreature.world.getFluid(blockposition2).a(TagsFluid.WATER)) { +- if (flag || !entitycreature.world.getFluid(blockposition2).a((Tag) TagsFluid.WATER)) { + Fluid fluid = entitycreature.world.getFluidIfLoaded(blockposition2); // Paper -+ if (flag || (fluid != null && !fluid.a(TagsFluid.WATER))) { // Paper - PathType pathtype = PathfinderNormal.b(entitycreature.world, blockposition2.getX(), blockposition2.getY(), blockposition2.getZ()); ++ if (flag || (fluid != null && !fluid.a((Tag) TagsFluid.WATER))) { // Paper + PathType pathtype = PathfinderNormal.a((IBlockAccess) entitycreature.world, blockposition2.i()); if (entitycreature.a(pathtype) == 0.0F) { diff --git a/Spigot-Server-Patches/Prevent-Saving-Bad-entities-to-chunks.patch b/Spigot-Server-Patches/Prevent-Saving-Bad-entities-to-chunks.patch index 088874163c..748fe3a33e 100644 --- a/Spigot-Server-Patches/Prevent-Saving-Bad-entities-to-chunks.patch +++ b/Spigot-Server-Patches/Prevent-Saving-Bad-entities-to-chunks.patch @@ -83,7 +83,7 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { List[] aentityslice = chunk.getEntitySlices(); // Spigot int i = aentityslice.length; @@ -91,7 +91,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 for (int j = 0; j < i; ++j) { List entityslice = aentityslice[j]; // Spigot Iterator iterator = entityslice.iterator(); -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { throw (IllegalStateException) SystemUtils.c(new IllegalStateException("Removing entity while ticking!")); } diff --git a/Spigot-Server-Patches/Prevent-mob-spawning-from-loading-generating-chunks.patch b/Spigot-Server-Patches/Prevent-mob-spawning-from-loading-generating-chunks.patch index 7ca33a57ab..b7d1b289c4 100644 --- a/Spigot-Server-Patches/Prevent-mob-spawning-from-loading-generating-chunks.patch +++ b/Spigot-Server-Patches/Prevent-mob-spawning-from-loading-generating-chunks.patch @@ -10,23 +10,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/SpawnerCreature.java +++ b/src/main/java/net/minecraft/server/SpawnerCreature.java @@ -0,0 +0,0 @@ public final class SpawnerCreature { - int l = blockposition1.getZ(); - - if (k >= 1) { -- IBlockData iblockdata = chunk.getType(blockposition1); -+ IBlockData iblockdata = worldserver.getTypeIfLoadedAndInBounds(blockposition1); // Paper - don't load chunks for mob spawn - -- if (!iblockdata.isOccluding(chunk, blockposition1)) { -+ if (iblockdata != null && !iblockdata.isOccluding(chunk, blockposition1)) { // Paper - don't load chunks for mob spawn - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - int i1 = 0; + StructureManager structuremanager = worldserver.getStructureManager(); + ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator(); + int i = blockposition.getY(); +- IBlockData iblockdata = ichunkaccess.getType(blockposition); ++ IBlockData iblockdata = worldserver.getTypeIfLoadedAndInBounds(blockposition); // Paper - don't load chunks for mob spawn +- if (!iblockdata.isOccluding(ichunkaccess, blockposition)) { ++ if (iblockdata != null && !iblockdata.isOccluding(ichunkaccess, blockposition)) { // Paper - don't load chunks for mob spawn + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + int j = 0; + int k = 0; @@ -0,0 +0,0 @@ public final class SpawnerCreature { - if (entityhuman != null) { - double d0 = entityhuman.g((double) f, (double) k, (double) f1); + if (entityhuman != null) { + double d2 = entityhuman.g(d0, (double) i, d1); -- if (d0 > 576.0D && !blockposition.a((IPosition) (new Vec3D((double) f, (double) k, (double) f1)), 24.0D)) { -+ if (d0 > 576.0D && !blockposition.a((IPosition) (new Vec3D((double) f, (double) k, (double) f1)), 24.0D) && worldserver.isLoadedAndInBounds(blockposition_mutableblockposition)) { // Paper - don't load chunks for mob spawn - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(blockposition_mutableblockposition); - - if (Objects.equals(chunkcoordintpair, chunk.getPos()) || worldserver.getChunkProvider().a(chunkcoordintpair)) { +- if (a(worldserver, ichunkaccess, blockposition_mutableblockposition, d2)) { ++ if (a(worldserver, ichunkaccess, blockposition_mutableblockposition, d2) && worldserver.isLoadedAndInBounds(blockposition_mutableblockposition)) { // Paper - don't load chunks for mob spawn + if (biomebase_biomemeta == null) { + biomebase_biomemeta = a(worldserver, structuremanager, chunkgenerator, enumcreaturetype, worldserver.random, (BlockPosition) blockposition_mutableblockposition); + if (biomebase_biomemeta == null) { diff --git a/Spigot-Server-Patches/Print-Error-details-when-failing-to-save-player-data.patch b/Spigot-Server-Patches/Print-Error-details-when-failing-to-save-player-data.patch index b8f833177d..1196df6656 100644 --- a/Spigot-Server-Patches/Print-Error-details-when-failing-to-save-player-data.patch +++ b/Spigot-Server-Patches/Print-Error-details-when-failing-to-save-player-data.patch @@ -8,9 +8,9 @@ diff --git a/src/main/java/net/minecraft/server/WorldNBTStorage.java b/src/main/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldNBTStorage.java +++ b/src/main/java/net/minecraft/server/WorldNBTStorage.java -@@ -0,0 +0,0 @@ public class WorldNBTStorage implements IPlayerFileData { +@@ -0,0 +0,0 @@ public class WorldNBTStorage { - file.renameTo(file1); + SystemUtils.a(file1, file, file2); } catch (Exception exception) { - WorldNBTStorage.LOGGER.warn("Failed to save player data for {}", entityhuman.getDisplayName().getString()); + WorldNBTStorage.LOGGER.error("Failed to save player data for {}", entityhuman.getName(), exception); // Paper diff --git a/Spigot-Server-Patches/Re-add-vanilla-entity-warnings-for-duplicates.patch b/Spigot-Server-Patches/Re-add-vanilla-entity-warnings-for-duplicates.patch index 5dd0611fa5..59b21a72d2 100644 --- a/Spigot-Server-Patches/Re-add-vanilla-entity-warnings-for-duplicates.patch +++ b/Spigot-Server-Patches/Re-add-vanilla-entity-warnings-for-duplicates.patch @@ -11,7 +11,7 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { if (entity1 == null) { return false; } else { diff --git a/Spigot-Server-Patches/Reset-players-airTicks-on-respawn.patch b/Spigot-Server-Patches/Reset-players-airTicks-on-respawn.patch index 6a4caacbda..d9eb6c5f49 100644 --- a/Spigot-Server-Patches/Reset-players-airTicks-on-respawn.patch +++ b/Spigot-Server-Patches/Reset-players-airTicks-on-respawn.patch @@ -12,8 +12,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } -+ public int getMaxAirTicks() { return bw(); } // Paper - OBFHELPER - public int bw() { ++ public int getMaxAirTicks() { return bD(); } // Paper - OBFHELPER + public int bD() { return 300; } diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java diff --git a/Spigot-Server-Patches/Send-nearby-packets-from-world-player-list-not-serve.patch b/Spigot-Server-Patches/Send-nearby-packets-from-world-player-list-not-serve.patch deleted file mode 100644 index 16b9bc13ae..0000000000 --- a/Spigot-Server-Patches/Send-nearby-packets-from-world-player-list-not-serve.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mystiflow -Date: Fri, 6 Jul 2018 13:21:30 +0100 -Subject: [PATCH] Send nearby packets from world player list not server list - - -diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/PlayerList.java -+++ b/src/main/java/net/minecraft/server/PlayerList.java -@@ -0,0 +0,0 @@ public abstract class PlayerList { - } - - public void sendPacketNearby(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, double d3, DimensionManager dimensionmanager, Packet packet) { -- for (int i = 0; i < this.players.size(); ++i) { -- EntityPlayer entityplayer = (EntityPlayer) this.players.get(i); -+ // Paper start - Use world list instead of server list where preferable -+ sendPacketNearby(entityhuman, d0, d1, d2, d3, dimensionmanager, null, packet); // Retained for compatibility -+ } -+ -+ public void sendPacketNearby(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, double d3, WorldServer world, Packet packet) { -+ sendPacketNearby(entityhuman, d0, d1, d2, d3, world.worldProvider.getDimensionManager(), world, packet); -+ } -+ -+ public void sendPacketNearby(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, double d3, DimensionManager dimensionmanager, @Nullable WorldServer world, Packet packet) { -+ if (world == null && entityhuman != null && entityhuman.world instanceof WorldServer) { -+ world = (WorldServer) entityhuman.world; -+ } -+ -+ List players1 = world == null ? players : world.players; -+ for (int j = 0; j < players1.size(); ++j) { -+ EntityHuman entity = players1.get(j); -+ if (!(entity instanceof EntityPlayer)) continue; -+ EntityPlayer entityplayer = (EntityPlayer) entity; -+ // Paper end - - // CraftBukkit start - Test if player receiving packet can see the source of the packet - if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { -@@ -0,0 +0,0 @@ public abstract class PlayerList { - } - // CraftBukkit end - -- if (entityplayer != entityhuman && entityplayer.dimension == dimensionmanager) { -+ if (entityplayer != entityhuman && (world != null || entityplayer.dimension == dimensionmanager)) { // Paper - double d4 = d0 - entityplayer.locX(); - double d5 = d1 - entityplayer.locY(); - double d6 = d2 - entityplayer.locZ(); -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { - } - // CraftBukkit end - this.globalEntityList.add(entitylightning); -- this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entitylightning.locX(), entitylightning.locY(), entitylightning.locZ(), 512.0D, this.worldProvider.getDimensionManager(), new PacketPlayOutSpawnEntityWeather(entitylightning)); -+ this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entitylightning.locX(), entitylightning.locY(), entitylightning.locZ(), 512.0D, this, new PacketPlayOutSpawnEntityWeather(entitylightning)); // Paper - use world instead of dimension - } - - @Override -@@ -0,0 +0,0 @@ public class WorldServer extends World { - BlockActionData blockactiondata = (BlockActionData) this.I.removeFirst(); - - if (this.a(blockactiondata)) { -- this.server.getPlayerList().sendPacketNearby((EntityHuman) null, (double) blockactiondata.a().getX(), (double) blockactiondata.a().getY(), (double) blockactiondata.a().getZ(), 64.0D, this.worldProvider.getDimensionManager(), new PacketPlayOutBlockAction(blockactiondata.a(), blockactiondata.b(), blockactiondata.c(), blockactiondata.d())); -+ this.server.getPlayerList().sendPacketNearby((EntityHuman) null, (double) blockactiondata.a().getX(), (double) blockactiondata.a().getY(), (double) blockactiondata.a().getZ(), 64.0D, this, new PacketPlayOutBlockAction(blockactiondata.a(), blockactiondata.b(), blockactiondata.c(), blockactiondata.d())); - } - } - -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -0,0 +0,0 @@ public class CraftWorld implements World { - double z = loc.getZ(); - - PacketPlayOutCustomSoundEffect packet = new PacketPlayOutCustomSoundEffect(new MinecraftKey(sound), SoundCategory.valueOf(category.name()), new Vec3D(x, y, z), volume, pitch); -- world.getMinecraftServer().getPlayerList().sendPacketNearby(null, x, y, z, volume > 1.0F ? 16.0F * volume : 16.0D, this.world.getWorldProvider().getDimensionManager(), packet); -+ world.getMinecraftServer().getPlayerList().sendPacketNearby(null, x, y, z, volume > 1.0F ? 16.0F * volume : 16.0D, this.world, packet); // Paper - this.world.dimension -> this.world - } - - private static Map> gamerules; diff --git a/Spigot-Server-Patches/Server-Tick-Events.patch b/Spigot-Server-Patches/Server-Tick-Events.patch index 765ea183b6..52c96c6ddd 100644 --- a/Spigot-Server-Patches/Server-Tick-Events.patch +++ b/Spigot-Server-Patches/Server-Tick-Events.patch @@ -28,5 +28,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end + this.methodProfiler.enter("tallying"); - long l = this.f[this.ticks % 100] = SystemUtils.getMonotonicNanos() - i; + long l = this.h[this.ticks % 100] = SystemUtils.getMonotonicNanos() - i; diff --git a/Spigot-Server-Patches/Set-Zombie-last-tick-at-start-of-drowning-process.patch b/Spigot-Server-Patches/Set-Zombie-last-tick-at-start-of-drowning-process.patch index 99202529ec..930dd28dc3 100644 --- a/Spigot-Server-Patches/Set-Zombie-last-tick-at-start-of-drowning-process.patch +++ b/Spigot-Server-Patches/Set-Zombie-last-tick-at-start-of-drowning-process.patch @@ -10,10 +10,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityZombie.java +++ b/src/main/java/net/minecraft/server/EntityZombie.java @@ -0,0 +0,0 @@ public class EntityZombie extends EntityMonster { - ++this.bC; - if (this.bC >= 600) { + ++this.bA; + if (this.bA >= 600) { this.startDrownedConversion(300); + this.lastTick = MinecraftServer.currentTick; // Paper - Make sure this is set at start of process - GH-1887 } } else { - this.bC = -1; + this.bA = -1; diff --git a/Spigot-Server-Patches/SkeletonHorse-Additions.patch b/Spigot-Server-Patches/SkeletonHorse-Additions.patch index 18f470be5e..e24df8ae7e 100644 --- a/Spigot-Server-Patches/SkeletonHorse-Additions.patch +++ b/Spigot-Server-Patches/SkeletonHorse-Additions.patch @@ -10,10 +10,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/EntityHorseSkeleton.java @@ -0,0 +0,0 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { - private final PathfinderGoalHorseTrap bF = new PathfinderGoalHorseTrap(this); - private boolean bG; -- private int bH; -+ private int bH; public int getTrapTime() { return this.bH; } // Paper - OBFHELPER + private final PathfinderGoalHorseTrap bD = new PathfinderGoalHorseTrap(this); + private boolean bE; +- private int bF; ++ private int bF; public int getTrapTime() { return this.bF; } // Paper - OBFHELPER public EntityHorseSkeleton(EntityTypes entitytypes, World world) { super(entitytypes, world); @@ -21,15 +21,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return 0.96F; } -+ public boolean isTrap() { return this.eq(); } // Paper - OBFHELPER - public boolean eq() { - return this.bG; ++ public boolean isTrap() { return this.eN(); } // Paper - OBFHELPER + public boolean eN() { + return this.bE; } -+ public void setTrap(boolean trap) { this.r(trap); } // Paper - OBFHELPER - public void r(boolean flag) { - if (flag != this.bG) { - this.bG = flag; ++ public void setTrap(boolean trap) { this.t(trap); } // Paper - OBFHELPER + public void t(boolean flag) { + if (flag != this.bE) { + this.bE = flag; diff --git a/src/main/java/net/minecraft/server/PathfinderGoalHorseTrap.java b/src/main/java/net/minecraft/server/PathfinderGoalHorseTrap.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalHorseTrap.java @@ -39,9 +39,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void e() { + if (!new com.destroystokyo.paper.event.entity.SkeletonHorseTrapEvent((org.bukkit.entity.SkeletonHorse) this.a.getBukkitEntity()).callEvent()) return; // Paper - DifficultyDamageScaler difficultydamagescaler = this.a.world.getDamageScaler(new BlockPosition(this.a)); + DifficultyDamageScaler difficultydamagescaler = this.a.world.getDamageScaler(this.a.getChunkCoordinates()); - this.a.r(false); + this.a.t(false); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java diff --git a/Spigot-Server-Patches/Slime-Pathfinder-Events.patch b/Spigot-Server-Patches/Slime-Pathfinder-Events.patch index 36f83110d1..56902859c0 100644 --- a/Spigot-Server-Patches/Slime-Pathfinder-Events.patch +++ b/Spigot-Server-Patches/Slime-Pathfinder-Events.patch @@ -24,17 +24,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import java.util.ArrayList; import java.util.List; @@ -0,0 +0,0 @@ public class EntitySlime extends EntityInsentient implements IMonster { - super.b(nbttagcompound); + super.saveData(nbttagcompound); nbttagcompound.setInt("Size", this.getSize() - 1); - nbttagcompound.setBoolean("wasOnGround", this.bx); + nbttagcompound.setBoolean("wasOnGround", this.bw); + nbttagcompound.setBoolean("Paper.canWander", this.canWander); // Paper } @Override @@ -0,0 +0,0 @@ public class EntitySlime extends EntityInsentient implements IMonster { this.setSize(i + 1, false); - super.a(nbttagcompound); - this.bx = nbttagcompound.getBoolean("wasOnGround"); + super.loadData(nbttagcompound); + this.bw = nbttagcompound.getBoolean("wasOnGround"); + // Paper start - check exists before loading or this will be loaded as false + if (nbttagcompound.hasKey("Paper.canWander")) { + this.canWander = nbttagcompound.getBoolean("Paper.canWander"); @@ -42,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end } - public boolean ev() { + public boolean eR() { @@ -0,0 +0,0 @@ public class EntitySlime extends EntityInsentient implements IMonster { @Override @@ -56,8 +56,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public boolean a() { -- return (this.a.isInWater() || this.a.aH()) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime; -+ return (this.a.isInWater() || this.a.aH()) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime && this.a.canWander && new SlimeSwimEvent((Slime) this.a.getBukkitEntity()).callEvent(); // Paper +- return (this.a.isInWater() || this.a.aN()) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime; ++ return (this.a.isInWater() || this.a.aN()) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime && this.a.canWander && new SlimeSwimEvent((Slime) this.a.getBukkitEntity()).callEvent(); // Paper } @Override @@ -65,8 +65,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public boolean a() { -- return this.a.getGoalTarget() == null && (this.a.onGround || this.a.isInWater() || this.a.aH() || this.a.hasEffect(MobEffects.LEVITATION)) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime; -+ return this.a.canWander && this.a.getGoalTarget() == null && (this.a.onGround || this.a.isInWater() || this.a.aH() || this.a.hasEffect(MobEffects.LEVITATION)) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime; +- return this.a.getGoalTarget() == null && (this.a.onGround || this.a.isInWater() || this.a.aN() || this.a.hasEffect(MobEffects.LEVITATION)) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime; ++ return this.a.canWander && this.a.getGoalTarget() == null && (this.a.onGround || this.a.isInWater() || this.a.aN() || this.a.hasEffect(MobEffects.LEVITATION)) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime; } @Override @@ -118,7 +118,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override @@ -0,0 +0,0 @@ public class EntitySlime extends EntityInsentient implements IMonster { this.a.a((Entity) this.a.getGoalTarget(), 10.0F, 10.0F); - ((EntitySlime.ControllerMoveSlime) this.a.getControllerMove()).a(this.a.yaw, this.a.eq()); + ((EntitySlime.ControllerMoveSlime) this.a.getControllerMove()).a(this.a.yaw, this.a.eM()); } + + // Paper start - clear timer and target when goal resets diff --git a/Spigot-Server-Patches/Support-Overriding-World-Seeds.patch b/Spigot-Server-Patches/Support-Overriding-World-Seeds.patch deleted file mode 100644 index ba3d04c74f..0000000000 --- a/Spigot-Server-Patches/Support-Overriding-World-Seeds.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Mon, 17 Sep 2018 23:05:31 -0400 -Subject: [PATCH] Support Overriding World Seeds - -Allows you to add to paper.yml - -seed-overrides: - world_name: some seed value - -This will ignore every where a seed is set/created/loaded and force -a world to use the specified seed. - -This seed will end up being saved to the world data file, so it is -a permanent change in that it won't go back if you remove it from paper.yml - -diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperConfig.java -+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java -@@ -0,0 +0,0 @@ import java.lang.reflect.Modifier; - import java.util.HashMap; - import java.util.List; - import java.util.Map; -+import java.util.Set; - import java.util.concurrent.TimeUnit; - import java.util.logging.Level; - import java.util.regex.Pattern; -@@ -0,0 +0,0 @@ import com.google.common.collect.Lists; - import net.minecraft.server.MinecraftServer; - import org.bukkit.Bukkit; - import org.bukkit.command.Command; -+import org.bukkit.configuration.ConfigurationSection; - import org.bukkit.configuration.InvalidConfigurationException; - import org.bukkit.configuration.file.YamlConfiguration; - import co.aikar.timings.Timings; -@@ -0,0 +0,0 @@ public class PaperConfig { - } - tabSpamLimit = getInt("settings.spam-limiter.tab-spam-limit", tabSpamLimit); - } -+ -+ public static Map seedOverride = new java.util.HashMap<>(); -+ private static void worldSeedOverrides() { -+ ConfigurationSection seeds = config.getConfigurationSection("seed-overrides"); -+ if (seeds != null) { -+ TimingsManager.hiddenConfigs.add("seed-overrides"); -+ for (String key : seeds.getKeys(false)) { -+ String seedString = seeds.getString(key); -+ long seed; -+ try { -+ seed = Long.parseLong(seedString); -+ } catch (Exception e) { -+ seed = (long) seedString.hashCode(); -+ } -+ log("Seed Override: " + key + " => " + seed); -+ seedOverride.put(key, seed); -+ } -+ } -+ } - } -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant 200) { + } else if (this.g.bC > 200) { World world = this.g.world; // CraftBukkit start @@ -92,13 +76,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + world.setTypeAndData(this.e.up(), (IBlockData) Blocks.TURTLE_EGG.getBlockData().set(BlockTurtleEgg.b, layEggEvent.getEggCount()), 3); } // CraftBukkit end - this.g.r(false); + this.g.setHasEgg(false); @@ -0,0 +0,0 @@ public class EntityTurtle extends EntityAnimal { @Override public boolean a() { -- return this.a.isBaby() ? false : (this.a.eq() ? true : (this.a.getRandom().nextInt(700) != 0 ? false : !this.a.es().a((IPosition) this.a.getPositionVector(), 64.0D))); -+ return this.a.isBaby() ? false : (this.a.eq() ? true : (this.a.getRandom().nextInt(700) != 0 ? false : !this.a.es().a((IPosition) this.a.getPositionVector(), 64.0D))) && new com.destroystokyo.paper.event.entity.TurtleGoHomeEvent((org.bukkit.entity.Turtle) this.a.getBukkitEntity()).callEvent(); // Paper +- return this.a.isBaby() ? false : (this.a.hasEgg() ? true : (this.a.getRandom().nextInt(700) != 0 ? false : !this.a.getHomePos().a((IPosition) this.a.getPositionVector(), 64.0D))); ++ return this.a.isBaby() ? false : (this.a.hasEgg() ? true : (this.a.getRandom().nextInt(700) != 0 ? false : !this.a.getHomePos().a((IPosition) this.a.getPositionVector(), 64.0D))) && new com.destroystokyo.paper.event.entity.TurtleGoHomeEvent((org.bukkit.entity.Turtle) this.a.getBukkitEntity()).callEvent(); // Paper } @Override diff --git a/Spigot-Server-Patches/Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch b/Spigot-Server-Patches/Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch index f4e8d621b2..a7b9a6486f 100644 --- a/Spigot-Server-Patches/Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch +++ b/Spigot-Server-Patches/Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch @@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private static final DataWatcherObject POWERED = DataWatcher.a(EntityCreeper.class, DataWatcherRegistry.i); - private static final DataWatcherObject d = DataWatcher.a(EntityCreeper.class, DataWatcherRegistry.i); + private static final DataWatcherObject d = DataWatcher.a(EntityCreeper.class, DataWatcherRegistry.i); private static final DataWatcherObject isIgnitedDW = d; // Paper OBFHELPER - private int bw; + private int bv; private int fuseTicks; public int maxFuseTicks = 30; @@ -0,0 +0,0 @@ public class EntityCreeper extends EntityMonster { diff --git a/Spigot-Server-Patches/Use-ConcurrentHashMap-in-JsonList.patch b/Spigot-Server-Patches/Use-ConcurrentHashMap-in-JsonList.patch index bb1f035072..7fbff83acb 100644 --- a/Spigot-Server-Patches/Use-ConcurrentHashMap-in-JsonList.patch +++ b/Spigot-Server-Patches/Use-ConcurrentHashMap-in-JsonList.patch @@ -28,24 +28,47 @@ diff --git a/src/main/java/net/minecraft/server/JsonList.java b/src/main/java/ne index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/JsonList.java +++ b/src/main/java/net/minecraft/server/JsonList.java -@@ -0,0 +0,0 @@ public class JsonList> { +@@ -0,0 +0,0 @@ import java.io.BufferedReader; + import java.io.BufferedWriter; + import java.io.File; + import java.io.IOException; ++import java.lang.reflect.ParameterizedType; // Paper ++import java.lang.reflect.Type; // Paper + import java.nio.charset.StandardCharsets; + import java.util.Collection; + import java.util.Iterator; +@@ -0,0 +0,0 @@ public abstract class JsonList> { protected static final Logger LOGGER = LogManager.getLogger(); - protected final Gson b; + private static final Gson b = (new GsonBuilder()).setPrettyPrinting().create(); private final File c; - private final Map d = Maps.newHashMap(); + // Paper - replace HashMap is ConcurrentHashMap + private final Map d = Maps.newConcurrentMap(); private final Map getBackingMap() { return this.d; } // Paper - OBFHELPER - private boolean e = true; - private static final ParameterizedType f = new ParameterizedType() { - public Type[] getActualTypeArguments() { -@@ -0,0 +0,0 @@ public class JsonList> { ++ private boolean e = true; ++ private static final ParameterizedType f = new ParameterizedType() { ++ public Type[] getActualTypeArguments() { ++ return new Type[]{JsonListEntry.class}; ++ } ++ ++ public Type getRawType() { ++ return List.class; ++ } ++ ++ public Type getOwnerType() { ++ return null; ++ } ++ }; + + public JsonList(File file) { + this.c = file; +@@ -0,0 +0,0 @@ public abstract class JsonList> { @Nullable public V get(K k0) { -- this.h(); +- this.g(); - return (V) this.d.get(this.a(k0)); // CraftBukkit - fix decompile error + // Paper start -+ // this.h(); ++ // this.g(); + // return (V) this.d.get(this.a(k0)); // CraftBukkit - fix decompile error + return (V) this.getBackingMap().computeIfPresent(this.getMappingKey(k0), (k, v) -> { + return v.hasExpired() ? null : v; @@ -54,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public void remove(K k0) { -@@ -0,0 +0,0 @@ public class JsonList> { +@@ -0,0 +0,0 @@ public abstract class JsonList> { // CraftBukkit end public boolean isEmpty() { @@ -67,18 +90,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected String a(K k0) { return k0.toString(); } -@@ -0,0 +0,0 @@ public class JsonList> { +@@ -0,0 +0,0 @@ public abstract class JsonList> { return this.d.containsKey(this.a(k0)); } -+ private void removeStaleEntries() { h(); } // Paper - OBFHELPER - private void h() { ++ private void removeStaleEntries() { g(); } // Paper - OBFHELPER + private void g() { - List list = Lists.newArrayList(); + /*List list = Lists.newArrayList(); Iterator iterator = this.d.values().iterator(); while (iterator.hasNext()) { -@@ -0,0 +0,0 @@ public class JsonList> { +@@ -0,0 +0,0 @@ public abstract class JsonList> { K k0 = (K) iterator.next(); // CraftBukkit - decompile error this.d.remove(this.a(k0)); @@ -89,22 +112,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end } - protected JsonListEntry a(JsonObject jsonobject) { -@@ -0,0 +0,0 @@ public class JsonList> { + protected abstract JsonListEntry a(JsonObject jsonobject); +@@ -0,0 +0,0 @@ public abstract class JsonList> { } public void save() throws IOException { + this.removeStaleEntries(); // Paper - remove expired values before saving - Collection collection = this.d.values(); - String s = this.b.toJson(collection); - BufferedWriter bufferedwriter = null; + JsonArray jsonarray = new JsonArray(); + + this.d.values().stream().map((jsonlistentry) -> { diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -0,0 +0,0 @@ public abstract class PlayerList { - } else if (!this.isWhitelisted(gameprofile, event)) { // Paper - chatmessage = new ChatMessage("multiplayer.disconnect.not_whitelisted", new Object[0]); + } else if (!this.isWhitelisted(gameprofile)) { + chatmessage = new ChatMessage("multiplayer.disconnect.not_whitelisted"); //event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot // Paper - moved to isWhitelisted - } else if (getIPBans().isBanned(socketaddress) && !getIPBans().get(socketaddress).hasExpired()) { + } else if (getIPBans().isBanned(socketaddress) && getIPBans().get(socketaddress) != null && !getIPBans().get(socketaddress).hasExpired()) { // Paper - fix NPE with temp ip bans diff --git a/Spigot-Server-Patches/Use-TerminalConsoleAppender-for-console-improvements.patch b/Spigot-Server-Patches/Use-TerminalConsoleAppender-for-console-improvements.patch index 92c15e858e..3b26010d1e 100644 --- a/Spigot-Server-Patches/Use-TerminalConsoleAppender-for-console-improvements.patch +++ b/Spigot-Server-Patches/Use-TerminalConsoleAppender-for-console-improvements.patch @@ -189,12 +189,12 @@ diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -0,0 +0,0 @@ import org.apache.commons.lang3.Validate; - import org.apache.logging.log4j.LogManager; +@@ -0,0 +0,0 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; // CraftBukkit start + import com.google.common.collect.ImmutableSet; -import jline.console.ConsoleReader; -+// Paper ++// import jline.console.ConsoleReader; // Paper import joptsimple.OptionSet; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.CraftServer; diff --git a/Spigot-Server-Patches/Use-a-Queue-for-Queueing-Commands.patch b/Spigot-Server-Patches/Use-a-Queue-for-Queueing-Commands.patch index 92721c1e66..b9c66d5f56 100644 --- a/Spigot-Server-Patches/Use-a-Queue-for-Queueing-Commands.patch +++ b/Spigot-Server-Patches/Use-a-Queue-for-Queueing-Commands.patch @@ -12,9 +12,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer private static final Logger LOGGER = LogManager.getLogger(); - private static final Pattern i = Pattern.compile("^[a-fA-F0-9]{40}$"); + private static final Pattern k = Pattern.compile("^[a-fA-F0-9]{40}$"); - private final List serverCommandQueue = Collections.synchronizedList(Lists.newArrayList()); -+ private final java.util.Queue serverCommandQueue = new java.util.concurrent.ConcurrentLinkedQueue(); // Paper - use a proper queue ++ private final java.util.Queue serverCommandQueue = new java.util.concurrent.ConcurrentLinkedQueue<>(); // Paper - use a proper queue private RemoteStatusListener remoteStatusListener; public final RemoteControlCommandListener remoteControlCommandListener; private RemoteControlListener remoteControlListener; diff --git a/Spigot-Server-Patches/Use-proper-max-length-when-serialising-BungeeCord-te.patch b/Spigot-Server-Patches/Use-proper-max-length-when-serialising-BungeeCord-te.patch index 77ccab1823..a65ad8efad 100644 --- a/Spigot-Server-Patches/Use-proper-max-length-when-serialising-BungeeCord-te.patch +++ b/Spigot-Server-Patches/Use-proper-max-length-when-serialising-BungeeCord-te.patch @@ -9,8 +9,8 @@ diff --git a/src/main/java/net/minecraft/server/PacketPlayOutChat.java b/src/mai index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutChat.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutChat.java -@@ -0,0 +0,0 @@ package net.minecraft.server; - import java.io.IOException; +@@ -0,0 +0,0 @@ import java.io.IOException; + import java.util.UUID; public class PacketPlayOutChat implements Packet { - diff --git a/Spigot-Server-Patches/Vanished-players-don-t-have-rights.patch b/Spigot-Server-Patches/Vanished-players-don-t-have-rights.patch index ef465d316b..cee8d24803 100644 --- a/Spigot-Server-Patches/Vanished-players-don-t-have-rights.patch +++ b/Spigot-Server-Patches/Vanished-players-don-t-have-rights.patch @@ -4,6 +4,18 @@ Date: Mon, 23 Jul 2018 14:22:26 +0200 Subject: [PATCH] Vanished players don't have rights +diff --git a/src/main/java/net/minecraft/server/BlockBase.java b/src/main/java/net/minecraft/server/BlockBase.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/BlockBase.java ++++ b/src/main/java/net/minecraft/server/BlockBase.java +@@ -0,0 +0,0 @@ public abstract class BlockBase { + return this.a != null ? this.a.b : this.b(iblockaccess, blockposition, VoxelShapeCollision.a()); + } + ++ public final VoxelShape getCollisionShape(IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return this.b(iblockaccess, blockposition, voxelshapecollision); } // Paper - OBFHELPER + public VoxelShape b(IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return this.getBlock().c(this.p(), iblockaccess, blockposition, voxelshapecollision); + } diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/Entity.java @@ -21,35 +33,34 @@ diff --git a/src/main/java/net/minecraft/server/EntityFireworks.java b/src/main/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityFireworks.java +++ b/src/main/java/net/minecraft/server/EntityFireworks.java -@@ -0,0 +0,0 @@ public class EntityFireworks extends Entity implements IProjectile { +@@ -0,0 +0,0 @@ public class EntityFireworks extends IProjectile { + this.move(EnumMoveType.SELF, vec3d); + this.setMot(vec3d); + } +- + MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, this::a, RayTrace.BlockCollisionOption.COLLIDER); - vec3d = this.getMot(); - MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, this.getBoundingBox().a(vec3d).g(1.0D), (entity) -> { -+ // Paper start - Cancel hit for vanished players -+ if (this.spawningEntity != null && entity instanceof EntityPlayer && this.world instanceof WorldServer) { -+ Entity spawningEntity = ((WorldServer) this.world).getEntity(this.spawningEntity); -+ if (spawningEntity instanceof EntityPlayer) { -+ org.bukkit.entity.Player collided = (org.bukkit.entity.Player) entity.getBukkitEntity(); -+ org.bukkit.entity.Player shooter = (org.bukkit.entity.Player) spawningEntity.getBukkitEntity(); -+ if (!shooter.canSee(collided)) return false; -+ } -+ } -+ // Paper end - return !entity.isSpectator() && entity.isAlive() && entity.isInteractable(); - }, RayTrace.BlockCollisionOption.COLLIDER, true); - -diff --git a/src/main/java/net/minecraft/server/IBlockData.java b/src/main/java/net/minecraft/server/IBlockData.java + if (!this.noclip) { +diff --git a/src/main/java/net/minecraft/server/IProjectile.java b/src/main/java/net/minecraft/server/IProjectile.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/IBlockData.java -+++ b/src/main/java/net/minecraft/server/IBlockData.java -@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements - return this.c != null ? this.c.g : this.b(iblockaccess, blockposition, VoxelShapeCollision.a()); - } - -+ public final VoxelShape getCollisionShape(IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return this.b(iblockaccess, blockposition, voxelshapecollision); } // Paper - OBFHELPER - public VoxelShape b(IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { - return this.getBlock().b(this, iblockaccess, blockposition, voxelshapecollision); - } +--- a/src/main/java/net/minecraft/server/IProjectile.java ++++ b/src/main/java/net/minecraft/server/IProjectile.java +@@ -0,0 +0,0 @@ public abstract class IProjectile extends Entity { + protected boolean a(Entity entity) { + if (!entity.isSpectator() && entity.isAlive() && entity.isInteractable()) { + Entity entity1 = this.getShooter(); +- ++ // Paper start - Cancel hit for vanished players ++ if (entity1 instanceof EntityPlayer) { ++ org.bukkit.entity.Player collided = (org.bukkit.entity.Player) entity.getBukkitEntity(); ++ org.bukkit.entity.Player shooter = (org.bukkit.entity.Player) entity1.getBukkitEntity(); ++ if (!shooter.canSee(collided)) return false; ++ } + return entity1 == null || this.d || !entity1.isSameVehicle(entity); ++ // Paper end + } else { + return false; + } diff --git a/src/main/java/net/minecraft/server/ItemBlock.java b/src/main/java/net/minecraft/server/ItemBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ItemBlock.java @@ -58,9 +69,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 EntityHuman entityhuman = blockactioncontext.getEntity(); VoxelShapeCollision voxelshapecollision = entityhuman == null ? VoxelShapeCollision.a() : VoxelShapeCollision.a((Entity) entityhuman); // CraftBukkit start - store default return -- boolean defaultReturn = (!this.T_() || iblockdata.canPlace(blockactioncontext.getWorld(), blockactioncontext.getClickPosition())) && blockactioncontext.getWorld().a(iblockdata, blockactioncontext.getClickPosition(), voxelshapecollision); +- boolean defaultReturn = (!this.isCheckCollisions() || iblockdata.canPlace(blockactioncontext.getWorld(), blockactioncontext.getClickPosition())) && blockactioncontext.getWorld().a(iblockdata, blockactioncontext.getClickPosition(), voxelshapecollision); + World world = blockactioncontext.getWorld(); // Paper -+ boolean defaultReturn = (!this.T_() || iblockdata.canPlace(blockactioncontext.getWorld(), blockactioncontext.getClickPosition())) && world.checkEntityCollision(iblockdata, entityhuman, voxelshapecollision, blockactioncontext.getClickPosition(), true); // Paper ++ boolean defaultReturn = (!this.isCheckCollisions() || iblockdata.canPlace(blockactioncontext.getWorld(), blockactioncontext.getClickPosition())) && world.checkEntityCollision(iblockdata, entityhuman, voxelshapecollision, blockactioncontext.getClickPosition(), true); // Paper org.bukkit.entity.Player player = (blockactioncontext.getEntity() instanceof EntityPlayer) ? (org.bukkit.entity.Player) blockactioncontext.getEntity().getBukkitEntity() : null; BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(blockactioncontext.getWorld(), blockactioncontext.getClickPosition()), player, CraftBlockData.fromData(iblockdata), defaultReturn); @@ -145,7 +156,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end + @Override - public boolean p_() { + public boolean s_() { return this.isClientSide; diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/Vex-getSummoner-API.patch b/Spigot-Server-Patches/Vex-getSummoner-API.patch index c1fe7423d7..aafee41f81 100644 --- a/Spigot-Server-Patches/Vex-getSummoner-API.patch +++ b/Spigot-Server-Patches/Vex-getSummoner-API.patch @@ -13,8 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } -+ public EntityInsentient getOwner() { return l(); } // Paper - OBFHELPER - public EntityInsentient l() { ++ public EntityInsentient getOwner() { return eL(); } // Paper - OBFHELPER + public EntityInsentient eL() { return this.c; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java diff --git a/Spigot-Server-Patches/WitchConsumePotionEvent.patch b/Spigot-Server-Patches/WitchConsumePotionEvent.patch index 31d7703abd..6ab972a40f 100644 --- a/Spigot-Server-Patches/WitchConsumePotionEvent.patch +++ b/Spigot-Server-Patches/WitchConsumePotionEvent.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/EntityWitch.java @@ -0,0 +0,0 @@ public class EntityWitch extends EntityRaider implements IRangedEntity { - this.setSlot(EnumItemSlot.MAINHAND, ItemStack.a); + this.setSlot(EnumItemSlot.MAINHAND, ItemStack.b); if (itemstack.getItem() == Items.POTION) { - List list = PotionUtil.getEffects(itemstack); + // Paper start diff --git a/Spigot-Server-Patches/WitchReadyPotionEvent.patch b/Spigot-Server-Patches/WitchReadyPotionEvent.patch index 121d41a635..00410edec8 100644 --- a/Spigot-Server-Patches/WitchReadyPotionEvent.patch +++ b/Spigot-Server-Patches/WitchReadyPotionEvent.patch @@ -18,6 +18,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + org.bukkit.inventory.ItemStack bukkitStack = com.destroystokyo.paper.event.entity.WitchReadyPotionEvent.process((org.bukkit.entity.Witch) this.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(potion)); + this.setSlot(EnumItemSlot.MAINHAND, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(bukkitStack)); + // Paper end - this.by = this.getItemInMainHand().k(); - this.t(true); - this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_WITCH_DRINK, this.getSoundCategory(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F); + this.bx = this.getItemInMainHand().k(); + this.v(true); + if (!this.isSilent()) { diff --git a/Spigot-Server-Patches/WitchThrowPotionEvent.patch b/Spigot-Server-Patches/WitchThrowPotionEvent.patch index 8b1d9b9d59..10e52e8e91 100644 --- a/Spigot-Server-Patches/WitchThrowPotionEvent.patch +++ b/Spigot-Server-Patches/WitchThrowPotionEvent.patch @@ -27,4 +27,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end entitypotion.pitch -= -20.0F; entitypotion.shoot(d0, d1 + (double) (f1 * 0.2F), d2, 0.75F, 8.0F); - this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_WITCH_THROW, this.getSoundCategory(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F); + if (!this.isSilent()) { diff --git a/Spigot-Server-Patches/Workaround-for-vehicle-tracking-issue-on-disconnect.patch b/Spigot-Server-Patches/Workaround-for-vehicle-tracking-issue-on-disconnect.patch index fd2c661a39..ce224f2784 100644 --- a/Spigot-Server-Patches/Workaround-for-vehicle-tracking-issue-on-disconnect.patch +++ b/Spigot-Server-Patches/Workaround-for-vehicle-tracking-issue-on-disconnect.patch @@ -9,8 +9,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - public void n() { - this.cq = true; + public void p() { + this.co = true; this.ejectPassengers(); + + // Paper start - Workaround an issue where the vehicle doesn't track the passenger disconnection dismount. diff --git a/Spigot-Server-Patches/add-more-information-to-Entity.toString.patch b/Spigot-Server-Patches/add-more-information-to-Entity.toString.patch index 5db4a75691..705436afb6 100644 --- a/Spigot-Server-Patches/add-more-information-to-Entity.toString.patch +++ b/Spigot-Server-Patches/add-more-information-to-Entity.toString.patch @@ -13,8 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public String toString() { -- return String.format(Locale.ROOT, "%s['%s'/%d, l='%s', x=%.2f, y=%.2f, z=%.2f]", this.getClass().getSimpleName(), this.getDisplayName().getText(), this.id, this.world == null ? "~NULL~" : this.world.getWorldData().getName(), this.locX(), this.locY(), this.locZ()); -+ return String.format(Locale.ROOT, "%s[\'%s\'/%d, uuid=\'%s\', l=\'%s\', x=%.2f, y=%.2f, z=%.2f, cx=%d, cz=%d, tl=%d, v=%b, d=%b]", new Object[] { this.getClass().getSimpleName(), this.getDisplayName().getText(), Integer.valueOf(this.id), this.uniqueID.toString(), this.world == null ? "~NULL~" : this.world.getWorldData().getName(), Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ), getChunkX(), getChunkZ(), this.ticksLived, this.valid, this.dead}); // Paper - add more information +- return String.format(Locale.ROOT, "%s['%s'/%d, l='%s', x=%.2f, y=%.2f, z=%.2f]", this.getClass().getSimpleName(), this.getDisplayName().getString(), this.id, this.world == null ? "~NULL~" : this.world.toString(), this.locX(), this.locY(), this.locZ()); ++ return String.format(Locale.ROOT, "%s['%s'/%d, uuid='%s', l='%s', x=%.2f, y=%.2f, z=%.2f, cx=%d, cz=%d, tl=%d, v=%b, d=%b]", new Object[] { this.getClass().getSimpleName(), this.getDisplayName().getString(), Integer.valueOf(this.id), this.uniqueID.toString(), this.world == null ? "~NULL~" : this.world.toString(), Double.valueOf(this.locX()), Double.valueOf(this.locY()), Double.valueOf(this.locZ()), getChunkX(), getChunkZ(), this.ticksLived, this.valid, this.dead}); // Paper - add more information } public boolean isInvulnerable(DamageSource damagesource) { diff --git a/Spigot-Server-Patches/force-entity-dismount-during-teleportation.patch b/Spigot-Server-Patches/force-entity-dismount-during-teleportation.patch index 4f5b0955ff..ef177f3574 100644 --- a/Spigot-Server-Patches/force-entity-dismount-during-teleportation.patch +++ b/Spigot-Server-Patches/force-entity-dismount-during-teleportation.patch @@ -27,9 +27,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } -- public void stopRiding() { +- public void bb() { + // Paper start -+ public void stopRiding() { stopRiding(false); } ++ public void bb() { stopRiding(false); } + public void stopRiding(boolean suppressCancellation) { + // Paper end if (this.vehicle != null) { @@ -80,10 +80,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } - @Override -- public void stopRiding() { -- super.stopRiding(); +- public void bb() { +- super.bb(); + // Paper start -+ @Override public void stopRiding() { stopRiding(false); } ++ @Override public void bb() { stopRiding(false); } + @Override public void stopRiding(boolean suppressCancellation) { + // Paper end + super.stopRiding(suppressCancellation); // Paper - suppress @@ -95,7 +95,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { - return ((Byte) this.datawatcher.get(EntityLiving.ao) & 4) != 0; + return ((Byte) this.datawatcher.get(EntityLiving.an) & 4) != 0; } - @Override diff --git a/Spigot-Server-Patches/incremental-chunk-saving.patch b/Spigot-Server-Patches/incremental-chunk-saving.patch deleted file mode 100644 index 66538b3a80..0000000000 --- a/Spigot-Server-Patches/incremental-chunk-saving.patch +++ /dev/null @@ -1,320 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Shane Freeder -Date: Sun, 9 Jun 2019 03:53:22 +0100 -Subject: [PATCH] incremental chunk saving - - -diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -0,0 +0,0 @@ public class PaperWorldConfig { - keepLoadedRange = (short) (getInt("keep-spawn-loaded-range", Math.min(spigotConfig.viewDistance, 10)) * 16); - log( "Keep Spawn Loaded Range: " + (keepLoadedRange/16)); - } -+ -+ public int autoSavePeriod = -1; -+ private void autoSavePeriod() { -+ autoSavePeriod = getInt("auto-save-interval", -1); -+ if (autoSavePeriod > 0) { -+ log("Auto Save Interval: " +autoSavePeriod + " (" + (autoSavePeriod / 20) + "s)"); -+ } else if (autoSavePeriod < 0) { -+ autoSavePeriod = net.minecraft.server.MinecraftServer.getServer().autosavePeriod; -+ } -+ } -+ -+ public int maxAutoSaveChunksPerTick = 24; -+ private void maxAutoSaveChunksPerTick() { -+ maxAutoSaveChunksPerTick = getInt("max-auto-save-chunks-per-tick", 24); -+ } - } -diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/Chunk.java -+++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { - private TickList o; - private TickList p; - private boolean q; -- private long lastSaved; -+ public long lastSaved; // Paper - private volatile boolean s; - private long inhabitedTime; - @Nullable -diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/ChunkProviderServer.java -+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - } // Paper - Timings - } - -+ // Paper start - duplicate save, but call incremental -+ public void saveIncrementally() { -+ this.tickDistanceManager(); -+ try (co.aikar.timings.Timing timed = world.timings.chunkSaveData.startTiming()) { // Paper - Timings -+ this.playerChunkMap.saveIncrementally(); -+ } // Paper - Timings -+ } -+ // Paper end -+ - @Override - public void close() throws IOException { - // CraftBukkit start -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); - public int autosavePeriod; -+ public boolean serverAutoSave = false; // Paper - public File bukkitDataPackFolder; - public CommandDispatcher vanillaCommandDispatcher; - private boolean forceTicks; -@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit -- MinecraftServer.LOGGER.debug("Autosave started"); -+ //if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit // Paper - move down -+ //MinecraftServer.LOGGER.debug("Autosave started"); // Paper -+ serverAutoSave = (autosavePeriod > 0 && this.ticks % autosavePeriod == 0); // Paper - this.methodProfiler.enter("save"); -+ if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // Paper - this.playerList.savePlayers(); -- this.saveChunks(true, false, false); -+ }// Paper -+ // Paper start -+ for (WorldServer world : getWorlds()) { -+ if (world.paperConfig.autoSavePeriod > 0) { -+ try { -+ world.saveIncrementally(serverAutoSave); -+ } catch (ExceptionWorldConflict exceptionWorldConflict) { -+ MinecraftServer.LOGGER.warn(exceptionWorldConflict.getMessage()); -+ } -+ } -+ } -+ // Paper end -+ - this.methodProfiler.exit(); -- MinecraftServer.LOGGER.debug("Autosave finished"); -- } -+ //MinecraftServer.LOGGER.debug("Autosave finished"); // Paper -+ //} // Paper - - this.methodProfiler.enter("snooper"); - if (((DedicatedServer) this).getDedicatedServerProperties().snooperEnabled && !this.snooper.d() && this.ticks > 100) { // Spigot -diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/PlayerChunk.java -+++ b/src/main/java/net/minecraft/server/PlayerChunk.java -@@ -0,0 +0,0 @@ public class PlayerChunk { - - private final PlayerChunkMap chunkMap; // Paper - -+ long lastAutoSaveTime; // Paper - incremental autosave -+ long inactiveTimeStart; // Paper - incremental autosave -+ - public PlayerChunk(ChunkCoordIntPair chunkcoordintpair, int i, LightEngine lightengine, PlayerChunk.c playerchunk_c, PlayerChunk.d playerchunk_d) { - this.statusFutures = new AtomicReferenceArray(PlayerChunk.CHUNK_STATUSES.size()); - this.fullChunkFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE; -@@ -0,0 +0,0 @@ public class PlayerChunk { - boolean flag2 = playerchunk_state.isAtLeast(PlayerChunk.State.BORDER); - boolean flag3 = playerchunk_state1.isAtLeast(PlayerChunk.State.BORDER); - -+ boolean prevHasBeenLoaded = this.hasBeenLoaded; // Paper - this.hasBeenLoaded |= flag3; -+ // Paper start - incremental autosave -+ if (this.hasBeenLoaded & !prevHasBeenLoaded) { -+ long timeSinceAutoSave = this.inactiveTimeStart - this.lastAutoSaveTime; -+ if (timeSinceAutoSave < 0) { -+ // safest bet is to assume autosave is needed here -+ timeSinceAutoSave = this.chunkMap.world.paperConfig.autoSavePeriod; -+ } -+ this.lastAutoSaveTime = this.chunkMap.world.getTime() - timeSinceAutoSave; -+ this.chunkMap.autoSaveQueue.add(this); -+ } -+ // Paper end - if (!flag2 && flag3) { - // Paper start - cache ticking ready status - int expectCreateCount = ++this.fullChunkCreateCount; -@@ -0,0 +0,0 @@ public class PlayerChunk { - } - - public void m() { -+ boolean prev = this.hasBeenLoaded; // Paper -+ this.hasBeenLoaded = getChunkState(this.ticketLevel).isAtLeast(PlayerChunk.State.BORDER); -+ // Paper start - incremental autosave -+ if (prev != this.hasBeenLoaded) { -+ if (this.hasBeenLoaded) { -+ long timeSinceAutoSave = this.inactiveTimeStart - this.lastAutoSaveTime; -+ if (timeSinceAutoSave < 0) { -+ // safest bet is to assume autosave is needed here -+ timeSinceAutoSave = this.chunkMap.world.paperConfig.autoSavePeriod; -+ } -+ this.lastAutoSaveTime = this.chunkMap.world.getTime() - timeSinceAutoSave; -+ this.chunkMap.autoSaveQueue.add(this); -+ } else { -+ this.inactiveTimeStart = this.chunkMap.world.getTime(); -+ this.chunkMap.autoSaveQueue.remove(this); -+ } -+ } -+ // Paper end -+ } -+ -+ // Paper start - incremental autosave -+ public boolean setHasBeenLoaded() { - this.hasBeenLoaded = getChunkState(this.ticketLevel).isAtLeast(PlayerChunk.State.BORDER); -+ return this.hasBeenLoaded; - } -+ // Paper end - - public void a(ProtoChunkExtension protochunkextension) { - for (int i = 0; i < this.statusFutures.length(); ++i) { -diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/PlayerChunkMap.java -+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - - } - -+ // Paper start - incremental autosave -+ final it.unimi.dsi.fastutil.objects.ObjectRBTreeSet autoSaveQueue = new it.unimi.dsi.fastutil.objects.ObjectRBTreeSet<>((playerchunk1, playerchunk2) -> { -+ int timeCompare = Long.compare(playerchunk1.lastAutoSaveTime, playerchunk2.lastAutoSaveTime); -+ if (timeCompare != 0) { -+ return timeCompare; -+ } -+ -+ return Long.compare(MCUtil.getCoordinateKey(playerchunk1.location), MCUtil.getCoordinateKey(playerchunk2.location)); -+ }); -+ -+ protected void saveIncrementally() { -+ int savedThisTick = 0; -+ // optimized since we search far less chunks to hit ones that need to be saved -+ List reschedule = new ArrayList<>(this.world.paperConfig.maxAutoSaveChunksPerTick); -+ long currentTick = this.world.getTime(); -+ long maxSaveTime = currentTick - this.world.paperConfig.autoSavePeriod; -+ -+ for (Iterator iterator = this.autoSaveQueue.iterator(); iterator.hasNext();) { -+ PlayerChunk playerchunk = iterator.next(); -+ if (playerchunk.lastAutoSaveTime > maxSaveTime) { -+ break; -+ } -+ -+ iterator.remove(); -+ -+ IChunkAccess ichunkaccess = playerchunk.getChunkSave().getNow(null); -+ if (ichunkaccess instanceof Chunk) { -+ boolean shouldSave = ((Chunk)ichunkaccess).lastSaved <= maxSaveTime; -+ -+ if (shouldSave && this.saveChunk(ichunkaccess)) { -+ ++savedThisTick; -+ -+ if (!playerchunk.setHasBeenLoaded()) { -+ // do not fall through to reschedule logic -+ playerchunk.inactiveTimeStart = currentTick; -+ if (savedThisTick >= this.world.paperConfig.maxAutoSaveChunksPerTick) { -+ break; -+ } -+ continue; -+ } -+ } -+ } -+ -+ reschedule.add(playerchunk); -+ -+ if (savedThisTick >= this.world.paperConfig.maxAutoSaveChunksPerTick) { -+ break; -+ } -+ } -+ -+ for (int i = 0, len = reschedule.size(); i < len; ++i) { -+ PlayerChunk playerchunk = reschedule.get(i); -+ playerchunk.lastAutoSaveTime = this.world.getTime(); -+ this.autoSaveQueue.add(playerchunk); -+ } -+ } -+ // Paper end -+ - protected void save(boolean flag) { - if (flag) { - List list = (List) this.visibleChunks.values().stream().filter(PlayerChunk::hasBeenLoaded).peek(PlayerChunk::m).collect(Collectors.toList()); -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - - this.world.unloadChunk(chunk); - } -+ this.autoSaveQueue.remove(playerchunk); // Paper - - this.lightEngine.a(ichunkaccess.getPos()); - this.lightEngine.queueUpdate(); -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - playerchunk.a(new ProtoChunkExtension(chunk)); - } - -+ chunk.setLastSaved(this.world.getTime() - 1); // Paper - avoid autosaving newly generated/loaded chunks -+ - chunk.a(() -> { - return PlayerChunk.getChunkState(playerchunk.getTicketLevel()); - }); -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { - return this.worldProvider.c(); - } - -+ // Paper start - derived from below -+ public void saveIncrementally(boolean doFull) throws ExceptionWorldConflict { -+ ChunkProviderServer chunkproviderserver = this.getChunkProvider(); -+ -+ if (doFull) { -+ org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); -+ } -+ -+ try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { -+ if (doFull) { -+ this.saveData(); -+ } -+ -+ timings.worldSaveChunks.startTiming(); // Paper -+ if (!this.isSavingDisabled()) chunkproviderserver.saveIncrementally(); -+ timings.worldSaveChunks.stopTiming(); // Paper -+ -+ -+ // CraftBukkit start - moved from MinecraftServer.saveChunks -+ // PAIL - rename -+ if (doFull) { -+ WorldServer worldserver1 = this; -+ WorldData worlddata = worldserver1.getWorldData(); -+ -+ worldserver1.getWorldBorder().save(worlddata); -+ worlddata.setCustomBossEvents(this.server.getBossBattleCustomData().save()); -+ worldserver1.getDataManager().saveWorldData(worlddata, this.server.getPlayerList().save()); -+ // CraftBukkit end -+ } -+ } -+ } -+ // Paper end -+ - public void save(@Nullable IProgressUpdate iprogressupdate, boolean flag, boolean flag1) throws ExceptionWorldConflict { - ChunkProviderServer chunkproviderserver = this.getChunkProvider(); - - if (!flag1) { -- org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit -+ if (flag) org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit - try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper - if (iprogressupdate != null) { - iprogressupdate.a(new ChatMessage("menu.savingLevel", new Object[0])); -@@ -0,0 +0,0 @@ public class WorldServer extends World { - // CraftBukkit end - } - -+ protected void saveData() throws ExceptionWorldConflict { this.m_(); } // Paper - OBFHELPER - protected void m_() throws ExceptionWorldConflict { - this.checkSession(); - this.worldProvider.i(); diff --git a/work/Bukkit b/work/Bukkit index 32fcd349d4..6f3c5f4a5a 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 32fcd349d4074c564116bbeb4b481332460902ee +Subproject commit 6f3c5f4a5a0867ef265df9d58b48bdc43079e3dd diff --git a/work/CraftBukkit b/work/CraftBukkit index 2b00831c95..3f0c333870 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 2b00831c95f8dda096ad22ae88bc615d9dd31ea1 +Subproject commit 3f0c333870ba74705e98d19322174d6f0c10c900