From fe2a0ea50019b4f4dd8cbabc62d877560430f5bd Mon Sep 17 00:00:00 2001 From: Aikar Date: Fri, 26 Jun 2020 02:29:44 -0400 Subject: [PATCH] Latest progress - restored patches, some issues resolved --- ...ies-option-to-debug-dupe-uuid-issues.patch | 4 +- .../Add-World-Util-Methods.patch | 21 +- ...to-disable-ender-dragon-legacy-check.patch | 18 ++ ...Allow-disabling-armour-stand-ticking.patch | 164 ------------ Spigot-Server-Patches/Anti-Xray.patch | 2 +- .../Asynchronous-chunk-IO-and-loading.patch | 11 +- ...owned-for-Villager-Aggression-Config.patch | 19 ++ .../Chunk-debug-command.patch | 2 +- ...le-Keep-Spawn-Loaded-range-per-world.patch | 2 +- ...le-speed-for-water-flowing-over-lava.patch | 4 +- .../Entity-Activation-Range-2.0.patch | 16 +- Spigot-Server-Patches/Entity-Origin-API.patch | 4 +- .../Entity-fromMobSpawner.patch | 2 +- Spigot-Server-Patches/Fix-Light-Command.patch | 6 +- Spigot-Server-Patches/Here-s-Johnny.patch | 38 +++ ...plement-EntityKnockbackByEntityEvent.patch | 63 ++++- Spigot-Server-Patches/MC-Dev-fixes.patch | 37 +++ Spigot-Server-Patches/MC-Utils.patch | 12 + ...ault-permission-message-configurable.patch | 2 +- ...ckPhysicsEvent-if-a-plugin-has-a-lis.patch | 7 +- ...ptimise-BlockState-s-hashCode-equals.patch | 9 - ...e-Biome-Mob-Lookups-for-Mob-Spawning.patch | 25 +- .../Optimize-CraftBlockData-Creation.patch | 49 ++++ ...-Manager-and-add-advanced-packet-sup.patch | 9 +- ...ze-NibbleArray-to-use-pooled-buffers.patch | 11 +- .../Optimize-Server-World-Map.patch | 242 ------------------ .../Paper-config-files.patch | 1 + .../Player.setPlayerProfile-API.patch | 12 +- ...to-current-Chunk-for-Entity-and-Bloc.patch | 2 +- Spigot-Server-Patches/Timings-v2.patch | 7 +- Spigot-Server-Patches/Turtle-API.patch | 5 + ...tance-map-to-optimise-entity-tracker.patch | 2 +- ...etChunkIfLoadedImmediately-in-places.patch | 2 +- .../incremental-chunk-saving.patch | 6 +- 34 files changed, 338 insertions(+), 478 deletions(-) delete mode 100644 Spigot-Server-Patches/Allow-disabling-armour-stand-ticking.patch create mode 100644 Spigot-Server-Patches/Check-Drowned-for-Villager-Aggression-Config.patch create mode 100644 Spigot-Server-Patches/Here-s-Johnny.patch create mode 100644 Spigot-Server-Patches/Optimize-CraftBlockData-Creation.patch delete mode 100644 Spigot-Server-Patches/Optimize-Server-World-Map.patch 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 20c6b35293..9be54d7784 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 @@ -56,14 +56,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- 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 { + public final Convertable.ConversionSession convertable; 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()); + } - public Chunk getChunkIfLoaded(int x, int z) { + @Override public Chunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI return this.chunkProvider.getChunkAt(x, z, false); @@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { // CraftBukkit start diff --git a/Spigot-Server-Patches/Add-World-Util-Methods.patch b/Spigot-Server-Patches/Add-World-Util-Methods.patch index f38467e359..ba7611bedf 100644 --- a/Spigot-Server-Patches/Add-World-Util-Methods.patch +++ b/Spigot-Server-Patches/Add-World-Util-Methods.patch @@ -17,8 +17,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public boolean isLoadedAndInBounds(BlockPosition blockposition) { + return getWorldBorder().isInBounds(blockposition) && getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) != null; + } -+ public Chunk getChunkIfLoaded(BlockPosition blockposition) { -+ return getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); ++ ++ public Chunk getChunkIfLoaded(int x, int z) { ++ return ((WorldServer) this).getChunkProvider().getChunkAtIfLoadedImmediately(x, z); ++ } ++ public final Chunk getChunkIfLoaded(BlockPosition blockposition) { ++ return ((WorldServer) this).getChunkProvider().getChunkAtIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + } + + // reduces need to do isLoaded before getType @@ -40,3 +44,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public boolean a(BlockPosition blockposition) { return (double) (blockposition.getX() + 1) > this.e() && (double) blockposition.getX() < this.g() && (double) (blockposition.getZ() + 1) > this.f() && (double) blockposition.getZ() < this.h(); } +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 { + public final Convertable.ConversionSession convertable; + public final UUID uuid; + +- public Chunk getChunkIfLoaded(int x, int z) { ++ @Override public Chunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI + return this.chunkProvider.getChunkAt(x, z, false); + } + 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 db52112c64..c6a4124285 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 @@ -46,3 +46,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.world = worldserver; if (nbttagcompound.hasKeyOfType("DragonKilled", 99)) { if (nbttagcompound.b("Dragon")) { +@@ -0,0 +0,0 @@ public class EnderDragonBattle { + + private void a(BlockPosition blockposition) { + this.world.triggerEffect(3000, blockposition, 0); +- WorldGenerator.END_GATEWAY.b((WorldGenFeatureConfiguration) WorldGenEndGatewayConfiguration.a()).a(this.world, this.world.getStructureManager(), this.world.getChunkProvider().getChunkGenerator(), new Random(), blockposition); ++ WorldGenerator.END_GATEWAY.b(WorldGenEndGatewayConfiguration.a()).a(this.world, this.world.getStructureManager(), this.world.getChunkProvider().getChunkGenerator(), new Random(), blockposition); // Paper - decompile error + } + + private void a(boolean flag) { +@@ -0,0 +0,0 @@ public class EnderDragonBattle { + } + } + +- worldgenendtrophy.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.k).a(this.world, this.world.getStructureManager(), this.world.getChunkProvider().getChunkGenerator(), new Random(), this.exitPortalLocation); ++ worldgenendtrophy.b(WorldGenFeatureConfiguration.k).a(this.world, this.world.getStructureManager(), this.world.getChunkProvider().getChunkGenerator(), new Random(), this.exitPortalLocation); // Paper - decompile error + } + + private EntityEnderDragon o() { diff --git a/Spigot-Server-Patches/Allow-disabling-armour-stand-ticking.patch b/Spigot-Server-Patches/Allow-disabling-armour-stand-ticking.patch deleted file mode 100644 index dd8f1d9a7d..0000000000 --- a/Spigot-Server-Patches/Allow-disabling-armour-stand-ticking.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Riley Park -Date: Wed, 15 Aug 2018 01:26:09 -0700 -Subject: [PATCH] Allow disabling armour stand ticking - - -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 armorStandEntityLookups() { - armorStandEntityLookups = getBoolean("armor-stands-do-collision-entity-lookups", true); - } -+ -+ public boolean armorStandTick = true; -+ private void armorStandTick() { -+ this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick); -+ log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default"); -+ } - } -diff --git a/src/main/java/net/minecraft/server/EntityArmorStand.java b/src/main/java/net/minecraft/server/EntityArmorStand.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/EntityArmorStand.java -+++ b/src/main/java/net/minecraft/server/EntityArmorStand.java -@@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - public Vector3f leftLegPose; - public Vector3f rightLegPose; - public boolean canMove = true; // Paper -+ // Paper start - Allow ArmorStands not to tick -+ public boolean canTick = true; -+ public boolean canTickSetByAPI = false; -+ private boolean noTickPoseDirty = false; -+ private boolean noTickEquipmentDirty = false; -+ // Paper end - - public EntityArmorStand(EntityTypes entitytypes, World world) { - super(entitytypes, world); -@@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - 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.G = 0.0F; - } - -@@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - this.armorItems.set(enumitemslot.b(), itemstack); - } - -+ this.noTickEquipmentDirty = true; // Paper - Allow equipment to be updated even when tick disabled - } - - @Override -@@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - } - - nbttagcompound.set("Pose", this.B()); -+ if (this.canTickSetByAPI) nbttagcompound.setBoolean("Paper.CanTickOverride", this.canTick); // Paper - persist no tick setting - } - - @Override -@@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - this.setBasePlate(nbttagcompound.getBoolean("NoBasePlate")); - this.setMarker(nbttagcompound.getBoolean("Marker")); - this.noclip = !this.A(); -+ // Paper start - persist no tick -+ if (nbttagcompound.hasKey("Paper.CanTickOverride")) { -+ this.canTick = nbttagcompound.getBoolean("Paper.CanTickOverride"); -+ this.canTickSetByAPI = true; -+ } -+ // Paper end - NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Pose"); - - this.g(nbttagcompound1); -@@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - - @Override - public void tick() { -+ // Paper start -+ if (!this.canTick) { -+ if (this.noTickPoseDirty) { -+ this.noTickPoseDirty = false; -+ this.updatePose(); -+ } -+ -+ if (this.noTickEquipmentDirty) { -+ this.noTickEquipmentDirty = false; -+ this.updateEntityEquipment(); -+ } -+ -+ return; -+ } -+ // Paper end -+ - super.tick(); -+ // Paper start - Split into separate method -+ updatePose(); -+ } -+ -+ public void updatePose() { -+ // Paper end - Vector3f vector3f = (Vector3f) this.datawatcher.get(EntityArmorStand.c); - - if (!this.headPose.equals(vector3f)) { -@@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - public void setHeadPose(Vector3f vector3f) { - this.headPose = vector3f; - this.datawatcher.set(EntityArmorStand.c, vector3f); -+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking - } - - public void setBodyPose(Vector3f vector3f) { - this.bodyPose = vector3f; - this.datawatcher.set(EntityArmorStand.d, vector3f); -+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking - } - - public void setLeftArmPose(Vector3f vector3f) { - this.leftArmPose = vector3f; - this.datawatcher.set(EntityArmorStand.e, vector3f); -+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking - } - - public void setRightArmPose(Vector3f vector3f) { - this.rightArmPose = vector3f; - this.datawatcher.set(EntityArmorStand.f, vector3f); -+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking - } - - public void setLeftLegPose(Vector3f vector3f) { - this.leftLegPose = vector3f; - this.datawatcher.set(EntityArmorStand.g, vector3f); -+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking - } - - public void setRightLegPose(Vector3f vector3f) { - this.rightLegPose = 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/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 -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java -@@ -0,0 +0,0 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { - public boolean isSlotDisabled(org.bukkit.inventory.EquipmentSlot slot) { - return getHandle().isSlotDisabled(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot)); - } -+ -+ @Override -+ public boolean canTick() { -+ return this.getHandle().canTick; -+ } -+ -+ @Override -+ public void setCanTick(final boolean tick) { -+ this.getHandle().canTick = tick; -+ this.getHandle().canTickSetByAPI = true; -+ } - // Paper end - } diff --git a/Spigot-Server-Patches/Anti-Xray.patch b/Spigot-Server-Patches/Anti-Xray.patch index 73bde20765..29e5b2e0e2 100644 --- a/Spigot-Server-Patches/Anti-Xray.patch +++ b/Spigot-Server-Patches/Anti-Xray.patch @@ -197,7 +197,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + IBlockData blockData = ChunkSection.GLOBAL_PALETTE.getObject(i); + + if (blockData != null) { -+ solidGlobal[i] = blockData.getBlock().isOccluding(blockData, emptyChunk, zeroPos) ++ solidGlobal[i] = blockData.isOccluding(emptyChunk, zeroPos) + && blockData.getBlock() != Blocks.SPAWNER && blockData.getBlock() != Blocks.BARRIER && blockData.getBlock() != Blocks.SHULKER_BOX; + // shulker box checks TE. + } diff --git a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch index a1099c9e45..59a8abc786 100644 --- a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch @@ -140,7 +140,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public final Timing chunkUnloadDataSave; + public WorldTimingsHandler(World server) { - String name = server.worldData.getName() +" - "; + String name = server.getWorld().getName() +" - "; @@ -0,0 +0,0 @@ public class WorldTimingsHandler { @@ -341,7 +341,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +package com.destroystokyo.paper.io; + +import net.minecraft.server.ChunkCoordIntPair; -+import net.minecraft.server.ExceptionWorldConflict; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.RegionFile; @@ -882,15 +881,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + // check if another process is writing -+ try { -+ this.world.checkSession(); -+ } catch (final ExceptionWorldConflict ex) { ++ /*try { TODO: Can we restore this? ++ ((WorldServer)this.world).checkSession(); ++ } catch (final Exception ex) { + LOGGER.fatal("Couldn't save chunk; already in use by another instance of Minecraft?", ex); + // we don't need to set the write counter to -1 as we know at this stage there's no point in re-scheduling + // writes since they'll fail anyways. + return; + } -+ ++*/ + for (;;) { + final long writeCounter; + final NBTTagCompound data; diff --git a/Spigot-Server-Patches/Check-Drowned-for-Villager-Aggression-Config.patch b/Spigot-Server-Patches/Check-Drowned-for-Villager-Aggression-Config.patch new file mode 100644 index 0000000000..266dd029d2 --- /dev/null +++ b/Spigot-Server-Patches/Check-Drowned-for-Villager-Aggression-Config.patch @@ -0,0 +1,19 @@ +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::j)); +- 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.bv)); + } diff --git a/Spigot-Server-Patches/Chunk-debug-command.patch b/Spigot-Server-Patches/Chunk-debug-command.patch index 02fd77ff94..68c32e57d8 100644 --- a/Spigot-Server-Patches/Chunk-debug-command.patch +++ b/Spigot-Server-Patches/Chunk-debug-command.patch @@ -320,7 +320,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return Integer.compare(v1.location.z, v2.location.z); + }); + -+ worldData.addProperty("name", world.getWorldData().getName()); ++ worldData.addProperty("name", world.getWorld().getName()); + worldData.addProperty("view-distance", world.spigotConfig.viewDistance); + worldData.addProperty("keep-spawn-loaded", world.keepSpawnInMemory); + worldData.addProperty("keep-spawn-loaded-range", world.paperConfig.keepLoadedRange); 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 c24cf6cc84..aef440b533 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 @@ -55,7 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + worldserver.addTicketsForSpawn(radiusBlocks, blockposition); } + // Paper end -+ LOGGER.info("Loaded " + chunkproviderserver.b() + " spawn chunks for world " + worldserver.getWorldData().getName()); // Paper ++ LOGGER.info("Loaded " + chunkproviderserver.b() + " spawn chunks for world " + worldserver.getWorld().getName()); // Paper // CraftBukkit start // this.nextTick = SystemUtils.getMonotonicMillis() + 10L; diff --git a/Spigot-Server-Patches/Configurable-speed-for-water-flowing-over-lava.patch b/Spigot-Server-Patches/Configurable-speed-for-water-flowing-over-lava.patch index 26449fed76..a77bf072f3 100644 --- a/Spigot-Server-Patches/Configurable-speed-for-water-flowing-over-lava.patch +++ b/Spigot-Server-Patches/Configurable-speed-for-water-flowing-over-lava.patch @@ -9,8 +9,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- 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 { - this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick); - log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default"); + private void armorStandEntityLookups() { + armorStandEntityLookups = getBoolean("armor-stands-do-collision-entity-lookups", true); } + + public int waterOverLavaFlowSpeed; diff --git a/Spigot-Server-Patches/Entity-Activation-Range-2.0.patch b/Spigot-Server-Patches/Entity-Activation-Range-2.0.patch index b854d7156d..b1c477a1a5 100644 --- a/Spigot-Server-Patches/Entity-Activation-Range-2.0.patch +++ b/Spigot-Server-Patches/Entity-Activation-Range-2.0.patch @@ -13,18 +13,6 @@ Adds water Mobs to activation range config and nerfs fish Adds flying monsters to control ghast and phantoms Adds villagers as separate config -diff --git a/src/main/java/net/minecraft/server/BehaviorController.java b/src/main/java/net/minecraft/server/BehaviorController.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BehaviorController.java -+++ b/src/main/java/net/minecraft/server/BehaviorController.java -@@ -0,0 +0,0 @@ public class BehaviorController { - - } - -+ public boolean hasActivity(Activity activity) { return c(activity); } // Paper - OBFHELPER - public boolean c(Activity activity) { - return this.j.contains(activity); - } 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 @@ -636,14 +624,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + if (config.villagersActiveForPanic) { + for (Activity activity : VILLAGER_PANIC_IMMUNITIES) { -+ if (behaviorController.hasActivity(activity)) { ++ if (behaviorController.c(activity)) { + return 20*5; + } + } + } + + if (config.villagersWorkImmunityAfter > 0 && inactiveFor >= config.villagersWorkImmunityAfter) { -+ if (behaviorController.hasActivity(Activity.WORK)) { ++ if (behaviorController.c(Activity.WORK)) { + return config.villagersWorkImmunityFor; + } + } diff --git a/Spigot-Server-Patches/Entity-Origin-API.patch b/Spigot-Server-Patches/Entity-Origin-API.patch index f73077115e..7827409589 100644 --- a/Spigot-Server-Patches/Entity-Origin-API.patch +++ b/Spigot-Server-Patches/Entity-Origin-API.patch @@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public org.bukkit.projectiles.ProjectileSource projectileSource; // For projectiles only public boolean forceExplosionKnockback; // SPIGOT-949 public Timing tickTimer = MinecraftTimings.getEntityTimings(this); // Paper -+ public Location origin; // Paper ++ public org.bukkit.Location origin; // Paper // Spigot start public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this); public final boolean defaultActivationState; @@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - Restore the entity's origin location + NBTTagList originTag = nbttagcompound.getList("Paper.Origin", 6); + if (!originTag.isEmpty()) { -+ origin = new Location(world.getWorld(), originTag.getDoubleAt(0), originTag.getDoubleAt(1), originTag.getDoubleAt(2)); ++ origin = new org.bukkit.Location(world.getWorld(), originTag.getDoubleAt(0), originTag.getDoubleAt(1), originTag.getDoubleAt(2)); + } + // Paper end + diff --git a/Spigot-Server-Patches/Entity-fromMobSpawner.patch b/Spigot-Server-Patches/Entity-fromMobSpawner.patch index 74e3392f20..62c20bc626 100644 --- a/Spigot-Server-Patches/Entity-fromMobSpawner.patch +++ b/Spigot-Server-Patches/Entity-fromMobSpawner.patch @@ -29,7 +29,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } catch (Throwable throwable) { @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke if (!originTag.isEmpty()) { - origin = new Location(world.getWorld(), originTag.getDoubleAt(0), originTag.getDoubleAt(1), originTag.getDoubleAt(2)); + origin = new org.bukkit.Location(world.getWorld(), originTag.getDoubleAt(0), originTag.getDoubleAt(1), originTag.getDoubleAt(2)); } + + spawnedViaMobSpawner = nbttagcompound.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status diff --git a/Spigot-Server-Patches/Fix-Light-Command.patch b/Spigot-Server-Patches/Fix-Light-Command.patch index 2fbdef8430..481217a097 100644 --- a/Spigot-Server-Patches/Fix-Light-Command.patch +++ b/Spigot-Server-Patches/Fix-Light-Command.patch @@ -94,10 +94,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + lightengine.a(world.paperConfig.lightQueueSize + 16 * 256); // ensure full chunk can fit into queue + sender.sendMessage("Updating Light " + coord); ++ int cx = chunk.getPos().x << 4; ++ int cz = chunk.getPos().z << 4; + for (int y = 0; y < world.getHeight(); y++) { + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { -+ BlockPosition pos = new BlockPosition(chunk.getPos().getBlockX() + x, y, chunk.getPos().getBlockZ() + z); ++ BlockPosition pos = new BlockPosition(cx + x, y, cz + z); + lightengine.a(pos); + } + } @@ -107,7 +109,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (visibleChunk != null) { + world.getChunkProvider().playerChunkMap.addLightTask(visibleChunk, () -> { + MinecraftServer.getServer().processQueue.add(() -> { -+ visibleChunk.sendPacketToTrackedPlayers(new PacketPlayOutLightUpdate(chunk.getPos(), lightengine), false); ++ visibleChunk.sendPacketToTrackedPlayers(new PacketPlayOutLightUpdate(chunk.getPos(), lightengine, true), false); + updateLight(sender, world, lightengine, queue); + }); + }); diff --git a/Spigot-Server-Patches/Here-s-Johnny.patch b/Spigot-Server-Patches/Here-s-Johnny.patch new file mode 100644 index 0000000000..af5164a214 --- /dev/null +++ b/Spigot-Server-Patches/Here-s-Johnny.patch @@ -0,0 +1,38 @@ +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 bv; ++ private boolean bv; public boolean isJohnny() { return bv; } public void setJohnny(boolean johnny) { bv = 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/Implement-EntityKnockbackByEntityEvent.patch b/Spigot-Server-Patches/Implement-EntityKnockbackByEntityEvent.patch index 12af235190..957fe3c9b1 100644 --- a/Spigot-Server-Patches/Implement-EntityKnockbackByEntityEvent.patch +++ b/Spigot-Server-Patches/Implement-EntityKnockbackByEntityEvent.patch @@ -5,10 +5,68 @@ Subject: [PATCH] Implement EntityKnockbackByEntityEvent This event is called when an entity receives knockback by another entity. +diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- 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 { + if (flag5) { + if (i > 0) { + if (entity instanceof EntityLiving) { ++ ((EntityLiving) entity).knockingBackEntity = this; // Paper + ((EntityLiving) entity).a((float) i * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F))); ++ ((EntityLiving) entity).knockingBackEntity = null; // Paper + } else { + entity.h((double) (-MathHelper.sin(this.yaw * 0.017453292F) * (float) i * 0.5F), 0.1D, (double) (MathHelper.cos(this.yaw * 0.017453292F) * (float) i * 0.5F)); + } +@@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving { + if (entityliving != this && entityliving != entity && !this.r(entityliving) && (!(entityliving instanceof EntityArmorStand) || !((EntityArmorStand) entityliving).isMarker()) && this.h((Entity) entityliving) < 9.0D) { + // CraftBukkit start - Only apply knockback if the damage hits + if (entityliving.damageEntity(DamageSource.playerAttack(this).sweep(), f4)) { ++ ((EntityLiving) entity).knockingBackEntity = this; // Paper + entityliving.a(0.4F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F))); ++ ((EntityLiving) entity).knockingBackEntity = null; // Paper + } + // CraftBukkit end + } +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 (flag) { + if (f1 > 0.0F && entity instanceof EntityLiving) { ++ ((EntityLiving) entity).knockingBackEntity = this; // Paper + ((EntityLiving) entity).a(f1 * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F))); ++ ((EntityLiving) entity).knockingBackEntity = null; // Paper + this.setMot(this.getMot().d(0.6D, 1.0D, 0.6D)); + } + 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 { + } + + this.aw = (float) (MathHelper.d(d1, d0) * 57.2957763671875D - (double) this.yaw); ++ this.knockingBackEntity = entity1 instanceof EntityLiving ? ((EntityLiving) entity1) : null; // Paper + this.a(0.4F, d0, d1); ++ this.knockingBackEntity = null; // Paper + } else { + this.aw = (float) ((int) (Math.random() * 2.0D) * 180); + } +@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { + } + + protected void f(EntityLiving entityliving) { ++ ((EntityLiving) entityliving).knockingBackEntity = this; // Paper + entityliving.a(0.5F, entityliving.locX() - this.locX(), entityliving.locZ() - this.locZ()); ++ ((EntityLiving) entityliving).knockingBackEntity = null; // Paper + } + + private boolean f(DamageSource damagesource) { @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { Vec3D vec3d1 = (new Vec3D(d0, 0.0D, d1)).d().a((double) f); @@ -19,10 +77,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + org.bukkit.util.Vector delta = new org.bukkit.util.Vector(currentMot.x - vec3d.x, currentMot.y - vec3d.y, currentMot.z - vec3d.z); + // Restore old velocity to be able to access it in the event + this.setMot(vec3d); -+ if (entity == null || new com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent((LivingEntity) getBukkitEntity(), entity.getBukkitEntity(), f, delta).callEvent()) { ++ if (knockingBackEntity == null || new com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent((LivingEntity) getBukkitEntity(), knockingBackEntity.getBukkitEntity(), f, delta).callEvent()) { + this.setMot(vec3d.x + delta.getX(), vec3d.y + delta.getY(), vec3d.z + delta.getZ()); + } + // Paper end } } ++ EntityLiving knockingBackEntity; // Paper + @Nullable + protected SoundEffect getSoundHurt(DamageSource damagesource) { diff --git a/Spigot-Server-Patches/MC-Dev-fixes.patch b/Spigot-Server-Patches/MC-Dev-fixes.patch index 3718d2b5fa..71f013b968 100644 --- a/Spigot-Server-Patches/MC-Dev-fixes.patch +++ b/Spigot-Server-Patches/MC-Dev-fixes.patch @@ -279,6 +279,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return true; } } +diff --git a/src/main/java/net/minecraft/server/IBlockState.java b/src/main/java/net/minecraft/server/IBlockState.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/IBlockState.java ++++ b/src/main/java/net/minecraft/server/IBlockState.java +@@ -0,0 +0,0 @@ public abstract class IBlockState> { + private final Codec> e; + + protected IBlockState(String s, Class oclass) { +- this.d = Codec.STRING.comapFlatMap((s1) -> { +- return (DataResult) this.b(s1).map(DataResult::success).orElseGet(() -> { +- return DataResult.error("Unable to read property: " + this + " with value: " + s1); +- }); +- }, this::a); +- this.e = this.d.xmap(this::b, IBlockState.a::b); ++ this.d = Codec.STRING.comapFlatMap((s1) -> this.b(s1).map(DataResult::success).orElseGet(() -> { // Paper - decompile error ++ return DataResult.error("Unable to read property: " + this + " with value: " + s1); ++ }), this::a); ++ this.e = this.d.xmap(this::b, (IBlockState.a param) -> param.b()); // Paper - decompile fix + this.a = oclass; + this.b = s; + } diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/IEntityAccess.java @@ -423,6 +444,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } +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 IAsyncTaskHandlerReentrantmap(resourcepackrepository::a).filter(Objects::nonNull).map(ResourcePackLoader::d).collect(ImmutableList.toImmutableList()); // CraftBukkit - decompile error // Paper - decompile error + }, this).thenCompose((immutablelist) -> { +- return DataPackResources.a(immutablelist, this.j() ? CommandDispatcher.ServerType.DEDICATED : CommandDispatcher.ServerType.INTEGRATED, this.h(), this.executorService, this); ++ return DataPackResources.a((List) immutablelist, this.j() ? CommandDispatcher.ServerType.DEDICATED : CommandDispatcher.ServerType.INTEGRATED, this.h(), this.executorService, this); // Paper - decompile error + }).thenAcceptAsync((datapackresources) -> { + this.dataPackResources.close(); + this.dataPackResources = datapackresources; diff --git a/src/main/java/net/minecraft/server/NBTBase.java b/src/main/java/net/minecraft/server/NBTBase.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/NBTBase.java diff --git a/Spigot-Server-Patches/MC-Utils.patch b/Spigot-Server-Patches/MC-Utils.patch index b8afa8782c..f17ed02a0d 100644 --- a/Spigot-Server-Patches/MC-Utils.patch +++ b/Spigot-Server-Patches/MC-Utils.patch @@ -2318,6 +2318,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public IBlockData getType(BlockPosition blockposition) { return Blocks.AIR.getBlockData(); +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.e : Block.a(this.getCollisionShape(iblockaccess, blockposition)); + } + ++ public IBlockData getBlockData() { return p(); } // Paper - OBFHELPER + protected abstract IBlockData p(); + + public boolean isAlwaysDestroyable() { 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 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 caa6fe2b3f..2b34660d3a 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/Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch b/Spigot-Server-Patches/Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch index 4d7d691f1a..14ccdbaaae 100644 --- a/Spigot-Server-Patches/Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch +++ b/Spigot-Server-Patches/Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch @@ -70,11 +70,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- 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 { + private int tickPosition; public final Convertable.ConversionSession convertable; public final UUID uuid; - + boolean hasPhysicsEvent = true; // Paper -+ - public Chunk getChunkIfLoaded(int x, int z) { + + @Override public Chunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI return this.chunkProvider.getChunkAt(x, z, false); - } diff --git a/Spigot-Server-Patches/Optimise-BlockState-s-hashCode-equals.patch b/Spigot-Server-Patches/Optimise-BlockState-s-hashCode-equals.patch index 8c1260258b..d6ace15978 100644 --- a/Spigot-Server-Patches/Optimise-BlockState-s-hashCode-equals.patch +++ b/Spigot-Server-Patches/Optimise-BlockState-s-hashCode-equals.patch @@ -54,15 +54,6 @@ diff --git a/src/main/java/net/minecraft/server/IBlockState.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/IBlockState.java +++ b/src/main/java/net/minecraft/server/IBlockState.java -@@ -0,0 +0,0 @@ public abstract class IBlockState> { - return DataResult.error("Unable to read property: " + this + " with value: " + s1); - }); - }, this::a); -- this.e = this.d.xmap(this::b, IBlockState.a::b); -+ this.e = this.d.xmap(this::b, (IBlockState.a param) -> { return param.b(); }); // Paper - decompile fix - this.a = oclass; - this.b = s; - } @@ -0,0 +0,0 @@ public abstract class IBlockState> { } 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 86b6e5b476..f1f8c6ed2e 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 @@ -10,14 +10,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/BiomeBase.java +++ b/src/main/java/net/minecraft/server/BiomeBase.java @@ -0,0 +0,0 @@ public class BiomeBase { - protected final Map>> r; - protected final List> s = Lists.newArrayList(); - 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(() -> { + this.r.put(worldgenstage_decoration, Lists.newArrayList()); + } + +- this.v = Maps.newHashMap(); ++ this.v = Maps.newEnumMap(EnumCreatureType.class); // Paper + EnumCreatureType[] aenumcreaturetype = EnumCreatureType.values(); + + i = aenumcreaturetype.length; @@ -0,0 +0,0 @@ public class BiomeBase { for (j = 0; j < i; ++j) { EnumCreatureType enumcreaturetype = aenumcreaturetype[j]; @@ -27,6 +27,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } else { +@@ -0,0 +0,0 @@ public class BiomeBase { + this.u = (Map) list.stream().collect(Collectors.toMap((structurefeature) -> { + return structurefeature.b; + }, Function.identity())); +- this.v = map2; ++ this.v = Maps.newEnumMap(EnumCreatureType.class); this.v.putAll(map2); // Paper + this.x = list1; + this.l = (String) optional.orElse(null); // Paper - decompile fix + Stream stream = map1.values().stream().flatMap(Collection::stream).filter((worldgenfeatureconfigured) -> { @@ -0,0 +0,0 @@ public class BiomeBase { return this.l; } diff --git a/Spigot-Server-Patches/Optimize-CraftBlockData-Creation.patch b/Spigot-Server-Patches/Optimize-CraftBlockData-Creation.patch new file mode 100644 index 0000000000..d8e1cc58b6 --- /dev/null +++ b/Spigot-Server-Patches/Optimize-CraftBlockData-Creation.patch @@ -0,0 +1,49 @@ +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/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 { + this.o = blockbase_info.t; + this.p = blockbase_info.u; + } ++ // Paper start - impl cached craft block data, lazy load to fix issue with loading at the wrong time ++ private org.bukkit.craftbukkit.block.data.CraftBlockData cachedCraftBlockData; ++ ++ public org.bukkit.craftbukkit.block.data.CraftBlockData createCraftBlockData() { ++ if (cachedCraftBlockData == null) cachedCraftBlockData = org.bukkit.craftbukkit.block.data.CraftBlockData.createData(getBlockData()); ++ return (org.bukkit.craftbukkit.block.data.CraftBlockData) cachedCraftBlockData.clone(); ++ } ++ // Paper end + + public void a() { + if (!this.getBlock().o()) { +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 10a915a758..28eda373bd 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 @@ -309,6 +309,13 @@ diff --git a/src/main/java/net/minecraft/server/Packet.java b/src/main/java/net/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/Packet.java +++ b/src/main/java/net/minecraft/server/Packet.java +@@ -0,0 +0,0 @@ + package net.minecraft.server; + ++import io.netty.channel.ChannelFuture; // Paper + import java.io.IOException; + + public interface Packet { @@ -0,0 +0,0 @@ public interface Packet { void a(T t0); @@ -323,7 +330,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * @param player Null if not at PLAY stage yet + * @param future Can be null if packet was cancelled + */ -+ default void onPacketDispatchFinish(@javax.annotation.Nullable EntityPlayer player, @javax.annotation.Nullable io.netty.channel.ChannelFuture future) {} ++ default void onPacketDispatchFinish(@javax.annotation.Nullable EntityPlayer player, @javax.annotation.Nullable ChannelFuture future) {} + default boolean hasFinishListener() { return false; } + default boolean isReady() { return true; } + default java.util.List getExtraPackets() { return null; } diff --git a/Spigot-Server-Patches/Optimize-NibbleArray-to-use-pooled-buffers.patch b/Spigot-Server-Patches/Optimize-NibbleArray-to-use-pooled-buffers.patch index b3b2dca4eb..37d0fc4e1d 100644 --- a/Spigot-Server-Patches/Optimize-NibbleArray-to-use-pooled-buffers.patch +++ b/Spigot-Server-Patches/Optimize-NibbleArray-to-use-pooled-buffers.patch @@ -250,6 +250,15 @@ diff --git a/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java b/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java +@@ -0,0 +0,0 @@ + package net.minecraft.server; + + import com.google.common.collect.Lists; ++import io.netty.channel.ChannelFuture; // Paper ++ + import java.io.IOException; + import java.util.Iterator; + import java.util.List; @@ -0,0 +0,0 @@ public class PacketPlayOutLightUpdate implements Packet { private List h; private boolean i; @@ -265,7 +274,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ public void onPacketDispatchFinish(EntityPlayer player, io.netty.channel.ChannelFuture future) { ++ public void onPacketDispatchFinish(EntityPlayer player, ChannelFuture future) { + if (remainingSends.decrementAndGet() <= 0) { + // incase of any race conditions, schedule this delayed + MCUtil.scheduleTask(5, () -> { diff --git a/Spigot-Server-Patches/Optimize-Server-World-Map.patch b/Spigot-Server-Patches/Optimize-Server-World-Map.patch deleted file mode 100644 index 9a52f6dc4e..0000000000 --- a/Spigot-Server-Patches/Optimize-Server-World-Map.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Mon, 17 Sep 2018 23:37:31 -0400 -Subject: [PATCH] Optimize Server World Map - -Minecraft moved worlds to a hashmap in 1.13.1. -This creates inconsistent order for iteration of the map. - -This patch restores World management to be back as an Array. - -.values() will allow us to iterate as it was pre 1.13.1 by -ArrayList, giving consistent ordering and effecient iteration performance. - -KeySet and EntrySet iteration is proxied to the List iterator, -and should retain manipulation behavior but nothing should be doing that. - -Getting a World by dimension ID is now back a constant time operation. - -Hopefully no other plugins try to mess with this map, as we are only handling -known NMS used methods, but we can add more if naughty plugins are found later. - -diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldMap.java b/src/main/java/com/destroystokyo/paper/PaperWorldMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/PaperWorldMap.java -@@ -0,0 +0,0 @@ -+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; -+import java.util.AbstractSet; -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.HashMap; -+import java.util.Iterator; -+import java.util.List; -+import java.util.Map; -+import java.util.Set; -+ -+public class PaperWorldMap extends HashMap, WorldServer> { -+ private final List worlds = new ArrayList<>(); -+ private final List worldsIterable = new ArrayList() { -+ @Override -+ public Iterator iterator() { -+ Iterator iterator = super.iterator(); -+ return new Iterator() { -+ private WorldServer last; -+ -+ @Override -+ public boolean hasNext() { -+ return iterator.hasNext(); -+ } -+ -+ @Override -+ public WorldServer next() { -+ this.last = iterator.next(); -+ return last; -+ } -+ -+ @Override -+ public void remove() { -+ worlds.set(last.worldProvider.getDimensionManager().getDimensionID() + 1, null); -+ } -+ }; -+ } -+ }; -+ @Override -+ public int size() { -+ return worldsIterable.size(); -+ } -+ -+ @Override -+ public boolean isEmpty() { -+ return worldsIterable.isEmpty(); -+ } -+ -+ @Override -+ public WorldServer get(Object key) { -+ // Will hit the below method -+ return key instanceof ResourceKey ? get((ResourceKey) key) : null; -+ } -+ // 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; -+ } -+ -+ @Override -+ public boolean containsKey(Object key) { -+ // will hit below method -+ return key instanceof DimensionManager && containsKey((DimensionManager) key); -+ } -+ public boolean containsKey(DimensionManager key) { -+ return get(key) != null; -+ } -+ -+ @Override -+ public WorldServer put(ResourceKey key, WorldServer value) { -+ while (worlds.size() <= key.getDimensionID()+1) { -+ worlds.add(null); -+ } -+ WorldServer old = worlds.set(key.getDimensionID()+1, value); -+ if (old != null) { -+ worldsIterable.remove(old); -+ } -+ worldsIterable.add(value); -+ return old; -+ } -+ -+ @Override -+ public void putAll(Map, ? extends WorldServer> m) { -+ for (Entry, ? extends WorldServer> e : m.entrySet()) { -+ put(e.getKey(), e.getValue()); -+ } -+ } -+ -+ @Override -+ public WorldServer remove(Object key) { -+ return key instanceof DimensionManager ? remove((DimensionManager) key) : null; -+ } -+ -+ public WorldServer remove(DimensionManager key) { -+ WorldServer old; -+ if (key.getDimensionID()+1 == worlds.size() - 1) { -+ old = worlds.remove(key.getDimensionID()+1); -+ } else { -+ old = worlds.set(key.getDimensionID() + 1, null); -+ } -+ if (old != null) { -+ worldsIterable.remove(old); -+ } -+ return old; -+ } -+ -+ @Override -+ public void clear() { -+ throw new RuntimeException("What the hell are you doing?"); -+ } -+ -+ @Override -+ public boolean containsValue(Object value) { -+ return value instanceof WorldServer && get(((WorldServer) value).getDimensionKey()) != null; -+ } -+ -+ @Nonnull -+ @Override -+ public Set> keySet() { -+ return new AbstractSet>() { -+ @Override -+ public Iterator> iterator() { -+ Iterator iterator = worldsIterable.iterator(); -+ return new Iterator>() { -+ -+ @Override -+ public boolean hasNext() { -+ return iterator.hasNext(); -+ } -+ -+ @Override -+ public ResourceKey next() { -+ return iterator.next().getDimensionKey(); -+ } -+ -+ @Override -+ public void remove() { -+ iterator.remove(); -+ } -+ }; -+ } -+ -+ @Override -+ public int size() { -+ return worlds.size(); -+ } -+ }; -+ } -+ -+ @Override -+ public Collection values() { -+ return worldsIterable; -+ } -+ -+ @Override -+ public Set, WorldServer>> entrySet() { -+ return new AbstractSet, WorldServer>>() { -+ @Override -+ public Iterator, WorldServer>> iterator() { -+ Iterator iterator = worldsIterable.iterator(); -+ return new Iterator, WorldServer>>() { -+ -+ @Override -+ public boolean hasNext() { -+ return iterator.hasNext(); -+ } -+ -+ @Override -+ public Entry, WorldServer> next() { -+ WorldServer entry = iterator.next(); -+ return new SimpleEntry<>(entry.getDimensionKey(), entry); -+ } -+ -+ @Override -+ public void remove() { -+ iterator.remove(); -+ } -+ }; -+ } -+ -+ @Override -+ public int size() { -+ return worldsIterable.size(); -+ } -+ }; -+ } -+} -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, WorldServer> worldServer; -+ public final Map, WorldServer> worldServer = new com.destroystokyo.paper.PaperWorldMap(); // Paper; - private PlayerList playerList; - 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(), 0)); + net.minecraft.server.MinecraftServer.getServer().getPlayerList().updateClient(handle); diff --git a/Spigot-Server-Patches/Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch b/Spigot-Server-Patches/Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch index ce6f87f910..e53354a27f 100644 --- a/Spigot-Server-Patches/Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch +++ b/Spigot-Server-Patches/Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch @@ -128,7 +128,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private java.lang.ref.WeakReference currentChunk = null; + public Chunk getCurrentChunk() { + final Chunk chunk = currentChunk != null ? currentChunk.get() : null; -+ return chunk != null && chunk.isLoaded() ? chunk : null; ++ return chunk != null && chunk.loaded ? chunk : null; + } + public void setCurrentChunk(Chunk chunk) { + this.currentChunk = chunk != null ? new java.lang.ref.WeakReference<>(chunk) : null; diff --git a/Spigot-Server-Patches/Timings-v2.patch b/Spigot-Server-Patches/Timings-v2.patch index fe546d753f..9eaceba285 100644 --- a/Spigot-Server-Patches/Timings-v2.patch +++ b/Spigot-Server-Patches/Timings-v2.patch @@ -608,7 +608,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public final Timing miscMobSpawning; + + public WorldTimingsHandler(World server) { -+ String name = server.worldData.getName() +" - "; ++ String name = server.getWorld().getName() +" - "; + + mobSpawn = Timings.ofSafe(name + "mobSpawn"); + doChunkUnload = Timings.ofSafe(name + "doChunkUnload"); @@ -663,7 +663,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + public static Timing getTickList(WorldServer worldserver, String timingsType) { -+ return Timings.ofSafe(worldserver.getWorldData().getName() + " - Scheduled " + timingsType); ++ return Timings.ofSafe(worldserver.getWorld().getName() + " - Scheduled " + timingsType); + } +} diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java @@ -678,6 +678,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 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; @@ -1687,7 +1688,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 org.spigotmc.ActivationRange.activateEntities(this); // Spigot timings.entityTick.startTiming(); // Spigot -+ TimingHistory.entityTicks += this.globalEntityList.size(); // Paper ++ TimingHistory.entityTicks += this.entitiesById.size(); // Paper while (objectiterator.hasNext()) { Entry entry = (Entry) objectiterator.next(); Entity entity = (Entity) entry.getValue(); diff --git a/Spigot-Server-Patches/Turtle-API.patch b/Spigot-Server-Patches/Turtle-API.patch index c33badcdf0..f678048f06 100644 --- a/Spigot-Server-Patches/Turtle-API.patch +++ b/Spigot-Server-Patches/Turtle-API.patch @@ -23,6 +23,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return (BlockPosition) this.datawatcher.get(EntityTurtle.bw); } @@ -0,0 +0,0 @@ public class EntityTurtle extends EntityAnimal { + return (Boolean) this.datawatcher.get(EntityTurtle.bx); + } + +- private void setHasEgg(boolean flag) { ++ public void setHasEgg(boolean flag) { // Paper this.datawatcher.set(EntityTurtle.bx, flag); } diff --git a/Spigot-Server-Patches/Use-distance-map-to-optimise-entity-tracker.patch b/Spigot-Server-Patches/Use-distance-map-to-optimise-entity-tracker.patch index 15817fc888..2a7b598adc 100644 --- a/Spigot-Server-Patches/Use-distance-map-to-optimise-entity-tracker.patch +++ b/Spigot-Server-Patches/Use-distance-map-to-optimise-entity-tracker.patch @@ -51,7 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } -+ public final int applyTrackingRangeScale(int value) { return this.b(i); } // Paper - OBFHELPER ++ public final int applyTrackingRangeScale(int value) { return this.b(value); } // Paper - OBFHELPER public int b(int i) { return i; } diff --git a/Spigot-Server-Patches/Use-getChunkIfLoadedImmediately-in-places.patch b/Spigot-Server-Patches/Use-getChunkIfLoadedImmediately-in-places.patch index 553fb38569..37c99acefa 100644 --- a/Spigot-Server-Patches/Use-getChunkIfLoadedImmediately-in-places.patch +++ b/Spigot-Server-Patches/Use-getChunkIfLoadedImmediately-in-places.patch @@ -71,7 +71,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { } - public Chunk getChunkIfLoaded(int x, int z) { + @Override public Chunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI - return this.chunkProvider.getChunkAt(x, z, false); + return this.chunkProvider.getChunkAtIfLoadedImmediately(x, z); // Paper } diff --git a/Spigot-Server-Patches/incremental-chunk-saving.patch b/Spigot-Server-Patches/incremental-chunk-saving.patch index 56e383a305..69b2449d46 100644 --- a/Spigot-Server-Patches/incremental-chunk-saving.patch +++ b/Spigot-Server-Patches/incremental-chunk-saving.patch @@ -90,11 +90,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start + for (WorldServer world : getWorlds()) { + if (world.paperConfig.autoSavePeriod > 0) { -+ try { -+ world.saveIncrementally(serverAutoSave); -+ } catch (ExceptionWorldConflict exceptionWorldConflict) { -+ MinecraftServer.LOGGER.warn(exceptionWorldConflict.getMessage()); -+ } ++ world.saveIncrementally(serverAutoSave); + } + } + // Paper end