From 872f10bf7b9d250166cc298dc448fa46f232182e Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 24 Jun 2020 04:38:17 -0400 Subject: [PATCH 01/91] Initial prep for 1.16 Remove patcehs we know need to go add comment on one im not sure should be dropped go ahead and fix patched repos to turn off gpg signing, as this helps rebase/apply --continue commands not suck. Go ahead and prep the pom file change --- Spigot-API-Patches/POM-changes.patch | 2 +- Spigot-Server-Patches/Fix-MC-161754.patch | 2 +- ...ro-tick-instant-grow-farms-MC-113809.patch | 96 --------- Spigot-Server-Patches/POM-Changes.patch | 4 +- ...-Villager-AI-optimizations-DROP-1.16.patch | 195 ------------------ scripts/applyPatches.sh | 1 + 6 files changed, 5 insertions(+), 295 deletions(-) delete mode 100644 Spigot-Server-Patches/Fix-zero-tick-instant-grow-farms-MC-113809.patch delete mode 100644 Spigot-Server-Patches/Port-20w15a-Villager-AI-optimizations-DROP-1.16.patch diff --git a/Spigot-API-Patches/POM-changes.patch b/Spigot-API-Patches/POM-changes.patch index db82c76e90..949639be87 100644 --- a/Spigot-API-Patches/POM-changes.patch +++ b/Spigot-API-Patches/POM-changes.patch @@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - spigot-api + com.destroystokyo.paper + paper-api - 1.15.2-R0.1-SNAPSHOT + 1.16-R0.1-SNAPSHOT jar - Spigot-API diff --git a/Spigot-Server-Patches/Fix-MC-161754.patch b/Spigot-Server-Patches/Fix-MC-161754.patch index ecb8057b72..b27cbf5962 100644 --- a/Spigot-Server-Patches/Fix-MC-161754.patch +++ b/Spigot-Server-Patches/Fix-MC-161754.patch @@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public boolean canUse(EntityHuman entityhuman) { - return this.c.a(entityhuman) && this.d.isAlive() && this.d.g((Entity) entityhuman) < 8.0F; -+ return this.c.a(entityhuman) && (this.d.isAlive() && this.d.valid) && this.d.g((Entity) entityhuman) < 8.0F; // Paper - Fix MC-161754 ++ return this.c.a(entityhuman) && (this.d.isAlive() && this.d.valid) && this.d.g((Entity) entityhuman) < 8.0F; // Paper - Fix MC-161754 - evaluate we might still want this in 1.16 as im not confident mojang fixed this, and made it worse } @Override diff --git a/Spigot-Server-Patches/Fix-zero-tick-instant-grow-farms-MC-113809.patch b/Spigot-Server-Patches/Fix-zero-tick-instant-grow-farms-MC-113809.patch deleted file mode 100644 index f2340f049c..0000000000 --- a/Spigot-Server-Patches/Fix-zero-tick-instant-grow-farms-MC-113809.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Phoenix616 -Date: Sun, 15 Sep 2019 11:32:32 -0500 -Subject: [PATCH] Fix zero-tick instant grow farms MC-113809 - - -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 { - disableRelativeProjectileVelocity = getBoolean("game-mechanics.disable-relative-projectile-velocity", false); - } - -+ public boolean fixZeroTickInstantGrowFarms = true; -+ private void fixZeroTickInstantGrowFarms() { -+ fixZeroTickInstantGrowFarms = getBoolean("fix-zero-tick-instant-grow-farms", fixZeroTickInstantGrowFarms); -+ } -+ - public boolean altItemDespawnRateEnabled; - public Map altItemDespawnRateMap; - private void altItemDespawnRate() { -diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java -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 { - private final float g; - protected final BlockStateList blockStateList; - private IBlockData blockData; -+ public boolean randomTick = false; // Paper - fix MC-113809 - protected final boolean v; - private final boolean i; - private final boolean j; -diff --git a/src/main/java/net/minecraft/server/BlockBamboo.java b/src/main/java/net/minecraft/server/BlockBamboo.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BlockBamboo.java -+++ b/src/main/java/net/minecraft/server/BlockBamboo.java -@@ -0,0 +0,0 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { - if (!iblockdata.canPlace(worldserver, blockposition)) { - worldserver.b(blockposition, true); - } else if ((Integer) iblockdata.get(BlockBamboo.f) == 0) { -+ if (worldserver.paperConfig.fixZeroTickInstantGrowFarms && !randomTick) return; // Paper - fix MC-113809 - if (random.nextInt(Math.max(1, (int) (100.0F / worldserver.spigotConfig.bambooModifier) * 3)) == 0 && worldserver.isEmpty(blockposition.up()) && worldserver.getLightLevel(blockposition.up(), 0) >= 9) { // Spigot - int i = this.b(worldserver, blockposition) + 1; - -diff --git a/src/main/java/net/minecraft/server/BlockCactus.java b/src/main/java/net/minecraft/server/BlockCactus.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BlockCactus.java -+++ b/src/main/java/net/minecraft/server/BlockCactus.java -@@ -0,0 +0,0 @@ public class BlockCactus extends Block { - if (!iblockdata.canPlace(worldserver, blockposition)) { - worldserver.b(blockposition, true); - } else { -+ if (worldserver.paperConfig.fixZeroTickInstantGrowFarms && !randomTick) return; // Paper - fix MC-113809 - BlockPosition blockposition1 = blockposition.up(); - - if (worldserver.isEmpty(blockposition1)) { -diff --git a/src/main/java/net/minecraft/server/BlockChorusFlower.java b/src/main/java/net/minecraft/server/BlockChorusFlower.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BlockChorusFlower.java -+++ b/src/main/java/net/minecraft/server/BlockChorusFlower.java -@@ -0,0 +0,0 @@ public class BlockChorusFlower extends Block { - if (!iblockdata.canPlace(worldserver, blockposition)) { - worldserver.b(blockposition, true); - } else { -+ if (worldserver.paperConfig.fixZeroTickInstantGrowFarms && !randomTick) return; // Paper - fix MC-113809 - BlockPosition blockposition1 = blockposition.up(); - - if (worldserver.isEmpty(blockposition1) && blockposition1.getY() < 256) { -diff --git a/src/main/java/net/minecraft/server/BlockReed.java b/src/main/java/net/minecraft/server/BlockReed.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BlockReed.java -+++ b/src/main/java/net/minecraft/server/BlockReed.java -@@ -0,0 +0,0 @@ public class BlockReed extends Block { - if (!iblockdata.canPlace(worldserver, blockposition)) { - worldserver.b(blockposition, true); - } else if (worldserver.isEmpty(blockposition.up())) { -+ if (worldserver.paperConfig.fixZeroTickInstantGrowFarms && !randomTick) return; // Paper - fix MC-113809 - int i; - - for (i = 1; worldserver.getType(blockposition.down(i)).getBlock() == this; ++i) { -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 { - IBlockData iblockdata = chunksection.getType(blockposition2.getX() - j, blockposition2.getY() - j1, blockposition2.getZ() - k); - - if (iblockdata.q()) { -+ iblockdata.getBlock().randomTick = true; // Paper - fix MC-113809 - iblockdata.b(this, blockposition2, this.random); -+ iblockdata.getBlock().randomTick = false; // Paper - fix MC-113809 - } - - Fluid fluid = iblockdata.getFluid(); diff --git a/Spigot-Server-Patches/POM-Changes.patch b/Spigot-Server-Patches/POM-Changes.patch index 28508323ff..c7beadb737 100644 --- a/Spigot-Server-Patches/POM-Changes.patch +++ b/Spigot-Server-Patches/POM-Changes.patch @@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - spigot + paper jar - 1.15.2-R0.1-SNAPSHOT + 1.16-R0.1-SNAPSHOT - Spigot - https://www.spigotmc.org/ + Paper @@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + UTF-8 unknown - 1.15.2 + 1.16 @@ -0,0 +0,0 @@ diff --git a/Spigot-Server-Patches/Port-20w15a-Villager-AI-optimizations-DROP-1.16.patch b/Spigot-Server-Patches/Port-20w15a-Villager-AI-optimizations-DROP-1.16.patch deleted file mode 100644 index ec3c0d962e..0000000000 --- a/Spigot-Server-Patches/Port-20w15a-Villager-AI-optimizations-DROP-1.16.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Callahan -Date: Wed, 8 Apr 2020 18:00:17 -0500 -Subject: [PATCH] Port 20w15a Villager AI optimizations - DROP 1.16 - - -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 implements MinecraftSeri - this.g = Sets.newHashSet(); - this.h = Activity.IDLE; - this.i = -9999L; -- collection.forEach((memorymoduletype) -> { -- Optional optional = (Optional) this.memories.put(memorymoduletype, Optional.empty()); -- }); -- collection1.forEach((sensortype) -> { -- Sensor sensor = (Sensor) this.sensors.put(sensortype, sensortype.a()); -- }); -- this.sensors.values().forEach((sensor) -> { -- Iterator iterator = sensor.a().iterator(); -- -- while (iterator.hasNext()) { -- MemoryModuleType memorymoduletype = (MemoryModuleType) iterator.next(); -- -- this.memories.put(memorymoduletype, Optional.empty()); -+ // Paper start - Port 20w15a pathfinder optimizations -+ for (final MemoryModuleType memoryModuleType : collection) { -+ this.memories.put(memoryModuleType, Optional.empty()); -+ } -+ for (final SensorType> sensorType : collection1) { -+ this.sensors.put(sensorType, sensorType.a()); -+ } -+ for (final Sensor sensor : this.sensors.values()) { -+ for (final MemoryModuleType memoryModuleType : sensor.a()) { -+ this.memories.put(memoryModuleType, Optional.empty()); - } -- -- }); -- Iterator iterator = dynamic.get("memories").asMap(Function.identity(), Function.identity()).entrySet().iterator(); -- -- while (iterator.hasNext()) { -- Entry, Dynamic> entry = (Entry) iterator.next(); -- -- this.a((MemoryModuleType) IRegistry.MEMORY_MODULE_TYPE.get(new MinecraftKey(((Dynamic) entry.getKey()).asString(""))), (Dynamic) entry.getValue()); - } -- -+ for (final Map.Entry, Dynamic> entry : dynamic.get("memories").asMap(Function.identity(), Function.identity()).entrySet()) { -+ this.a((MemoryModuleType) IRegistry.MEMORY_MODULE_TYPE.get(new MinecraftKey((entry.getKey()).asString(""))), entry.getValue()); -+ } -+ // Paper end - Port 20w15a pathfinder optimizations - } - - public boolean hasMemory(MemoryModuleType memorymoduletype) { -@@ -0,0 +0,0 @@ public class BehaviorController implements MinecraftSeri - } - - private void a(MemoryModuleType memorymoduletype, Dynamic dynamic) { -- this.setMemory(memorymoduletype, ((Function) memorymoduletype.getSerializer().orElseThrow(RuntimeException::new)).apply(dynamic)); -+ this.setMemory(memorymoduletype, (memorymoduletype.getSerializer().orElseThrow(RuntimeException::new)).apply(dynamic)); // Paper - decompile fix - } - - public void removeMemory(MemoryModuleType memorymoduletype) { -@@ -0,0 +0,0 @@ public class BehaviorController implements MinecraftSeri - this.f = set; - } - -+ // Paper start - Port 20w15a pathfinder optimizations - @Deprecated -- public Stream> d() { -- return this.c.values().stream().flatMap((map) -> { -- return map.values().stream(); -- }).flatMap(Collection::stream).filter((behavior) -> { -- return behavior.a() == Behavior.Status.RUNNING; -- }); -+ public java.util.List> d() { -+ final java.util.List> behaviorList = (java.util.List>) new it.unimi.dsi.fastutil.objects.ObjectArrayList(); -+ for (final Map>> map : this.c.values()) { -+ for (final Set> set : map.values()) { -+ for (final Behavior behavior : set) { -+ if (behavior.a() == Behavior.Status.RUNNING) { -+ behaviorList.add(behavior); -+ } -+ } -+ } -+ } -+ return behaviorList; -+ // Paper end - Port 20w15a pathfinder optimizations - } - - public void a(Activity activity) { -@@ -0,0 +0,0 @@ public class BehaviorController implements MinecraftSeri - - public BehaviorController f() { - BehaviorController behaviorcontroller = new BehaviorController<>(this.memories.keySet(), this.sensors.keySet(), new Dynamic(DynamicOpsNBT.a, new NBTTagCompound())); -- -- this.memories.forEach((memorymoduletype, optional) -> { -- optional.ifPresent((object) -> { -- Optional optional1 = (Optional) behaviorcontroller.memories.put(memorymoduletype, Optional.of(object)); -- }); -- }); -+ // Paper start - Port 20w15a pathfinder optimizations -+ for (final Entry, Optional> entry : this.memories.entrySet()) { -+ final MemoryModuleType memoryModuleType = entry.getKey(); -+ if (entry.getValue().isPresent()) { -+ behaviorcontroller.memories.put(memoryModuleType, entry.getValue()); -+ } -+ } -+ // Paper end - Port 20w15a pathfinder optimizations - return behaviorcontroller; - } - -@@ -0,0 +0,0 @@ public class BehaviorController implements MinecraftSeri - public void b(WorldServer worldserver, E e0) { - long i = e0.world.getTime(); - -- this.d().forEach((behavior) -> { -+ for(Behavior behavior : this.d()) { // Paper - Port 20w15a pathfinder optimizations - behavior.e(worldserver, e0, i); -- }); -+ } - } - - @Override - public T a(DynamicOps dynamicops) { -- T t0 = dynamicops.createMap((Map) this.memories.entrySet().stream().filter((entry) -> { -+ T t0 = dynamicops.createMap(this.memories.entrySet().stream().filter((entry) -> { // Paper - decompile fix - return ((MemoryModuleType) entry.getKey()).getSerializer().isPresent() && ((Optional) entry.getValue()).isPresent(); - }).map((entry) -> { - return Pair.of(dynamicops.createString(IRegistry.MEMORY_MODULE_TYPE.getKey(entry.getKey()).toString()), ((MinecraftSerializable) ((Optional) entry.getValue()).get()).a(dynamicops)); -@@ -0,0 +0,0 @@ public class BehaviorController implements MinecraftSeri - - private void d(WorldServer worldserver, E e0) { - long i = worldserver.getTime(); -- -- this.c.values().stream().flatMap((map) -> { -- return map.entrySet().stream(); -- }).filter((entry) -> { -- return this.g.contains(entry.getKey()); -- }).map(Entry::getValue).flatMap(Collection::stream).filter((behavior) -> { -- return behavior.a() == Behavior.Status.STOPPED; -- }).forEach((behavior) -> { -- behavior.b(worldserver, e0, i); -- }); -+ // Paper start - Port 20w15a pathfinder optimizations -+ for (final Map>> map : this.c.values()) { -+ for (final Map.Entry>> entry : map.entrySet()) { -+ final Activity activity = entry.getKey(); -+ if (this.g.contains(activity)) { -+ final Set> set = entry.getValue(); -+ for (final Behavior behavior : set) { -+ if (behavior.a() == Behavior.Status.STOPPED) { -+ behavior.b(worldserver, e0, i); -+ } -+ } -+ } -+ } -+ } -+ // Paper end - Port 20w15a pathfinder optimizations - } - - private void e(WorldServer worldserver, E e0) { - long i = worldserver.getTime(); - -- this.d().forEach((behavior) -> { -+ for (final Behavior behavior : this.d()) { // Paper - Port 20w15a pathfinder optimizations - behavior.c(worldserver, e0, i); -- }); -+ } - } - - private boolean d(Activity activity) { -- return ((Set) this.e.get(activity)).stream().allMatch((pair) -> { -- MemoryModuleType memorymoduletype = (MemoryModuleType) pair.getFirst(); -- MemoryStatus memorystatus = (MemoryStatus) pair.getSecond(); -- -- return this.a(memorymoduletype, memorystatus); -- }); -+ // Paper start - Port 20w15a pathfinder optimizations -+ if (!this.e.containsKey(activity)) { -+ return false; -+ } -+ for (final Pair, MemoryStatus> pair : this.e.get(activity)) { -+ MemoryModuleType memorymoduletype = pair.getFirst(); -+ MemoryStatus memorystatus = pair.getSecond(); -+ if (!this.a(memorymoduletype, memorystatus)) { -+ return false; -+ } -+ } -+ return true; -+ // Paper end - Port 20w15a pathfinder optimizations - } - - private boolean a(Object object) { diff --git a/scripts/applyPatches.sh b/scripts/applyPatches.sh index e4c073fda2..e700fde80b 100755 --- a/scripts/applyPatches.sh +++ b/scripts/applyPatches.sh @@ -39,6 +39,7 @@ function applyPatch { statusfile=".git/patch-apply-failed" rm -f "$statusfile" + git config commit.gpgsign false $gitcmd am --abort >/dev/null 2>&1 # Special case Windows handling because of ARG_MAX constraint From e212d4bb1910adf1efd0be1eab9b206439754187 Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 24 Jun 2020 21:10:30 -0400 Subject: [PATCH 02/91] 1.16.1 prep --- Spigot-API-Patches/POM-changes.patch | 2 +- .../Asynchronous-chunk-IO-and-loading.patch | 2 +- Spigot-Server-Patches/Fix-MC-161754.patch | 2 +- Spigot-Server-Patches/Fix-MC-93764.patch | 19 -------- Spigot-Server-Patches/MC-Dev-fixes.patch | 45 ------------------- Spigot-Server-Patches/MC-Utils.patch | 4 +- ...ptimise-BlockState-s-hashCode-equals.patch | 18 ++++---- Spigot-Server-Patches/POM-Changes.patch | 4 +- scripts/rebuildPatches.sh | 2 +- work/BuildData | 2 +- work/Bukkit | 2 +- work/CraftBukkit | 2 +- work/Spigot | 2 +- 13 files changed, 21 insertions(+), 85 deletions(-) delete mode 100644 Spigot-Server-Patches/Fix-MC-93764.patch diff --git a/Spigot-API-Patches/POM-changes.patch b/Spigot-API-Patches/POM-changes.patch index 949639be87..db82c76e90 100644 --- a/Spigot-API-Patches/POM-changes.patch +++ b/Spigot-API-Patches/POM-changes.patch @@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - spigot-api + com.destroystokyo.paper + paper-api - 1.16-R0.1-SNAPSHOT + 1.15.2-R0.1-SNAPSHOT jar - Spigot-API diff --git a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch index 4d47d44ba3..da0da43621 100644 --- a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch @@ -4083,7 +4083,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // we do this so we do not re-read the chunk data on disk @@ -0,0 +0,0 @@ public class CraftWorld implements World { - return new CraftDragonBattle(((WorldProviderTheEnd) worldProvider).o()); // PAIL rename getDragonBattle + return new CraftDragonBattle(worldProvider.o()); // PAIL rename getDragonBattle } + // Paper start + @Override diff --git a/Spigot-Server-Patches/Fix-MC-161754.patch b/Spigot-Server-Patches/Fix-MC-161754.patch index b27cbf5962..ecb8057b72 100644 --- a/Spigot-Server-Patches/Fix-MC-161754.patch +++ b/Spigot-Server-Patches/Fix-MC-161754.patch @@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public boolean canUse(EntityHuman entityhuman) { - return this.c.a(entityhuman) && this.d.isAlive() && this.d.g((Entity) entityhuman) < 8.0F; -+ return this.c.a(entityhuman) && (this.d.isAlive() && this.d.valid) && this.d.g((Entity) entityhuman) < 8.0F; // Paper - Fix MC-161754 - evaluate we might still want this in 1.16 as im not confident mojang fixed this, and made it worse ++ return this.c.a(entityhuman) && (this.d.isAlive() && this.d.valid) && this.d.g((Entity) entityhuman) < 8.0F; // Paper - Fix MC-161754 } @Override diff --git a/Spigot-Server-Patches/Fix-MC-93764.patch b/Spigot-Server-Patches/Fix-MC-93764.patch deleted file mode 100644 index 41d327bee6..0000000000 --- a/Spigot-Server-Patches/Fix-MC-93764.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: BillyGalbreath -Date: Fri, 19 Oct 2018 19:38:45 -0500 -Subject: [PATCH] Fix MC-93764 - - -diff --git a/src/main/java/net/minecraft/server/WorldProviderTheEnd.java b/src/main/java/net/minecraft/server/WorldProviderTheEnd.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/WorldProviderTheEnd.java -+++ b/src/main/java/net/minecraft/server/WorldProviderTheEnd.java -@@ -0,0 +0,0 @@ public class WorldProviderTheEnd extends WorldProvider { - - @Override - public float a(long i, float f) { -- return 0.0F; -+ return 0.5F; // Paper - fix MC-93764 - } - - @Override diff --git a/Spigot-Server-Patches/MC-Dev-fixes.patch b/Spigot-Server-Patches/MC-Dev-fixes.patch index bd71312095..9cb1d0b91c 100644 --- a/Spigot-Server-Patches/MC-Dev-fixes.patch +++ b/Spigot-Server-Patches/MC-Dev-fixes.patch @@ -84,51 +84,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public List> g() { -diff --git a/src/main/java/net/minecraft/server/BlockDataAbstract.java b/src/main/java/net/minecraft/server/BlockDataAbstract.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BlockDataAbstract.java -+++ b/src/main/java/net/minecraft/server/BlockDataAbstract.java -@@ -0,0 +0,0 @@ public abstract class BlockDataAbstract implements IBlockDataHolder { - } - - private > String a(IBlockState iblockstate, Comparable comparable) { -- return iblockstate.a(comparable); -+ return iblockstate.a((T) comparable); // Paper - decompiler fix - } - }; - protected final O a; -@@ -0,0 +0,0 @@ public abstract class BlockDataAbstract implements IBlockDataHolder { - } - - public > S a(IBlockState iblockstate) { -- return this.set(iblockstate, (Comparable) a(iblockstate.getValues(), this.get(iblockstate))); -+ return this.set(iblockstate, a(iblockstate.getValues(), this.get(iblockstate))); // Paper - decompile fix - } - - protected static T a(Collection collection, T t0) { -- Iterator iterator = collection.iterator(); -+ Iterator iterator = collection.iterator(); // Paper - decompiler fix - - do { - if (!iterator.hasNext()) { -@@ -0,0 +0,0 @@ public abstract class BlockDataAbstract implements IBlockDataHolder { - if (comparable == null) { - throw new IllegalArgumentException("Cannot get property " + iblockstate + " as it does not exist in " + this.a); - } else { -- return (Comparable) iblockstate.b().cast(comparable); -+ return iblockstate.b().cast(comparable); // Paper - decompiler fix - } - } - -@@ -0,0 +0,0 @@ public abstract class BlockDataAbstract implements IBlockDataHolder { - if (comparable == null) { - throw new IllegalArgumentException("Cannot set property " + iblockstate + " as it does not exist in " + this.a); - } else if (comparable == v0) { -- return this; -+ return (S) this; // Paper - decompiler fix - } else { - S s0 = this.e.get(iblockstate, v0); - 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/MC-Utils.patch b/Spigot-Server-Patches/MC-Utils.patch index dc4849eed2..df4974773c 100644 --- a/Spigot-Server-Patches/MC-Utils.patch +++ b/Spigot-Server-Patches/MC-Utils.patch @@ -2318,11 +2318,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public IBlockData getType(BlockPosition blockposition) { return Blocks.AIR.getBlockData(); -diff --git a/src/main/java/net/minecraft/server/BlockDataAbstract.java b/src/main/java/net/minecraft/server/BlockDataAbstract.java +diff --git a/src/main/java/net/minecraft/server/BlockData.java b/src/main/java/net/minecraft/server/BlockData.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockDataAbstract.java +++ b/src/main/java/net/minecraft/server/BlockDataAbstract.java -@@ -0,0 +0,0 @@ public abstract class BlockDataAbstract implements IBlockDataHolder { +@@ -0,0 +0,0 @@ public abstract static class BlockDataAbstract implements IBlockDataHolder { return Collections.unmodifiableCollection(this.d.keySet()); } diff --git a/Spigot-Server-Patches/Optimise-BlockState-s-hashCode-equals.patch b/Spigot-Server-Patches/Optimise-BlockState-s-hashCode-equals.patch index e6b1753a7b..b632c7e2a3 100644 --- a/Spigot-Server-Patches/Optimise-BlockState-s-hashCode-equals.patch +++ b/Spigot-Server-Patches/Optimise-BlockState-s-hashCode-equals.patch @@ -8,20 +8,20 @@ object identity checks safely. Use a simpler optimized hashcode -diff --git a/src/main/java/net/minecraft/server/BlockState.java b/src/main/java/net/minecraft/server/BlockState.java +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/BlockState.java -+++ b/src/main/java/net/minecraft/server/BlockState.java -@@ -0,0 +0,0 @@ public abstract class BlockState> implements IBlockState +--- 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> } public boolean equals(Object object) { - if (this == object) { - return true; -- } else if (!(object instanceof BlockState)) { +- } else if (!(object instanceof IBlockState)) { - return false; - } else { -- BlockState blockstate = (BlockState) object; +- IBlockState blockstate = (IBlockState) object; - - return this.a.equals(blockstate.a) && this.b.equals(blockstate.b); - } @@ -44,7 +44,7 @@ diff --git a/src/main/java/net/minecraft/server/BlockStateBoolean.java b/src/mai index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockStateBoolean.java +++ b/src/main/java/net/minecraft/server/BlockStateBoolean.java -@@ -0,0 +0,0 @@ public class BlockStateBoolean extends BlockState { +@@ -0,0 +0,0 @@ public class BlockStateBoolean extends IBlockState { return obool.toString(); } @@ -58,7 +58,7 @@ diff --git a/src/main/java/net/minecraft/server/BlockStateEnum.java b/src/main/j index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockStateEnum.java +++ b/src/main/java/net/minecraft/server/BlockStateEnum.java -@@ -0,0 +0,0 @@ public class BlockStateEnum & INamable> extends BlockState +@@ -0,0 +0,0 @@ public class BlockStateEnum & INamable> extends IBlockState return ((INamable) t0).getName(); } @@ -72,7 +72,7 @@ diff --git a/src/main/java/net/minecraft/server/BlockStateInteger.java b/src/mai index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockStateInteger.java +++ b/src/main/java/net/minecraft/server/BlockStateInteger.java -@@ -0,0 +0,0 @@ public class BlockStateInteger extends BlockState { +@@ -0,0 +0,0 @@ public class BlockStateInteger extends IBlockState { return this.a; } diff --git a/Spigot-Server-Patches/POM-Changes.patch b/Spigot-Server-Patches/POM-Changes.patch index c7beadb737..28508323ff 100644 --- a/Spigot-Server-Patches/POM-Changes.patch +++ b/Spigot-Server-Patches/POM-Changes.patch @@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - spigot + paper jar - 1.16-R0.1-SNAPSHOT + 1.15.2-R0.1-SNAPSHOT - Spigot - https://www.spigotmc.org/ + Paper @@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + UTF-8 unknown - 1.16 + 1.15.2 @@ -0,0 +0,0 @@ diff --git a/scripts/rebuildPatches.sh b/scripts/rebuildPatches.sh index 7dd38d46fd..df1934b491 100755 --- a/scripts/rebuildPatches.sh +++ b/scripts/rebuildPatches.sh @@ -9,7 +9,7 @@ gitcmd="git -c commit.gpgsign=false -c core.safecrlf=false" echo "Rebuilding patch files from current fork state..." nofilter="0" -if [ "$2" = "nofilter" ]; then +if [ "$2" == "nofilter" ] || [ "$2" == "noclean" ]; then nofilter="1" fi function cleanupPatches { diff --git a/work/BuildData b/work/BuildData index 455d45a424..be3371e674 160000 --- a/work/BuildData +++ b/work/BuildData @@ -1 +1 @@ -Subproject commit 455d45a4244894335cd07451bdda79ccd380aff6 +Subproject commit be3371e67489b5a2293306e24420793106baadc1 diff --git a/work/Bukkit b/work/Bukkit index 149527f7b1..32fcd349d4 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 149527f7b10f992ef22186e85f13ded96ab76a63 +Subproject commit 32fcd349d4074c564116bbeb4b481332460902ee diff --git a/work/CraftBukkit b/work/CraftBukkit index be6aaf046e..2b00831c95 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit be6aaf046eed614b0034ec42d5ef5e6f7de16ff0 +Subproject commit 2b00831c95f8dda096ad22ae88bc615d9dd31ea1 diff --git a/work/Spigot b/work/Spigot index a99063f771..758abbeee4 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit a99063f77142a462546e31413de6c6190e913f11 +Subproject commit 758abbeee4e12f5ff65470999dd9955d0ebb49cd From 1a45fc25f50316927ec6979fc283f3e1729c5635 Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 24 Jun 2020 22:33:35 -0400 Subject: [PATCH 03/91] API update --- Spigot-API-Patches/Add-Material-Tags.patch | 40 +++++++++---------- ...low-plugins-to-use-SLF4J-for-logging.patch | 2 +- Spigot-API-Patches/Fireworks-API-s.patch | 18 ++------- Spigot-API-Patches/POM-changes.patch | 9 +---- Spigot-API-Patches/Potential-bed-API.patch | 33 +++++++++++++-- .../Use-ASM-for-event-executors.patch | 2 +- 6 files changed, 56 insertions(+), 48 deletions(-) diff --git a/Spigot-API-Patches/Add-Material-Tags.patch b/Spigot-API-Patches/Add-Material-Tags.patch index 077cc2fbff..327145a9de 100644 --- a/Spigot-API-Patches/Add-Material-Tags.patch +++ b/Spigot-API-Patches/Add-Material-Tags.patch @@ -313,18 +313,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .ensureSize("DYES", 16); + + /** -+ * Covers all 6 wood variants of gates. ++ * Covers all variants of gates. + */ + public static final MaterialSetTag FENCE_GATES = new MaterialSetTag(keyFor("fence_gates")) + .endsWith("_GATE") -+ .ensureSize("FENCE_GATES", 6); ++ .ensureSize("FENCE_GATES", 8); + + /** -+ * Covers all 6 wood variants and nether brick fence. ++ * Covers all variants of fences. + */ + public static final MaterialSetTag FENCES = new MaterialSetTag(keyFor("fences")) + .endsWith("_FENCE") -+ .ensureSize("FENCES", 7); ++ .ensureSize("FENCES", 9); + + /** + * Covers all 4 variants of fish buckets. @@ -407,18 +407,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .add(Material.BROWN_MUSHROOM, Material.RED_MUSHROOM); + + /** -+ * Covers all 12 music disc items. ++ * Covers all music disc items. + */ + public static final MaterialSetTag MUSIC_DISCS = new MaterialSetTag(keyFor("music_discs")) -+ .startsWith("MUSIC_DISC_") -+ .ensureSize("MUSIC_DISCS", 12); ++ .startsWith("MUSIC_DISC_"); + + /** -+ * Covers all 8 ores. ++ * Covers all ores. + */ + public static final MaterialSetTag ORES = new MaterialSetTag(keyFor("ores")) ++ .add(Material.ANCIENT_DEBRIS) + .endsWith("_ORE") -+ .ensureSize("ORES", 8); ++ .ensureSize("ORES", 10); + + /** + * Covers all piston typed items and blocks including the piston head and moving piston. @@ -435,11 +435,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .ensureSize("POTATOES", 3); + + /** -+ * Covers all 6 wooden pressure plates and the 2 weighted pressure plates and 1 stone pressure plate. ++ * Covers all wooden pressure plates and the weighted pressure plates and 1 stone pressure plate. + */ + public static final MaterialSetTag PRESSURE_PLATES = new MaterialSetTag(keyFor("pressure_plates")) + .endsWith("_PRESSURE_PLATE") -+ .ensureSize("PRESSURE_PLATES", 9); ++ .ensureSize("PRESSURE_PLATES", 12); + + /** + * Covers the 3 variants of prismarine blocks. @@ -518,7 +518,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + */ + public static final MaterialSetTag SPAWN_EGGS = new MaterialSetTag(keyFor("spawn_eggs")) + .endsWith("_SPAWN_EGG") -+ .ensureSize("SPAWN_EGGS", 59); ++ .ensureSize("SPAWN_EGGS", 63); + + /** + * Covers all 16 colors of stained glass. @@ -535,31 +535,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .ensureSize("STAINED_GLASS_PANES", 16); + + /** -+ * Covers all 7 variants of trapdoors. ++ * Covers all variants of trapdoors. + */ + public static final MaterialSetTag TRAPDOORS = new MaterialSetTag(keyFor("trapdoors")) + .endsWith("_TRAPDOOR") -+ .ensureSize("TRAPDOORS", 7); ++ .ensureSize("TRAPDOORS", 9); + + /** -+ * Covers all 6 wood variants of fences. ++ * Covers all wood variants of fences. + */ + public static final MaterialSetTag WOODEN_FENCES = new MaterialSetTag(keyFor("wooden_fences")) + .endsWith("_FENCE") + .not(Material.NETHER_BRICK_FENCE) -+ .ensureSize("WOODEN_FENCES", 6); ++ .ensureSize("WOODEN_FENCES", 8); + + /** -+ * Covers all 6 wood variants of trapdoors. ++ * Covers all wood variants of trapdoors. + */ + public static final MaterialSetTag WOODEN_TRAPDOORS = new MaterialSetTag(keyFor("wooden_trapdoors")) + .endsWith("_TRAPDOOR") + .not(Material.IRON_TRAPDOOR) -+ .ensureSize("WOODEN_TRAPDOORS", 6); ++ .ensureSize("WOODEN_TRAPDOORS", 8); + + public static final MaterialSetTag WOODEN_GATES = new MaterialSetTag(keyFor("wooden_gates")) + .endsWith("_GATE") -+ .ensureSize("WOODEN_GATES", 6); ++ .ensureSize("WOODEN_GATES", 8); + + public static final MaterialSetTag PURPUR = new MaterialSetTag(keyFor("purpur")) + .startsWith("PURPUR_") @@ -567,7 +567,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + public static final MaterialSetTag SIGNS = new MaterialSetTag(keyFor("signs")) + .endsWith("_SIGN") -+ .ensureSize("SIGNS", 12); ++ .ensureSize("SIGNS", 16); + + public static final MaterialSetTag TORCH = new MaterialSetTag(keyFor("torch")) + .add(Material.TORCH, Material.WALL_TORCH) diff --git a/Spigot-API-Patches/Allow-plugins-to-use-SLF4J-for-logging.patch b/Spigot-API-Patches/Allow-plugins-to-use-SLF4J-for-logging.patch index 6cb7c490bb..d73b94e9ce 100644 --- a/Spigot-API-Patches/Allow-plugins-to-use-SLF4J-for-logging.patch +++ b/Spigot-API-Patches/Allow-plugins-to-use-SLF4J-for-logging.patch @@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/pom.xml +++ b/pom.xml @@ -0,0 +0,0 @@ - 18.0.0 + 19.0.0 provided + diff --git a/Spigot-API-Patches/Fireworks-API-s.patch b/Spigot-API-Patches/Fireworks-API-s.patch index 9be2c8750b..13f1350920 100644 --- a/Spigot-API-Patches/Fireworks-API-s.patch +++ b/Spigot-API-Patches/Fireworks-API-s.patch @@ -10,29 +10,19 @@ diff --git a/src/main/java/org/bukkit/entity/Firework.java b/src/main/java/org/b index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/entity/Firework.java +++ b/src/main/java/org/bukkit/entity/Firework.java -@@ -0,0 +0,0 @@ package org.bukkit.entity; - import org.bukkit.inventory.meta.FireworkMeta; - import org.jetbrains.annotations.NotNull; - -+import java.util.UUID; -+import org.jetbrains.annotations.Nullable; -+ - public interface Firework extends Entity { - - /** -@@ -0,0 +0,0 @@ public interface Firework extends Entity { +@@ -0,0 +0,0 @@ public interface Firework extends Projectile { * @param shotAtAngle the new shotAtAngle */ void setShotAtAngle(boolean shotAtAngle); + + // Paper start -+ @Nullable -+ public UUID getSpawningEntity(); ++ @org.jetbrains.annotations.Nullable ++ public java.util.UUID getSpawningEntity(); + /** + * If this firework is boosting an entity, return it + * @return The entity being boosted + */ -+ @Nullable ++ @org.jetbrains.annotations.Nullable + public LivingEntity getBoostedEntity(); + // Paper end } diff --git a/Spigot-API-Patches/POM-changes.patch b/Spigot-API-Patches/POM-changes.patch index db82c76e90..ca290017ed 100644 --- a/Spigot-API-Patches/POM-changes.patch +++ b/Spigot-API-Patches/POM-changes.patch @@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - spigot-api + com.destroystokyo.paper + paper-api - 1.15.2-R0.1-SNAPSHOT + 1.16.1-R0.1-SNAPSHOT jar - Spigot-API @@ -86,13 +86,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 com.google.guava @@ -0,0 +0,0 @@ - - org.ow2.asm - asm-tree -- 7.3.1 -+ 8.0.1 - test - diff --git a/Spigot-API-Patches/Potential-bed-API.patch b/Spigot-API-Patches/Potential-bed-API.patch index 272af16d0f..e6e0b4f696 100644 --- a/Spigot-API-Patches/Potential-bed-API.patch +++ b/Spigot-API-Patches/Potential-bed-API.patch @@ -12,9 +12,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/src/main/java/org/bukkit/entity/HumanEntity.java @@ -0,0 +0,0 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder - @Nullable - public Location getBedSpawnLocation(); + */ + public int getSleepTicks(); ++ /** ++ * Gets the Location where the player will spawn at their bed, null if ++ * they have not slept in one or their current bed spawn is invalid. ++ * ++ * @return Bed Spawn Location if bed exists, otherwise null. ++ */ ++ @Nullable ++ public Location getBedSpawnLocation(); ++ + // Paper start - Potential bed api + /** + * Gets the Location of the player's bed, null if they have not slept @@ -26,7 +35,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Nullable + public Location getPotentialBedLocation(); + // Paper end ++ ++ /** ++ * Sets the Location where the player will spawn at their bed. ++ * ++ * @param location where to set the respawn location ++ */ ++ public void setBedSpawnLocation(@Nullable Location location); ++ ++ /** ++ * Sets the Location where the player will spawn at their bed. ++ * ++ * @param location where to set the respawn location ++ * @param force whether to forcefully set the respawn location even if a ++ * valid bed is not present ++ */ ++ public void setBedSpawnLocation(@Nullable Location location, boolean force); + /** - * Sets the Location where the player will spawn at their bed. - * + * Attempts to make the entity sleep at the given location. + *
diff --git a/Spigot-API-Patches/Use-ASM-for-event-executors.patch b/Spigot-API-Patches/Use-ASM-for-event-executors.patch index 7c5e515953..602d2ebef2 100644 --- a/Spigot-API-Patches/Use-ASM-for-event-executors.patch +++ b/Spigot-API-Patches/Use-ASM-for-event-executors.patch @@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/pom.xml +++ b/pom.xml @@ -0,0 +0,0 @@ - 8.0.1 + 8.0.1 test
+ From 175f83e9d05b20f89db95f9aa13a0096649df5d8 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 25 Jun 2020 00:02:26 -0400 Subject: [PATCH 04/91] Current progress --- Spigot-Server-Patches/POM-Changes.patch | 10 +++---- .../Paper-config-files.patch | 26 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Spigot-Server-Patches/POM-Changes.patch b/Spigot-Server-Patches/POM-Changes.patch index 28508323ff..ee23f17e5b 100644 --- a/Spigot-Server-Patches/POM-Changes.patch +++ b/Spigot-Server-Patches/POM-Changes.patch @@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - spigot + paper jar - 1.15.2-R0.1-SNAPSHOT + 1.16.1-R0.1-SNAPSHOT - Spigot - https://www.spigotmc.org/ + Paper @@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + UTF-8 unknown - 1.15.2 + 1.16.1 @@ -0,0 +0,0 @@ @@ -56,7 +56,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 compile @@ -0,0 +0,0 @@ - 7.3.1 + 8.0.1 compile + @@ -196,12 +196,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class Main { } - if (false && Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) { + if (Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) { - Date buildDate = new Date(Integer.parseInt(Main.class.getPackage().getImplementationVendor()) * 1000L); + Date buildDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(Main.class.getPackage().getImplementationVendor()); // Paper Calendar deadline = Calendar.getInstance(); - deadline.add(Calendar.DAY_OF_YEAR, -21); + deadline.add(Calendar.DAY_OF_YEAR, -3); diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java diff --git a/Spigot-Server-Patches/Paper-config-files.patch b/Spigot-Server-Patches/Paper-config-files.patch index 98a9672e7e..1085b63bac 100644 --- a/Spigot-Server-Patches/Paper-config-files.patch +++ b/Spigot-Server-Patches/Paper-config-files.patch @@ -543,14 +543,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override public boolean a(Entity entity) { long i = ChunkCoordIntPair.pair(MathHelper.floor(entity.locX()) >> 4, MathHelper.floor(entity.locZ()) >> 4); - return this.a(i, PlayerChunk::b); + return this.a(i, (Function>>) PlayerChunk::b); // CraftBukkit - decompile error } - @Override - public boolean a(ChunkCoordIntPair chunkcoordintpair) { + public final boolean isEntityTickingChunk(ChunkCoordIntPair chunkcoordintpair) { return this.a(chunkcoordintpair); } // Paper - OBFHELPER + @Override public boolean a(ChunkCoordIntPair chunkcoordintpair) { - return this.a(chunkcoordintpair.pair(), PlayerChunk::b); + return this.a(chunkcoordintpair.pair(), (Function>>) PlayerChunk::b); // CraftBukkit - decompile error } diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java @@ -558,7 +558,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/DedicatedServer.java @@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer - org.spigotmc.SpigotConfig.init((File) options.valueOf("spigot-settings")); + org.spigotmc.SpigotConfig.init((java.io.File) options.valueOf("spigot-settings")); org.spigotmc.SpigotConfig.registerCommands(); // Spigot end + // Paper start @@ -571,14 +571,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + com.destroystokyo.paper.PaperConfig.registerCommands(); + // Paper end - this.setSpawnAnimals(dedicatedserverproperties.spawnAnimals); - this.setSpawnNPCs(dedicatedserverproperties.spawnNpcs); + this.setPVP(dedicatedserverproperties.pvp); + this.setAllowFlight(dedicatedserverproperties.allowFlight); 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 { - private static final DataWatcherObject aC = DataWatcher.a(Entity.class, DataWatcherRegistry.i); + private static final DataWatcherObject aA = DataWatcher.a(Entity.class, DataWatcherRegistry.i); protected static final DataWatcherObject POSE = DataWatcher.a(Entity.class, DataWatcherRegistry.s); public boolean inChunk; - public int chunkX; @@ -587,23 +587,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public int chunkX; public int getChunkX() { return chunkX; } // Paper - OBFHELPER + public int chunkY; public int getChunkY() { return chunkY; } // Paper - OBFHELPER + public int chunkZ; public int getChunkZ() { return chunkZ; } // Paper - OBFHELPER + private boolean aB; public long Z; public long aa; - public long ab; diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityTypes.java +++ b/src/main/java/net/minecraft/server/EntityTypes.java @@ -0,0 +0,0 @@ package net.minecraft.server; - import com.mojang.datafixers.DataFixUtils; - import java.util.Collections; + + import com.google.common.collect.ImmutableSet; import java.util.Optional; +import java.util.Set; // Paper import java.util.UUID; import java.util.function.Function; import java.util.stream.Stream; @@ -0,0 +0,0 @@ public class EntityTypes { - return new EntityTypes<>(this.a, this.b, this.c, this.d, this.e, this.f, this.g); + return new EntityTypes<>(this.a, this.b, this.d, this.e, this.f, this.g, this.c, this.j, this.h, this.i); } } + @@ -628,8 +628,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private org.spigotmc.TickLimiter entityLimiter; @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - protected World(WorldData worlddata, DimensionManager dimensionmanager, BiFunction bifunction, GameProfilerFiller gameprofilerfiller, boolean flag, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { - this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot + protected World(WorldDataMutable worlddatamutable, ResourceKey resourcekey, ResourceKey resourcekey1, DimensionManager dimensionmanager, Supplier supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { + this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot + this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(worlddata.getName(), this.spigotConfig); // Paper this.generator = gen; this.world = new CraftWorld((WorldServer) this, gen, env); @@ -644,7 +644,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot + com.destroystokyo.paper.PaperConfig.init((File) console.options.valueOf("paper-settings")); // Paper for (WorldServer world : console.getWorlds()) { - world.worldData.setDifficulty(config.difficulty); + world.worldDataServer.setDifficulty(config.difficulty); world.setSpawnFlags(config.spawnMonsters, config.spawnAnimals); @@ -0,0 +0,0 @@ public final class CraftServer implements Server { world.ticksPerAmbientSpawns = this.getTicksPerAmbientSpawns(); From 5287c1ba7c017c9df5896a5409fa815d0dc8cf70 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 25 Jun 2020 05:27:25 -0400 Subject: [PATCH 05/91] Current progress - Leaf, tag your it --- ...-MinecraftKey-Information-to-Objects.patch | 4 +- ...-despawn-distances-for-living-entiti.patch | 15 +- ...d-version-history-to-version-command.patch | 2 +- ...chunks-are-slime-spawn-chunks-toggle.patch | 12 +- ...d-mobs-to-jump-and-take-water-damage.patch | 27 +- .../Basic-PlayerProfile-API.patch | 6 +- ...entation-of-tile-entity-removal-list.patch | 4 +- ...e-before-converting-and-renaming-pla.patch | 4 +- ...figurable-baby-zombie-movement-speed.patch | 20 +- ...ctus-and-reed-natural-growth-heights.patch | 10 +- .../Configurable-end-credits.patch | 16 +- .../Configurable-fishing-time-ranges.patch | 12 +- ...nfigurable-top-of-nether-void-damage.patch | 14 +- .../Disable-explosion-knockback.patch | 13 +- .../Disable-ice-and-snow.patch | 2 +- Spigot-Server-Patches/Disable-thunder.patch | 6 +- ...ck-and-tnt-entities-at-the-specified.patch | 2 +- Spigot-Server-Patches/Entity-Origin-API.patch | 6 +- ...-explosions-processing-dead-entities.patch | 15 +- .../Further-improve-server-tick-loop.patch | 6 +- Spigot-Server-Patches/MC-Dev-fixes.patch | 353 ++++++++---------- Spigot-Server-Patches/MC-Utils.patch | 299 +++++++-------- .../Optimize-explosions.patch | 8 +- .../Player-Tab-List-and-Title-APIs.patch | 6 +- .../Player-affects-spawning-API.patch | 90 ++++- ...sition-the-first-time-an-entity-is-s.patch | 4 +- ...ient-crashes-server-lists-and-Mojang.patch | 4 +- ...to-current-Chunk-for-Entity-and-Bloc.patch | 44 +-- Spigot-Server-Patches/Timings-v2.patch | 246 +++++------- 29 files changed, 585 insertions(+), 665 deletions(-) diff --git a/Spigot-Server-Patches/Add-MinecraftKey-Information-to-Objects.patch b/Spigot-Server-Patches/Add-MinecraftKey-Information-to-Objects.patch index c66c13b883..005f87cf20 100644 --- a/Spigot-Server-Patches/Add-MinecraftKey-Information-to-Objects.patch +++ b/Spigot-Server-Patches/Add-MinecraftKey-Information-to-Objects.patch @@ -63,7 +63,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end } - protected abstract void a(NBTTagCompound nbttagcompound); + protected abstract void loadData(NBTTagCompound nbttagcompound); diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityTypes.java @@ -74,7 +74,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public boolean isPersistable() { return a(); } // Paper - OBFHELPER public boolean a() { - return this.bc; + return this.bh; } diff --git a/src/main/java/net/minecraft/server/KeyedObject.java b/src/main/java/net/minecraft/server/KeyedObject.java new file mode 100644 diff --git a/Spigot-Server-Patches/Add-configurable-despawn-distances-for-living-entiti.patch b/Spigot-Server-Patches/Add-configurable-despawn-distances-for-living-entiti.patch index 725c4f252e..66a8613e41 100644 --- a/Spigot-Server-Patches/Add-configurable-despawn-distances-for-living-entiti.patch +++ b/Spigot-Server-Patches/Add-configurable-despawn-distances-for-living-entiti.patch @@ -34,16 +34,19 @@ 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 { - if (entityhuman != null) { - double d0 = entityhuman.h(this); + int i = this.getEntityType().e().f(); + int j = i * i; -- if (d0 > 16384.0D) { // CraftBukkit - remove isTypeNotPersistent() check -+ if (d0 > world.paperConfig.hardDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // Paper - custom despawn distances +- if (d0 > (double) j) { // CraftBukkit - remove isTypeNotPersistent() check ++ if (d0 > (double) world.paperConfig.hardDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // Paper - custom despawn distances this.die(); } -- if (this.ticksFarFromPlayer > 600 && this.random.nextInt(800) == 0 && d0 > 1024.0D) { // CraftBukkit - remove isTypeNotPersistent() check + int k = this.getEntityType().e().g(); + int l = k * k; + +- if (this.ticksFarFromPlayer > 600 && this.random.nextInt(800) == 0 && d0 > (double) l) { // CraftBukkit - remove isTypeNotPersistent() check + if (this.ticksFarFromPlayer > 600 && this.random.nextInt(800) == 0 && d0 > world.paperConfig.softDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // Paper - custom despawn distances this.die(); - } else if (d0 < 1024.0D) { + } else if (d0 < (double) l) { this.ticksFarFromPlayer = 0; diff --git a/Spigot-Server-Patches/Add-version-history-to-version-command.patch b/Spigot-Server-Patches/Add-version-history-to-version-command.patch index d60751d83f..1ca4d68f82 100644 --- a/Spigot-Server-Patches/Add-version-history-to-version-command.patch +++ b/Spigot-Server-Patches/Add-version-history-to-version-command.patch @@ -202,4 +202,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now // Paper end - this.setSpawnAnimals(dedicatedserverproperties.spawnAnimals); + this.setPVP(dedicatedserverproperties.pvp); diff --git a/Spigot-Server-Patches/All-chunks-are-slime-spawn-chunks-toggle.patch b/Spigot-Server-Patches/All-chunks-are-slime-spawn-chunks-toggle.patch index bd71ff3d96..2f01b77bc6 100644 --- a/Spigot-Server-Patches/All-chunks-are-slime-spawn-chunks-toggle.patch +++ b/Spigot-Server-Patches/All-chunks-are-slime-spawn-chunks-toggle.patch @@ -23,11 +23,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntitySlime.java +++ b/src/main/java/net/minecraft/server/EntitySlime.java @@ -0,0 +0,0 @@ public class EntitySlime extends EntityInsentient implements IMonster { - } + } - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(blockposition); -- boolean flag = SeededRandom.a(chunkcoordintpair.x, chunkcoordintpair.z, generatoraccess.getSeed(), generatoraccess.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot -+ boolean flag = generatoraccess.getMinecraftWorld().paperConfig.allChunksAreSlimeChunks || SeededRandom.a(chunkcoordintpair.x, chunkcoordintpair.z, generatoraccess.getSeed(), generatoraccess.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(blockposition); +- boolean flag = SeededRandom.a(chunkcoordintpair.x, chunkcoordintpair.z, ((GeneratorAccessSeed) generatoraccess).getSeed(), generatoraccess.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot ++ boolean flag = generatoraccess.getMinecraftWorld().paperConfig.allChunksAreSlimeChunks || SeededRandom.a(chunkcoordintpair.x, chunkcoordintpair.z, ((GeneratorAccessSeed) generatoraccess).getSeed(), generatoraccess.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper - if (random.nextInt(10) == 0 && flag && blockposition.getY() < 40) { - return a(entitytypes, generatoraccess, enummobspawn, blockposition, random); + if (random.nextInt(10) == 0 && flag && blockposition.getY() < 40) { + return a(entitytypes, generatoraccess, enummobspawn, blockposition, random); diff --git a/Spigot-Server-Patches/Allow-nerfed-mobs-to-jump-and-take-water-damage.patch b/Spigot-Server-Patches/Allow-nerfed-mobs-to-jump-and-take-water-damage.patch index 91f9a199df..a1a2c91eb2 100644 --- a/Spigot-Server-Patches/Allow-nerfed-mobs-to-jump-and-take-water-damage.patch +++ b/Spigot-Server-Patches/Allow-nerfed-mobs-to-jump-and-take-water-damage.patch @@ -38,23 +38,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return this.isInWater() || this.isInRain(); } -+ public boolean isInWaterOrRainOrBubble() { return ay(); } // Paper - OBFHELPER - public boolean ay() { - return this.isInWater() || this.isInRain() || this.l(); ++ public boolean isInWaterOrRainOrBubble() { return aC(); } // Paper - OBFHELPER + public boolean aC() { + return this.isInWater() || this.isInRain() || this.k(); } -diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/java/net/minecraft/server/EntityEnderman.java -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 { - @Override - protected void mobTick() { - if (this.ay()) { -- this.damageEntity(DamageSource.DROWN, 1.0F); -+ this.damageEntity(DamageSource.DROWN, 1.0F); // Paper - copied in patch 13 (allow nerfed mobs to jump, float and take water damage) - } - - if (this.world.isDay() && this.ticksLived >= this.bA + 600) { 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 @@ -66,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Nullable public PathfinderGoalFloat goalFloat; // Paper public PathfinderGoalSelector targetSelector; private EntityLiving goalTarget; - private final EntitySenses bw; + private final EntitySenses bv; @@ -0,0 +0,0 @@ public abstract class EntityInsentient extends EntityLiving { @Override protected final void doTick() { @@ -84,7 +71,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end this.world.getMethodProfiler().enter("sensing"); - this.bw.a(); + this.bv.a(); this.world.getMethodProfiler().exit(); diff --git a/src/main/java/net/minecraft/server/PathfinderGoalFloat.java b/src/main/java/net/minecraft/server/PathfinderGoalFloat.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -102,9 +89,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public final boolean validConditions() { return this.a(); } // Paper - OBFHELPER @Override public boolean a() { - double d0 = (double) this.a.getHeadHeight() < 0.4D ? 0.2D : 0.4D; -@@ -0,0 +0,0 @@ public class PathfinderGoalFloat extends PathfinderGoal { - return this.a.isInWater() && this.a.co() > d0 || this.a.aH(); + return this.a.isInWater() && this.a.b((Tag) TagsFluid.WATER) > this.a.cw() || this.a.aN(); } + public void update() { this.e(); } // Paper - OBFHELPER diff --git a/Spigot-Server-Patches/Basic-PlayerProfile-API.patch b/Spigot-Server-Patches/Basic-PlayerProfile-API.patch index a15cdbb8dc..15df7c9edb 100644 --- a/Spigot-Server-Patches/Basic-PlayerProfile-API.patch +++ b/Spigot-Server-Patches/Basic-PlayerProfile-API.patch @@ -194,13 +194,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public boolean complete(boolean textures, boolean onlineMode) { + MinecraftServer server = MinecraftServer.getServer(); + -+ boolean isCompleteFromCache = this.completeFromCache(false, onlineMode); ++ boolean isCompleteFromCache = this.completeFromCache(true, onlineMode); + if (onlineMode && (!isCompleteFromCache || textures && !hasTextures())) { + GameProfile result = server.getSessionService().fillProfileProperties(profile, true); + if (result != null) { + copyProfileProperties(result, this.profile, true); + } -+ server.getUserCache().saveProfile(this.profile); ++ if (this.profile.isComplete()) { ++ server.getUserCache().saveProfile(this.profile); ++ } + } + return profile.isComplete() && (!onlineMode || !textures || hasTextures()); + } diff --git a/Spigot-Server-Patches/Change-implementation-of-tile-entity-removal-list.patch b/Spigot-Server-Patches/Change-implementation-of-tile-entity-removal-list.patch index a35bf1643f..1e9cd879f4 100644 --- a/Spigot-Server-Patches/Change-implementation-of-tile-entity-removal-list.patch +++ b/Spigot-Server-Patches/Change-implementation-of-tile-entity-removal-list.patch @@ -16,5 +16,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - protected final List tileEntityListUnload = Lists.newArrayList(); + protected final java.util.Set tileEntityListUnload = com.google.common.collect.Sets.newHashSet(); public final Thread serverThread; - private int c; - protected int i = (new Random()).nextInt(); + private final boolean debugWorld; + private int d; diff --git a/Spigot-Server-Patches/Check-online-mode-before-converting-and-renaming-pla.patch b/Spigot-Server-Patches/Check-online-mode-before-converting-and-renaming-pla.patch index 90d023cb52..bf04c65165 100644 --- a/Spigot-Server-Patches/Check-online-mode-before-converting-and-renaming-pla.patch +++ b/Spigot-Server-Patches/Check-online-mode-before-converting-and-renaming-pla.patch @@ -8,12 +8,12 @@ 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 file = new File(this.playerDir, entityhuman.getUniqueIDString() + ".dat"); // Spigot Start boolean usingWrongFile = false; - if ( !file.exists() ) + if ( org.bukkit.Bukkit.getOnlineMode() && !file.exists() ) // Paper - Check online mode first { - file = new File( this.playerDir, UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + entityhuman.getName() ).getBytes( "UTF-8" ) ).toString() + ".dat"); + file = new File( this.playerDir, java.util.UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + entityhuman.getName() ).getBytes( "UTF-8" ) ).toString() + ".dat"); if ( file.exists() ) diff --git a/Spigot-Server-Patches/Configurable-baby-zombie-movement-speed.patch b/Spigot-Server-Patches/Configurable-baby-zombie-movement-speed.patch index 15a9b8aa41..e59066753e 100644 --- a/Spigot-Server-Patches/Configurable-baby-zombie-movement-speed.patch +++ b/Spigot-Server-Patches/Configurable-baby-zombie-movement-speed.patch @@ -28,24 +28,24 @@ diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/jav 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 { +@@ -0,0 +0,0 @@ import org.bukkit.event.entity.EntityTransformEvent; + public class EntityZombie extends EntityMonster { - protected static final IAttribute d = (new AttributeRanged((IAttribute) null, "zombie.spawnReinforcements", 0.0D, 0.0D, 1.0D)).a("Spawn Reinforcements Chance"); private static final UUID b = UUID.fromString("B9766B59-9566-4402-BC1F-2EE2A276D836"); - private static final AttributeModifier c = new AttributeModifier(EntityZombie.b, "Baby speed boost", 0.5D, AttributeModifier.Operation.MULTIPLY_BASE); -+ private final AttributeModifier c = new AttributeModifier(EntityZombie.b, "Baby speed boost", world.paperConfig.babyZombieMovementModifier, AttributeModifier.Operation.MULTIPLY_BASE); private final AttributeModifier babyModifier = this.c; // Paper - remove static - Make baby speed configurable - private static final DataWatcherObject bw = DataWatcher.a(EntityZombie.class, DataWatcherRegistry.i); - private static final DataWatcherObject bx = DataWatcher.a(EntityZombie.class, DataWatcherRegistry.b); ++ private final AttributeModifier c = new AttributeModifier(EntityZombie.b, "Baby speed boost", 0.5D, AttributeModifier.Operation.MULTIPLY_BASE); private final AttributeModifier babyModifier = this.c; // Paper - remove static - Make baby speed configurable + private static final DataWatcherObject d = DataWatcher.a(EntityZombie.class, DataWatcherRegistry.i); + private static final DataWatcherObject bv = DataWatcher.a(EntityZombie.class, DataWatcherRegistry.b); public static final DataWatcherObject DROWN_CONVERTING = DataWatcher.a(EntityZombie.class, DataWatcherRegistry.i); @@ -0,0 +0,0 @@ public class EntityZombie extends EntityMonster { if (this.world != null && !this.world.isClientSide) { - AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); + AttributeModifiable attributemodifiable = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); -- attributeinstance.removeModifier(EntityZombie.c); -+ attributeinstance.removeModifier(this.babyModifier); // Paper +- attributemodifiable.removeModifier(EntityZombie.c); ++ attributemodifiable.removeModifier(this.babyModifier); // Paper if (flag) { -- attributeinstance.addModifier(EntityZombie.c); -+ attributeinstance.addModifier(this.babyModifier); // Paper +- attributemodifiable.b(EntityZombie.c); ++ attributemodifiable.b(this.babyModifier); // Paper } } diff --git a/Spigot-Server-Patches/Configurable-cactus-and-reed-natural-growth-heights.patch b/Spigot-Server-Patches/Configurable-cactus-and-reed-natural-growth-heights.patch index aaf8ab4f52..4fd8b1eab7 100644 --- a/Spigot-Server-Patches/Configurable-cactus-and-reed-natural-growth-heights.patch +++ b/Spigot-Server-Patches/Configurable-cactus-and-reed-natural-growth-heights.patch @@ -27,14 +27,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/BlockCactus.java +++ b/src/main/java/net/minecraft/server/BlockCactus.java @@ -0,0 +0,0 @@ public class BlockCactus extends Block { - ; - } + ; + } -- if (i < 3) { +- if (i < 3) { + if (i < worldserver.paperConfig.cactusMaxHeight) { // Paper - Configurable growth height - int j = (Integer) iblockdata.get(BlockCactus.AGE); + int j = (Integer) iblockdata.get(BlockCactus.AGE); - if (j >= (byte) range(3, ((100.0F / worldserver.spigotConfig.cactusModifier) * 15) + 0.5F, 15)) { // Spigot + if (j >= (byte) range(3, ((100.0F / worldserver.spigotConfig.cactusModifier) * 15) + 0.5F, 15)) { // Spigot diff --git a/src/main/java/net/minecraft/server/BlockReed.java b/src/main/java/net/minecraft/server/BlockReed.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockReed.java diff --git a/Spigot-Server-Patches/Configurable-end-credits.patch b/Spigot-Server-Patches/Configurable-end-credits.patch index dc1d22d7a9..95723e15ee 100644 --- a/Spigot-Server-Patches/Configurable-end-credits.patch +++ b/Spigot-Server-Patches/Configurable-end-credits.patch @@ -24,19 +24,19 @@ 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 { - private long cj = SystemUtils.getMonotonicMillis(); + private long ch = SystemUtils.getMonotonicMillis(); private Entity spectatedEntity; public boolean worldChangeInvuln; -- private boolean cm; -+ private boolean cm; private void setHasSeenCredits(boolean has) { this.cm = has; } // Paper - OBFHELPER - private final RecipeBookServer recipeBook; - private Vec3D co; - private int cp; +- private boolean ck; ++ private boolean ck; private void setHasSeenCredits(boolean has) { this.ck = has; } // Paper - OBFHELPER + private final RecipeBookServer recipeBook = new RecipeBookServer(); + private Vec3D cm; + private int cn; @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.getWorldServer().removePlayer(this); if (!this.viewingCredits) { this.viewingCredits = true; + if (world.paperConfig.disableEndCredits) this.setHasSeenCredits(true); // Paper - Toggle to always disable end credits - this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(4, this.cm ? 0.0F : 1.0F)); - this.cm = true; + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.e, this.ck ? 0.0F : 1.0F)); + this.ck = true; } diff --git a/Spigot-Server-Patches/Configurable-fishing-time-ranges.patch b/Spigot-Server-Patches/Configurable-fishing-time-ranges.patch index bfa56c3c15..c90f101c7b 100644 --- a/Spigot-Server-Patches/Configurable-fishing-time-ranges.patch +++ b/Spigot-Server-Patches/Configurable-fishing-time-ranges.patch @@ -25,14 +25,14 @@ diff --git a/src/main/java/net/minecraft/server/EntityFishingHook.java b/src/mai index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityFishingHook.java +++ b/src/main/java/net/minecraft/server/EntityFishingHook.java -@@ -0,0 +0,0 @@ public class EntityFishingHook extends Entity { - this.aq = MathHelper.nextInt(this.random, 20, 80); +@@ -0,0 +0,0 @@ public class EntityFishingHook extends IProjectile { + this.ap = MathHelper.nextInt(this.random, 20, 80); } } else { -- this.ap = MathHelper.nextInt(this.random, 100, 600); -+ this.ap = MathHelper.nextInt(this.random, world.paperConfig.fishingMinTicks, world.paperConfig.fishingMaxTicks); // Paper - this.ap -= this.au * 20 * 5; -+ this.ap = Math.max(0, this.ap); // Paper - Don't allow negative values +- this.ao = MathHelper.nextInt(this.random, 100, 600); ++ this.ao = MathHelper.nextInt(this.random, world.paperConfig.fishingMinTicks, world.paperConfig.fishingMaxTicks); // Paper + this.ao -= this.av * 20 * 5; ++ this.ao = Math.max(0, this.ao); // Paper - Don't allow negative values; } } diff --git a/Spigot-Server-Patches/Configurable-top-of-nether-void-damage.patch b/Spigot-Server-Patches/Configurable-top-of-nether-void-damage.patch index a47afdd088..8c6619990c 100644 --- a/Spigot-Server-Patches/Configurable-top-of-nether-void-damage.patch +++ b/Spigot-Server-Patches/Configurable-top-of-nether-void-damage.patch @@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Extracted to own function + /* if (this.locY() < -64.0D) { - this.af(); + this.ai(); } + */ + this.performVoidDamage(); @@ -55,9 +55,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start + protected void performVoidDamage() { -+ if (this.locY < -64.0D || (this.world.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER ++ if (this.locY() < -64.0D || (this.world.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER + && world.paperConfig.doNetherTopVoidDamage() -+ && this.locY >= world.paperConfig.netherVoidTopDamageHeight)) { ++ && this.locY() >= world.paperConfig.netherVoidTopDamageHeight)) { + + this.doVoidDamage(); + } @@ -68,11 +68,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.portalCooldown > 0) { --this.portalCooldown; @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - this.fireTicks = 0; + this.setFireTicks(0); } -+ protected final void doVoidDamage() { this.af(); } // Paper - OBFHELPER - protected void af() { ++ protected final void doVoidDamage() { this.ai(); } // Paper - OBFHELPER + protected void ai() { this.die(); } diff --git a/src/main/java/net/minecraft/server/EntityMinecartAbstract.java b/src/main/java/net/minecraft/server/EntityMinecartAbstract.java @@ -87,7 +87,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Extracted to own function + /* if (this.locY() < -64.0D) { - this.af(); + this.ai(); } + */ + this.performVoidDamage(); diff --git a/Spigot-Server-Patches/Disable-explosion-knockback.patch b/Spigot-Server-Patches/Disable-explosion-knockback.patch index 54365aa390..4a190a8f62 100644 --- a/Spigot-Server-Patches/Disable-explosion-knockback.patch +++ b/Spigot-Server-Patches/Disable-explosion-knockback.patch @@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } -+ boolean knockbackCancelled = world.paperConfig.disableExplosionKnockback && damagesource.isExplosion() && this instanceof EntityHuman; // Paper - Disable explosion knockback ++ boolean knockbackCancelled = world.paperConfig.disableExplosionKnockback && damagesource.isExplosion() && this instanceof EntityHuman; // Paper - Disable explosion knockback if (flag1) { if (flag) { this.world.broadcastEntityEffect(this, (byte) 29); @@ -34,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 b0 = 2; } -+ if (!knockbackCancelled) // Paper - Disable explosion knockback ++ if (!knockbackCancelled) // Paper - Disable explosion knockback this.world.broadcastEntityEffect(this, b0); } @@ -42,9 +42,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } -+ if (knockbackCancelled) this.world.broadcastEntityEffect(this, (byte) 2); // Paper - Disable explosion knockback -+ - 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(); diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java @@ -64,7 +63,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 EntityHuman entityhuman = (EntityHuman) entity; - if (!entityhuman.isSpectator() && (!entityhuman.isCreative() || !entityhuman.abilities.isFlying)) { -+ if (!entityhuman.isSpectator() && (!entityhuman.isCreative() && !world.paperConfig.disableExplosionKnockback || !entityhuman.abilities.isFlying)) { // Paper - Disable explosion knockback - this.l.put(entityhuman, new Vec3D(d8 * d13, d9 * d13, d10 * d13)); ++ if (!entityhuman.isSpectator() && (!entityhuman.isCreative() || !entityhuman.abilities.isFlying) && !world.paperConfig.disableExplosionKnockback) { // Paper - Disable explosion knockback + this.m.put(entityhuman, new Vec3D(d8 * d13, d9 * d13, d10 * d13)); } } diff --git a/Spigot-Server-Patches/Disable-ice-and-snow.patch b/Spigot-Server-Patches/Disable-ice-and-snow.patch index 60fd5201c7..6342a07597 100644 --- a/Spigot-Server-Patches/Disable-ice-and-snow.patch +++ b/Spigot-Server-Patches/Disable-ice-and-snow.patch @@ -22,7 +22,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 { } gameprofilerfiller.exitEnter("iceandsnow"); diff --git a/Spigot-Server-Patches/Disable-thunder.patch b/Spigot-Server-Patches/Disable-thunder.patch index 85a76453bf..afd1f5970d 100644 --- a/Spigot-Server-Patches/Disable-thunder.patch +++ b/Spigot-Server-Patches/Disable-thunder.patch @@ -22,12 +22,12 @@ 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 { gameprofilerfiller.enter("thunder"); BlockPosition blockposition; -- if (flag && this.U() && this.random.nextInt(100000) == 0) { -+ if (!this.paperConfig.disableThunder && flag && this.U() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder +- if (flag && this.T() && this.random.nextInt(100000) == 0) { ++ if (!this.paperConfig.disableThunder && flag && this.T() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder blockposition = this.a(this.a(j, 0, k, 15)); if (this.isRainingAt(blockposition)) { DifficultyDamageScaler difficultydamagescaler = this.getDamageScaler(blockposition); diff --git a/Spigot-Server-Patches/Drop-falling-block-and-tnt-entities-at-the-specified.patch b/Spigot-Server-Patches/Drop-falling-block-and-tnt-entities-at-the-specified.patch index 1bafe490f2..af341d497d 100644 --- a/Spigot-Server-Patches/Drop-falling-block-and-tnt-entities-at-the-specified.patch +++ b/Spigot-Server-Patches/Drop-falling-block-and-tnt-entities-at-the-specified.patch @@ -55,7 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end if (!this.world.isClientSide) { - blockposition = new BlockPosition(this); + blockposition = this.getChunkCoordinates(); boolean flag = this.block.getBlock() instanceof BlockConcretePowder; diff --git a/src/main/java/net/minecraft/server/EntityTNTPrimed.java b/src/main/java/net/minecraft/server/EntityTNTPrimed.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/Entity-Origin-API.patch b/Spigot-Server-Patches/Entity-Origin-API.patch index 686b9239b0..f73077115e 100644 --- a/Spigot-Server-Patches/Entity-Origin-API.patch +++ b/Spigot-Server-Patches/Entity-Origin-API.patch @@ -44,7 +44,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being loaded"); @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - protected abstract void b(NBTTagCompound nbttagcompound); + protected abstract void saveData(NBTTagCompound nbttagcompound); + protected NBTTagList createList(double... adouble) { return a(adouble); } // Paper - OBFHELPER protected NBTTagList a(double... adouble) { @@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/EntityTNTPrimed.java @@ -0,0 +0,0 @@ public class EntityTNTPrimed extends Entity { @Override - protected void a(NBTTagCompound nbttagcompound) { + protected void loadData(NBTTagCompound nbttagcompound) { this.setFuseTicks(nbttagcompound.getShort("Fuse")); + // Paper start - Try and load origin location from the old NBT tags for backwards compatibility + if (nbttagcompound.hasKey("SourceLoc_x")) { @@ -104,7 +104,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 { this.navigators.add(((EntityInsentient) entity).getNavigation()); } entity.valid = true; // CraftBukkit diff --git a/Spigot-Server-Patches/Fix-lag-from-explosions-processing-dead-entities.patch b/Spigot-Server-Patches/Fix-lag-from-explosions-processing-dead-entities.patch index 9acc3d7896..327ea01a89 100644 --- a/Spigot-Server-Patches/Fix-lag-from-explosions-processing-dead-entities.patch +++ b/Spigot-Server-Patches/Fix-lag-from-explosions-processing-dead-entities.patch @@ -9,18 +9,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/Explosion.java +++ b/src/main/java/net/minecraft/server/Explosion.java @@ -0,0 +0,0 @@ public class Explosion { - int i1 = MathHelper.floor(this.posY + (double) f3 + 1.0D); - int j1 = MathHelper.floor(this.posZ - (double) f3 - 1.0D); - int k1 = MathHelper.floor(this.posZ + (double) f3 + 1.0D); + int i1 = MathHelper.floor(this.posY + (double) f2 + 1.0D); + int j1 = MathHelper.floor(this.posZ - (double) f2 - 1.0D); + int k1 = MathHelper.floor(this.posZ + (double) f2 + 1.0D); - List list = this.world.getEntities(this.source, new AxisAlignedBB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1)); -+ // Paper start - Fix lag from explosions processing dead entities -+ List list = this.world.getEntities(this.source, new AxisAlignedBB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1), new com.google.common.base.Predicate() { -+ @Override -+ public boolean apply(Entity entity) { -+ return IEntitySelector.canAITarget().test(entity) && !entity.dead; -+ } -+ }); -+ // Paper end ++ List list = this.world.getEntities(this.source, new AxisAlignedBB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1), (com.google.common.base.Predicate) entity -> IEntitySelector.canAITarget().test(entity) && !entity.dead); // Paper - Fix lag from explosions processing dead entities Vec3D vec3d = new Vec3D(this.posX, this.posY, this.posZ); for (int l1 = 0; l1 < list.size(); ++l1) { diff --git a/Spigot-Server-Patches/Further-improve-server-tick-loop.patch b/Spigot-Server-Patches/Further-improve-server-tick-loop.patch index 4774ed3aa5..3396fefad8 100644 --- a/Spigot-Server-Patches/Further-improve-server-tick-loop.patch +++ b/Spigot-Server-Patches/Further-improve-server-tick-loop.patch @@ -90,7 +90,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper End // Spigot End - public void run() { + protected void v() { @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant { - villageplace.a(this.a.c(), (blockposition1) -> { + villageplace.a(this.b.c(), (blockposition1) -> { return blockposition1.equals(blockposition); }, blockposition, 1); -- entitycreature.getBehaviorController().setMemory(this.b, (Object) GlobalPos.create(worldserver.getWorldProvider().getDimensionManager(), blockposition)); -+ entitycreature.getBehaviorController().setMemory(this.b, GlobalPos.create(worldserver.getWorldProvider().getDimensionManager(), blockposition)); +- entitycreature.getBehaviorController().setMemory(this.c, (Object) GlobalPos.create(worldserver.getDimensionKey(), blockposition)); ++ entitycreature.getBehaviorController().setMemory(this.c, GlobalPos.create(worldserver.getDimensionKey(), blockposition)); // Paper - decompile fix + this.f.clear(); PacketDebug.c(worldserver, blockposition); }); - } else if (this.f < 5) { diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java 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 { +@@ -0,0 +0,0 @@ import org.apache.logging.log4j.Logger; + public class BiomeBase { + + public static final Logger LOGGER = LogManager.getLogger(); +- public static final Codec b = RecordCodecBuilder.create((instance) -> { +- RecordCodecBuilder recordcodecbuilder = BiomeBase.Precipitation.d.fieldOf("precipitation").forGetter((biomebase) -> { +- return biomebase.o; +- }); +- RecordCodecBuilder recordcodecbuilder1 = BiomeBase.Geography.r.fieldOf("category").forGetter((biomebase) -> { +- return biomebase.n; +- }); +- RecordCodecBuilder recordcodecbuilder2 = Codec.FLOAT.fieldOf("depth").forGetter((biomebase) -> { +- return biomebase.h; +- }); +- RecordCodecBuilder recordcodecbuilder3 = Codec.FLOAT.fieldOf("scale").forGetter((biomebase) -> { +- return biomebase.i; +- }); +- RecordCodecBuilder recordcodecbuilder4 = Codec.FLOAT.fieldOf("temperature").forGetter((biomebase) -> { +- return biomebase.j; +- }); +- RecordCodecBuilder recordcodecbuilder5 = Codec.FLOAT.fieldOf("downfall").forGetter((biomebase) -> { +- return biomebase.k; +- }); +- RecordCodecBuilder recordcodecbuilder6 = BiomeFog.a.fieldOf("effects").forGetter((biomebase) -> { +- return biomebase.p; +- }); +- RecordCodecBuilder recordcodecbuilder7 = Codec.INT.fieldOf("sky_color").forGetter((biomebase) -> { +- return biomebase.t; +- }); +- RecordCodecBuilder recordcodecbuilder8 = WorldGenSurfaceComposite.a.fieldOf("surface_builder").forGetter((biomebase) -> { +- return biomebase.m; +- }); +- Codec codec = WorldGenStage.Features.c; +- Codec codec1 = WorldGenCarverWrapper.a.listOf(); +- Logger logger = BiomeBase.LOGGER; +- +- logger.getClass(); +- RecordCodecBuilder recordcodecbuilder9 = Codec.simpleMap(codec, codec1.promotePartial(SystemUtils.a("Carver: ", logger::error)), INamable.a(WorldGenStage.Features.values())).fieldOf("carvers").forGetter((biomebase) -> { +- return biomebase.q; +- }); +- +- codec1 = WorldGenStage.Decoration.k; +- Codec codec2 = WorldGenFeatureConfigured.b.listOf(); +- Logger logger1 = BiomeBase.LOGGER; +- +- logger1.getClass(); +- RecordCodecBuilder recordcodecbuilder10 = Codec.simpleMap(codec1, codec2.promotePartial(SystemUtils.a("Feature: ", logger1::error)), INamable.a(WorldGenStage.Decoration.values())).fieldOf("features").forGetter((biomebase) -> { +- return biomebase.r; +- }); +- +- codec2 = StructureFeature.a.listOf(); +- logger1 = BiomeBase.LOGGER; +- logger1.getClass(); +- RecordCodecBuilder recordcodecbuilder11 = codec2.promotePartial(SystemUtils.a("Structure start: ", logger1::error)).fieldOf("starts").forGetter((biomebase) -> { +- return (List) biomebase.u.values().stream().sorted(Comparator.comparing((structurefeature) -> { +- return IRegistry.STRUCTURE_FEATURE.getKey(structurefeature.b); +- })).collect(Collectors.toList()); +- }); +- Codec codec3 = EnumCreatureType.g; +- Codec codec4 = BiomeBase.BiomeMeta.b.listOf(); +- Logger logger2 = BiomeBase.LOGGER; +- +- logger2.getClass(); +- return instance.group(recordcodecbuilder, recordcodecbuilder1, recordcodecbuilder2, recordcodecbuilder3, recordcodecbuilder4, recordcodecbuilder5, recordcodecbuilder6, recordcodecbuilder7, recordcodecbuilder8, recordcodecbuilder9, recordcodecbuilder10, recordcodecbuilder11, Codec.simpleMap(codec3, codec4.promotePartial(SystemUtils.a("Spawn data: ", logger2::error)), INamable.a(EnumCreatureType.values())).fieldOf("spawners").forGetter((biomebase) -> { +- return biomebase.v; +- }), BiomeBase.d.a.listOf().fieldOf("climate_parameters").forGetter((biomebase) -> { +- return biomebase.x; +- }), Codec.STRING.optionalFieldOf("parent").forGetter((biomebase) -> { +- return Optional.ofNullable(biomebase.l); +- })).apply(instance, BiomeBase::new); ++ // Paper decompile error - Spigots stupid decompiler ++ public static final Codec b = RecordCodecBuilder.create(i -> { ++ Codec k1 = WorldGenStage.Decoration.k; // Erase type - WorldGenstage.Decoration has wrong type ++ return i.group( ++ Precipitation.d.fieldOf("precipitation").forGetter(biome -> biome.o), ++ Geography.r.fieldOf("category").forGetter(biome -> biome.n), ++ Codec.FLOAT.fieldOf("depth").forGetter(biome -> biome.h), ++ Codec.FLOAT.fieldOf("scale").forGetter(biome -> biome.i), ++ Codec.FLOAT.fieldOf("temperature").forGetter(biome -> biome.j), ++ Codec.FLOAT.fieldOf("downfall").forGetter(biome -> biome.k), ++ BiomeFog.a.fieldOf("effects").forGetter(biome -> biome.p), ++ Codec.INT.fieldOf("sky_color").forGetter(biome -> biome.t), ++ WorldGenSurfaceComposite.a.fieldOf("surface_builder").forGetter(biome -> biome.m), ++ Codec.simpleMap(WorldGenStage.Features.c, WorldGenCarverWrapper.a.listOf().promotePartial(SystemUtils.a("Carver: ", LOGGER::error)), INamable.a(WorldGenStage.Features.values())).fieldOf("carvers").forGetter(biome -> biome.q), ++ Codec.simpleMap((Codec) k1, WorldGenFeatureConfigured.b.listOf().promotePartial(SystemUtils.a("Feature: ", LOGGER::error)), INamable.a(WorldGenStage.Decoration.values())).fieldOf("features").forGetter(biome -> biome.r), ++ StructureFeature.a.listOf().promotePartial(SystemUtils.a("Structure start: ", LOGGER::error)).fieldOf("starts").forGetter(biome -> biome.u.values().stream().sorted(Comparator.comparing(cf -> IRegistry.STRUCTURE_FEATURE.getKey(cf.b))).collect(Collectors.toList())), ++ Codec.simpleMap(EnumCreatureType.g, BiomeMeta.b.listOf().promotePartial(SystemUtils.a("Spawn data: ", LOGGER::error)), INamable.a(EnumCreatureType.values())).fieldOf("spawners").forGetter(biome -> biome.v), ++ d.a.listOf().fieldOf("climate_parameters").forGetter(biome -> biome.x), ++ Codec.STRING.optionalFieldOf("parent").forGetter(biome -> Optional.ofNullable(biome.l)) ++ ).apply(i, BiomeBase::new); ++ // Paper end + }); + public static final Set c = Sets.newHashSet(); +- public static final RegistryBlockID d = new RegistryBlockID<>(); +- protected static final NoiseGenerator3 e = new NoiseGenerator3(new SeededRandom(1234L), ImmutableList.of(0)); ++ public static final RegistryBlockID reg = new RegistryBlockID<>(); // Paper - decompile error - rename ++ protected static final NoiseGenerator3 NOISE_GENERATOR_3 = new NoiseGenerator3(new SeededRandom(1234L), ImmutableList.of(0)); // Paper - decompile error - rename + public static final NoiseGenerator3 f = new NoiseGenerator3(new SeededRandom(2345L), ImmutableList.of(0)); + @Nullable + protected String g; +@@ -0,0 +0,0 @@ public class BiomeBase { @Nullable public static BiomeBase a(BiomeBase biomebase) { -- return (BiomeBase) BiomeBase.c.fromId(IRegistry.BIOME.a((Object) biomebase)); -+ return (BiomeBase) BiomeBase.c.fromId(IRegistry.BIOME.a(biomebase)); // Paper - decompile fix +- return (BiomeBase) BiomeBase.d.fromId(IRegistry.BIOME.a((Object) biomebase)); ++ return (BiomeBase) BiomeBase.reg.fromId(IRegistry.BIOME.a(biomebase)); // Paper - decompile fix / rename } public static WorldGenCarverWrapper a(WorldGenCarverAbstract worldgencarverabstract, C c0) { -@@ -0,0 +0,0 @@ public abstract class BiomeBase { +@@ -0,0 +0,0 @@ public class BiomeBase { + }, Function.identity())); + this.v = map2; + this.x = list1; +- this.l = (String) optional.orElse((Object) null); ++ this.l = (String) optional.orElse(null); // Paper - decompile fix + Stream stream = map1.values().stream().flatMap(Collection::stream).filter((worldgenfeatureconfigured) -> { + return worldgenfeatureconfigured.d == WorldGenerator.DECORATED_FLOWER; + }); +@@ -0,0 +0,0 @@ public class BiomeBase { - @Nullable - public C b(StructureGenerator structuregenerator) { -- return (WorldGenFeatureConfiguration) this.t.get(structuregenerator); -+ return (C) this.t.get(structuregenerator); // Paper - decompile fix - } + protected float a(BlockPosition blockposition) { + if (blockposition.getY() > 64) { +- float f = (float) (BiomeBase.e.a((double) ((float) blockposition.getX() / 8.0F), (double) ((float) blockposition.getZ() / 8.0F), false) * 4.0D); ++ float f = (float) (BiomeBase.NOISE_GENERATOR_3.a((double) ((float) blockposition.getX() / 8.0F), (double) ((float) blockposition.getZ() / 8.0F), false) * 4.0D); // Paper - decompile error - rename - public List> g() { -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 - OfInt ofint = dynamic.asIntStream().spliterator(); - int[] aint = new int[3]; - -- if (ofint.tryAdvance((i) -> { -+ if (ofint.tryAdvance((Consumer) (i) -> { // Paper - decomile fix - aint[0] = i; -- }) && ofint.tryAdvance((i) -> { -+ }) && ofint.tryAdvance((Consumer) (i) -> { // Paper - decompile fix - aint[1] = i; - })) { -- ofint.tryAdvance((i) -> { -+ ofint.tryAdvance((Consumer) (i) -> { // Paper - decompile fix - aint[2] = i; - }); - } + return this.getTemperature() - (f + (float) blockposition.getY() - 64.0F) * 0.05F / 30.0F; + } else { diff --git a/src/main/java/net/minecraft/server/BlockStateEnum.java b/src/main/java/net/minecraft/server/BlockStateEnum.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockStateEnum.java +++ b/src/main/java/net/minecraft/server/BlockStateEnum.java -@@ -0,0 +0,0 @@ public class BlockStateEnum & INamable> extends BlockState +@@ -0,0 +0,0 @@ public class BlockStateEnum & INamable> extends IBlockState protected BlockStateEnum(String s, Class oclass, Collection collection) { super(s, oclass); this.a = ImmutableSet.copyOf(collection); @@ -160,19 +249,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, true)); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); -diff --git a/src/main/java/net/minecraft/server/Fluid.java b/src/main/java/net/minecraft/server/Fluid.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/Fluid.java -+++ b/src/main/java/net/minecraft/server/Fluid.java -@@ -0,0 +0,0 @@ public interface Fluid extends IBlockDataHolder { - if (immutablemap.isEmpty()) { - object = dynamicops.createMap(ImmutableMap.of(dynamicops.createString("Name"), dynamicops.createString(IRegistry.FLUID.getKey(fluid.getType()).toString()))); - } else { -- object = dynamicops.createMap(ImmutableMap.of(dynamicops.createString("Name"), dynamicops.createString(IRegistry.FLUID.getKey(fluid.getType()).toString()), dynamicops.createString("Properties"), dynamicops.createMap((Map) immutablemap.entrySet().stream().map((entry) -> { -+ object = dynamicops.createMap(ImmutableMap.of(dynamicops.createString("Name"), dynamicops.createString(IRegistry.FLUID.getKey(fluid.getType()).toString()), dynamicops.createString("Properties"), dynamicops.createMap(immutablemap.entrySet().stream().map((entry) -> { // Paper - decompile fix - return Pair.of(dynamicops.createString(((IBlockState) entry.getKey()).a()), dynamicops.createString(IBlockDataHolder.b((IBlockState) entry.getKey(), (Comparable) entry.getValue()))); - }).collect(Collectors.toMap(Pair::getFirst, Pair::getSecond))))); - } diff --git a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java @@ -203,67 +279,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return true; } } -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 - - public static Dynamic a(DynamicOps dynamicops, IBlockData iblockdata) { - ImmutableMap, Comparable> immutablemap = iblockdata.getStateMap(); -- Object object; -+ T object; // Paper - decompile fix - - if (immutablemap.isEmpty()) { - object = dynamicops.createMap(ImmutableMap.of(dynamicops.createString("Name"), dynamicops.createString(IRegistry.BLOCK.getKey(iblockdata.getBlock()).toString()))); - } else { -- object = dynamicops.createMap(ImmutableMap.of(dynamicops.createString("Name"), dynamicops.createString(IRegistry.BLOCK.getKey(iblockdata.getBlock()).toString()), dynamicops.createString("Properties"), dynamicops.createMap((Map) immutablemap.entrySet().stream().map((entry) -> { -+ object = dynamicops.createMap(ImmutableMap.of(dynamicops.createString("Name"), dynamicops.createString(IRegistry.BLOCK.getKey(iblockdata.getBlock()).toString()), dynamicops.createString("Properties"), dynamicops.createMap(immutablemap.entrySet().stream().map((entry) -> { // Paper - decompile fix - return Pair.of(dynamicops.createString(((IBlockState) entry.getKey()).a()), dynamicops.createString(IBlockDataHolder.b((IBlockState) entry.getKey(), (Comparable) entry.getValue()))); - }).collect(Collectors.toMap(Pair::getFirst, Pair::getSecond))))); - } -@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements - if (!iblockdata.o()) { - this.f = null; - } else { -- this.f = new VoxelShape[IBlockData.a.a.length]; -+ this.f = new VoxelShape[a.length]; // Paper - decompile fix - VoxelShape voxelshape = block.i(iblockdata, BlockAccessAir.INSTANCE, BlockPosition.ZERO); -- EnumDirection[] aenumdirection = IBlockData.a.a; -+ EnumDirection[] aenumdirection = a; // Paper - decompile fix - - i = aenumdirection.length; - -@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements - return this.g.b(enumdirection_enumaxis) < 0.0D || this.g.c(enumdirection_enumaxis) > 1.0D; - }); - this.i = new boolean[6]; -- EnumDirection[] aenumdirection1 = IBlockData.a.a; -+ EnumDirection[] aenumdirection1 = a; // Paper - decompile fix - int k = aenumdirection1.length; - - for (i = 0; i < k; ++i) { 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 +++ b/src/main/java/net/minecraft/server/IEntityAccess.java -@@ -0,0 +0,0 @@ public interface IEntityAccess { - return Stream.empty(); - } else { - AxisAlignedBB axisalignedbb1 = axisalignedbb.g(1.0E-7D); -- Stream stream = this.getEntities(entity, axisalignedbb1).stream().filter((entity1) -> { -+ Stream stream = this.getEntities(entity, axisalignedbb1).stream().filter((entity1) -> { // Paper - decompile fix - return !set.contains(entity1); - }).filter((entity1) -> { - return entity == null || !entity.isSameVehicle(entity1); -@@ -0,0 +0,0 @@ public interface IEntityAccess { - return Stream.of(entity1.au(), entity == null ? null : entity.j(entity1)); - }).filter(Objects::nonNull); - -- axisalignedbb1.getClass(); - return stream.filter(axisalignedbb1::c).map(VoxelShapes::a); - } - } @@ -0,0 +0,0 @@ public interface IEntityAccess { @Nullable @@ -309,41 +328,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/IOWorker.java +++ b/src/main/java/net/minecraft/server/IOWorker.java @@ -0,0 +0,0 @@ public class IOWorker implements AutoCloseable { - if (throwable != null) { - completablefuture.completeExceptionally(throwable); - } else { -- completablefuture.complete((Object) null); -+ completablefuture.complete(null); // Paper - Decompile fix - } - - }); + return this.a(() -> { + try { + this.d.a(); +- return Either.left((Object) null); ++ return Either.left(null); // Paper - decompile error + } catch (Exception exception) { + IOWorker.LOGGER.warn("Failed to synchronized chunks", exception); + return Either.right(exception); @@ -0,0 +0,0 @@ public class IOWorker implements AutoCloseable { - })); + } + + private void c() { +- this.c.a((Object) (new PairedQueue.b(IOWorker.Priority.LOW.ordinal(), this::b))); ++ this.c.a((new PairedQueue.b(IOWorker.Priority.LOW.ordinal(), this::b))); // Paper - decompile error + } - completablefuture1.whenComplete((object, throwable) -> { -- completablefuture.complete((Object) null); -+ completablefuture.complete(null); // Paper - decompile fix - }); - }; - }); -@@ -0,0 +0,0 @@ public class IOWorker implements AutoCloseable { private void a(ChunkCoordIntPair chunkcoordintpair, IOWorker.a ioworker_a) { try { - this.e.write(chunkcoordintpair, ioworker_a.a); + this.d.write(chunkcoordintpair, ioworker_a.a); - ioworker_a.b.complete((Object) null); + ioworker_a.b.complete(null); // Paper - decompile fix } catch (Exception exception) { IOWorker.LOGGER.error("Failed to store chunk {}", chunkcoordintpair, exception); ioworker_a.b.completeExceptionally(exception); -@@ -0,0 +0,0 @@ public class IOWorker implements AutoCloseable { - private void g() { - try { - this.e.close(); -- this.h.complete((Object) null); -+ this.h.complete(null); // Paper - decompile fix - } catch (Exception exception) { - IOWorker.LOGGER.error("Failed to close storage", exception); - this.h.completeExceptionally(exception); diff --git a/src/main/java/net/minecraft/server/LightEngineStorageSky.java b/src/main/java/net/minecraft/server/LightEngineStorageSky.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/LightEngineStorageSky.java @@ -365,15 +373,6 @@ diff --git a/src/main/java/net/minecraft/server/LightEngineThreaded.java b/src/m index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/LightEngineThreaded.java +++ b/src/main/java/net/minecraft/server/LightEngineThreaded.java -@@ -0,0 +0,0 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { - } - - private void a(int i, int j, IntSupplier intsupplier, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable) { -- this.e.a((Object) ChunkTaskQueueSorter.a(() -> { -+ this.e.a(ChunkTaskQueueSorter.a(() -> { // Paper - decompile error - this.c.add(Pair.of(lightenginethreaded_update, runnable)); - if (this.c.size() >= this.f) { - this.b(); @@ -0,0 +0,0 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { public void queueUpdate() { @@ -388,13 +387,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/LootItemFunctionExplorationMap.java +++ b/src/main/java/net/minecraft/server/LootItemFunctionExplorationMap.java @@ -0,0 +0,0 @@ public class LootItemFunctionExplorationMap extends LootItemFunctionConditional - } + public b() {} public void a(JsonObject jsonobject, LootItemFunctionExplorationMap lootitemfunctionexplorationmap, JsonSerializationContext jsonserializationcontext) { - super.a(jsonobject, (LootItemFunctionConditional) lootitemfunctionexplorationmap, jsonserializationcontext); + super.a(jsonobject, lootitemfunctionexplorationmap, jsonserializationcontext); // Paper - decompile fix - if (!lootitemfunctionexplorationmap.d.equals("Buried_Treasure")) { - jsonobject.add("destination", jsonserializationcontext.serialize(lootitemfunctionexplorationmap.d)); + if (!lootitemfunctionexplorationmap.e.equals(LootItemFunctionExplorationMap.a)) { + jsonobject.add("destination", jsonserializationcontext.serialize(lootitemfunctionexplorationmap.e.i())); } diff --git a/src/main/java/net/minecraft/server/LootSelectorEntry.java b/src/main/java/net/minecraft/server/LootSelectorEntry.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -472,31 +471,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 }); } -diff --git a/src/main/java/net/minecraft/server/RegionFileSection.java b/src/main/java/net/minecraft/server/RegionFileSection.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/RegionFileSection.java -+++ b/src/main/java/net/minecraft/server/RegionFileSection.java -@@ -0,0 +0,0 @@ public class RegionFileSection implements AutoC - Optional optional = this.d(i); - - if (optional.isPresent()) { -- return (MinecraftSerializable) optional.get(); -+ return optional.get(); // Paper - decompile fix - } else { -- R r0 = (MinecraftSerializable) this.f.apply(() -> { -+ R r0 = this.f.apply(() -> { // Paper - decompile fix - this.a(i); - }); - -@@ -0,0 +0,0 @@ public class RegionFileSection implements AutoC - for (int l = 0; l < 16; ++l) { - long i1 = SectionPosition.a(chunkcoordintpair, l).v(); - Optional optional = optionaldynamic.get(Integer.toString(l)).get().map((dynamic2) -> { -- return (MinecraftSerializable) this.e.apply(() -> { -+ return this.e.apply(() -> { // Paper - decompile fix - this.a(i1); - }, dynamic2); - }); diff --git a/src/main/java/net/minecraft/server/RegistryBlockID.java b/src/main/java/net/minecraft/server/RegistryBlockID.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/RegistryBlockID.java @@ -567,7 +541,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class SystemUtils { } - public static Strategy i() { + public static Strategy k() { - return SystemUtils.IdentityHashingStrategy.INSTANCE; + return (Strategy) SystemUtils.IdentityHashingStrategy.INSTANCE; // Paper - decompile fix } @@ -629,19 +603,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } private static boolean a(ChunkSection chunksection) { -- Stream stream = VillagePlaceType.e(); -+ Stream stream = VillagePlaceType.e(); // Paper - decompile fix +- Set set = VillagePlaceType.x; ++ Set set = VillagePlaceType.x; // Paper - decompile error + +- set.getClass(); ++ //set.getClass(); // Paper - decompile error + return chunksection.a(set::contains); + } - chunksection.getClass(); - return stream.anyMatch(chunksection::a); @@ -0,0 +0,0 @@ public class VillagePlace extends RegionFileSection { SectionPosition.b(new ChunkCoordIntPair(blockposition), Math.floorDiv(i, 16)).map((sectionposition) -> { - return Pair.of(sectionposition, this.d(sectionposition.v())); + return Pair.of(sectionposition, this.d(sectionposition.s())); }).filter((pair) -> { - return !(Boolean) ((Optional) pair.getSecond()).map(VillagePlaceSection::a).orElse(false); + return !(Boolean) (pair.getSecond()).map(VillagePlaceSection::a).orElse(false); // Paper - decompile fix }).map((pair) -> { - return ((SectionPosition) pair.getFirst()).u(); + return ((SectionPosition) pair.getFirst()).r(); }).filter((chunkcoordintpair) -> { @@ -0,0 +0,0 @@ public class VillagePlace extends RegionFileSection { @@ -663,15 +640,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - public static final Map> a = (Map) SystemUtils.a((Object) Maps.newHashMap(), (hashmap) -> { + public static final Map> a = SystemUtils.a(Maps.newHashMap(), (hashmap) -> { // Paper - decompile fix hashmap.put(VillagerProfession.FARMER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.WHEAT, 20, 16, 2), new VillagerTrades.b(Items.POTATO, 26, 16, 2), new VillagerTrades.b(Items.CARROT, 22, 16, 2), new VillagerTrades.b(Items.BEETROOT, 15, 16, 2), new VillagerTrades.h(Items.BREAD, 1, 6, 16, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Blocks.PUMPKIN, 6, 12, 10), new VillagerTrades.h(Items.PUMPKIN_PIE, 1, 4, 5), new VillagerTrades.h(Items.APPLE, 1, 4, 16, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.COOKIE, 3, 18, 10), new VillagerTrades.b(Blocks.MELON, 4, 12, 20)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Blocks.CAKE, 1, 1, 12, 15), new VillagerTrades.i(MobEffects.NIGHT_VISION, 100, 15), new VillagerTrades.i(MobEffects.JUMP, 160, 15), new VillagerTrades.i(MobEffects.WEAKNESS, 140, 15), new VillagerTrades.i(MobEffects.BLINDNESS, 120, 15), new VillagerTrades.i(MobEffects.POISON, 280, 15), new VillagerTrades.i(MobEffects.SATURATION, 7, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.GOLDEN_CARROT, 3, 3, 30), new VillagerTrades.h(Items.GLISTERING_MELON_SLICE, 4, 3, 30)}))); -- hashmap.put(VillagerProfession.FISHERMAN, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.STRING, 20, 16, 2), new VillagerTrades.b(Items.COAL, 10, 16, 2), new VillagerTrades.g(Items.COD, 6, Items.COOKED_COD, 6, 16, 1), new VillagerTrades.h(Items.COD_BUCKET, 3, 1, 16, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COD, 15, 16, 10), new VillagerTrades.g(Items.SALMON, 6, Items.COOKED_SALMON, 6, 16, 5), new VillagerTrades.h(Items.pT, 2, 1, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.SALMON, 13, 16, 20), new VillagerTrades.e(Items.FISHING_ROD, 3, 3, 10, 0.2F)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.TROPICAL_FISH, 6, 12, 30)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PUFFERFISH, 4, 12, 30), new VillagerTrades.c(1, 12, 30, ImmutableMap.builder().put(VillagerType.PLAINS, Items.OAK_BOAT).put(VillagerType.TAIGA, Items.SPRUCE_BOAT).put(VillagerType.SNOW, Items.SPRUCE_BOAT).put(VillagerType.DESERT, Items.JUNGLE_BOAT).put(VillagerType.JUNGLE, Items.JUNGLE_BOAT).put(VillagerType.SAVANNA, Items.ACACIA_BOAT).put(VillagerType.SWAMP, Items.DARK_OAK_BOAT).build())}))); -+ hashmap.put(VillagerProfession.FISHERMAN, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.STRING, 20, 16, 2), new VillagerTrades.b(Items.COAL, 10, 16, 2), new VillagerTrades.g(Items.COD, 6, Items.COOKED_COD, 6, 16, 1), new VillagerTrades.h(Items.COD_BUCKET, 3, 1, 16, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COD, 15, 16, 10), new VillagerTrades.g(Items.SALMON, 6, Items.COOKED_SALMON, 6, 16, 5), new VillagerTrades.h(Items.pT, 2, 1, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.SALMON, 13, 16, 20), new VillagerTrades.e(Items.FISHING_ROD, 3, 3, 10, 0.2F)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.TROPICAL_FISH, 6, 12, 30)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PUFFERFISH, 4, 12, 30), new VillagerTrades.c(1, 12, 30, ImmutableMap.builder().put(VillagerType.PLAINS, Items.OAK_BOAT).put(VillagerType.TAIGA, Items.SPRUCE_BOAT).put(VillagerType.SNOW, Items.SPRUCE_BOAT).put(VillagerType.DESERT, Items.JUNGLE_BOAT).put(VillagerType.JUNGLE, Items.JUNGLE_BOAT).put(VillagerType.SAVANNA, Items.ACACIA_BOAT).put(VillagerType.SWAMP, Items.DARK_OAK_BOAT).build())}))); // Paper - decompile fix +- hashmap.put(VillagerProfession.FISHERMAN, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.STRING, 20, 16, 2), new VillagerTrades.b(Items.COAL, 10, 16, 2), new VillagerTrades.g(Items.COD, 6, Items.COOKED_COD, 6, 16, 1), new VillagerTrades.h(Items.COD_BUCKET, 3, 1, 16, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COD, 15, 16, 10), new VillagerTrades.g(Items.SALMON, 6, Items.COOKED_SALMON, 6, 16, 5), new VillagerTrades.h(Items.rm, 2, 1, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.SALMON, 13, 16, 20), new VillagerTrades.e(Items.FISHING_ROD, 3, 3, 10, 0.2F)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.TROPICAL_FISH, 6, 12, 30)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PUFFERFISH, 4, 12, 30), new VillagerTrades.c(1, 12, 30, ImmutableMap.builder().put(VillagerType.PLAINS, Items.OAK_BOAT).put(VillagerType.TAIGA, Items.SPRUCE_BOAT).put(VillagerType.SNOW, Items.SPRUCE_BOAT).put(VillagerType.DESERT, Items.JUNGLE_BOAT).put(VillagerType.JUNGLE, Items.JUNGLE_BOAT).put(VillagerType.SAVANNA, Items.ACACIA_BOAT).put(VillagerType.SWAMP, Items.DARK_OAK_BOAT).build())}))); ++ hashmap.put(VillagerProfession.FISHERMAN, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.STRING, 20, 16, 2), new VillagerTrades.b(Items.COAL, 10, 16, 2), new VillagerTrades.g(Items.COD, 6, Items.COOKED_COD, 6, 16, 1), new VillagerTrades.h(Items.COD_BUCKET, 3, 1, 16, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COD, 15, 16, 10), new VillagerTrades.g(Items.SALMON, 6, Items.COOKED_SALMON, 6, 16, 5), new VillagerTrades.h(Items.rm, 2, 1, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.SALMON, 13, 16, 20), new VillagerTrades.e(Items.FISHING_ROD, 3, 3, 10, 0.2F)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.TROPICAL_FISH, 6, 12, 30)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PUFFERFISH, 4, 12, 30), new VillagerTrades.c(1, 12, 30, ImmutableMap.builder().put(VillagerType.PLAINS, Items.OAK_BOAT).put(VillagerType.TAIGA, Items.SPRUCE_BOAT).put(VillagerType.SNOW, Items.SPRUCE_BOAT).put(VillagerType.DESERT, Items.JUNGLE_BOAT).put(VillagerType.JUNGLE, Items.JUNGLE_BOAT).put(VillagerType.SAVANNA, Items.ACACIA_BOAT).put(VillagerType.SWAMP, Items.DARK_OAK_BOAT).build())}))); // hashmap.put(VillagerProfession.SHEPHERD, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Blocks.WHITE_WOOL, 18, 16, 2), new VillagerTrades.b(Blocks.BROWN_WOOL, 18, 16, 2), new VillagerTrades.b(Blocks.BLACK_WOOL, 18, 16, 2), new VillagerTrades.b(Blocks.GRAY_WOOL, 18, 16, 2), new VillagerTrades.h(Items.SHEARS, 2, 1, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.WHITE_DYE, 12, 16, 10), new VillagerTrades.b(Items.GRAY_DYE, 12, 16, 10), new VillagerTrades.b(Items.BLACK_DYE, 12, 16, 10), new VillagerTrades.b(Items.LIGHT_BLUE_DYE, 12, 16, 10), new VillagerTrades.b(Items.LIME_DYE, 12, 16, 10), new VillagerTrades.h(Blocks.WHITE_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.ORANGE_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.MAGENTA_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.LIGHT_BLUE_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.YELLOW_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.LIME_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.PINK_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.GRAY_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.LIGHT_GRAY_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.CYAN_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.PURPLE_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.BLUE_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.BROWN_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.GREEN_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.RED_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.BLACK_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.WHITE_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.ORANGE_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.MAGENTA_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.LIGHT_BLUE_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.YELLOW_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.LIME_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.PINK_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.GRAY_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.LIGHT_GRAY_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.CYAN_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.PURPLE_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.BLUE_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.BROWN_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.GREEN_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.RED_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.BLACK_CARPET, 1, 4, 16, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.YELLOW_DYE, 12, 16, 20), new VillagerTrades.b(Items.LIGHT_GRAY_DYE, 12, 16, 20), new VillagerTrades.b(Items.ORANGE_DYE, 12, 16, 20), new VillagerTrades.b(Items.RED_DYE, 12, 16, 20), new VillagerTrades.b(Items.PINK_DYE, 12, 16, 20), new VillagerTrades.h(Blocks.WHITE_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.YELLOW_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.RED_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.BLACK_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.BLUE_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.BROWN_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.CYAN_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.GRAY_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.GREEN_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.LIGHT_BLUE_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.LIGHT_GRAY_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.LIME_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.MAGENTA_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.ORANGE_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.PINK_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.PURPLE_BED, 3, 1, 12, 10)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.BROWN_DYE, 12, 16, 30), new VillagerTrades.b(Items.PURPLE_DYE, 12, 16, 30), new VillagerTrades.b(Items.BLUE_DYE, 12, 16, 30), new VillagerTrades.b(Items.GREEN_DYE, 12, 16, 30), new VillagerTrades.b(Items.MAGENTA_DYE, 12, 16, 30), new VillagerTrades.b(Items.CYAN_DYE, 12, 16, 30), new VillagerTrades.h(Items.WHITE_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.BLUE_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.LIGHT_BLUE_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.RED_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.PINK_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.GREEN_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.LIME_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.GRAY_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.BLACK_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.PURPLE_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.MAGENTA_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.CYAN_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.BROWN_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.YELLOW_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.ORANGE_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.LIGHT_GRAY_BANNER, 3, 1, 12, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.PAINTING, 2, 3, 30)}))); - hashmap.put(VillagerProfession.FLETCHER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.STICK, 32, 16, 2), new VillagerTrades.h(Items.ARROW, 1, 16, 1), new VillagerTrades.g(Blocks.GRAVEL, 10, Items.FLINT, 10, 12, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.FLINT, 26, 12, 10), new VillagerTrades.h(Items.BOW, 2, 1, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.STRING, 14, 16, 20), new VillagerTrades.h(Items.CROSSBOW, 3, 1, 10)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.FEATHER, 24, 16, 30), new VillagerTrades.e(Items.BOW, 2, 3, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.dE, 8, 12, 30), new VillagerTrades.e(Items.CROSSBOW, 3, 3, 15), new VillagerTrades.j(Items.ARROW, 5, Items.TIPPED_ARROW, 5, 2, 12, 30)}))); -- hashmap.put(VillagerProfession.LIBRARIAN, a(ImmutableMap.builder().put(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PAPER, 24, 16, 2), new VillagerTrades.d(1), new VillagerTrades.h(Blocks.BOOKSHELF, 9, 1, 12, 1)}).put(2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.BOOK, 4, 12, 10), new VillagerTrades.d(5), new VillagerTrades.h(Items.pR, 1, 1, 5)}).put(3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.INK_SAC, 5, 12, 20), new VillagerTrades.d(10), new VillagerTrades.h(Items.am, 1, 4, 10)}).put(4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.WRITABLE_BOOK, 2, 12, 30), new VillagerTrades.d(15), new VillagerTrades.h(Items.CLOCK, 5, 1, 15), new VillagerTrades.h(Items.COMPASS, 4, 1, 15)}).put(5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.NAME_TAG, 20, 1, 30)}).build())); -+ hashmap.put(VillagerProfession.LIBRARIAN, a(ImmutableMap.builder().put(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PAPER, 24, 16, 2), new VillagerTrades.d(1), new VillagerTrades.h(Blocks.BOOKSHELF, 9, 1, 12, 1)}).put(2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.BOOK, 4, 12, 10), new VillagerTrades.d(5), new VillagerTrades.h(Items.pR, 1, 1, 5)}).put(3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.INK_SAC, 5, 12, 20), new VillagerTrades.d(10), new VillagerTrades.h(Items.am, 1, 4, 10)}).put(4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.WRITABLE_BOOK, 2, 12, 30), new VillagerTrades.d(15), new VillagerTrades.h(Items.CLOCK, 5, 1, 15), new VillagerTrades.h(Items.COMPASS, 4, 1, 15)}).put(5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.NAME_TAG, 20, 1, 30)}).build())); // Paper - decompile fix - hashmap.put(VillagerProfession.CARTOGRAPHER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PAPER, 24, 16, 2), new VillagerTrades.h(Items.MAP, 7, 1, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.df, 11, 16, 10), new VillagerTrades.k(13, "Monument", MapIcon.Type.MONUMENT, 12, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COMPASS, 1, 12, 20), new VillagerTrades.k(14, "Mansion", MapIcon.Type.MANSION, 12, 10)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.ITEM_FRAME, 7, 1, 15), new VillagerTrades.h(Items.WHITE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.BLUE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.LIGHT_BLUE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.RED_BANNER, 3, 1, 15), new VillagerTrades.h(Items.PINK_BANNER, 3, 1, 15), new VillagerTrades.h(Items.GREEN_BANNER, 3, 1, 15), new VillagerTrades.h(Items.LIME_BANNER, 3, 1, 15), new VillagerTrades.h(Items.GRAY_BANNER, 3, 1, 15), new VillagerTrades.h(Items.BLACK_BANNER, 3, 1, 15), new VillagerTrades.h(Items.PURPLE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.MAGENTA_BANNER, 3, 1, 15), new VillagerTrades.h(Items.CYAN_BANNER, 3, 1, 15), new VillagerTrades.h(Items.BROWN_BANNER, 3, 1, 15), new VillagerTrades.h(Items.YELLOW_BANNER, 3, 1, 15), new VillagerTrades.h(Items.ORANGE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.LIGHT_GRAY_BANNER, 3, 1, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.GLOBE_BANNER_PATTERN, 8, 1, 30)}))); + hashmap.put(VillagerProfession.FLETCHER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.STICK, 32, 16, 2), new VillagerTrades.h(Items.ARROW, 1, 16, 1), new VillagerTrades.g(Blocks.GRAVEL, 10, Items.FLINT, 10, 12, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.FLINT, 26, 12, 10), new VillagerTrades.h(Items.BOW, 2, 1, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.STRING, 14, 16, 20), new VillagerTrades.h(Items.CROSSBOW, 3, 1, 10)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.FEATHER, 24, 16, 30), new VillagerTrades.e(Items.BOW, 2, 3, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.es, 8, 12, 30), new VillagerTrades.e(Items.CROSSBOW, 3, 3, 15), new VillagerTrades.j(Items.ARROW, 5, Items.TIPPED_ARROW, 5, 2, 12, 30)}))); +- hashmap.put(VillagerProfession.LIBRARIAN, a(ImmutableMap.builder().put(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PAPER, 24, 16, 2), new VillagerTrades.d(1), new VillagerTrades.h(Blocks.BOOKSHELF, 9, 1, 12, 1)}).put(2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.BOOK, 4, 12, 10), new VillagerTrades.d(5), new VillagerTrades.h(Items.rj, 1, 1, 5)}).put(3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.INK_SAC, 5, 12, 20), new VillagerTrades.d(10), new VillagerTrades.h(Items.az, 1, 4, 10)}).put(4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.WRITABLE_BOOK, 2, 12, 30), new VillagerTrades.d(15), new VillagerTrades.h(Items.CLOCK, 5, 1, 15), new VillagerTrades.h(Items.COMPASS, 4, 1, 15)}).put(5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.NAME_TAG, 20, 1, 30)}).build())); ++ hashmap.put(VillagerProfession.LIBRARIAN, a(ImmutableMap.builder().put(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PAPER, 24, 16, 2), new VillagerTrades.d(1), new VillagerTrades.h(Blocks.BOOKSHELF, 9, 1, 12, 1)}).put(2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.BOOK, 4, 12, 10), new VillagerTrades.d(5), new VillagerTrades.h(Items.rj, 1, 1, 5)}).put(3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.INK_SAC, 5, 12, 20), new VillagerTrades.d(10), new VillagerTrades.h(Items.az, 1, 4, 10)}).put(4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.WRITABLE_BOOK, 2, 12, 30), new VillagerTrades.d(15), new VillagerTrades.h(Items.CLOCK, 5, 1, 15), new VillagerTrades.h(Items.COMPASS, 4, 1, 15)}).put(5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.NAME_TAG, 20, 1, 30)}).build())); // Integer, IMerchantRecipeOption[] + hashmap.put(VillagerProfession.CARTOGRAPHER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PAPER, 24, 16, 2), new VillagerTrades.h(Items.MAP, 7, 1, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.dP, 11, 16, 10), new VillagerTrades.k(13, StructureGenerator.MONUMENT, MapIcon.Type.MONUMENT, 12, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COMPASS, 1, 12, 20), new VillagerTrades.k(14, StructureGenerator.MANSION, MapIcon.Type.MANSION, 12, 10)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.ITEM_FRAME, 7, 1, 15), new VillagerTrades.h(Items.WHITE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.BLUE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.LIGHT_BLUE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.RED_BANNER, 3, 1, 15), new VillagerTrades.h(Items.PINK_BANNER, 3, 1, 15), new VillagerTrades.h(Items.GREEN_BANNER, 3, 1, 15), new VillagerTrades.h(Items.LIME_BANNER, 3, 1, 15), new VillagerTrades.h(Items.GRAY_BANNER, 3, 1, 15), new VillagerTrades.h(Items.BLACK_BANNER, 3, 1, 15), new VillagerTrades.h(Items.PURPLE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.MAGENTA_BANNER, 3, 1, 15), new VillagerTrades.h(Items.CYAN_BANNER, 3, 1, 15), new VillagerTrades.h(Items.BROWN_BANNER, 3, 1, 15), new VillagerTrades.h(Items.YELLOW_BANNER, 3, 1, 15), new VillagerTrades.h(Items.ORANGE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.LIGHT_GRAY_BANNER, 3, 1, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.GLOBE_BANNER_PATTERN, 8, 1, 30)}))); hashmap.put(VillagerProfession.CLERIC, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.ROTTEN_FLESH, 32, 16, 2), new VillagerTrades.h(Items.REDSTONE, 1, 2, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.GOLD_INGOT, 3, 12, 10), new VillagerTrades.h(Items.LAPIS_LAZULI, 1, 1, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.RABBIT_FOOT, 2, 12, 20), new VillagerTrades.h(Blocks.GLOWSTONE, 4, 1, 12, 10)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.SCUTE, 4, 12, 30), new VillagerTrades.b(Items.GLASS_BOTTLE, 9, 12, 30), new VillagerTrades.h(Items.ENDER_PEARL, 5, 1, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.NETHER_WART, 22, 12, 30), new VillagerTrades.h(Items.EXPERIENCE_BOTTLE, 3, 1, 30)}))); - hashmap.put(VillagerProfession.ARMORER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COAL, 15, 16, 2), new VillagerTrades.h(new ItemStack(Items.IRON_LEGGINGS), 7, 1, 12, 1, 0.2F), new VillagerTrades.h(new ItemStack(Items.IRON_BOOTS), 4, 1, 12, 1, 0.2F), new VillagerTrades.h(new ItemStack(Items.IRON_HELMET), 5, 1, 12, 1, 0.2F), new VillagerTrades.h(new ItemStack(Items.IRON_CHESTPLATE), 9, 1, 12, 1, 0.2F)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.IRON_INGOT, 4, 12, 10), new VillagerTrades.h(new ItemStack(Items.pQ), 36, 1, 12, 5, 0.2F), new VillagerTrades.h(new ItemStack(Items.CHAINMAIL_BOOTS), 1, 1, 12, 5, 0.2F), new VillagerTrades.h(new ItemStack(Items.CHAINMAIL_LEGGINGS), 3, 1, 12, 5, 0.2F)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.LAVA_BUCKET, 1, 12, 20), new VillagerTrades.b(Items.DIAMOND, 1, 12, 20), new VillagerTrades.h(new ItemStack(Items.CHAINMAIL_HELMET), 1, 1, 12, 10, 0.2F), new VillagerTrades.h(new ItemStack(Items.CHAINMAIL_CHESTPLATE), 4, 1, 12, 10, 0.2F), new VillagerTrades.h(new ItemStack(Items.SHIELD), 5, 1, 12, 10, 0.2F)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.e(Items.DIAMOND_LEGGINGS, 14, 3, 15, 0.2F), new VillagerTrades.e(Items.DIAMOND_BOOTS, 8, 3, 15, 0.2F)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.e(Items.DIAMOND_HELMET, 8, 3, 30, 0.2F), new VillagerTrades.e(Items.DIAMOND_CHESTPLATE, 16, 3, 30, 0.2F)}))); + hashmap.put(VillagerProfession.ARMORER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COAL, 15, 16, 2), new VillagerTrades.h(new ItemStack(Items.IRON_LEGGINGS), 7, 1, 12, 1, 0.2F), new VillagerTrades.h(new ItemStack(Items.IRON_BOOTS), 4, 1, 12, 1, 0.2F), new VillagerTrades.h(new ItemStack(Items.IRON_HELMET), 5, 1, 12, 1, 0.2F), new VillagerTrades.h(new ItemStack(Items.IRON_CHESTPLATE), 9, 1, 12, 1, 0.2F)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.IRON_INGOT, 4, 12, 10), new VillagerTrades.h(new ItemStack(Items.ri), 36, 1, 12, 5, 0.2F), new VillagerTrades.h(new ItemStack(Items.CHAINMAIL_BOOTS), 1, 1, 12, 5, 0.2F), new VillagerTrades.h(new ItemStack(Items.CHAINMAIL_LEGGINGS), 3, 1, 12, 5, 0.2F)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.LAVA_BUCKET, 1, 12, 20), new VillagerTrades.b(Items.DIAMOND, 1, 12, 20), new VillagerTrades.h(new ItemStack(Items.CHAINMAIL_HELMET), 1, 1, 12, 10, 0.2F), new VillagerTrades.h(new ItemStack(Items.CHAINMAIL_CHESTPLATE), 4, 1, 12, 10, 0.2F), new VillagerTrades.h(new ItemStack(Items.SHIELD), 5, 1, 12, 10, 0.2F)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.e(Items.DIAMOND_LEGGINGS, 14, 3, 15, 0.2F), new VillagerTrades.e(Items.DIAMOND_BOOTS, 8, 3, 15, 0.2F)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.e(Items.DIAMOND_HELMET, 8, 3, 30, 0.2F), new VillagerTrades.e(Items.DIAMOND_CHESTPLATE, 16, 3, 30, 0.2F)}))); diff --git a/src/main/java/net/minecraft/server/VoxelShapeMergerList.java b/src/main/java/net/minecraft/server/VoxelShapeMergerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/VoxelShapeMergerList.java @@ -685,18 +662,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.b.add(i - 1); this.c.add(j - 1); this.a.add(d1); -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 - builder.put(dynamicops.createString("type"), dynamicops.createString(IRegistry.t.getKey(this.a).toString())).put(dynamicops.createString("entries"), this.b.a(dynamicops, (iblockdata) -> { - return IBlockData.a(dynamicops, iblockdata); - })); -- return (new Dynamic(dynamicops, dynamicops.createMap(builder.build()))).getValue(); -+ return (new Dynamic(dynamicops, dynamicops.createMap(builder.build()))).getValue(); // Paper - decompile fix - } - } diff --git a/src/main/java/net/minecraft/server/WorldPersistentData.java b/src/main/java/net/minecraft/server/WorldPersistentData.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldPersistentData.java diff --git a/Spigot-Server-Patches/MC-Utils.patch b/Spigot-Server-Patches/MC-Utils.patch index df4974773c..b8afa8782c 100644 --- a/Spigot-Server-Patches/MC-Utils.patch +++ b/Spigot-Server-Patches/MC-Utils.patch @@ -2291,8 +2291,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return this.distanceSquared(iposition.getX(), iposition.getY(), iposition.getZ(), true) < d0 * d0; } -+ public final double distanceSquared(BaseBlockPosition baseblockposition) { return m(baseblockposition); } // Paper - OBFHELPER - public double m(BaseBlockPosition baseblockposition) { ++ public final double distanceSquared(BaseBlockPosition baseblockposition) { return j(baseblockposition); } // Paper - OBFHELPER + public double j(BaseBlockPosition baseblockposition) { return this.distanceSquared((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ(), true); } diff --git a/src/main/java/net/minecraft/server/BlockAccessAir.java b/src/main/java/net/minecraft/server/BlockAccessAir.java @@ -2318,23 +2318,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public IBlockData getType(BlockPosition blockposition) { return Blocks.AIR.getBlockData(); -diff --git a/src/main/java/net/minecraft/server/BlockData.java b/src/main/java/net/minecraft/server/BlockData.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BlockDataAbstract.java -+++ b/src/main/java/net/minecraft/server/BlockDataAbstract.java -@@ -0,0 +0,0 @@ public abstract static class BlockDataAbstract implements IBlockDataHolder { - return Collections.unmodifiableCollection(this.d.keySet()); - } - -+ public final > boolean hasProperty(IBlockState iblockstate) { return this.b(iblockstate); } // Paper - OBFHELPER - public > boolean b(IBlockState iblockstate) { - return this.d.containsKey(iblockstate); - } 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 +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { return d0 == 0.0D && d1 == 0.0D && d2 == 0.0D ? this : new BlockPosition((double) this.getX() + d0, (double) this.getY() + d1, (double) this.getZ() + d2); } @@ -2342,7 +2330,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public BlockPosition b(int i, int j, int k) { return i == 0 && j == 0 && k == 0 ? this : new BlockPosition(this.getX() + i, this.getY() + j, this.getZ() + k); } -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { return new BlockPosition(this.getY() * baseblockposition.getZ() - this.getZ() * baseblockposition.getY(), this.getZ() * baseblockposition.getX() - this.getX() * baseblockposition.getZ(), this.getX() * baseblockposition.getY() - this.getY() * baseblockposition.getX()); } @@ -2351,58 +2339,66 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public BlockPosition immutableCopy() { return this; } -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali - super(i, j, k); - } - -+ public static BlockPosition.PooledBlockPosition acquire() { return r(); } // Paper - OBFHELPER - public static BlockPosition.PooledBlockPosition r() { - return f(0, 0, 0); - } -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali - return this.d; +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { + return super.a(enumblockrotation).immutableCopy(); } + 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; -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali - return this.c(entity.locX(), entity.locY(), entity.locZ()); + this.o(i); + this.p(j); +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { + return this; } + public BlockPosition.MutableBlockPosition setValues(double d0, double d1, double d2) { return c(d0, d1, d2);} // Paper - OBFHELPER public BlockPosition.MutableBlockPosition c(double d0, double d1, double d2) { return this.d(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); } -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali - return this.d(this.b + i, this.c + j, this.d + k); +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { + } } -+ public final void setX(final int x) { this.o(x); } // Paper - OBFHELPER ++ public final void setX(final int x) { super.o(x); } // Paper - OBFHELPER + @Override public void o(int i) { - this.b = i; + super.o(i); } -+ public final void setY(final int y) { this.p(y); } // Paper - OBFHELPER ++ public final void setY(final int y) { super.p(y); } // Paper - OBFHELPER + @Override public void p(int i) { - this.c = i; + super.p(i); } -+ public final void setZ(final int z) { this.q(z); } // Paper - OBFHELPER ++ public final void setZ(final int z) { super.q(z); } // Paper - OBFHELPER + @Override public void q(int i) { - this.d = i; + super.q(i); +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { + return new BlockPosition(this); } + } ++ ++ // Paper start ++ public static class PooledBlockPosition extends BlockPosition.MutableBlockPosition implements AutoCloseable { ++ @Deprecated ++ public void close() {} ++ @Deprecated ++ public static BlockPosition.PooledBlockPosition acquire() { return new PooledBlockPosition(); } ++ } ++ // Paper end + } 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 @@ import org.apache.logging.log4j.Logger; - public class Chunk implements IChunkAccess { +@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { private static final Logger LOGGER = LogManager.getLogger(); + @Nullable - public static final ChunkSection a = null; -+ public static final ChunkSection a = null; public static final ChunkSection EMPTY_CHUNK_SECTION = Chunk.a; // Paper - OBFHELPER ++ public static final ChunkSection a = null; public static final ChunkSection EMPTY_CHUNK_SECTION = a; // Paper - OBFHELPER private final ChunkSection[] sections; private BiomeStorage d; private final Map e; @@ -2418,7 +2414,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { this.n = new ShortList[16]; this.entitySlices = (List[]) (new List[16]); // Spigot - this.world = world; + this.world = (WorldServer) world; // CraftBukkit - type - this.loc = chunkcoordintpair; + this.loc = chunkcoordintpair; this.coordinateKey = MCUtil.getCoordinateKey(chunkcoordintpair); // Paper - cache coordinate key this.i = chunkconverter; @@ -2734,7 +2730,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { private final ChunkMapDistance chunkMapDistance; - public final ChunkGenerator chunkGenerator; + public final ChunkGenerator chunkGenerator; private final WorldServer world; - private final Thread serverThread; + public final Thread serverThread; // Paper - private -> public @@ -2742,9 +2738,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private final ChunkProviderServer.a serverThreadQueue; public final PlayerChunkMap playerChunkMap; @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - private final ChunkStatus[] cacheStatus = new ChunkStatus[4]; private final IChunkAccess[] cacheChunk = new IChunkAccess[4]; - + @Nullable + private SpawnerCreature.d p; + // Paper start + final com.destroystokyo.paper.util.concurrent.WeakSeqLock loadedChunkMapSeqLock = new com.destroystokyo.paper.util.concurrent.WeakSeqLock(); + final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap loadedChunkMap = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(8192, 0.5f); @@ -2863,7 +2859,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(x, z); + Long identifier = Long.valueOf(this.chunkFutureAwaitCounter++); -+ this.addTicketAtLevel(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, identifier); ++ this.chunkMapDistance.addTicketAtLevel(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, identifier); + this.tickDistanceManager(); + + PlayerChunk chunk = this.playerChunkMap.getUpdatingChunk(chunkPos.pair()); @@ -2900,17 +2896,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } finally { + // due to odd behaviour with CB unload implementation we need to have these AFTER the load callback. -+ ChunkProviderServer.this.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, ticketLevel, chunkPos); -+ ChunkProviderServer.this.removeTicketAtLevel(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, identifier); ++ ChunkProviderServer.this.chunkMapDistance.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, ticketLevel, chunkPos); ++ ChunkProviderServer.this.chunkMapDistance.removeTicketAtLevel(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, identifier); + } + }, this.serverThreadQueue); + } + // Paper end -+ -+ - public ChunkProviderServer(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator chunkgenerator, int i, WorldLoadListener worldloadlistener, Supplier supplier) { + + public ChunkProviderServer(WorldServer worldserver, Convertable.ConversionSession convertable_conversionsession, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator chunkgenerator, int i, boolean flag, WorldLoadListener worldloadlistener, Supplier supplier) { this.world = worldserver; - this.serverThreadQueue = new ChunkProviderServer.a(worldserver); @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { this.cacheChunk[0] = ichunkaccess; } @@ -2961,6 +2955,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable @Override public IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) { +@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { + + this.p = spawnercreature_d; + this.world.getMethodProfiler().exit(); +- List list = Lists.newArrayList(this.playerChunkMap.f()); +- +- Collections.shuffle(list); +- list.forEach((playerchunk) -> { ++ //List list = Lists.newArrayList(this.playerChunkMap.f()); // Paper ++ //Collections.shuffle(list); // Paper ++ this.playerChunkMap.f().forEach((playerchunk) -> { // Paper - no... just no... + Optional optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); + + if (optional.isPresent()) { diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ChunkSection.java @@ -2978,12 +2986,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/DataBits.java +++ b/src/main/java/net/minecraft/server/DataBits.java @@ -0,0 +0,0 @@ public class DataBits { - } + return (int) (k >> l & this.d); } + public long[] getDataBits() { return this.a(); } // Paper - OBFHELPER public long[] a() { - return this.a; + return this.b; } diff --git a/src/main/java/net/minecraft/server/DataPalette.java b/src/main/java/net/minecraft/server/DataPalette.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -2996,7 +3004,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + default int getOrCreateIdFor(T object) { return this.a(object); } // Paper - OBFHELPER int a(T t0); - boolean b(T t0); + boolean a(Predicate predicate); + @Nullable default T getObject(int dataBits) { return this.a(dataBits); } // Paper - OBFHELPER @Nullable @@ -3044,18 +3052,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void b(PacketDataSerializer packetdataserializer) { this.a(); packetdataserializer.writeByte(this.i); -diff --git a/src/main/java/net/minecraft/server/DimensionManager.java b/src/main/java/net/minecraft/server/DimensionManager.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/DimensionManager.java -+++ b/src/main/java/net/minecraft/server/DimensionManager.java -@@ -0,0 +0,0 @@ public class DimensionManager implements MinecraftSerializable { - return this.folder.isEmpty() ? file : new File(file, this.folder); - } - -+ public WorldServer world; // Paper - store ref to world this manager is for - public WorldProvider getWorldProvider(World world) { - return (WorldProvider) this.providerFactory.apply(world, this); - } 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 @@ -3064,12 +3060,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } -+ public final AxisAlignedBB getCollisionBox(){return au();} //Paper - OBFHELPER - @Nullable - public AxisAlignedBB au() { +- @Nullable +- public AxisAlignedBB ay() { ++ ++ @Nullable public final AxisAlignedBB getCollisionBox(){return ay();} //Paper - OBFHELPER ++ @Nullable public AxisAlignedBB ay() { return null; + } + @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener { - return false; + return EnumInteractionResult.PASS; } + public final AxisAlignedBB getHardCollisionBox(Entity entity){ return j(entity);}//Paper - OBFHELPER @@ -3106,8 +3106,8 @@ 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 { - public org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes; public boolean collides = true; + public Set collidableExemptions = new HashSet<>(); public boolean canPickUpLoot; + public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper @@ -3136,11 +3136,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper + public EntityPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) { - super((World) worldserver, gameprofile); - playerinteractmanager.player = this; + super(worldserver, worldserver.getSpawn(), gameprofile); + this.spawnDimension = World.OVERWORLD; @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - this.H = 1.0F; - this.a(worldserver); + this.G = 1.0F; + this.b(worldserver); + this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper + @@ -3151,8 +3151,8 @@ diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityTypes.java +++ b/src/main/java/net/minecraft/server/EntityTypes.java -@@ -0,0 +0,0 @@ import com.mojang.datafixers.DataFixUtils; - import java.util.Collections; +@@ -0,0 +0,0 @@ package net.minecraft.server; + import com.google.common.collect.ImmutableSet; import java.util.Optional; import java.util.Set; // Paper +import java.util.Map; // Paper @@ -3160,14 +3160,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import java.util.function.Function; import java.util.stream.Stream; @@ -0,0 +0,0 @@ public class EntityTypes { - return this.bj.height; + return this.bq.height; } - @Nullable - public T a(World world) { + public T create(World world) { return this.a(world); } // Paper - OBFHELPER + @Nullable public T a(World world) { // Paper - OBFHELPER - return this.ba.create(this, world); + return this.be.create(this, world); } diff --git a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java @@ -3217,33 +3217,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end + default int h(BlockPosition blockposition) { - return this.getType(blockposition).h(); - } -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.c != null && this.c.f != null ? this.c.f[enumdirection.ordinal()] : VoxelShapes.a(this.j(iblockaccess, blockposition), enumdirection); - } - -+ public final boolean exceedsCube(){ return f();} // Paper - OBFHELPER - public boolean f() { - return this.c == null || this.c.h; + return this.getType(blockposition).f(); } diff --git a/src/main/java/net/minecraft/server/IOWorker.java b/src/main/java/net/minecraft/server/IOWorker.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/IOWorker.java +++ b/src/main/java/net/minecraft/server/IOWorker.java @@ -0,0 +0,0 @@ public class IOWorker implements AutoCloseable { - private final Thread b; - private final AtomicBoolean c = new AtomicBoolean(); - private final Queue d = Queues.newConcurrentLinkedQueue(); -- private final RegionFileCache e; -+ private final RegionFileCache e; public RegionFileCache getRegionFileCache() { return e; } // Paper - OBFHELPER - private final Map f = Maps.newLinkedHashMap(); - private boolean g = true; - private CompletableFuture h = new CompletableFuture(); + private static final Logger LOGGER = LogManager.getLogger(); + private final AtomicBoolean b = new AtomicBoolean(); + private final ThreadedMailbox c; +- private final RegionFileCache d; ++ private final RegionFileCache d;public RegionFileCache getRegionFileCache() { return d; } // Paper - OBFHELPER + private final Map e = Maps.newLinkedHashMap(); + + protected IOWorker(File file, boolean flag, String s) { diff --git a/src/main/java/net/minecraft/server/IWorldReader.java b/src/main/java/net/minecraft/server/IWorldReader.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/IWorldReader.java @@ -3260,27 +3248,15 @@ diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/n index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java -@@ -0,0 +0,0 @@ import org.bukkit.event.world.StructureGrowEvent; - public final class ItemStack { - +@@ -0,0 +0,0 @@ public final class ItemStack { + })).apply(instance, ItemStack::new); + }); private static final Logger LOGGER = LogManager.getLogger(); -- public static final ItemStack a = new ItemStack((Item) null); -+ public static final ItemStack a = new ItemStack((Item) null);public static final ItemStack NULL_ITEM = a; // Paper - OBFHELPER - public static final DecimalFormat b = H(); - private int count; - private int e; -+ // Paper start -+ private org.bukkit.craftbukkit.inventory.CraftItemStack bukkitStack; -+ public org.bukkit.inventory.ItemStack getBukkitStack() { -+ if (bukkitStack == null || bukkitStack.getHandle() != this) { -+ bukkitStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this); -+ } -+ return bukkitStack; -+ } -+ // Paper end - @Deprecated - private Item item; - private NBTTagCompound tag; +- public static final ItemStack b = new ItemStack((Item) null); ++ public static final ItemStack b = new ItemStack((Item) null);public static final ItemStack NULL_ITEM = b; // Paper - OBFHELPER + public static final DecimalFormat c = (DecimalFormat) SystemUtils.a((new DecimalFormat("#.##")), (decimalformat) -> { // CraftBukkit - decompile error + decimalformat.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT)); + }); @@ -0,0 +0,0 @@ public final class ItemStack { return this.tag != null ? this.tag.getList("Enchantments", 10) : new NBTTagList(); } @@ -3295,6 +3271,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public static ItemStack fromBukkitCopy(org.bukkit.inventory.ItemStack itemstack) { + return CraftItemStack.asNMSCopy(itemstack); + } ++ private org.bukkit.craftbukkit.inventory.CraftItemStack bukkitStack; ++ public org.bukkit.inventory.ItemStack getBukkitStack() { ++ if (bukkitStack == null || bukkitStack.getHandle() != this) { ++ bukkitStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this); ++ } ++ return bukkitStack; ++ } + // Paper end public void setTag(@Nullable NBTTagCompound nbttagcompound) { this.tag = nbttagcompound; @@ -3782,24 +3765,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + asyncExecutor.execute(run); + } + -+ @Nullable -+ public static TileEntityHopper getHopper(World world, BlockPosition pos) { -+ Chunk chunk = world.getChunkIfLoaded(pos.getX() >> 4, pos.getZ() >> 4); -+ if (chunk != null && chunk.getType(new BlockPosition(pos.getX(), pos.getY(), pos.getZ())).getBlock() == Blocks.HOPPER) { -+ TileEntity tileEntity = chunk.getTileEntityImmediately(pos); -+ if (tileEntity instanceof TileEntityHopper) { -+ return (TileEntityHopper) tileEntity; -+ } -+ } -+ return null; -+ } -+ + @Nonnull -+ public static World getNMSWorld(@Nonnull org.bukkit.World world) { ++ public static WorldServer getNMSWorld(@Nonnull org.bukkit.World world) { + return ((CraftWorld) world).getHandle(); + } + -+ public static World getNMSWorld(@Nonnull org.bukkit.entity.Entity entity) { ++ public static WorldServer getNMSWorld(@Nonnull org.bukkit.entity.Entity entity) { + return getNMSWorld(entity.getWorld()); + } + @@ -3840,8 +3811,8 @@ 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 map; + public final Map map; // Paper - private NBTTagCompound(Map map) { + protected NBTTagCompound(Map map) { this.map = map; @@ -0,0 +0,0 @@ public class NBTTagCompound implements NBTBase { this.map.put(s, NBTTagLong.a(i)); @@ -3868,15 +3839,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public void setUUID(String prefix, UUID uuid) { a(prefix, uuid); } // Paper - OBFHELPER public void a(String s, UUID uuid) { - this.setLong(s + "Most", uuid.getMostSignificantBits()); - this.setLong(s + "Least", uuid.getLeastSignificantBits()); + this.map.put(s, GameProfileSerializer.a(uuid)); } + + @Nullable public UUID getUUID(String prefix) { return a(prefix); } // Paper - OBFHELPER + @Nullable public UUID a(String s) { - return new UUID(this.getLong(s + "Most"), this.getLong(s + "Least")); + return GameProfileSerializer.a(this.get(s)); } diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -3946,7 +3916,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private byte[] f; private byte[] getData() { return this.f; } // Paper - OBFHELPER private List g; private boolean h; - + private boolean i; @@ -0,0 +0,0 @@ public class PacketPlayOutMapChunk implements Packet { return bytebuf; } @@ -4171,12 +4141,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + int chunkZ = MCUtil.getChunkCoordinate(player.locZ()); + // Note: players need to be explicitly added to distance maps before they can be updated + } -+ -+ + // Paper end + - public PlayerChunkMap(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator chunkgenerator, WorldLoadListener worldloadlistener, Supplier supplier, int i) { - super(new File(worldserver.getWorldProvider().getDimensionManager().a(file), "region"), datafixer); + public PlayerChunkMap(WorldServer worldserver, Convertable.ConversionSession convertable_conversionsession, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator chunkgenerator, WorldLoadListener worldloadlistener, Supplier supplier, int i, boolean flag) { + super(new File(convertable_conversionsession.a(worldserver.getDimensionKey()), "region"), datafixer, flag); this.visibleChunks = this.updatingChunks.clone(); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { }; @@ -4199,7 +4167,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + this.addPlayerToDistanceMaps(entityplayer); // Paper - distance maps } else { - SectionPosition sectionposition = entityplayer.K(); + SectionPosition sectionposition = entityplayer.N(); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { if (!flag2) { @@ -4299,8 +4267,8 @@ diff --git a/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java b/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java +++ b/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java -@@ -0,0 +0,0 @@ public class RegionLimitedWorldAccess implements GeneratorAccess { - return i >= ichunkaccess.getPos().x && i <= ichunkaccess1.getPos().x && j >= ichunkaccess.getPos().z && j <= ichunkaccess1.getPos().z; +@@ -0,0 +0,0 @@ public class RegionLimitedWorldAccess implements GeneratorAccessSeed { + return i >= this.n.x && i <= this.o.x && j >= this.n.z && j <= this.o.z; } + // Paper start - if loaded util @@ -4393,13 +4361,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import org.bukkit.event.block.BlockPhysicsEvent; // CraftBukkit end @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot - this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(worlddata.getName(), this.spigotConfig); // Paper + + protected World(WorldDataMutable worlddatamutable, ResourceKey resourcekey, ResourceKey resourcekey1, DimensionManager dimensionmanager, Supplier supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { + this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot +- this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(worlddata.getName(), this.spigotConfig); // Paper ++ this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig((((WorldDataServer)worlddatamutable).getName()), this.spigotConfig); // Paper this.generator = gen; -+ if (dimensionmanager.world == null) dimensionmanager.world = (WorldServer) this; // Paper this.world = new CraftWorld((WorldServer) this, gen, env); this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit - this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns(); // CraftBukkit @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { return (Chunk) this.getChunkAt(i, j, ChunkStatus.FULL); } @@ -4408,7 +4377,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Nullable + @Override + public IChunkAccess getChunkIfLoadedImmediately(int x, int z) { -+ return ((ChunkProviderServer)this.chunkProvider).getChunkAtIfLoadedImmediately(x, z); ++ return ((WorldServer)this).chunkProvider.getChunkAtIfLoadedImmediately(x, z); + } + + @Override @@ -4439,7 +4408,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override public IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) { - IChunkAccess ichunkaccess = this.chunkProvider.getChunkAt(i, j, chunkstatus, flag); + IChunkAccess ichunkaccess = this.getChunkProvider().getChunkAt(i, j, chunkstatus, flag); @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { public void a(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1) {} @@ -4460,11 +4429,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return this.b(entity.locX(), entity.locZ()); } -+ public final VoxelShape asVoxelShape(){ return a();} // Paper - OBFHELPER -+ - public VoxelShape a() { - return this.i.m(); ++ public final VoxelShape asVoxelShape(){ return c();} // Paper - OBFHELPER + public VoxelShape c() { + return this.j.m(); } +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 { + private final Map entitiesByUUID = Maps.newHashMap(); + private final Queue entitiesToAdd = Queues.newArrayDeque(); + private final List players = Lists.newArrayList(); +- private final ChunkProviderServer chunkProvider; ++ public final ChunkProviderServer chunkProvider; // Paper - public + boolean tickingEntities; + private final MinecraftServer server; + public final WorldDataServer worldDataServer; // CraftBukkit - type 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 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -4670,7 +4651,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java +++ b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java @@ -0,0 +0,0 @@ public class DummyGeneratorAccess implements GeneratorAccess { - public boolean a(BlockPosition blockposition, boolean flag, Entity entity) { + public boolean a(BlockPosition blockposition, boolean flag, Entity entity, int i) { throw new UnsupportedOperationException("Not supported yet."); } + diff --git a/Spigot-Server-Patches/Optimize-explosions.patch b/Spigot-Server-Patches/Optimize-explosions.patch index 4a2f5a3ce7..7d2822d932 100644 --- a/Spigot-Server-Patches/Optimize-explosions.patch +++ b/Spigot-Server-Patches/Optimize-explosions.patch @@ -128,12 +128,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant world.paperConfig.hardDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // Paper - custom despawn distances + if (entityhuman != null) { + double d0 = entityhuman.h((Entity) this); // CraftBukkit - decompile error diff --git a/src/main/java/net/minecraft/server/EntitySilverfish.java b/src/main/java/net/minecraft/server/EntitySilverfish.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntitySilverfish.java @@ -44,6 +44,80 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } else { return false; } +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 ++++ b/src/main/java/net/minecraft/server/IEntityAccess.java +@@ -0,0 +0,0 @@ public interface IEntityAccess { + } + } + +- @Nullable +- default EntityHuman a(double d0, double d1, double d2, double d3, @Nullable Predicate predicate) { ++ default EntityHuman findNearbyPlayer(Entity entity, double d0, @Nullable Predicate predicate) { return this.findNearbyPlayer(entity.locX(), entity.locY(), entity.locZ(), d0, predicate); } // Paper ++ @Nullable default EntityHuman findNearbyPlayer(double d0, double d1, double d2, double d3, @Nullable Predicate predicate) { return a(d0, d1, d2, d3, predicate); } // Paper - OBFHELPER ++ @Nullable default EntityHuman a(double d0, double d1, double d2, double d3, @Nullable Predicate predicate) { // Paper + double d4 = -1.0D; + EntityHuman entityhuman = null; + Iterator iterator = this.getPlayers().iterator(); +@@ -0,0 +0,0 @@ public interface IEntityAccess { + return this.a(d0, d1, d2, d3, predicate); + } + ++ // Paper end ++ default boolean isAffectsSpawningPlayerNearby(double d0, double d1, double d2, double d3) { ++ Iterator iterator = this.getPlayers().iterator(); ++ double d4; ++ do { ++ EntityHuman entityhuman; ++ do { ++ if (!iterator.hasNext()) { ++ return false; ++ } ++ ++ entityhuman = (EntityHuman) iterator.next(); ++ } while (!IEntitySelector.affectsSpawning.test(entityhuman)); ++ ++ d4 = entityhuman.g(d0, d1, d2); ++ } while (d3 >= 0.0D && d4 >= d3 * d3); ++ ++ return true; ++ } ++ // Paper end ++ + default boolean isPlayerNearby(double d0, double d1, double d2, double d3) { + Iterator iterator = this.getPlayers().iterator(); + +diff --git a/src/main/java/net/minecraft/server/IEntitySelector.java b/src/main/java/net/minecraft/server/IEntitySelector.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/IEntitySelector.java ++++ b/src/main/java/net/minecraft/server/IEntitySelector.java +@@ -0,0 +0,0 @@ public final class IEntitySelector { + return !entity.isSpectator(); + }; + ++ // Paper start ++ public static final Predicate affectsSpawning = (entity) -> { ++ return !entity.isSpectator() && entity.isAlive() && (entity instanceof EntityPlayer) && ((EntityPlayer) entity).affectsSpawning; ++ }; ++ // Paper end ++ + public static Predicate a(double d0, double d1, double d2, double d3) { + double d4 = d3 * d3; + +diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java ++++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java +@@ -0,0 +0,0 @@ public abstract class MobSpawnerAbstract { + private boolean h() { + BlockPosition blockposition = this.b(); + +- return this.a().isPlayerNearby((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, (double) this.requiredPlayerRange); ++ return this.a().isAffectsSpawningPlayerNearby((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, (double) this.requiredPlayerRange); // Paper + } + + public void c() { 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/Send-absolute-position-the-first-time-an-entity-is-s.patch b/Spigot-Server-Patches/Send-absolute-position-the-first-time-an-entity-is-s.patch index 63f4f84ca5..b855e2175b 100644 --- a/Spigot-Server-Patches/Send-absolute-position-the-first-time-an-entity-is-s.patch +++ b/Spigot-Server-Patches/Send-absolute-position-the-first-time-an-entity-is-s.patch @@ -8,8 +8,8 @@ diff --git a/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/src/ma index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java +++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java -@@ -0,0 +0,0 @@ package net.minecraft.server; - +@@ -0,0 +0,0 @@ import com.google.common.collect.Lists; + import com.mojang.datafixers.util.Pair; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; diff --git a/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch b/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch index bc94ff646c..6b9f14f647 100644 --- a/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch +++ b/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch @@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -0,0 +0,0 @@ public class Main { - deadline.add(Calendar.DAY_OF_YEAR, -21); + deadline.add(Calendar.DAY_OF_YEAR, -3); if (buildDate.before(deadline.getTime())) { System.err.println("*** Error, this build is outdated ***"); - System.err.println("*** Please download a new build as per instructions from https://www.spigotmc.org/go/outdated-spigot ***"); @@ -73,7 +73,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end + System.out.println("Loading libraries, please wait..."); - MinecraftServer.main(options); + net.minecraft.server.Main.main(options); } catch (Throwable t) { diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 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 e81295396c..ce6f87f910 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 @@ -11,15 +11,6 @@ diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/m 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 final ChunkSection[] sections; - private BiomeStorage d; - private final Map e; -- public boolean loaded; -+ public boolean loaded; public boolean isLoaded() { return loaded; } // Paper - OBFHELPER - public final World world; - public final Map heightMap; - private final ChunkConverter i; @@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { this(world, chunkcoordintpair, biomestorage, ChunkConverter.a, TickListEmpty.b(), TickListEmpty.b(), 0L, (ChunkSection[]) null, (Consumer) null); } @@ -92,20 +83,11 @@ diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/ 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 - private static final DataWatcherObject aB = DataWatcher.a(Entity.class, DataWatcherRegistry.i); - private static final DataWatcherObject aC = DataWatcher.a(Entity.class, DataWatcherRegistry.i); - protected static final DataWatcherObject POSE = DataWatcher.a(Entity.class, DataWatcherRegistry.s); -- public boolean inChunk; -+ public boolean inChunk; public boolean isAddedToChunk() { return inChunk; } // Paper - OBFHELPER - public int chunkX; public int getChunkX() { return chunkX; } // Paper - OBFHELPER - public int chunkY; public int getChunkY() { return chunkY; } // Paper - OBFHELPER - public int chunkZ; public int getChunkZ() { return chunkZ; } // Paper - OBFHELPER @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } public boolean isChunkLoaded() { -- return world.isChunkLoaded((int) Math.floor(this.locX) >> 4, (int) Math.floor(this.locZ) >> 4); +- return world.isChunkLoaded((int) Math.floor(this.locX()) >> 4, (int) Math.floor(this.locZ()) >> 4); + return getCurrentChunk() != null; } // CraftBukkit end @@ -124,31 +106,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + */ + public Chunk getCurrentChunk() { + final Chunk chunk = currentChunk != null ? currentChunk.get() : null; -+ if (chunk != null && chunk.isLoaded()) { ++ if (chunk != null && chunk.loaded) { + return chunk; + } + -+ return !isAddedToChunk() ? null : ((ChunkProviderServer) world.chunkProvider).getChunkAtIfLoadedMainThreadNoCache(getChunkX(), getChunkZ()); -+ } -+ -+ /** -+ * Returns the chunk at the location, using the entities local cache if avail -+ * Will only return null if the location specified is not loaded -+ */ -+ public Chunk getCurrentChunkAt(int x, int z) { -+ Chunk chunk = getCurrentChunk(); -+ if (chunk != null && getChunkX() == chunk.getPos().x && getChunkZ() == chunk.getPos().z) { -+ return chunk; -+ } -+ return ((ChunkProviderServer) world.chunkProvider).getChunkAtIfLoadedMainThreadNoCache(getChunkX(), getChunkZ()); -+ } -+ /** -+ * Returns the chunk at the entities current location, using the entities local cache if avail -+ * Ideally this is always the same as getCurrentChunk, but only becomes different in registration issues. -+ * Will only return null if the location specified is not loaded -+ */ -+ public Chunk getChunkAtLocation() { -+ return getCurrentChunkAt((int)Math.floor(locX) >> 4, (int)Math.floor(locZ) >> 4); ++ return !inChunk ? null : ((WorldServer)world).getChunkProvider().getChunkAtIfLoadedMainThreadNoCache(getChunkX(), getChunkZ()); + } + private MinecraftKey entityKey; diff --git a/Spigot-Server-Patches/Timings-v2.patch b/Spigot-Server-Patches/Timings-v2.patch index b1649830d0..fe546d753f 100644 --- a/Spigot-Server-Patches/Timings-v2.patch +++ b/Spigot-Server-Patches/Timings-v2.patch @@ -717,10 +717,10 @@ 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 { - protected final boolean q; - protected final SoundEffectType stepSound; - protected final Material material; +@@ -0,0 +0,0 @@ public class Block extends BlockBase implements IMaterial { + private static final VoxelShape c = a(7.0D, 0.0D, 7.0D, 9.0D, 10.0D, 9.0D); + protected final BlockStateList blockStateList; + private IBlockData blockData; + // Paper start + public co.aikar.timings.Timing timing; + public co.aikar.timings.Timing getTiming() { @@ -730,9 +730,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return timing; + } + // Paper end - protected final MaterialMapColor t; - private final float frictionFactor; - private final float f; + @Nullable + private String name; + @Nullable 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 @@ -794,49 +794,43 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.world.getMethodProfiler().exitEnter("unload"); this.playerChunkMap.unloadChunks(booleansupplier); @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - // CraftBukkit end + boolean flag2 = world.ticksPerAnimalSpawns != 0L && worlddata.getTime() % world.ticksPerAnimalSpawns == 0L; // CraftBukkit this.world.getMethodProfiler().enter("naturalSpawnCount"); + this.world.timings.countNaturalMobs.startTiming(); // Paper - timings int l = this.chunkMapDistance.b(); - EnumCreatureType[] aenumcreaturetype = EnumCreatureType.values(); - Object2IntMap object2intmap = this.world.l(); - + SpawnerCreature.d spawnercreature_d = SpawnerCreature.a(l, this.world.z(), this::a); + this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings - this.world.getMethodProfiler().exit(); - this.playerChunkMap.f().forEach((playerchunk) -> { - Optional optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); -@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - Chunk chunk = (Chunk) optional.get(); + this.p = spawnercreature_d; + this.world.getMethodProfiler().exit(); +@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { + + if (optional.isPresent()) { this.world.getMethodProfiler().enter("broadcast"); + this.world.timings.broadcastChunkUpdates.startTiming(); // Paper - timings - playerchunk.a(chunk); + playerchunk.a((Chunk) optional.get()); + this.world.timings.broadcastChunkUpdates.stopTiming(); // Paper - timings this.world.getMethodProfiler().exit(); - ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); + Optional optional1 = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); - if (!this.playerChunkMap.isOutsideOfRange(chunkcoordintpair)) { -+ // Paper end - chunk.setInhabitedTime(chunk.getInhabitedTime() + j); - if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(chunkcoordintpair, true)) { // Spigot - this.world.getMethodProfiler().enter("spawner"); @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - this.world.getMethodProfiler().exit(); - } + SpawnerCreature.a(this.world, chunk, spawnercreature_d, this.allowAnimals, this.allowMonsters, flag2); + } -- this.world.timings.doTickTiles.startTiming(); // Spigot -+ this.world.timings.chunkTicks.startTiming(); // Spigot // Paper - this.world.a(chunk, k); -- this.world.timings.doTickTiles.stopTiming(); // Spigot -+ this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper +- this.world.timings.doTickTiles.startTiming(); // Spigot ++ this.world.timings.chunkTicks.startTiming(); // Spigot // Paper + this.world.a(chunk, k); +- this.world.timings.doTickTiles.stopTiming(); // Spigot ++ this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper + } } } }); this.world.getMethodProfiler().enter("customSpawners"); if (flag1) { + try (co.aikar.timings.Timing ignored = this.world.timings.miscMobSpawning.startTiming()) { // Paper - timings - this.chunkGenerator.doMobSpawning(this.world, this.allowMonsters, this.allowAnimals); + this.world.doMobSpawning(this.allowMonsters, this.allowAnimals); + } // Paper - timings } @@ -849,7 +843,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.world.timings.tracker.stopTiming(); // Spigot } - @Override + private void a(long i, Consumer consumer) { diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java @@ -886,7 +880,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - } - private static NBTTagCompound a(ChunkCoordIntPair chunkcoordintpair, Map map, Map map1) { + private static NBTTagCompound a(ChunkCoordIntPair chunkcoordintpair, Map, StructureStart> map, Map, LongSet> map1) { diff --git a/src/main/java/net/minecraft/server/CustomFunction.java b/src/main/java/net/minecraft/server/CustomFunction.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/CustomFunction.java @@ -918,28 +912,19 @@ diff --git a/src/main/java/net/minecraft/server/CustomFunctionData.java b/src/ma index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/CustomFunctionData.java +++ b/src/main/java/net/minecraft/server/CustomFunctionData.java -@@ -0,0 +0,0 @@ public class CustomFunctionData implements IResourcePackListener { +@@ -0,0 +0,0 @@ public class CustomFunctionData { } else { int j; - try { + try (co.aikar.timings.Timing timing = customfunction.getTiming().startTiming()) { // Paper - this.h = true; + this.d = true; int k = 0; CustomFunction.c[] acustomfunction_c = customfunction.b(); diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/DedicatedServer.java -@@ -0,0 +0,0 @@ import java.util.List; - import java.util.Locale; - import java.util.Optional; - import java.util.Random; -+import java.util.concurrent.CompletableFuture; -+import java.util.concurrent.ExecutionException; - import java.util.function.BooleanSupplier; - import java.util.regex.Pattern; - import javax.annotation.Nullable; @@ -0,0 +0,0 @@ import org.apache.logging.log4j.Level; import org.bukkit.command.CommandSender; @@ -1044,7 +1029,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void move(EnumMoveType enummovetype, Vec3D vec3d) { - org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot if (this.noclip) { - this.a(this.getBoundingBox().b(vec3d)); + this.a(this.getBoundingBox().c(vec3d)); this.recalcPosition(); @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke @@ -1053,7 +1038,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot } - protected BlockPosition ag() { + protected BlockPosition ak() { 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 @@ -1073,8 +1058,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void tick() { - SpigotTimings.timerEntityBaseTick.startTiming(); // Spigot super.tick(); - this.o(); - this.r(); + this.u(); + this.x(); @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { } } @@ -1093,7 +1078,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot } - protected float f(float f, float f1) { + private void q() { @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { this.setMot(d4, d5, d6); @@ -1101,7 +1086,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - SpigotTimings.timerEntityAI.startTiming(); // Spigot if (this.isFrozen()) { this.jumping = false; - this.aZ = 0.0F; + this.aY = 0.0F; @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { this.doTick(); this.world.getMethodProfiler().exit(); @@ -1111,15 +1096,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.world.getMethodProfiler().exit(); this.world.getMethodProfiler().enter("jump"); @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { - this.n(); + this.t(); AxisAlignedBB axisalignedbb = this.getBoundingBox(); - SpigotTimings.timerEntityAIMove.startTiming(); // Spigot - this.e(new Vec3D((double) this.aZ, (double) this.ba, (double) this.bb)); + this.f(new Vec3D((double) this.aY, (double) this.aZ, (double) this.ba)); - SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot this.world.getMethodProfiler().exit(); this.world.getMethodProfiler().enter("push"); - if (this.bn > 0) { + if (this.bm > 0) { @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { this.a(axisalignedbb, this.getBoundingBox()); } @@ -1128,8 +1113,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.collideNearby(); - SpigotTimings.timerEntityAICollision.stopTiming(); // Spigot this.world.getMethodProfiler().exit(); - } - + if (!this.world.isClientSide && this.dN() && this.aC()) { + this.damageEntity(DamageSource.DROWN, 1.0F); 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 @@ -1142,17 +1127,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import co.aikar.timings.MinecraftTimings; // Paper import org.spigotmc.SlackActivityAccountant; // Spigot - public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant implements IMojangStatistics, ICommandListener, AutoCloseable, Runnable { + public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant implements IMojangStatistics, ICommandListener, AutoCloseable { @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant resourcePackRepository; + private final ScoreboardServer scoreboardServer; @Nullable @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant= 5000000000L) { + if (i - this.T >= 5000000000L) { @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant implements TickList { - private final List> h = Lists.newArrayList(); - private final Consumer> i; + private final List> g = Lists.newArrayList(); + private final Consumer> h; -- public TickListServer(WorldServer worldserver, Predicate predicate, Function function, Function function1, Consumer> consumer) { -+ public TickListServer(WorldServer worldserver, Predicate predicate, Function function, Function function1, Consumer> consumer, String timingsType) { // Paper +- public TickListServer(WorldServer worldserver, Predicate predicate, Function function, Consumer> consumer) { ++ public TickListServer(WorldServer worldserver, Predicate predicate, Function function, Consumer> consumer, String timingsType) { // Paper this.a = predicate; this.b = function; - this.c = function1; - this.f = worldserver; - this.i = consumer; + this.e = worldserver; + this.h = consumer; + this.timingCleanup = co.aikar.timings.WorldTimingsHandler.getTickList(worldserver, timingsType + " - Cleanup"); + this.timingTicking = co.aikar.timings.WorldTimingsHandler.getTickList(worldserver, timingsType + " - Ticking"); } @@ -1551,7 +1535,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 int i = this.nextTickList.size(); @@ -0,0 +0,0 @@ public class TickListServer implements TickList { - this.f.getMethodProfiler().enter("cleaning"); + this.e.getMethodProfiler().enter("cleaning"); + this.timingCleanup.startTiming(); // Paper NextTickListEntry nextticklistentry; @@ -1564,17 +1548,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.timingCleanup.stopTiming(); // Paper + this.timingTicking.startTiming(); // Paper - this.f.getMethodProfiler().exitEnter("ticking"); + this.e.getMethodProfiler().exitEnter("ticking"); - while ((nextticklistentry = (NextTickListEntry) this.g.poll()) != null) { + while ((nextticklistentry = (NextTickListEntry) this.f.poll()) != null) { @@ -0,0 +0,0 @@ public class TickListServer implements TickList { + } } - this.f.getMethodProfiler().exit(); + this.timingTicking.stopTiming(); // Paper - this.h.clear(); + this.e.getMethodProfiler().exit(); this.g.clear(); - } + this.f.clear(); diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/TileEntity.java @@ -1598,20 +1582,11 @@ diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/m 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 @@ - package net.minecraft.server; - -+import co.aikar.timings.Timing; -+import co.aikar.timings.Timings; - import com.google.common.collect.Lists; - import java.io.IOException; - import java.util.Collection; -@@ -0,0 +0,0 @@ import org.apache.logging.log4j.util.Supplier; +@@ -0,0 +0,0 @@ import org.apache.logging.log4j.Logger; import java.util.HashMap; import java.util.Map; import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.SpigotTimings; // Spigot -+import org.bukkit.block.BlockState; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.block.CapturedBlockState; @@ -1654,10 +1629,10 @@ 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 @@ - package net.minecraft.server; - +@@ -0,0 +0,0 @@ package net.minecraft.server; import com.google.common.annotations.VisibleForTesting; + import com.google.common.collect.ImmutableList; + import com.google.common.collect.Iterables; +import co.aikar.timings.TimingHistory; // Paper +import co.aikar.timings.Timings; // Paper import com.google.common.collect.Lists; @@ -1669,69 +1644,54 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import org.bukkit.WeatherType; -import org.bukkit.craftbukkit.SpigotTimings; // Spigot import org.bukkit.craftbukkit.event.CraftEventFactory; + import org.bukkit.craftbukkit.util.WorldUUID; import org.bukkit.event.entity.CreatureSpawnEvent; - import org.bukkit.event.server.MapInitializeEvent; -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { // CraftBukkit end this.nextTickListBlock = new TickListServer<>(this, (block) -> { return block == null || block.getBlockData().isAir(); -- }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b); -+ }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b, "Blocks"); // Paper - Timings +- }, IRegistry.BLOCK::getKey, this::b); ++ }, IRegistry.BLOCK::getKey, this::b, "Blocks"); // Paper - Timings this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> { return fluidtype == null || fluidtype == FluidTypes.EMPTY; -- }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a); -+ }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a, "Fluids"); // Paper - Timings +- }, IRegistry.FLUID::getKey, this::a); ++ }, IRegistry.FLUID::getKey, this::a, "Fluids"); // Paper - Timings this.navigators = Sets.newHashSet(); - this.I = new ObjectLinkedOpenHashSet(); - this.dataManager = worldnbtstorage; -@@ -0,0 +0,0 @@ public class WorldServer extends World { + this.L = new ObjectLinkedOpenHashSet(); + this.Q = flag1; +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.N(); - this.a(); + this.b(); gameprofilerfiller.exitEnter("chunkSource"); + this.timings.chunkProviderTick.startTiming(); // Paper - timings this.getChunkProvider().tick(booleansupplier); + this.timings.chunkProviderTick.stopTiming(); // Paper - timings gameprofilerfiller.exitEnter("tickPending"); - timings.doTickPending.startTiming(); // Spigot -+ timings.scheduledBlocks.startTiming(); // Spigot - if (this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES) { ++ timings.scheduledBlocks.startTiming(); // Paper + if (!this.isDebugWorld()) { this.nextTickListBlock.b(); this.nextTickListFluid.b(); } - timings.doTickPending.stopTiming(); // Spigot -+ timings.scheduledBlocks.stopTiming(); // Spigot ++ timings.scheduledBlocks.stopTiming(); // Paper gameprofilerfiller.exitEnter("raid"); + this.timings.raids.startTiming(); // Paper - timings this.persistentRaid.a(); - if (this.mobSpawnerTrader != null) { - this.mobSpawnerTrader.a(); - } + this.timings.raids.stopTiming(); // Paper - timings - gameprofilerfiller.exitEnter("blockEvents"); timings.doSounds.startTiming(); // Spigot -@@ -0,0 +0,0 @@ public class WorldServer extends World { + this.ah(); +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { org.spigotmc.ActivationRange.activateEntities(this); // Spigot timings.entityTick.startTiming(); // Spigot + TimingHistory.entityTicks += this.globalEntityList.size(); // Paper while (objectiterator.hasNext()) { Entry entry = (Entry) objectiterator.next(); - Entity entity1 = (Entity) entry.getValue(); -@@ -0,0 +0,0 @@ public class WorldServer extends World { - - this.tickingEntities = false; - -+ try (co.aikar.timings.Timing ignored = this.timings.newEntities.startTiming()) { // Paper - timings - while ((entity = (Entity) this.entitiesToAdd.poll()) != null) { - this.registerEntity(entity); - } -+ } // Paper - timings - - gameprofilerfiller.exit(); - timings.tickEntities.stopTiming(); // Spigot -@@ -0,0 +0,0 @@ public class WorldServer extends World { + Entity entity = (Entity) entry.getValue(); +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { } gameprofilerfiller.exitEnter("tickBlocks"); @@ -1739,7 +1699,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (i > 0) { ChunkSection[] achunksection = chunk.getSections(); int l = achunksection.length; -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { } } } @@ -1748,25 +1708,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 gameprofilerfiller.exit(); } -@@ -0,0 +0,0 @@ public class WorldServer extends World { - - public void entityJoinedWorld(Entity entity) { - if (entity instanceof EntityHuman || this.getChunkProvider().a(entity)) { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { + if (!(entity instanceof EntityHuman) && !this.getChunkProvider().a(entity)) { + this.chunkCheck(entity); + } else { + ++TimingHistory.entityTicks; // Paper - timings // Spigot start if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { entity.ticksLived++; -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { + return; } // Spigot end - + TimingHistory.activatedEntityTicks++; // Paper - timings entity.tickTimer.startTiming(); // Spigot + try { // Paper - timings entity.f(entity.locX(), entity.locY(), entity.locZ()); entity.lastYaw = entity.yaw; entity.lastPitch = entity.pitch; -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.a(entity, entity1); } } @@ -1776,16 +1736,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { if (!flag1) { 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])); + iprogressupdate.a(new ChatMessage("menu.savingLevel")); } -@@ -0,0 +0,0 @@ public class WorldServer extends World { - iprogressupdate.c(new ChatMessage("menu.savingChunks", new Object[0])); +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { + iprogressupdate.c(new ChatMessage("menu.savingChunks")); } + timings.worldSaveChunks.startTiming(); // Paper @@ -1843,6 +1803,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 -import net.minecraft.server.Entity; -import net.minecraft.server.TileEntity; -import net.minecraft.server.World; +-import net.minecraft.server.WorldDataServer; -import org.bukkit.craftbukkit.scheduler.CraftTask; -import org.bukkit.plugin.java.JavaPluginLoader; -import org.bukkit.scheduler.BukkitTask; @@ -1973,7 +1934,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - public final CustomTimingsHandler syncChunkLoadPostTimer; - - public WorldTimingsHandler(World server) { -- String name = server.worldData.getName() +" - "; +- String name = ((WorldDataServer) server.worldData).getName() + " - "; - - mobSpawn = new CustomTimingsHandler("** " + name + "mobSpawn"); - doChunkUnload = new CustomTimingsHandler("** " + name + "doChunkUnload"); @@ -2137,11 +2098,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // Paper end -- CraftTask(final Plugin plugin, final Object task, final int id, final long period) { -+ CraftTask(final Plugin plugin, final Object task, final int id, final long period) { // Paper - this.plugin = plugin; - if (task instanceof Runnable) { - this.rTask = (Runnable) task; @@ -0,0 +0,0 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot } this.id = id; From fbbf45ec423929d415b22eeebec875606034da60 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 25 Jun 2020 04:00:35 -0700 Subject: [PATCH 06/91] more progress --- .../Add-World-Util-Methods.patch | 2 +- ...-to-configure-frosted_ice-properties.patch | 17 ++--- ...dd-configurable-portal-search-radius.patch | 16 ++--- .../Add-exception-reporting-event.patch | 39 +++++------ ...ent-to-allow-plugins-to-handle-clien.patch | 23 +++++-- ...urable-Non-Player-Arrow-Despawn-Rate.patch | 4 +- .../Configurable-Player-Collision.patch | 4 +- .../Configurable-RCON-IP-address.patch | 16 ++--- ...ble-inter-world-teleportation-safety.patch | 4 +- ...le-spawn-chances-for-skeleton-horses.patch | 2 +- .../Custom-replacement-for-eaten-items.patch | 2 +- .../Do-not-load-chunks-for-Pathfinding.patch | 67 +++++++++---------- .../Don-t-tick-Skulls-unused-code.patch | 6 +- ...Entity-AddTo-RemoveFrom-World-Events.patch | 4 +- .../EntityPathfindEvent.patch | 18 ++--- ...r-redstone-torch-rapid-clock-removal.patch | 24 +++---- .../Fix-Double-World-Add-issues.patch | 2 +- .../Fix-Old-Sign-Conversion.patch | 14 ++-- .../Handle-Item-Meta-Inconsistencies.patch | 12 ++-- .../Implement-PlayerLocaleChangeEvent.patch | 39 +++++------ ...item-frames-performance-and-bug-fixe.patch | 16 ++--- ...-API-Replenishable-Lootables-Feature.patch | 28 +++++--- ...mative-vehicle-moved-wrongly-message.patch | 19 ------ ...ckPhysicsEvent-if-a-plugin-has-a-lis.patch | 25 +++---- ...on-Wither-Death-sounds-to-same-world.patch | 34 +++++----- .../Optimize-UserCache-Thread-Safe.patch | 2 +- ...Location-getType-and-getBlockData-fo.patch | 21 +++--- .../Optional-TNT-doesn-t-move-in-water.patch | 7 +- .../Prevent-Fire-from-loading-chunks.patch | 43 ++++++------ .../Remove-Debug-checks-from-DataBits.patch | 47 ++++++------- ...Remove-unused-World-Tile-Entity-List.patch | 8 +-- .../Undead-horse-leashing.patch | 31 +++++++-- .../Use-a-Shared-Random-for-Entities.patch | 8 +-- ...th-absorb-values-and-repair-bad-data.patch | 4 +- ...-possibility-for-getServer-singleton.patch | 16 ++--- 35 files changed, 305 insertions(+), 319 deletions(-) delete mode 100644 Spigot-Server-Patches/More-informative-vehicle-moved-wrongly-message.patch diff --git a/Spigot-Server-Patches/Add-World-Util-Methods.patch b/Spigot-Server-Patches/Add-World-Util-Methods.patch index 9e8f4617d9..f38467e359 100644 --- a/Spigot-Server-Patches/Add-World-Util-Methods.patch +++ b/Spigot-Server-Patches/Add-World-Util-Methods.patch @@ -38,5 +38,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public final boolean isInBounds(BlockPosition blockposition) { return this.a(blockposition); } // Paper - OBFHELPER public boolean a(BlockPosition blockposition) { - return (double) (blockposition.getX() + 1) > this.c() && (double) blockposition.getX() < this.e() && (double) (blockposition.getZ() + 1) > this.d() && (double) blockposition.getZ() < this.f(); + 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/Spigot-Server-Patches/Add-ability-to-configure-frosted_ice-properties.patch b/Spigot-Server-Patches/Add-ability-to-configure-frosted_ice-properties.patch index 8e60f73a49..87a465a350 100644 --- a/Spigot-Server-Patches/Add-ability-to-configure-frosted_ice-properties.patch +++ b/Spigot-Server-Patches/Add-ability-to-configure-frosted_ice-properties.patch @@ -30,21 +30,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class BlockIceFrost extends BlockIce { @Override - public void tick(IBlockData iblockdata, WorldServer worldserver, BlockPosition blockposition, Random random) { + public void tickAlways(IBlockData iblockdata, WorldServer worldserver, BlockPosition blockposition, Random random) { + if (!worldserver.paperConfig.frostedIceEnabled) return; // Paper - add ability to disable frosted ice if ((random.nextInt(3) == 0 || this.a(worldserver, blockposition, 4)) && worldserver.getLightLevel(blockposition) > 11 - (Integer) iblockdata.get(BlockIceFrost.a) - iblockdata.b((IBlockAccess) worldserver, blockposition) && this.e(iblockdata, (World) worldserver, blockposition)) { - BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.r(); - Throwable throwable = null; + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + EnumDirection[] aenumdirection = EnumDirection.values(); @@ -0,0 +0,0 @@ public class BlockIceFrost extends BlockIce { - IBlockData iblockdata1 = worldserver.getType(blockposition_pooledblockposition); + IBlockData iblockdata1 = worldserver.getType(blockposition_mutableblockposition); - if (iblockdata1.getBlock() == this && !this.e(iblockdata1, (World) worldserver, blockposition_pooledblockposition)) { -- worldserver.getBlockTickList().a(blockposition_pooledblockposition, this, MathHelper.nextInt(random, 20, 40)); -+ worldserver.getBlockTickList().a(blockposition_pooledblockposition, this, MathHelper.nextInt(random, worldserver.paperConfig.frostedIceDelayMin, worldserver.paperConfig.frostedIceDelayMax)); // Paper - use configurable min/max delay - } + if (iblockdata1.a((Block) this) && !this.e(iblockdata1, (World) worldserver, blockposition_mutableblockposition)) { +- worldserver.getBlockTickList().a(blockposition_mutableblockposition, this, MathHelper.nextInt(random, 20, 40)); ++ worldserver.getBlockTickList().a(blockposition_mutableblockposition, this, MathHelper.nextInt(random, worldserver.paperConfig.frostedIceDelayMin, worldserver.paperConfig.frostedIceDelayMax)); // Paper - use configurable min/max delay } - } catch (Throwable throwable1) { -@@ -0,0 +0,0 @@ public class BlockIceFrost extends BlockIce { } } else { diff --git a/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch b/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch index 786c7972ed..f5aaed2731 100644 --- a/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch +++ b/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch @@ -28,8 +28,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 blockposition = new BlockPosition(d0, this.locY(), d1); // CraftBukkit start -- EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent(this, worldserver1, blockposition, 128); -+ EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent(this, worldserver1, blockposition, world.paperConfig.portalSearchRadius); // Paper - use portal search radius +- EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent(this, worldserver, blockposition, 128); ++ EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent(this, worldserver, blockposition, worldserver.paperConfig.portalSearchRadius); // Paper - use portal search radius if (event == null) { return null; } @@ -40,11 +40,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { // CraftBukkit start Location enter = this.getBukkitEntity().getLocation(); - Location exit = (worldserver1 == null) ? null : new Location(worldserver1.getWorld(), d0, d1, d2, f1, f); -- PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, dimensionmanager.getType() == DimensionManager.THE_END ? 0 : 16); -+ int configuredSearchRadius = (worldserver1 == null ? worldserver : worldserver1).paperConfig.portalSearchRadius; -+ int configuredCreateRadius = (worldserver1 == null ? worldserver : worldserver1).paperConfig.portalCreateRadius; -+ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, configuredSearchRadius, true, dimensionmanager.getType() == DimensionManager.THE_END ? 0 : configuredCreateRadius); // Paper - configurable portal search radius + Location exit = (worldserver == null) ? null : new Location(worldserver.getWorld(), d0, d1, d2, f1, f); +- PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, resourcekey == World.THE_END ? 0 : 16); ++ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, worldserver.paperConfig.portalSearchRadius, true, resourcekey == World.THE_END ? 0 : worldserver.paperConfig.portalCreateRadius); Bukkit.getServer().getPluginManager().callEvent(event); if (event.isCancelled() || event.getTo() == null) { return null; @@ -63,10 +61,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable @@ -0,0 +0,0 @@ public class PortalTravelAgent { // CraftBukkit end - VillagePlace villageplace = this.world.B(); + VillagePlace villageplace = this.world.x(); - villageplace.a(this.world, blockposition, 128); + villageplace.a(this.world, blockposition, searchRadius); // Paper - This impacts the # of chunks searched for entries List list = (List) villageplace.b((villageplacetype) -> { - return villageplacetype == VillagePlaceType.u; + return villageplacetype == VillagePlaceType.v; }, blockposition, searchRadius, VillagePlace.Occupancy.ANY).collect(Collectors.toList()); // CraftBukkit - searchRadius diff --git a/Spigot-Server-Patches/Add-exception-reporting-event.patch b/Spigot-Server-Patches/Add-exception-reporting-event.patch index 8f56a02ddf..c94eaf0751 100644 --- a/Spigot-Server-Patches/Add-exception-reporting-event.patch +++ b/Spigot-Server-Patches/Add-exception-reporting-event.patch @@ -83,7 +83,7 @@ diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/m 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 @@ import java.util.function.BooleanSupplier; +@@ -0,0 +0,0 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -124,14 +124,6 @@ diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/j 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 { - this.world.checkSession(); - } catch (ExceptionWorldConflict exceptionworldconflict) { - PlayerChunkMap.LOGGER.error("Couldn't save chunk; already in use by another instance of Minecraft?", exceptionworldconflict); -+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exceptionworldconflict); // Paper - return false; - } - @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { return true; } catch (Exception exception) { @@ -173,15 +165,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit end @@ -0,0 +0,0 @@ public final class SpawnerCreature { - entityinsentient = (EntityInsentient) entity; - } catch (Exception exception) { - SpawnerCreature.LOGGER.warn("Failed to create mob", exception); -+ ServerInternalException.reportInternalException(exception); // Paper - return; - } - + } + } catch (Exception exception) { + SpawnerCreature.LOGGER.warn("Failed to create mob", exception); ++ ServerInternalException.reportInternalException(exception); // Paper + return null; + } + } @@ -0,0 +0,0 @@ public final class SpawnerCreature { - entity = biomebase_biomemeta.b.a(generatoraccess.getMinecraftWorld()); + entity = biomebase_biomemeta.c.a(generatoraccess.getMinecraftWorld()); } catch (Exception exception) { SpawnerCreature.LOGGER.warn("Failed to create mob", exception); + ServerInternalException.reportInternalException(exception); // Paper @@ -200,8 +192,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import java.util.Iterator; import javax.annotation.Nullable; -@@ -0,0 +0,0 @@ public class VillageSiege { - entityzombie.prepare(worldserver, worldserver.getDamageScaler(new BlockPosition(entityzombie)), EnumMobSpawn.EVENT, (GroupDataEntity) null, (NBTTagCompound) null); +@@ -0,0 +0,0 @@ public class VillageSiege implements MobSpawner { + entityzombie.prepare(worldserver, worldserver.getDamageScaler(entityzombie.getChunkCoordinates()), EnumMobSpawn.EVENT, (GroupDataEntity) null, (NBTTagCompound) null); } catch (Exception exception) { exception.printStackTrace(); + ServerInternalException.reportInternalException(exception); // Paper @@ -212,16 +204,17 @@ diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/m 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 @@ package net.minecraft.server; +@@ -0,0 +0,0 @@ + package net.minecraft.server; - import co.aikar.timings.Timing; - import co.aikar.timings.Timings; ++import co.aikar.timings.Timing; ++import co.aikar.timings.Timings; +import com.destroystokyo.paper.event.server.ServerExceptionEvent; +import com.destroystokyo.paper.exception.ServerInternalException; +import com.google.common.base.MoreObjects; import com.google.common.collect.Lists; + import com.mojang.serialization.Codec; import java.io.IOException; - import java.util.Collection; @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { gameprofilerfiller.exit(); } catch (Throwable throwable) { diff --git a/Spigot-Server-Patches/Add-handshake-event-to-allow-plugins-to-handle-clien.patch b/Spigot-Server-Patches/Add-handshake-event-to-allow-plugins-to-handle-clien.patch index 96164588d5..1039466c1f 100644 --- a/Spigot-Server-Patches/Add-handshake-event-to-allow-plugins-to-handle-clien.patch +++ b/Spigot-Server-Patches/Add-handshake-event-to-allow-plugins-to-handle-clien.patch @@ -10,9 +10,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/HandshakeListener.java +++ b/src/main/java/net/minecraft/server/HandshakeListener.java @@ -0,0 +0,0 @@ public class HandshakeListener implements PacketHandshakingInListener { - this.b.close(chatmessage); + // CraftBukkit end + private static final IChatBaseComponent a = new ChatComponentText("Ignoring status request"); + private final MinecraftServer b; +- private final NetworkManager c; ++ private final NetworkManager c; final NetworkManager getNetworkManager() { return this.c; } // Paper - OBFHELPER + + public HandshakeListener(MinecraftServer minecraftserver, NetworkManager networkmanager) { + this.b = minecraftserver; +@@ -0,0 +0,0 @@ public class HandshakeListener implements PacketHandshakingInListener { + this.c.close(chatmessage); } else { - this.b.setPacketListener(new LoginListener(this.a, this.b)); + this.c.setPacketListener(new LoginListener(this.b, this.c)); + // Paper start - handshake event + boolean proxyLogicEnabled = org.spigotmc.SpigotConfig.bungee; + boolean handledByEvent = false; @@ -23,15 +32,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // If we've failed somehow, let the client know so and go no further. + if (event.isFailed()) { + chatmessage = new ChatMessage(event.getFailMessage()); -+ this.b.sendPacket(new PacketLoginOutDisconnect(chatmessage)); -+ this.b.close(chatmessage); ++ this.getNetworkManager().sendPacket(new PacketLoginOutDisconnect(chatmessage)); ++ this.getNetworkManager().close(chatmessage); + return; + } + + packethandshakinginsetprotocol.hostname = event.getServerHostname(); -+ this.b.socketAddress = new java.net.InetSocketAddress(event.getSocketAddressHostname(), ((java.net.InetSocketAddress) this.b.getSocketAddress()).getPort()); -+ this.b.spoofedUUID = event.getUniqueId(); -+ this.b.spoofedProfile = gson.fromJson(event.getPropertiesJson(), com.mojang.authlib.properties.Property[].class); ++ this.getNetworkManager().socketAddress = new java.net.InetSocketAddress(event.getSocketAddressHostname(), ((java.net.InetSocketAddress) this.getNetworkManager().getSocketAddress()).getPort()); ++ this.getNetworkManager().spoofedUUID = event.getUniqueId(); ++ this.getNetworkManager().spoofedProfile = gson.fromJson(event.getPropertiesJson(), com.mojang.authlib.properties.Property[].class); + handledByEvent = true; // Hooray, we did it! + } + } diff --git a/Spigot-Server-Patches/Configurable-Non-Player-Arrow-Despawn-Rate.patch b/Spigot-Server-Patches/Configurable-Non-Player-Arrow-Despawn-Rate.patch index d5942357a4..93705f7192 100644 --- a/Spigot-Server-Patches/Configurable-Non-Player-Arrow-Despawn-Rate.patch +++ b/Spigot-Server-Patches/Configurable-Non-Player-Arrow-Despawn-Rate.patch @@ -33,9 +33,9 @@ diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityArrow.java +++ b/src/main/java/net/minecraft/server/EntityArrow.java -@@ -0,0 +0,0 @@ public abstract class EntityArrow extends Entity implements IProjectile { +@@ -0,0 +0,0 @@ public abstract class EntityArrow extends IProjectile { - protected void i() { + protected void h() { ++this.despawnCounter; - if (this.despawnCounter >= ((this instanceof EntityThrownTrident) ? world.spigotConfig.tridentDespawnRate : world.spigotConfig.arrowDespawnRate)) { // Spigot + if (this.despawnCounter >= (fromPlayer == PickupStatus.CREATIVE_ONLY ? world.paperConfig.creativeArrowDespawnRate : (fromPlayer == PickupStatus.DISALLOWED ? world.paperConfig.nonPlayerArrowDespawnRate : ((this instanceof EntityThrownTrident) ? world.spigotConfig.tridentDespawnRate : world.spigotConfig.arrowDespawnRate)))) { // Spigot // Paper - TODO: Extract this to init? diff --git a/Spigot-Server-Patches/Configurable-Player-Collision.patch b/Spigot-Server-Patches/Configurable-Player-Collision.patch index 9da00c4f5d..1c79fceb5e 100644 --- a/Spigot-Server-Patches/Configurable-Player-Collision.patch +++ b/Spigot-Server-Patches/Configurable-Player-Collision.patch @@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private final Map playersByName = new java.util.HashMap<>(); + @Nullable String collideRuleTeamName; // Paper - Team name used for collideRule - public PlayerList(MinecraftServer minecraftserver, int i) { + public PlayerList(MinecraftServer minecraftserver, IRegistryCustom.Dimension iregistrycustom_dimension, WorldNBTStorage worldnbtstorage, int i) { this.cserver = minecraftserver.server = new CraftServer((DedicatedServer) minecraftserver, this); @@ -0,0 +0,0 @@ public abstract class PlayerList { } @@ -80,7 +80,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end // CraftBukkit - Moved from above, added world - PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", entityplayer.getDisplayName().getString(), s1, entityplayer.getId(), entityplayer.world.worldData.getName(), entityplayer.locX(), entityplayer.locY(), entityplayer.locZ()); + PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", entityplayer.getDisplayName().getString(), s1, entityplayer.getId(), worldserver1.worldDataServer.getName(), entityplayer.locX(), entityplayer.locY(), entityplayer.locZ()); } @@ -0,0 +0,0 @@ public abstract class PlayerList { entityplayer.playerTick(); // SPIGOT-924 diff --git a/Spigot-Server-Patches/Configurable-RCON-IP-address.patch b/Spigot-Server-Patches/Configurable-RCON-IP-address.patch index 8077f1a123..87b4c10282 100644 --- a/Spigot-Server-Patches/Configurable-RCON-IP-address.patch +++ b/Spigot-Server-Patches/Configurable-RCON-IP-address.patch @@ -10,8 +10,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/DedicatedServerProperties.java +++ b/src/main/java/net/minecraft/server/DedicatedServerProperties.java @@ -0,0 +0,0 @@ public class DedicatedServerProperties extends PropertyManager.EditableProperty playerIdleTimeout; public final PropertyManager.EditableProperty whiteList; + public final GeneratorSettings generatorSettings; + public final String rconIp; // Paper - Add rcon ip + @@ -19,9 +19,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public DedicatedServerProperties(Properties properties, OptionSet optionset) { super(properties, optionset); @@ -0,0 +0,0 @@ public class DedicatedServerProperties extends PropertyManager b = Sets.newHashSet(); - private final PathPoint[] c = new PathPoint[32]; - private final int d; -- private final PathfinderAbstract e; -+ private final PathfinderAbstract e; public PathfinderAbstract getPathfinder() { return this.e; } // Paper - OBFHELPER + + private final PathPoint[] a = new PathPoint[32]; + private final int b; +- private final PathfinderAbstract c; ++ private final PathfinderAbstract c; public PathfinderAbstract getPathfinder() { return this.c; } // Paper - OBFHELPER + private final Path d = new Path(); public Pathfinder(PathfinderAbstract pathfinderabstract, int i) { - this.e = pathfinderabstract; diff --git a/src/main/java/net/minecraft/server/PathfinderNormal.java b/src/main/java/net/minecraft/server/PathfinderNormal.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PathfinderNormal.java +++ b/src/main/java/net/minecraft/server/PathfinderNormal.java @@ -0,0 +0,0 @@ public class PathfinderNormal extends PathfinderAbstract { - PathType pathtype = c(iblockaccess, i, j, k); + for (int j1 = -1; j1 <= 1; ++j1) { + if (l != 0 || j1 != 0) { + blockposition_mutableblockposition.d(i + l, j + i1, k + j1); +- IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); ++ // Paper start ++ IBlockData iblockdata = iblockaccess.getTypeIfLoaded(blockposition_mutableblockposition); ++ if (iblockdata == null) { ++ pathtype = PathType.BLOCKED; ++ } else { ++ // Paper end - if (pathtype == PathType.OPEN && j >= 1) { -- Block block = iblockaccess.getType(new BlockPosition(i, j - 1, k)).getBlock(); -+ Block block = iblockaccess.getBlockIfLoaded(new BlockPosition(i, j - 1, k)); // Paper -+ if (block == null) return PathType.BLOCKED; // Paper - PathType pathtype1 = c(iblockaccess, i, j - 1, k); - - pathtype = pathtype1 != PathType.WALKABLE && pathtype1 != PathType.OPEN && pathtype1 != PathType.WATER && pathtype1 != PathType.LAVA ? PathType.WALKABLE : PathType.OPEN; + if (iblockdata.a(Blocks.CACTUS)) { + return PathType.DANGER_CACTUS; @@ -0,0 +0,0 @@ public class PathfinderNormal extends PathfinderAbstract { - for (int i1 = -1; i1 <= 1; ++i1) { - for (int j1 = -1; j1 <= 1; ++j1) { - if (l != 0 || j1 != 0) { -- Block block = iblockaccess.getType(blockposition_pooledblockposition.d(l + i, i1 + j, j1 + k)).getBlock(); -- -+ // Paper start -+ Block block = iblockaccess.getBlockIfLoaded(blockposition_pooledblockposition.d(l + i, i1 + j, j1 + k)); -+ if (block == null) { -+ pathtype = PathType.BLOCKED; -+ } else -+ // Paper end - if (block == Blocks.CACTUS) { - pathtype = PathType.DANGER_CACTUS; - } else if (block != Blocks.FIRE && block != Blocks.LAVA) { + if (fluid.a((Tag) TagsFluid.LAVA)) { + return PathType.LAVA; + } ++ } // Paper + } + } + } @@ -0,0 +0,0 @@ public class PathfinderNormal extends PathfinderAbstract { + } - protected static PathType c(IBlockAccess iblockaccess, int i, int j, int k) { - BlockPosition blockposition = new BlockPosition(i, j, k); + protected static PathType b(IBlockAccess iblockaccess, BlockPosition blockposition) { - IBlockData iblockdata = iblockaccess.getType(blockposition); + IBlockData iblockdata = iblockaccess.getTypeIfLoaded(blockposition); // Paper + if (iblockdata == null) return PathType.BLOCKED; // Paper diff --git a/Spigot-Server-Patches/Don-t-tick-Skulls-unused-code.patch b/Spigot-Server-Patches/Don-t-tick-Skulls-unused-code.patch index 2b2a17c819..9002d10cda 100644 --- a/Spigot-Server-Patches/Don-t-tick-Skulls-unused-code.patch +++ b/Spigot-Server-Patches/Don-t-tick-Skulls-unused-code.patch @@ -15,8 +15,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 -public class TileEntitySkull extends TileEntity implements ITickable { +public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Paper - remove tickable - public GameProfile gameProfile; - private int b; + @Nullable + private static UserCache userCache; @@ -0,0 +0,0 @@ public class TileEntitySkull extends TileEntity implements ITickable { } @@ -24,5 +24,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - @Override + // Paper - remove override public void tick() { - Block block = this.getBlock().getBlock(); + IBlockData iblockdata = this.getBlock(); diff --git a/Spigot-Server-Patches/Entity-AddTo-RemoveFrom-World-Events.patch b/Spigot-Server-Patches/Entity-AddTo-RemoveFrom-World-Events.patch index ee9d135042..4f30b18bb3 100644 --- a/Spigot-Server-Patches/Entity-AddTo-RemoveFrom-World-Events.patch +++ b/Spigot-Server-Patches/Entity-AddTo-RemoveFrom-World-Events.patch @@ -8,7 +8,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 (entity instanceof EntityInsentient) { this.navigators.remove(((EntityInsentient) entity).getNavigation()); } @@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 entity.valid = false; // CraftBukkit } -@@ -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 diff --git a/Spigot-Server-Patches/EntityPathfindEvent.patch b/Spigot-Server-Patches/EntityPathfindEvent.patch index 5c26988631..ce1659a0b7 100644 --- a/Spigot-Server-Patches/EntityPathfindEvent.patch +++ b/Spigot-Server-Patches/EntityPathfindEvent.patch @@ -13,8 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public PathEntity a(Entity entity, int i) { -- return this.a(new BlockPosition(entity), i); -+ return this.a(new BlockPosition(entity), entity, i); // Paper - Forward target entity +- return this.a(entity.getChunkCoordinates(), i); ++ return this.a(entity.getChunkCoordinates(), entity, i); // Paper - Forward target entity } private int t() { @@ -46,8 +46,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable public PathEntity a(Entity entity, int i) { -- return this.a(ImmutableSet.of(new BlockPosition(entity)), 16, true, i); -+ return this.a(ImmutableSet.of(new BlockPosition(entity)), entity, 16, true, i); // Paper +- return this.a(ImmutableSet.of(entity.getChunkCoordinates()), 16, true, i); ++ return this.a(ImmutableSet.of(entity.getChunkCoordinates()), entity, 16, true, i); // Paper } @Nullable @@ -61,7 +61,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return null; } else if (this.a.locY() < 0.0D) { @@ -0,0 +0,0 @@ public abstract class NavigationAbstract { - } else if (this.c != null && !this.c.b() && set.contains(this.q)) { + } else if (this.c != null && !this.c.b() && set.contains(this.p)) { return this.c; } else { + // Paper start - Pathfind event @@ -82,8 +82,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end this.b.getMethodProfiler().enter("pathfind"); - float f = (float) this.p.getValue(); - BlockPosition blockposition = flag ? (new BlockPosition(this.a)).up() : new BlockPosition(this.a); + float f = (float) this.a.b(GenericAttributes.FOLLOW_RANGE); + BlockPosition blockposition = flag ? this.a.getChunkCoordinates().up() : this.a.getChunkCoordinates(); diff --git a/src/main/java/net/minecraft/server/NavigationFlying.java b/src/main/java/net/minecraft/server/NavigationFlying.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/NavigationFlying.java @@ -92,8 +92,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public PathEntity a(Entity entity, int i) { -- return this.a(new BlockPosition(entity), i); -+ return this.a(new BlockPosition(entity), entity, i); // Paper - Forward target entity +- return this.a(entity.getChunkCoordinates(), i); ++ return this.a(entity.getChunkCoordinates(), entity, i); // Paper - Forward target entity } @Override diff --git a/Spigot-Server-Patches/Faster-redstone-torch-rapid-clock-removal.patch b/Spigot-Server-Patches/Faster-redstone-torch-rapid-clock-removal.patch index fb14661c44..c8bd18c282 100644 --- a/Spigot-Server-Patches/Faster-redstone-torch-rapid-clock-removal.patch +++ b/Spigot-Server-Patches/Faster-redstone-torch-rapid-clock-removal.patch @@ -16,28 +16,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - private static final Map> b = new WeakHashMap(); + // Paper - Move the mapped list to World - protected BlockRedstoneTorch(Block.Info block_info) { - super(block_info); + protected BlockRedstoneTorch(BlockBase.Info blockbase_info) { + super(blockbase_info, ParticleParamRedstone.a); @@ -0,0 +0,0 @@ public class BlockRedstoneTorch extends BlockTorch { - } - - public static void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random, boolean flag) { -- List list = (List) BlockRedstoneTorch.b.get(world); -+ // Paper start -+ java.util.ArrayDeque redstoneUpdateInfos = world.redstoneUpdateInfos; - -- while (list != null && !list.isEmpty() && world.getTime() - ((BlockRedstoneTorch.RedstoneUpdateInfo) list.get(0)).b > 60L) { + @Override + public void tickAlways(IBlockData iblockdata, WorldServer worldserver, BlockPosition blockposition, Random random) { + boolean flag = this.a((World) worldserver, blockposition, iblockdata); +- List list = (List) BlockRedstoneTorch.b.get(worldserver); +- +- while (list != null && !list.isEmpty() && worldserver.getTime() - ((BlockRedstoneTorch.RedstoneUpdateInfo) list.get(0)).b > 60L) { - list.remove(0); ++ // Paper start ++ java.util.ArrayDeque redstoneUpdateInfos = worldserver.redstoneUpdateInfos; + if (redstoneUpdateInfos != null) { + BlockRedstoneTorch.RedstoneUpdateInfo curr; -+ while ((curr = redstoneUpdateInfos.peek()) != null && world.getTime() - curr.getTime() > 60L) { ++ while ((curr = redstoneUpdateInfos.peek()) != null && worldserver.getTime() - curr.getTime() > 60L) { + redstoneUpdateInfos.poll(); + } } + // Paper end // CraftBukkit start - org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); + org.bukkit.plugin.PluginManager manager = worldserver.getServer().getPluginManager(); @@ -0,0 +0,0 @@ public class BlockRedstoneTorch extends BlockTorch { } diff --git a/Spigot-Server-Patches/Fix-Double-World-Add-issues.patch b/Spigot-Server-Patches/Fix-Double-World-Add-issues.patch index b4d142b36b..8232620a50 100644 --- a/Spigot-Server-Patches/Fix-Double-World-Add-issues.patch +++ b/Spigot-Server-Patches/Fix-Double-World-Add-issues.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 { // CraftBukkit start private boolean addEntity0(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) { org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot diff --git a/Spigot-Server-Patches/Fix-Old-Sign-Conversion.patch b/Spigot-Server-Patches/Fix-Old-Sign-Conversion.patch index 2a4888b216..322059dc07 100644 --- a/Spigot-Server-Patches/Fix-Old-Sign-Conversion.patch +++ b/Spigot-Server-Patches/Fix-Old-Sign-Conversion.patch @@ -13,11 +13,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/DefinedStructure.java +++ b/src/main/java/net/minecraft/server/DefinedStructure.java @@ -0,0 +0,0 @@ public class DefinedStructure { - definedstructure_blockinfo.c.setInt("x", blockposition1.getX()); - definedstructure_blockinfo.c.setInt("y", blockposition1.getY()); - definedstructure_blockinfo.c.setInt("z", blockposition1.getZ()); + definedstructure_blockinfo.c.setLong("LootTableSeed", random.nextLong()); + } + + tileentity.isLoadingStructure = true; // Paper - tileentity.load(definedstructure_blockinfo.c); + tileentity.load(definedstructure_blockinfo.b, definedstructure_blockinfo.c); tileentity.a(definedstructureinfo.c()); tileentity.a(definedstructureinfo.d()); + tileentity.isLoadingStructure = false; // Paper @@ -44,8 +44,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } try { -- IChatBaseComponent ichatbasecomponent = IChatBaseComponent.ChatSerializer.a(s.isEmpty() ? "\"\"" : s); -+ //IChatBaseComponent ichatbasecomponent = IChatBaseComponent.ChatSerializer.a(s.isEmpty() ? "\"\"" : s); // Paper - move down - the old format might throw a json error +- IChatMutableComponent ichatmutablecomponent = IChatBaseComponent.ChatSerializer.a(s.isEmpty() ? "\"\"" : s); ++ //IChatMutableComponent ichatmutablecomponent = IChatBaseComponent.ChatSerializer.a(s.isEmpty() ? "\"\"" : s); // Paper - move down - the old format might throw a json error - if (oldSign) { + if (oldSign && !isLoadingStructure) { // Paper - saved structures will be in the new format, but will not have isConverted @@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 continue; } // CraftBukkit end -+ IChatBaseComponent ichatbasecomponent = IChatBaseComponent.ChatSerializer.a(s.isEmpty() ? "\"\"" : s); // Paper - after old sign ++ IChatMutableComponent ichatmutablecomponent = IChatBaseComponent.ChatSerializer.a(s.isEmpty() ? "\"\"" : s); // Paper - after old sign if (this.world instanceof WorldServer) { try { diff --git a/Spigot-Server-Patches/Handle-Item-Meta-Inconsistencies.patch b/Spigot-Server-Patches/Handle-Item-Meta-Inconsistencies.patch index 2f66ca49bc..9af29f576d 100644 --- a/Spigot-Server-Patches/Handle-Item-Meta-Inconsistencies.patch +++ b/Spigot-Server-Patches/Handle-Item-Meta-Inconsistencies.patch @@ -21,18 +21,18 @@ diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/n index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java -@@ -0,0 +0,0 @@ import com.mojang.brigadier.StringReader; - import com.mojang.brigadier.exceptions.CommandSyntaxException; +@@ -0,0 +0,0 @@ import com.mojang.serialization.Codec; + import com.mojang.serialization.codecs.RecordCodecBuilder; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; +import java.util.Collections; +import java.util.Comparator; import java.util.Locale; import java.util.Objects; - import java.util.Random; + import java.util.Optional; @@ -0,0 +0,0 @@ public final class ItemStack { - return decimalformat; - } + private ShapeDetectorBlock n; + private boolean o; + // Paper start + private static final java.util.Comparator enchantSorter = java.util.Comparator.comparing(o -> o.getString("id")); @@ -59,7 +59,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit start - make defensive copy as this data may be coming from the save thread this.tag = (NBTTagCompound) nbttagcompound.getCompound("tag").clone(); + processEnchantOrder(this.tag); // Paper - this.getItem().a(this.tag); + this.getItem().b(this.tag); // CraftBukkit end } @@ -0,0 +0,0 @@ public final class ItemStack { diff --git a/Spigot-Server-Patches/Implement-PlayerLocaleChangeEvent.patch b/Spigot-Server-Patches/Implement-PlayerLocaleChangeEvent.patch index 5338e4c77e..3d44288fc9 100644 --- a/Spigot-Server-Patches/Implement-PlayerLocaleChangeEvent.patch +++ b/Spigot-Server-Patches/Implement-PlayerLocaleChangeEvent.patch @@ -8,22 +8,21 @@ diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/jav index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java -@@ -0,0 +0,0 @@ import org.bukkit.inventory.MainHand; - public class EntityPlayer extends EntityHuman implements ICrafting { - - private static final Logger LOGGER = LogManager.getLogger(); -- public String locale = "en_us"; // CraftBukkit - lowercase -+ public String locale = null; // CraftBukkit - lowercase // Paper - default to null - public PlayerConnection playerConnection; - public final MinecraftServer server; - public final PlayerInteractManager playerInteractManager; @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + return s; + } + +- public String locale = "en_us"; // CraftBukkit - add, lowercase ++ public String locale = null; // CraftBukkit - lowercase // Paper - default to null + public void a(PacketPlayInSettings packetplayinsettings) { + // CraftBukkit start + if (getMainHand() != packetplayinsettings.getMainHand()) { PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(getBukkitEntity(), getMainHand() == EnumMainHand.LEFT ? MainHand.LEFT : MainHand.RIGHT); this.server.server.getPluginManager().callEvent(event); } -- if (!this.locale.equals(packetplayinsettings.b())) { -+ if (this.locale == null || !this.locale.equals(packetplayinsettings.b())) { // Paper - check for null - PlayerLocaleChangeEvent event = new PlayerLocaleChangeEvent(getBukkitEntity(), packetplayinsettings.b()); +- if (!this.locale.equals(packetplayinsettings.locale)) { ++ if (this.locale == null || !this.locale.equals(packetplayinsettings.locale)) { // Paper - check for null + PlayerLocaleChangeEvent event = new PlayerLocaleChangeEvent(getBukkitEntity(), packetplayinsettings.locale); this.server.server.getPluginManager().callEvent(event); } this.clientViewDistance = packetplayinsettings.viewDistance; @@ -31,14 +30,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - add PlayerLocaleChangeEvent + // Since the field is initialized to null, this event should always fire the first time the packet is received + String oldLocale = this.locale; - this.locale = packetplayinsettings.b(); ++ this.locale = packetplayinsettings.locale; + if (!this.locale.equals(oldLocale)) { + new com.destroystokyo.paper.event.player.PlayerLocaleChangeEvent(this.getBukkitEntity(), oldLocale, this.locale).callEvent(); + } + // Paper end - this.ch = packetplayinsettings.d(); - this.ci = packetplayinsettings.e(); - this.getDataWatcher().set(EntityPlayer.bq, (byte) packetplayinsettings.f()); + this.cf = packetplayinsettings.d(); + this.cg = packetplayinsettings.e(); + this.getDataWatcher().set(EntityPlayer.bp, (byte) packetplayinsettings.f()); 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 @@ -56,11 +55,3 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // Paper start -@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - } - } - -- @Override - public Set getHiddenPlayers() - { - Set ret = new HashSet(); diff --git a/Spigot-Server-Patches/Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/Spigot-Server-Patches/Improve-Maps-in-item-frames-performance-and-bug-fixe.patch index 00c882c097..7f5a361730 100644 --- a/Spigot-Server-Patches/Improve-Maps-in-item-frames-performance-and-bug-fixe.patch +++ b/Spigot-Server-Patches/Improve-Maps-in-item-frames-performance-and-bug-fixe.patch @@ -34,9 +34,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/WorldMap.java +++ b/src/main/java/net/minecraft/server/WorldMap.java @@ -0,0 +0,0 @@ public class WorldMap extends PersistentBase { - private final Map l = Maps.newHashMap(); + private final Map m = Maps.newHashMap(); public final Map decorations = Maps.newLinkedHashMap(); - private final Map m = Maps.newHashMap(); + private final Map n = Maps.newHashMap(); + private org.bukkit.craftbukkit.map.RenderData vanillaRender = new org.bukkit.craftbukkit.map.RenderData(); // Paper // CraftBukkit start @@ -50,12 +50,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } @@ -0,0 +0,0 @@ public class WorldMap extends PersistentBase { - this.l.put(mapiconbanner.f(), mapiconbanner); - this.a(mapiconbanner.c(), (GeneratorAccess) null, mapiconbanner.f(), (double) mapiconbanner.a().getX(), (double) mapiconbanner.a().getZ(), 180.0D, mapiconbanner.d()); - } -+ vanillaRender.buffer = colors; // Paper + this.m.put(mapiconbanner.f(), mapiconbanner); + this.a(mapiconbanner.c(), (GeneratorAccess) null, mapiconbanner.f(), (double) mapiconbanner.a().getX(), (double) mapiconbanner.a().getZ(), 180.0D, mapiconbanner.d()); + } ++ this.vanillaRender.buffer = colors; // Paper - NBTTagList nbttaglist1 = nbttagcompound.getList("frames", 10); + NBTTagList nbttaglist1 = nbttagcompound.getList("frames", 10); @@ -0,0 +0,0 @@ public class WorldMap extends PersistentBase { this.b(); @@ -105,7 +105,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 ( iter.next().trackee == entity ) { diff --git a/Spigot-Server-Patches/LootTable-API-Replenishable-Lootables-Feature.patch b/Spigot-Server-Patches/LootTable-API-Replenishable-Lootables-Feature.patch index df1d22a519..7c09d7729b 100644 --- a/Spigot-Server-Patches/LootTable-API-Replenishable-Lootables-Feature.patch +++ b/Spigot-Server-Patches/LootTable-API-Replenishable-Lootables-Feature.patch @@ -550,8 +550,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp @Override - protected void b(NBTTagCompound nbttagcompound) { - super.b(nbttagcompound); + protected void saveData(NBTTagCompound nbttagcompound) { + super.saveData(nbttagcompound); + this.lootableData.saveNbt(nbttagcompound); // Paper if (this.lootTable != null) { nbttagcompound.setString("LootTable", this.lootTable.toString()); @@ -565,10 +565,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp @Override - protected void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); + protected void loadData(NBTTagCompound nbttagcompound) { + super.loadData(nbttagcompound); + this.lootableData.loadNbt(nbttagcompound); // Paper - this.items = NonNullList.a(this.getSize(), ItemStack.a); + this.items = NonNullList.a(this.getSize(), ItemStack.b); if (nbttagcompound.hasKeyOfType("LootTable", 8)) { this.lootTable = new MinecraftKey(nbttagcompound.getString("LootTable")); this.lootTableSeed = nbttagcompound.getLong("LootTableSeed"); @@ -585,9 +585,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (this.lootableData.shouldReplenish(entityhuman) && this.world.getMinecraftServer() != null) { // Paper LootTable loottable = this.world.getMinecraftServer().getLootTableRegistry().getLootTable(this.lootTable); -- this.lootTable = null; + if (entityhuman instanceof EntityPlayer) { +@@ -0,0 +0,0 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp + } + + this.lootTable = null; + this.lootableData.processRefill(entityhuman); // Paper - LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).set(LootContextParameters.POSITION, new BlockPosition(this)).a(this.lootTableSeed); + LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).set(LootContextParameters.POSITION, this.getChunkCoordinates()).a(this.lootTableSeed); if (entityhuman != null) { diff --git a/src/main/java/net/minecraft/server/TileEntityLootable.java b/src/main/java/net/minecraft/server/TileEntityLootable.java @@ -609,7 +613,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class TileEntityLootable extends TileEntityContainer { } - protected boolean d(NBTTagCompound nbttagcompound) { + protected boolean b(NBTTagCompound nbttagcompound) { + this.lootableData.loadNbt(nbttagcompound); // Paper if (nbttagcompound.hasKeyOfType("LootTable", 8)) { this.lootTable = new MinecraftKey(nbttagcompound.getString("LootTable")); @@ -621,7 +625,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } - protected boolean e(NBTTagCompound nbttagcompound) { + protected boolean c(NBTTagCompound nbttagcompound) { + this.lootableData.saveNbt(nbttagcompound); // Paper if (this.lootTable == null) { return false; @@ -640,7 +644,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (this.lootableData.shouldReplenish(entityhuman) && this.world.getMinecraftServer() != null) { // Paper LootTable loottable = this.world.getMinecraftServer().getLootTableRegistry().getLootTable(this.lootTable); -- this.lootTable = null; + if (entityhuman instanceof EntityPlayer) { +@@ -0,0 +0,0 @@ public abstract class TileEntityLootable extends TileEntityContainer { + } + + this.lootTable = null; + this.lootableData.processRefill(entityhuman); // Paper LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).set(LootContextParameters.POSITION, new BlockPosition(this.position)).a(this.lootTableSeed); diff --git a/Spigot-Server-Patches/More-informative-vehicle-moved-wrongly-message.patch b/Spigot-Server-Patches/More-informative-vehicle-moved-wrongly-message.patch deleted file mode 100644 index 2c3b922bd7..0000000000 --- a/Spigot-Server-Patches/More-informative-vehicle-moved-wrongly-message.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zach Brown <1254957+zachbr@users.noreply.github.com> -Date: Thu, 28 Jul 2016 17:58:53 -0500 -Subject: [PATCH] More informative vehicle moved wrongly message - - -diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -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 @@ public class PlayerConnection implements PacketListenerPlayIn { - - if (d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot - flag1 = true; -- PlayerConnection.LOGGER.warn("{} moved wrongly!", entity.getDisplayName().getString()); -+ PlayerConnection.LOGGER.warn(entity.getName() + " (vehicle of " + this.player.getName() + ") moved wrongly!"); // Paper - More informative - } - Location curPos = this.getPlayer().getLocation(); // Spigot - 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 e4e8ab513c..4d7d691f1a 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 @@ -23,8 +23,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/BlockTallPlant.java +++ b/src/main/java/net/minecraft/server/BlockTallPlant.java @@ -0,0 +0,0 @@ public class BlockTallPlant extends BlockPlant { - @Override - public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { + + protected static void b(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { // CraftBukkit start - if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, blockposition).isCancelled()) { + if (((WorldServer)world).hasPhysicsEvent && org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, blockposition).isCancelled()) { // Paper @@ -36,13 +36,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 0; // Paper - if (true || worldserver.worldProvider.getDimensionManager() == DimensionManager.OVERWORLD || this.getAllowNether()) { // CraftBukkit - this.methodProfiler.a(() -> { - return worldserver.getWorldData().getName() + " " + IRegistry.DIMENSION_TYPE.getKey(worldserver.worldProvider.getDimensionManager()); + + this.methodProfiler.a(() -> { + return worldserver + " " + worldserver.getDimensionKey().a(); 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 @@ -69,11 +69,12 @@ 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 Convertable.ConversionSession convertable; + public final UUID uuid; - // CraftBukkit start - private int tickPosition; + boolean hasPhysicsEvent = true; // Paper - - // 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) { ++ + public Chunk getChunkIfLoaded(int x, int z) { + return this.chunkProvider.getChunkAt(x, z, false); + } diff --git a/Spigot-Server-Patches/Only-send-Dragon-Wither-Death-sounds-to-same-world.patch b/Spigot-Server-Patches/Only-send-Dragon-Wither-Death-sounds-to-same-world.patch index f1c36ea675..dc54b9c389 100644 --- a/Spigot-Server-Patches/Only-send-Dragon-Wither-Death-sounds-to-same-world.patch +++ b/Spigot-Server-Patches/Only-send-Dragon-Wither-Death-sounds-to-same-world.patch @@ -10,16 +10,14 @@ 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.bA == 1) { + if (this.deathAnimationTicks == 1 && !this.isSilent()) { // CraftBukkit start - Use relative location for far away sounds - // this.world.b(1028, new BlockPosition(this), 0); + // this.world.b(1028, this.getChunkCoordinates(), 0); - int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; - for (EntityPlayer player : (List) MinecraftServer.getServer().getPlayerList().players) { -+ // 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 -+ for (EntityPlayer player : ((WorldServer)world).getPlayers()) { ++ //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 -+ // Paper end double deltaX = this.locX() - player.locX(); double deltaZ = this.locZ() - player.locZ(); double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; @@ -28,16 +26,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- 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); -- int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; -- for (EntityPlayer player : (List) MinecraftServer.getServer().getPlayerList().players) { -+ // 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 -+ for (EntityPlayer player : ((WorldServer)world).getPlayers()) { -+ 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; + 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; +- for (EntityPlayer player : (List) MinecraftServer.getServer().getPlayerList().players) { ++ //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 + double deltaX = this.locX() - player.locX(); + double deltaZ = this.locZ() - player.locZ(); + double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; diff --git a/Spigot-Server-Patches/Optimize-UserCache-Thread-Safe.patch b/Spigot-Server-Patches/Optimize-UserCache-Thread-Safe.patch index 0d51432747..bd71d8f7b0 100644 --- a/Spigot-Server-Patches/Optimize-UserCache-Thread-Safe.patch +++ b/Spigot-Server-Patches/Optimize-UserCache-Thread-Safe.patch @@ -21,7 +21,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.getUserCache().c(false); // Paper } // Spigot end - } + diff --git a/src/main/java/net/minecraft/server/UserCache.java b/src/main/java/net/minecraft/server/UserCache.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/UserCache.java diff --git a/Spigot-Server-Patches/Optimize-isValidLocation-getType-and-getBlockData-fo.patch b/Spigot-Server-Patches/Optimize-isValidLocation-getType-and-getBlockData-fo.patch index 6e2c4a75fc..5495b4bf28 100644 --- a/Spigot-Server-Patches/Optimize-isValidLocation-getType-and-getBlockData-fo.patch +++ b/Spigot-Server-Patches/Optimize-isValidLocation-getType-and-getBlockData-fo.patch @@ -17,20 +17,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/BaseBlockPosition.java +++ b/src/main/java/net/minecraft/server/BaseBlockPosition.java @@ -0,0 +0,0 @@ public class BaseBlockPosition implements Comparable { - private final int b; - @Deprecated - private final int c; + private int b; + private int e; + + // Paper start + public boolean isValidLocation() { -+ return a >= -30000000 && c >= -30000000 && a < 30000000 && c < 30000000 && b >= 0 && b < 256; ++ return getX() >= -30000000 && getZ() >= -30000000 && getX() < 30000000 && getZ() < 30000000 && getY() >= 0 && getY() < 256; + } + public boolean isInvalidYLocation() { + return b < 0 || b >= 256; + } + // Paper end - ++ public BaseBlockPosition(int i, int j, int k) { this.a = i; + this.b = j; 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 @@ -64,7 +65,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public IBlockData getBlockData_unused(int i, int j, int k) { + // Paper end - if (this.world.P() == WorldType.DEBUG_ALL_BLOCK_STATES) { + if (this.world.isDebugWorld()) { IBlockData iblockdata = null; diff --git a/src/main/java/net/minecraft/server/ChunkEmpty.java b/src/main/java/net/minecraft/server/ChunkEmpty.java @@ -110,7 +111,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public ChunkSection(int i) { this(i, (short) 0, (short) 0, (short) 0); @@ -0,0 +0,0 @@ public class ChunkSection { - this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData()); + this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData()); } - public IBlockData getType(int i, int j, int k) { @@ -198,10 +199,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public static boolean isValidLocation(BlockPosition blockposition) { -- return !isOutsideWorld(blockposition) && blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() < 30000000; +- return !isOutsideWorld(blockposition) && e(blockposition); + return blockposition.isValidLocation(); } + public static boolean k(BlockPosition blockposition) { +@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + } + public static boolean isOutsideWorld(BlockPosition blockposition) { - return b(blockposition.getY()); + return blockposition.isInvalidYLocation(); diff --git a/Spigot-Server-Patches/Optional-TNT-doesn-t-move-in-water.patch b/Spigot-Server-Patches/Optional-TNT-doesn-t-move-in-water.patch index bb7c7bd285..16d0875b7c 100644 --- a/Spigot-Server-Patches/Optional-TNT-doesn-t-move-in-water.patch +++ b/Spigot-Server-Patches/Optional-TNT-doesn-t-move-in-water.patch @@ -38,11 +38,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } - public boolean bM() { + public boolean bU() { + // Paper start + return this.pushedByWater(); + } -+ + public boolean pushedByWater() { + // Paper end return true; @@ -64,7 +63,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + */ + // Send position and velocity updates to nearby players on every tick while the TNT is in water. + // This does pretty well at keeping their clients in sync with the server. -+ PlayerChunkMap.EntityTracker ete = this.tracker; ++ PlayerChunkMap.EntityTracker ete = ((WorldServer)this.world).getChunkProvider().playerChunkMap.trackedEntities.get(this.getId()); + if (ete != null) { + PacketPlayOutEntityVelocity velocityPacket = new PacketPlayOutEntityVelocity(this); + PacketPlayOutEntityTeleport positionPacket = new PacketPlayOutEntityTeleport(this); @@ -82,7 +81,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private void explode() { @@ -0,0 +0,0 @@ public class EntityTNTPrimed extends Entity { - public Packet L() { + public Packet O() { return new PacketPlayOutSpawnEntity(this); } + diff --git a/Spigot-Server-Patches/Prevent-Fire-from-loading-chunks.patch b/Spigot-Server-Patches/Prevent-Fire-from-loading-chunks.patch index e084c40960..1af6fc395c 100644 --- a/Spigot-Server-Patches/Prevent-Fire-from-loading-chunks.patch +++ b/Spigot-Server-Patches/Prevent-Fire-from-loading-chunks.patch @@ -10,34 +10,34 @@ diff --git a/src/main/java/net/minecraft/server/BlockFire.java b/src/main/java/n index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockFire.java +++ b/src/main/java/net/minecraft/server/BlockFire.java -@@ -0,0 +0,0 @@ public class BlockFire extends Block { - BlockStateBoolean blockstateboolean = (BlockStateBoolean) BlockFire.g.get(enumdirection); +@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { + BlockStateBoolean blockstateboolean = (BlockStateBoolean) BlockFire.p.get(enumdirection); if (blockstateboolean != null) { -- iblockdata1 = (IBlockData) iblockdata1.set(blockstateboolean, this.h(iblockaccess.getType(blockposition.shift(enumdirection)))); -+ iblockdata1 = (IBlockData) iblockdata1.set(blockstateboolean, this.h(iblockaccess.getTypeIfLoaded(blockposition.shift(enumdirection)))); // Paper - prevent chunk loads +- iblockdata1 = (IBlockData) iblockdata1.set(blockstateboolean, this.e(iblockaccess.getType(blockposition.shift(enumdirection)))); ++ iblockdata1 = (IBlockData) iblockdata1.set(blockstateboolean, this.e(iblockaccess.getTypeIfLoaded(blockposition.shift(enumdirection)))); // Paper - prevent chunk loads } } -@@ -0,0 +0,0 @@ public class BlockFire extends Block { +@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { } - blockposition_mutableblockposition.g(blockposition).e(l, j1, i1); + blockposition_mutableblockposition.a((BaseBlockPosition) blockposition, l, j1, i1); + if (!worldserver.isLoaded(blockposition_mutableblockposition)) continue; // Paper int l1 = this.a((IWorldReader) worldserver, (BlockPosition) blockposition_mutableblockposition); if (l1 > 0) { -@@ -0,0 +0,0 @@ public class BlockFire extends Block { +@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { } - private void a(World world, BlockPosition blockposition, int i, Random random, int j, BlockPosition sourceposition) { // CraftBukkit add sourceposition -- int k = this.i(world.getType(blockposition)); + private void trySpread(World world, BlockPosition blockposition, int i, Random random, int j, BlockPosition sourceposition) { // CraftBukkit add sourceposition +- int k = this.getBurnChance(world.getType(blockposition)); + // Paper start + final IBlockData iblockdata = world.getTypeIfLoaded(blockposition); + if (iblockdata == null) { + return; + } -+ int k = this.i(iblockdata); ++ int k = this.getBurnChance(iblockdata); + // Paper end if (random.nextInt(i) < k) { @@ -46,36 +46,35 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit start org.bukkit.block.Block theBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); -@@ -0,0 +0,0 @@ public class BlockFire extends Block { +@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { for (int j = 0; j < i; ++j) { EnumDirection enumdirection = aenumdirection[j]; -- if (this.h(iblockaccess.getType(blockposition.shift(enumdirection)))) { -+ if (this.h(iblockaccess.getTypeIfLoaded(blockposition.shift(enumdirection)))) { // Paper - prevent chunk loads +- if (this.e(iblockaccess.getType(blockposition.shift(enumdirection)))) { ++ if (this.e(iblockaccess.getTypeIfLoaded(blockposition.shift(enumdirection)))) { // Paper - prevent chunk loads return true; } } -@@ -0,0 +0,0 @@ public class BlockFire extends Block { +@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { for (int k = 0; k < j; ++k) { EnumDirection enumdirection = aenumdirection[k]; - IBlockData iblockdata = iworldreader.getType(blockposition.shift(enumdirection)); -- + // Paper start + IBlockData iblockdata = iworldreader.getTypeIfLoaded(blockposition.shift(enumdirection)); + if (iblockdata == null) { + continue; + } + // Paper end - i = Math.max(this.r(iblockdata), i); + + i = Math.max(this.getFlameChance(iblockdata), i); } +@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { -@@ -0,0 +0,0 @@ public class BlockFire extends Block { - } - - public boolean h(IBlockData iblockdata) { -- return this.r(iblockdata) > 0; -+ return iblockdata != null && this.r(iblockdata) > 0; // Paper - iblockdata can be nullable if chunk is unloaded now + @Override + protected boolean e(IBlockData iblockdata) { +- return this.getFlameChance(iblockdata) > 0; ++ return iblockdata != null && this.getFlameChance(iblockdata) > 0; // Paper - iblockdata can be nullable if chunk is unloaded now } @Override diff --git a/Spigot-Server-Patches/Remove-Debug-checks-from-DataBits.patch b/Spigot-Server-Patches/Remove-Debug-checks-from-DataBits.patch index db63772739..24214b1ed6 100644 --- a/Spigot-Server-Patches/Remove-Debug-checks-from-DataBits.patch +++ b/Spigot-Server-Patches/Remove-Debug-checks-from-DataBits.patch @@ -15,40 +15,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class DataBits { } - public DataBits(int i, int j, long[] along) { -- Validate.inclusiveBetween(1L, 32L, (long) i); -+ //Validate.inclusiveBetween(1L, 32L, (long) i); // Paper - this.d = j; - this.b = i; - this.a = along; -@@ -0,0 +0,0 @@ public class DataBits { - } - public int a(int i, int j) { -- Validate.inclusiveBetween(0L, (long) (this.d - 1), (long) i); -- Validate.inclusiveBetween(0L, this.c, (long) j); -+ //Validate.inclusiveBetween(0L, (long) (this.d - 1), (long) i); // Paper -+ //Validate.inclusiveBetween(0L, this.c, (long) j); // Paper - int k = i * this.b; - int l = k >> 6; - int i1 = (i + 1) * this.b - 1 >> 6; +- Validate.inclusiveBetween(0L, (long) (this.e - 1), (long) i); +- Validate.inclusiveBetween(0L, this.d, (long) j); ++ //Validate.inclusiveBetween(0L, (long) (this.e - 1), (long) i); // Paper ++ //Validate.inclusiveBetween(0L, this.d, (long) j); // Paper + int k = this.b(i); + long l = this.b[k]; + int i1 = (i - k * this.f) * this.c; @@ -0,0 +0,0 @@ public class DataBits { } public void b(int i, int j) { -- Validate.inclusiveBetween(0L, (long) (this.d - 1), (long) i); -- Validate.inclusiveBetween(0L, this.c, (long) j); -+ //Validate.inclusiveBetween(0L, (long) (this.d - 1), (long) i); // Paper -+ //Validate.inclusiveBetween(0L, this.c, (long) j); // Paper - int k = i * this.b; - int l = k >> 6; - int i1 = (i + 1) * this.b - 1 >> 6; +- Validate.inclusiveBetween(0L, (long) (this.e - 1), (long) i); +- Validate.inclusiveBetween(0L, this.d, (long) j); ++ //Validate.inclusiveBetween(0L, (long) (this.e - 1), (long) i); // Paper ++ //Validate.inclusiveBetween(0L, this.d, (long) j); // Paper + int k = this.b(i); + long l = this.b[k]; + int i1 = (i - k * this.f) * this.c; @@ -0,0 +0,0 @@ public class DataBits { } public int a(int i) { -- Validate.inclusiveBetween(0L, (long) (this.d - 1), (long) i); -+ //Validate.inclusiveBetween(0L, (long) (this.d - 1), (long) i); // Paper - int j = i * this.b; - int k = j >> 6; - int l = (i + 1) * this.b - 1 >> 6; +- Validate.inclusiveBetween(0L, (long) (this.e - 1), (long) i); ++ //Validate.inclusiveBetween(0L, (long) (this.e - 1), (long) i); // Paper + int j = this.b(i); + long k = this.b[j]; + int l = (i - j * this.f) * this.c; diff --git a/Spigot-Server-Patches/Remove-unused-World-Tile-Entity-List.patch b/Spigot-Server-Patches/Remove-unused-World-Tile-Entity-List.patch index 3e3cf42c33..46629b18d4 100644 --- a/Spigot-Server-Patches/Remove-unused-World-Tile-Entity-List.patch +++ b/Spigot-Server-Patches/Remove-unused-World-Tile-Entity-List.patch @@ -10,8 +10,8 @@ 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 { - - protected static final Logger LOGGER = LogManager.getLogger(); + public static final ResourceKey THE_NETHER = ResourceKey.a(IRegistry.ae, new MinecraftKey("the_nether")); + public static final ResourceKey THE_END = ResourceKey.a(IRegistry.ae, new MinecraftKey("the_end")); private static final EnumDirection[] a = EnumDirection.values(); - public final List tileEntityList = Lists.newArrayList(); + //public final List tileEntityList = Lists.newArrayList(); // Paper - remove unused list @@ -70,7 +70,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 { } bufferedwriter.write(String.format("entities: %d\n", this.entitiesById.size())); @@ -79,7 +79,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 bufferedwriter.write(String.format("block_ticks: %d\n", this.getBlockTickList().a())); bufferedwriter.write(String.format("fluid_ticks: %d\n", this.getFluidTickList().a())); bufferedwriter.write("distance_manager: " + playerchunkmap.e().c() + "\n"); -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { private void a(Writer writer) throws IOException { CSVWriter csvwriter = CSVWriter.a().a("x").a("y").a("z").a("type").a(writer); diff --git a/Spigot-Server-Patches/Undead-horse-leashing.patch b/Spigot-Server-Patches/Undead-horse-leashing.patch index c49aa7383b..301d9e4d57 100644 --- a/Spigot-Server-Patches/Undead-horse-leashing.patch +++ b/Spigot-Server-Patches/Undead-horse-leashing.patch @@ -24,11 +24,32 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityHorseAbstract.java +++ b/src/main/java/net/minecraft/server/EntityHorseAbstract.java @@ -0,0 +0,0 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven - - @Override - public boolean a(EntityHuman entityhuman) { -- return super.a(entityhuman) && this.getMonsterType() != EnumMonsterType.UNDEAD; -+ return world.paperConfig.allowLeashingUndeadHorse ? super.a(entityhuman) : super.a(entityhuman) && this.getMonsterType() != EnumMonsterType.UNDEAD; // Paper + this.bx = flag; } ++ // Paper start ++ @Override ++ public boolean canLeash(EntityHuman entityhuman) { ++ return world.paperConfig.allowLeashingUndeadHorse ? super.a(entityhuman) : super.a(entityhuman) && this.getMonsterType() != EnumMonsterType.UNDEAD; // Paper ++ } ++ // Paper end ++ @Override + protected void t(float f) { + if (f > 6.0F && this.fa()) { +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 { + } + + public boolean a(EntityHuman entityhuman) { ++ // Paper start - allow overriding ++ return this.canLeash(entityhuman); ++ } ++ public boolean canLeash(EntityHuman entityhuman) { ++ // Paper end - allow overriding + return !this.isLeashed() && !(this instanceof IMonster); + } + diff --git a/Spigot-Server-Patches/Use-a-Shared-Random-for-Entities.patch b/Spigot-Server-Patches/Use-a-Shared-Random-for-Entities.patch index 51dd540908..4e5e51641e 100644 --- a/Spigot-Server-Patches/Use-a-Shared-Random-for-Entities.patch +++ b/Spigot-Server-Patches/Use-a-Shared-Random-for-Entities.patch @@ -32,11 +32,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public CraftEntity getBukkitEntity() { @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - this.y = Vec3D.a; - this.av = 1.0F; - this.aw = 1.0F; + this.x = Vec3D.a; + this.at = 1.0F; + this.au = 1.0F; - this.random = new Random(); + this.random = SHARED_RANDOM; // Paper this.fireTicks = -this.getMaxFireTicks(); + this.M = new Object2DoubleArrayMap(2); this.justCreated = true; - this.uniqueID = MathHelper.a(this.random); diff --git a/Spigot-Server-Patches/handle-NaN-health-absorb-values-and-repair-bad-data.patch b/Spigot-Server-Patches/handle-NaN-health-absorb-values-and-repair-bad-data.patch index cdc1bec4a2..b666f22291 100644 --- a/Spigot-Server-Patches/handle-NaN-health-absorb-values-and-repair-bad-data.patch +++ b/Spigot-Server-Patches/handle-NaN-health-absorb-values-and-repair-bad-data.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { @Override - public void a(NBTTagCompound nbttagcompound) { + public void loadData(NBTTagCompound nbttagcompound) { - this.setAbsorptionHearts(nbttagcompound.getFloat("AbsorptionAmount")); + // Paper start - jvm keeps optimizing the setter + float absorptionAmount = nbttagcompound.getFloat("AbsorptionAmount"); @@ -21,7 +21,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.setAbsorptionHearts(absorptionAmount); + // Paper end if (nbttagcompound.hasKeyOfType("Attributes", 9) && this.world != null && !this.world.isClientSide) { - GenericAttributes.a(this.getAttributeMap(), nbttagcompound.getList("Attributes", 10)); + this.getAttributeMap().a(nbttagcompound.getList("Attributes", 10)); } @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { } diff --git a/Spigot-Server-Patches/remove-null-possibility-for-getServer-singleton.patch b/Spigot-Server-Patches/remove-null-possibility-for-getServer-singleton.patch index ecb9afbb40..5193bfb69e 100644 --- a/Spigot-Server-Patches/remove-null-possibility-for-getServer-singleton.patch +++ b/Spigot-Server-Patches/remove-null-possibility-for-getServer-singleton.patch @@ -11,20 +11,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ import org.spigotmc.SlackActivityAccountant; // Spigot - public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant implements IMojangStatistics, ICommandListener, AutoCloseable, Runnable { + public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant implements IMojangStatistics, ICommandListener, AutoCloseable { + private static MinecraftServer SERVER; // Paper public static final Logger LOGGER = LogManager.getLogger(); public static final File b = new File("usercache.json"); - private static final CompletableFuture i = CompletableFuture.completedFuture(Unit.INSTANCE); + public static final WorldSettings c = new WorldSettings("Demo World", EnumGamemode.SURVIVAL, false, EnumDifficulty.NORMAL, false, new GameRules(), DataPackConfiguration.a); @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant resourcepackrepository, Proxy proxy, DataFixer datafixer, DataPackResources datapackresources, MinecraftSessionService minecraftsessionservice, GameProfileRepository gameprofilerepository, UserCache usercache, WorldLoadListenerFactory worldloadlistenerfactory) { super("Server"); - this.ae = new ResourceManager(EnumResourcePackType.SERVER_DATA, this.serverThread); + SERVER = this; // Paper - better singleton - this.resourcePackRepository = new ResourcePackRepository<>(ResourcePackLoader::new); - this.craftingManager = new CraftingManager(); - this.tagRegistry = new TagRegistry(); + this.m = new GameProfilerSwitcher(SystemUtils.a, this::ag); + this.methodProfiler = GameProfilerDisabled.a; + this.serverPing = new ServerPing(); @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant Date: Thu, 25 Jun 2020 05:04:34 -0700 Subject: [PATCH 07/91] even more work --- ...to-control-if-armour-stands-can-move.patch | 2 +- .../Add-EntityZapEvent.patch | 43 ++++++----- .../Add-ProjectileCollideEvent.patch | 65 ++++++----------- ...uto-fix-bad-Y-levels-on-player-login.patch | 6 +- .../Bound-Treasure-Maps-to-World-Border.patch | 16 ++-- .../Cache-user-authenticator-threads.patch | 6 +- .../Chunk-registration-fixes.patch | 16 ++-- ...figurable-Cartographer-Treasure-Maps.patch | 10 +-- .../Configurable-flying-kick-messages.patch | 6 +- .../Don-t-let-fishinghooks-use-portals.patch | 14 ++-- ...PI-for-Reason-Source-Triggering-play.patch | 61 ++++++++++------ ...a-from-ArmorStand-and-SpawnEgg-items.patch | 6 +- Spigot-Server-Patches/Firework-API-s.patch | 62 ++++------------ ...more-aggressive-in-the-chunk-unload-.patch | 23 ++++-- ...ptimise-BlockState-s-hashCode-equals.patch | 73 +++++++++++-------- .../Optimise-removeQueue.patch | 2 +- .../Optimize-ItemStack.isEmpty.patch | 4 +- ...ok-reference-on-Craft-Entity-removal.patch | 2 +- 18 files changed, 199 insertions(+), 218 deletions(-) diff --git a/Spigot-Server-Patches/Add-API-methods-to-control-if-armour-stands-can-move.patch b/Spigot-Server-Patches/Add-API-methods-to-control-if-armour-stands-can-move.patch index 85dec620fa..32820d3025 100644 --- a/Spigot-Server-Patches/Add-API-methods-to-control-if-armour-stands-can-move.patch +++ b/Spigot-Server-Patches/Add-API-methods-to-control-if-armour-stands-can-move.patch @@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 super(entitytypes, world); @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - return this.getEntityType().k().a(f); + return this.getEntityType().l().a(f); } + + // Paper start diff --git a/Spigot-Server-Patches/Add-EntityZapEvent.patch b/Spigot-Server-Patches/Add-EntityZapEvent.patch index b984edefad..ba5de3cfb8 100644 --- a/Spigot-Server-Patches/Add-EntityZapEvent.patch +++ b/Spigot-Server-Patches/Add-EntityZapEvent.patch @@ -8,36 +8,35 @@ diff --git a/src/main/java/net/minecraft/server/EntityPig.java b/src/main/java/n index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityPig.java +++ b/src/main/java/net/minecraft/server/EntityPig.java -@@ -0,0 +0,0 @@ public class EntityPig extends EntityAnimal { - entitypigzombie.setCustomNameVisible(this.getCustomNameVisible()); - } +@@ -0,0 +0,0 @@ public class EntityPig extends EntityAnimal implements ISteerable, ISaddleable { + } -+ // Paper start -+ if (CraftEventFactory.callEntityZapEvent(this, entitylightning, entitypigzombie).isCancelled()) { -+ return; -+ } -+ // Paper end -+ - // CraftBukkit start - if (CraftEventFactory.callPigZapEvent(this, entitylightning, entitypigzombie).isCancelled()) { - return; + entitypigzombie.setPersistent(); ++ // Paper start ++ if (CraftEventFactory.callEntityZapEvent(this, entitylightning, entitypigzombie).isCancelled()) { ++ return; ++ } ++ // Paper end + // CraftBukkit start + if (CraftEventFactory.callPigZapEvent(this, entitylightning, entitypigzombie).isCancelled()) { + return; 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 - public void onLightningStrike(EntityLightning entitylightning) { - EntityWitch entitywitch = (EntityWitch) EntityTypes.WITCH.a(this.world); + EntityVillager.LOGGER.info("Villager {} was struck by lightning {}.", this, entitylightning); + EntityWitch entitywitch = (EntityWitch) EntityTypes.WITCH.a(this.world); -+ // Paper start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityZapEvent(this, entitylightning, entitywitch).isCancelled()) { -+ return; -+ } -+ // Paper end ++ // Paper start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityZapEvent(this, entitylightning, entitywitch).isCancelled()) { ++ return; ++ } ++ // Paper end + - entitywitch.setPositionRotation(this.locX(), this.locY(), this.locZ(), this.yaw, this.pitch); - entitywitch.prepare(this.world, this.world.getDamageScaler(new BlockPosition(entitywitch)), EnumMobSpawn.CONVERSION, (GroupDataEntity) null, (NBTTagCompound) null); - entitywitch.setNoAI(this.isNoAI()); + entitywitch.setPositionRotation(this.locX(), this.locY(), this.locZ(), this.yaw, this.pitch); + entitywitch.prepare(this.world, this.world.getDamageScaler(entitywitch.getChunkCoordinates()), EnumMobSpawn.CONVERSION, (GroupDataEntity) null, (NBTTagCompound) null); + entitywitch.setNoAI(this.isNoAI()); 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/Add-ProjectileCollideEvent.patch b/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch index 857068456a..bec046d55f 100644 --- a/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch +++ b/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch @@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityArrow.java +++ b/src/main/java/net/minecraft/server/EntityArrow.java -@@ -0,0 +0,0 @@ public abstract class EntityArrow extends Entity implements IProjectile { +@@ -0,0 +0,0 @@ public abstract class EntityArrow extends IProjectile { } } @@ -30,9 +30,9 @@ diff --git a/src/main/java/net/minecraft/server/EntityFireball.java b/src/main/j index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityFireball.java +++ b/src/main/java/net/minecraft/server/EntityFireball.java -@@ -0,0 +0,0 @@ public abstract class EntityFireball extends Entity { - ++this.g; - MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, true, this.g >= 25, this.shooter, RayTrace.BlockCollisionOption.COLLIDER); +@@ -0,0 +0,0 @@ public abstract class EntityFireball extends IProjectile { + + MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, this::a, RayTrace.BlockCollisionOption.COLLIDER); - if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { + // Paper start - Call ProjectileCollideEvent @@ -48,50 +48,33 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.a(movingobjectposition); // CraftBukkit start - Fire ProjectileHitEvent -diff --git a/src/main/java/net/minecraft/server/EntityFishingHook.java b/src/main/java/net/minecraft/server/EntityFishingHook.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/EntityFishingHook.java -+++ b/src/main/java/net/minecraft/server/EntityFishingHook.java -@@ -0,0 +0,0 @@ public class EntityFishingHook extends Entity { - return !entity.isSpectator() && (entity.isInteractable() || entity instanceof EntityItem) && (entity != this.owner || this.g >= 5); - }, RayTrace.BlockCollisionOption.COLLIDER, true); - -- if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { -+ // Paper start - Call ProjectileCollideEvent -+ if (movingobjectposition instanceof MovingObjectPositionEntity) { -+ com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileCollideEvent(this, (MovingObjectPositionEntity)movingobjectposition); -+ if (event.isCancelled()) { -+ movingobjectposition = null; -+ } -+ } -+ // Paper end -+ -+ if (movingobjectposition != null && movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { // Paper - add null check in case cancelled - org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition); // CraftBukkit - Call event - if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) { - this.hooked = ((MovingObjectPositionEntity) movingobjectposition).getEntity(); diff --git a/src/main/java/net/minecraft/server/EntityProjectile.java b/src/main/java/net/minecraft/server/EntityProjectile.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 { - this.ap = null; +@@ -0,0 +0,0 @@ public abstract class EntityProjectile extends IProjectile { } -- if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { -+ // Paper start - Call ProjectileCollideEvent -+ if (movingobjectposition instanceof MovingObjectPositionEntity) { -+ com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileCollideEvent(this, (MovingObjectPositionEntity)movingobjectposition); -+ if (event.isCancelled()) { -+ movingobjectposition = null; + if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS && !flag) { ++ // Paper start - Call ProjectileCollideEvent ++ if (movingobjectposition instanceof MovingObjectPositionEntity) { ++ com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileCollideEvent(this, (MovingObjectPositionEntity)movingobjectposition); ++ if (event.isCancelled()) { ++ movingobjectposition = null; ++ } + } -+ } -+ // Paper end -+ -+ if (movingobjectposition != null && movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { // Paper - add null check in case cancelled - if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.BLOCK && this.world.getType(((MovingObjectPositionBlock) movingobjectposition).getBlockPosition()).getBlock() == Blocks.NETHER_PORTAL) { - this.c(((MovingObjectPositionBlock) movingobjectposition).getBlockPosition()); - } else { ++ if (movingobjectposition != null) { ++ // Paper end + this.a(movingobjectposition); + // CraftBukkit start + if (this.dead) { + org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition); + } + // CraftBukkit end ++ } // Paper + } + + Vec3D vec3d = this.getMot(); 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/Auto-fix-bad-Y-levels-on-player-login.patch b/Spigot-Server-Patches/Auto-fix-bad-Y-levels-on-player-login.patch index 2b54be8e97..6242dbaed0 100644 --- a/Spigot-Server-Patches/Auto-fix-bad-Y-levels-on-player-login.patch +++ b/Spigot-Server-Patches/Auto-fix-bad-Y-levels-on-player-login.patch @@ -11,9 +11,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { @Override - public void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); + public void loadData(NBTTagCompound nbttagcompound) { + super.loadData(nbttagcompound); + if (this.locY() > 300) this.setPositionRaw(locX(), 257, locZ()); // Paper - bring down to a saner Y level if out of world if (nbttagcompound.hasKeyOfType("playerGameType", 99)) { if (this.getMinecraftServer().getForceGamemode()) { - this.playerInteractManager.setGameMode(this.getMinecraftServer().getGamemode()); + this.playerInteractManager.a(this.getMinecraftServer().getGamemode(), EnumGamemode.NOT_SET); diff --git a/Spigot-Server-Patches/Bound-Treasure-Maps-to-World-Border.patch b/Spigot-Server-Patches/Bound-Treasure-Maps-to-World-Border.patch index dced1406dd..a9aa588cf4 100644 --- a/Spigot-Server-Patches/Bound-Treasure-Maps-to-World-Border.patch +++ b/Spigot-Server-Patches/Bound-Treasure-Maps-to-World-Border.patch @@ -15,19 +15,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/StructureGenerator.java +++ b/src/main/java/net/minecraft/server/StructureGenerator.java @@ -0,0 +0,0 @@ public abstract class StructureGenerator + int i2 = l + k * k1; + int j2 = i1 + k * l1; + ChunkCoordIntPair chunkcoordintpair = this.a(structuresettingsfeature, j, seededrandom, i2, j2); ++ if (!iworldreader.getWorldBorder().isChunkInBounds(chunkcoordintpair.x, chunkcoordintpair.z)) { continue; } // Paper + IChunkAccess ichunkaccess = iworldreader.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, ChunkStatus.STRUCTURE_STARTS); + StructureStart structurestart = structuremanager.a(SectionPosition.a(ichunkaccess.getPos(), 0), this, ichunkaccess); - if (flag1 || flag2) { - ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, seededrandom, j, k, i1, j1); -+ if (!world.getWorldBorder().isChunkInBounds(chunkcoordintpair.x, chunkcoordintpair.z)) { continue; } // Paper - StructureStart structurestart = world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, ChunkStatus.STRUCTURE_STARTS).a(this.b()); - - if (structurestart != null && structurestart.e()) { diff --git a/src/main/java/net/minecraft/server/WorldBorder.java b/src/main/java/net/minecraft/server/WorldBorder.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldBorder.java +++ b/src/main/java/net/minecraft/server/WorldBorder.java @@ -0,0 +0,0 @@ public class WorldBorder { - return (double) (blockposition.getX() + 1) > this.c() && (double) blockposition.getX() < this.e() && (double) (blockposition.getZ() + 1) > this.d() && (double) blockposition.getZ() < this.f(); + return (double) (blockposition.getX() + 1) > this.e() && (double) blockposition.getX() < this.g() && (double) (blockposition.getZ() + 1) > this.f() && (double) blockposition.getZ() < this.h(); } + // Paper start @@ -43,5 +43,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end + public boolean isInBounds(ChunkCoordIntPair chunkcoordintpair) { - return (double) chunkcoordintpair.f() > this.c() && (double) chunkcoordintpair.d() < this.e() && (double) chunkcoordintpair.g() > this.d() && (double) chunkcoordintpair.e() < this.f(); + return (double) chunkcoordintpair.f() > this.e() && (double) chunkcoordintpair.d() < this.g() && (double) chunkcoordintpair.g() > this.f() && (double) chunkcoordintpair.e() < this.h(); } diff --git a/Spigot-Server-Patches/Cache-user-authenticator-threads.patch b/Spigot-Server-Patches/Cache-user-authenticator-threads.patch index 6b308ee461..e5c349a4f2 100644 --- a/Spigot-Server-Patches/Cache-user-authenticator-threads.patch +++ b/Spigot-Server-Patches/Cache-user-authenticator-threads.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ import com.google.common.collect.Lists; import com.mojang.authlib.GameProfile; import com.mojang.datafixers.util.Either; - import io.netty.util.concurrent.Future; + import com.mojang.serialization.DataResult; +import java.util.ArrayDeque; // Paper import java.util.Collection; +import java.util.Deque; // Paper @@ -63,6 +63,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.removeQueue.addAll(entityplayer.removeQueue); + } + // Paper end - this.cm = entityplayer.cm; - this.cr = entityplayer.cr; + this.ck = entityplayer.ck; + this.cp = entityplayer.cp; this.setShoulderEntityLeft(entityplayer.getShoulderEntityLeft()); diff --git a/Spigot-Server-Patches/Chunk-registration-fixes.patch b/Spigot-Server-Patches/Chunk-registration-fixes.patch index 261a9b880c..d5d3f53714 100644 --- a/Spigot-Server-Patches/Chunk-registration-fixes.patch +++ b/Spigot-Server-Patches/Chunk-registration-fixes.patch @@ -11,12 +11,12 @@ 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 { - public void chunkCheck(Entity entity) { - this.getMethodProfiler().enter("chunkCheck"); - int i = MathHelper.floor(entity.locX() / 16.0D); -- int j = MathHelper.floor(entity.locY() / 16.0D); -+ int j = Math.min(15, Math.max(0, MathHelper.floor(entity.locY() / 16.0D))); // Paper - stay consistent with chunk add/remove behavior; - int k = MathHelper.floor(entity.locZ() / 16.0D); +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { + if (entity.ck()) { + this.getMethodProfiler().enter("chunkCheck"); + int i = MathHelper.floor(entity.locX() / 16.0D); +- int j = MathHelper.floor(entity.locY() / 16.0D); ++ int j = Math.min(15, Math.max(0, MathHelper.floor(entity.locY() / 16.0D))); // Paper - stay consistent with chunk add/remove behavior + int k = MathHelper.floor(entity.locZ() / 16.0D); - if (!entity.inChunk || entity.chunkX != i || entity.chunkY != j || entity.chunkZ != k) { + if (!entity.inChunk || entity.chunkX != i || entity.chunkY != j || entity.chunkZ != k) { diff --git a/Spigot-Server-Patches/Configurable-Cartographer-Treasure-Maps.patch b/Spigot-Server-Patches/Configurable-Cartographer-Treasure-Maps.patch index 3fb5cf3a4b..2767a075d0 100644 --- a/Spigot-Server-Patches/Configurable-Cartographer-Treasure-Maps.patch +++ b/Spigot-Server-Patches/Configurable-Cartographer-Treasure-Maps.patch @@ -34,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class LootItemFunctionExplorationMap extends LootItemFunctionConditional if (blockposition != null) { - WorldServer worldserver = loottableinfo.c(); + WorldServer worldserver = loottableinfo.getWorld(); + // Paper start + if (!worldserver.paperConfig.enableTreasureMaps) { + /* @@ -44,7 +44,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return itemstack; + } + // Paper end - BlockPosition blockposition1 = worldserver.a(this.d, blockposition, this.g, this.h); + BlockPosition blockposition1 = worldserver.a(this.e, blockposition, this.h, this.i); if (blockposition1 != null) { diff --git a/src/main/java/net/minecraft/server/VillagerTrades.java b/src/main/java/net/minecraft/server/VillagerTrades.java @@ -55,9 +55,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return null; } else { WorldServer worldserver = (WorldServer) entity.world; -- BlockPosition blockposition = worldserver.a(this.b, new BlockPosition(entity), 100, true); -+ if (!worldserver.paperConfig.enableTreasureMaps) return null; //Paper -+ BlockPosition blockposition = worldserver.a(this.b, new BlockPosition(entity), 100, !worldserver.paperConfig.treasureMapsAlreadyDiscovered); //Paper +- BlockPosition blockposition = worldserver.a(this.b, entity.getChunkCoordinates(), 100, true); ++ if (!worldserver.paperConfig.enableTreasureMaps) return null; // Paper ++ BlockPosition blockposition = worldserver.a(this.b, entity.getChunkCoordinates(), 100, !worldserver.paperConfig.treasureMapsAlreadyDiscovered); // Paper if (blockposition != null) { ItemStack itemstack = ItemWorldMap.createFilledMapView(worldserver, blockposition.getX(), blockposition.getZ(), (byte) 2, true, true); diff --git a/Spigot-Server-Patches/Configurable-flying-kick-messages.patch b/Spigot-Server-Patches/Configurable-flying-kick-messages.patch index 56784df079..fdc7aa0f0e 100644 --- a/Spigot-Server-Patches/Configurable-flying-kick-messages.patch +++ b/Spigot-Server-Patches/Configurable-flying-kick-messages.patch @@ -25,10 +25,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { - if (this.B) { + if (this.B && !this.player.isSleeping()) { if (++this.C > 80) { PlayerConnection.LOGGER.warn("{} was kicked for floating too long!", this.player.getDisplayName().getString()); -- this.disconnect(new ChatMessage("multiplayer.disconnect.flying", new Object[0])); +- this.disconnect(new ChatMessage("multiplayer.disconnect.flying")); + this.disconnect(com.destroystokyo.paper.PaperConfig.flyingKickPlayerMessage); // Paper - use configurable kick message return; } @@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.D && this.player.getRootVehicle().getRidingPassenger() == this.player) { if (++this.E > 80) { PlayerConnection.LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getDisplayName().getString()); -- this.disconnect(new ChatMessage("multiplayer.disconnect.flying", new Object[0])); +- this.disconnect(new ChatMessage("multiplayer.disconnect.flying")); + this.disconnect(com.destroystokyo.paper.PaperConfig.flyingKickVehicleMessage); // Paper - use configurable kick message return; } diff --git a/Spigot-Server-Patches/Don-t-let-fishinghooks-use-portals.patch b/Spigot-Server-Patches/Don-t-let-fishinghooks-use-portals.patch index 085200f659..4eef9c894f 100644 --- a/Spigot-Server-Patches/Don-t-let-fishinghooks-use-portals.patch +++ b/Spigot-Server-Patches/Don-t-let-fishinghooks-use-portals.patch @@ -12,19 +12,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public boolean ac; public boolean impulse; public int portalCooldown; -- protected boolean af; -+ protected boolean af; public final boolean inPortal() { return this.af; } // Paper - OBFHELPER - protected int ag; - public DimensionManager dimension; - protected BlockPosition ai; +- protected boolean inPortal; ++ protected boolean inPortal; public final boolean inPortal() { return this.inPortal; } // Paper - OBFHELPER + protected int portalTicks; + protected BlockPosition ah; + protected Vec3D ai; diff --git a/src/main/java/net/minecraft/server/EntityFishingHook.java b/src/main/java/net/minecraft/server/EntityFishingHook.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityFishingHook.java +++ b/src/main/java/net/minecraft/server/EntityFishingHook.java -@@ -0,0 +0,0 @@ public class EntityFishingHook extends Entity { +@@ -0,0 +0,0 @@ public class EntityFishingHook extends IProjectile { this.setMot(this.getMot().a(0.92D)); - this.Z(); + this.ac(); + + // Paper start - These shouldn't be going through portals + if (this.inPortal()) { 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 33a7cbe276..6fcf7f9971 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 @@ -11,7 +11,7 @@ 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 { } } @@ -40,6 +40,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } world.triggerEffect(1042, blockposition, 0); +diff --git a/src/main/java/net/minecraft/server/EntityAnimal.java b/src/main/java/net/minecraft/server/EntityAnimal.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/EntityAnimal.java ++++ b/src/main/java/net/minecraft/server/EntityAnimal.java +@@ -0,0 +0,0 @@ public abstract class EntityAnimal extends EntityAgeable { + if (world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { + // CraftBukkit start - use event experience + if (experience > 0) { +- world.addEntity(new EntityExperienceOrb(world, this.locX(), this.locY(), this.locZ(), experience)); ++ world.addEntity(new EntityExperienceOrb(world, this.locX(), this.locY(), this.locZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer, entityageable)); // Paper + } + // CraftBukkit end + } diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityEnderDragon.java @@ -137,15 +150,28 @@ diff --git a/src/main/java/net/minecraft/server/EntityFishingHook.java b/src/mai index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityFishingHook.java +++ b/src/main/java/net/minecraft/server/EntityFishingHook.java -@@ -0,0 +0,0 @@ public class EntityFishingHook extends Entity { +@@ -0,0 +0,0 @@ public class EntityFishingHook extends IProjectile { this.world.addEntity(entityitem); // CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop() if (playerFishEvent.getExpToDrop() > 0) { -- this.owner.world.addEntity(new EntityExperienceOrb(this.owner.world, this.owner.locX(), this.owner.locY() + 0.5D, this.owner.locZ() + 0.5D, playerFishEvent.getExpToDrop())); -+ this.owner.world.addEntity(new EntityExperienceOrb(this.owner.world, this.owner.locX(), this.owner.locY() + 0.5D, this.owner.locZ() + 0.5D, playerFishEvent.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.FISHING, this.owner, this)); // Paper +- entityhuman.world.addEntity(new EntityExperienceOrb(entityhuman.world, entityhuman.locX(), entityhuman.locY() + 0.5D, entityhuman.locZ() + 0.5D, playerFishEvent.getExpToDrop())); ++ entityhuman.world.addEntity(new EntityExperienceOrb(entityhuman.world, entityhuman.locX(), entityhuman.locY() + 0.5D, entityhuman.locZ() + 0.5D, playerFishEvent.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.FISHING, this.getOwner(), this)); // Paper } // CraftBukkit end - if (itemstack1.getItem().a(TagsItem.FISHES)) { + if (itemstack1.getItem().a((Tag) TagsItem.FISHES)) { +diff --git a/src/main/java/net/minecraft/server/EntityFox.java b/src/main/java/net/minecraft/server/EntityFox.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/EntityFox.java ++++ b/src/main/java/net/minecraft/server/EntityFox.java +@@ -0,0 +0,0 @@ public class EntityFox extends EntityAnimal { + if (this.b.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { + // CraftBukkit start - use event experience + if (experience > 0) { +- this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX(), this.animal.locY(), this.animal.locZ(), experience)); ++ this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX(), this.animal.locY(), this.animal.locZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer, entityfox)); // Paper + } + // CraftBukkit end + } 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 @@ -212,19 +238,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } -diff --git a/src/main/java/net/minecraft/server/PathfinderGoalBreed.java b/src/main/java/net/minecraft/server/PathfinderGoalBreed.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/PathfinderGoalBreed.java -+++ b/src/main/java/net/minecraft/server/PathfinderGoalBreed.java -@@ -0,0 +0,0 @@ public class PathfinderGoalBreed extends PathfinderGoal { - if (this.b.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { - // CraftBukkit start - use event experience - if (experience > 0) { -- this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX(), this.animal.locY(), this.animal.locZ(), experience)); -+ this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX(), this.animal.locY(), this.animal.locZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer, entityageable)); // Paper - } - // CraftBukkit end - } diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PlayerInteractManager.java @@ -256,11 +269,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/TileEntityFurnace.java +++ b/src/main/java/net/minecraft/server/TileEntityFurnace.java @@ -0,0 +0,0 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I - while (i > 0) { - j = EntityExperienceOrb.getOrbValue(i); - i -= j; -- entityhuman.world.addEntity(new EntityExperienceOrb(entityhuman.world, entityhuman.locX(), entityhuman.locY() + 0.5D, entityhuman.locZ() + 0.5D, j)); -+ entityhuman.world.addEntity(new EntityExperienceOrb(entityhuman.world, entityhuman.locX(), entityhuman.locY() + 0.5D, entityhuman.locZ() + 0.5D, j, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, entityhuman)); // Paper + int k = EntityExperienceOrb.getOrbValue(j); + + j -= k; +- world.addEntity(new EntityExperienceOrb(world, vec3d.x, vec3d.y, vec3d.z, k)); ++ world.addEntity(new EntityExperienceOrb(world, vec3d.x, vec3d.y, vec3d.z, k, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, entityhuman)); // Paper } } @@ -275,7 +288,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - entity = new EntityExperienceOrb(world, x, y, z, 0); + entity = new EntityExperienceOrb(world, x, y, z, 0, org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM, null, null); // Paper } else if (LightningStrike.class.isAssignableFrom(clazz)) { - entity = new EntityLightning(world, x, y, z, false); + entity = EntityTypes.LIGHTNING_BOLT.a(world); } else if (Firework.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 diff --git a/Spigot-Server-Patches/Filter-bad-data-from-ArmorStand-and-SpawnEgg-items.patch b/Spigot-Server-Patches/Filter-bad-data-from-ArmorStand-and-SpawnEgg-items.patch index c0ed9d44cf..5df98b2968 100644 --- a/Spigot-Server-Patches/Filter-bad-data-from-ArmorStand-and-SpawnEgg-items.patch +++ b/Spigot-Server-Patches/Filter-bad-data-from-ArmorStand-and-SpawnEgg-items.patch @@ -35,9 +35,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/EntityFallingBlock.java @@ -0,0 +0,0 @@ public class EntityFallingBlock extends Entity { @Override - protected void a(NBTTagCompound nbttagcompound) { - this.block = GameProfileSerializer.d(nbttagcompound.getCompound("BlockState")); -+ + protected void loadData(NBTTagCompound nbttagcompound) { + this.block = GameProfileSerializer.c(nbttagcompound.getCompound("BlockState")); + // Paper start - Block FallingBlocks with Command Blocks + // Check mappings on update - dc = "repeating_command_block" - dd = "chain_command_block" + final Block b = this.block.getBlock(); @@ -45,7 +44,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.block = Blocks.STONE.getBlockData(); + } + // Paper end -+ this.ticksLived = nbttagcompound.getInt("Time"); if (nbttagcompound.hasKeyOfType("HurtEntities", 99)) { this.hurtEntities = nbttagcompound.getBoolean("HurtEntities"); diff --git a/Spigot-Server-Patches/Firework-API-s.patch b/Spigot-Server-Patches/Firework-API-s.patch index 1ec335e982..cd5ddd74de 100644 --- a/Spigot-Server-Patches/Firework-API-s.patch +++ b/Spigot-Server-Patches/Firework-API-s.patch @@ -8,26 +8,17 @@ 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 @@ package net.minecraft.server; - import java.util.Iterator; - import java.util.List; - import java.util.OptionalInt; -+import java.util.UUID; -+ - import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit - - public class EntityFireworks extends Entity implements IProjectile { -@@ -0,0 +0,0 @@ public class EntityFireworks extends Entity implements IProjectile { +@@ -0,0 +0,0 @@ public class EntityFireworks extends IProjectile { public static final DataWatcherObject SHOT_AT_ANGLE = DataWatcher.a(EntityFireworks.class, DataWatcherRegistry.i); private int ticksFlown; public int expectedLifespan; - private EntityLiving ridingEntity; + private EntityLiving ridingEntity; public final EntityLiving getBoostedEntity() { return this.ridingEntity; } // Paper - OBFHELPER -+ public UUID spawningEntity; // Paper ++ public java.util.UUID spawningEntity; // Paper public EntityFireworks(EntityTypes entitytypes, World world) { super(entitytypes, world); -@@ -0,0 +0,0 @@ public class EntityFireworks extends Entity implements IProjectile { +@@ -0,0 +0,0 @@ public class EntityFireworks extends IProjectile { } nbttagcompound.setBoolean("ShotAtAngle", (Boolean) this.datawatcher.get(EntityFireworks.SHOT_AT_ANGLE)); @@ -39,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } @Override -@@ -0,0 +0,0 @@ public class EntityFireworks extends Entity implements IProjectile { +@@ -0,0 +0,0 @@ public class EntityFireworks extends IProjectile { if (nbttagcompound.hasKey("ShotAtAngle")) { this.datawatcher.set(EntityFireworks.SHOT_AT_ANGLE, nbttagcompound.getBoolean("ShotAtAngle")); } @@ -56,10 +47,10 @@ 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 if (flag1) { - object = new EntityFireworks(world, itemstack1, entityliving.locX(), entityliving.getHeadY() - 0.15000000596046448D, entityliving.locZ(), true); + object = new EntityFireworks(world, itemstack1, entityliving, entityliving.locX(), entityliving.getHeadY() - 0.15000000596046448D, entityliving.locZ(), true); + ((EntityFireworks) object).spawningEntity = entityliving.getUniqueID(); // Paper } else { object = a(world, entityliving, itemstack, itemstack1); @@ -71,7 +62,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ItemFireworks extends Item { Vec3D vec3d = itemactioncontext.getPos(); EnumDirection enumdirection = itemactioncontext.getClickedFace(); - EntityFireworks entityfireworks = new EntityFireworks(world, vec3d.x + (double) enumdirection.getAdjacentX() * 0.15D, vec3d.y + (double) enumdirection.getAdjacentY() * 0.15D, vec3d.z + (double) enumdirection.getAdjacentZ() * 0.15D, itemstack); + EntityFireworks entityfireworks = new EntityFireworks(world, itemactioncontext.getEntity(), vec3d.x + (double) enumdirection.getAdjacentX() * 0.15D, vec3d.y + (double) enumdirection.getAdjacentY() * 0.15D, vec3d.z + (double) enumdirection.getAdjacentZ() * 0.15D, itemstack); + entityfireworks.spawningEntity = itemactioncontext.getEntity().getUniqueID(); // Paper world.addEntity(entityfireworks); @@ -94,53 +85,32 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/NBTTagCompound.java +++ b/src/main/java/net/minecraft/server/NBTTagCompound.java @@ -0,0 +0,0 @@ public class NBTTagCompound implements NBTBase { - return new UUID(this.getLong(s + "Most"), this.getLong(s + "Least")); + return GameProfileSerializer.a(this.get(s)); } -- public boolean b(String s) { -+ public final boolean hasUUID(String s) { return this.b(s); } public boolean b(String s) { // Paper - OBFHELPER - return this.hasKeyOfType(s + "Most", 99) && this.hasKeyOfType(s + "Least", 99); - } ++ public final boolean hasUUID(String s) { return this.b(s); } // Paper - OBFHELPER + public boolean b(String s) { + NBTBase nbtbase = this.get(s); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java -@@ -0,0 +0,0 @@ package org.bukkit.craftbukkit.entity; - - import java.util.Random; - import net.minecraft.server.EntityFireworks; -+import net.minecraft.server.EntityLiving; - import net.minecraft.server.ItemStack; - import net.minecraft.server.Items; - import org.bukkit.Material; -@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.CraftServer; - import org.bukkit.craftbukkit.inventory.CraftItemStack; - import org.bukkit.entity.EntityType; - import org.bukkit.entity.Firework; -+import org.bukkit.entity.LivingEntity; - import org.bukkit.inventory.meta.FireworkMeta; - -+import java.util.UUID; -+ - public class CraftFirework extends CraftEntity implements Firework { - - private final Random random = new Random(); -@@ -0,0 +0,0 @@ public class CraftFirework extends CraftEntity implements Firework { +@@ -0,0 +0,0 @@ public class CraftFirework extends CraftProjectile implements Firework { public void setShotAtAngle(boolean shotAtAngle) { getHandle().getDataWatcher().set(EntityFireworks.SHOT_AT_ANGLE, shotAtAngle); } + + // Paper start + @Override -+ public UUID getSpawningEntity() { ++ public java.util.UUID getSpawningEntity() { + return getHandle().spawningEntity; + } + + @Override -+ public LivingEntity getBoostedEntity() { -+ EntityLiving boostedEntity = getHandle().getBoostedEntity(); -+ return boostedEntity != null ? (LivingEntity) boostedEntity.getBukkitEntity() : null; ++ public org.bukkit.entity.LivingEntity getBoostedEntity() { ++ net.minecraft.server.EntityLiving boostedEntity = getHandle().getBoostedEntity(); ++ return boostedEntity != null ? (org.bukkit.entity.LivingEntity) boostedEntity.getBukkitEntity() : null; + } + // Paper end } diff --git a/Spigot-Server-Patches/Make-targetSize-more-aggressive-in-the-chunk-unload-.patch b/Spigot-Server-Patches/Make-targetSize-more-aggressive-in-the-chunk-unload-.patch index 0299dab3ac..33bb103e83 100644 --- a/Spigot-Server-Patches/Make-targetSize-more-aggressive-in-the-chunk-unload-.patch +++ b/Spigot-Server-Patches/Make-targetSize-more-aggressive-in-the-chunk-unload-.patch @@ -9,13 +9,22 @@ 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 { - this.u = new AtomicInteger(); + private final PlayerMap playerMap; + public final Int2ObjectMap trackedEntities; + private final Long2ByteMap z; +- private final Queue A; ++ private final Queue A; private final Queue getUnloadQueueTasks() { return this.A; } // Paper - OBFHELPER + private int viewDistance; + + // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.playerMap = new PlayerMap(); this.trackedEntities = new Int2ObjectOpenHashMap(); -- this.z = Queues.newConcurrentLinkedQueue(); -+ this.z = new com.destroystokyo.paper.utils.CachedSizeConcurrentLinkedQueue<>(); // Paper + this.z = new Long2ByteOpenHashMap(); +- this.A = Queues.newConcurrentLinkedQueue(); ++ this.A = new com.destroystokyo.paper.utils.CachedSizeConcurrentLinkedQueue<>(); // Paper - need constant-time size() this.definedStructureManager = definedstructuremanager; - this.w = worldserver.getWorldProvider().getDimensionManager().a(file); + this.w = convertable_conversionsession.a(worldserver.getDimensionKey()); this.world = worldserver; @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { // Spigot start @@ -30,9 +39,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Runnable runnable; -- while ((booleansupplier.getAsBoolean() || this.z.size() > 2000) && (runnable = (Runnable) this.z.poll()) != null) { -+ int queueTarget = Math.min(this.z.size() - 100, (int) (this.z.size() * UNLOAD_QUEUE_RESIZE_FACTOR)); // Paper - Target this queue as well -+ while ((booleansupplier.getAsBoolean() || this.z.size() > queueTarget) && (runnable = (Runnable) this.z.poll()) != null) { // Paper - Target this queue as well +- while ((booleansupplier.getAsBoolean() || this.A.size() > 2000) && (runnable = (Runnable) this.A.poll()) != null) { ++ int queueTarget = Math.min(this.getUnloadQueueTasks().size() - 100, (int) (this.getUnloadQueueTasks().size() * UNLOAD_QUEUE_RESIZE_FACTOR)); // Paper - Target this queue as well ++ while ((booleansupplier.getAsBoolean() || this.getUnloadQueueTasks().size() > queueTarget) && (runnable = (Runnable)this.getUnloadQueueTasks().poll()) != null) { // Paper - Target this queue as well runnable.run(); } diff --git a/Spigot-Server-Patches/Optimise-BlockState-s-hashCode-equals.patch b/Spigot-Server-Patches/Optimise-BlockState-s-hashCode-equals.patch index b632c7e2a3..8c1260258b 100644 --- a/Spigot-Server-Patches/Optimise-BlockState-s-hashCode-equals.patch +++ b/Spigot-Server-Patches/Optimise-BlockState-s-hashCode-equals.patch @@ -8,38 +8,6 @@ object identity checks safely. Use a simpler optimized hashcode -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> - } - - public boolean equals(Object object) { -- if (this == object) { -- return true; -- } else if (!(object instanceof IBlockState)) { -- return false; -- } else { -- IBlockState blockstate = (IBlockState) object; -- -- return this.a.equals(blockstate.a) && this.b.equals(blockstate.b); -- } -+ return this == object; // Paper - only one instance per configuration - } - -+ private static final java.util.concurrent.atomic.AtomicInteger hashId = new java.util.concurrent.atomic.AtomicInteger(1); // Paper - only one instance per configuration -+ private final int hashCode = 92821 * hashId.getAndIncrement(); // Paper - only one instance per configuration - public final int hashCode() { -- if (this.c == null) { -- this.c = this.c(); -- } -- -- return this.c; -+ return this.hashCode; // Paper - only one instance per configuration - } - - public int c() { diff --git a/src/main/java/net/minecraft/server/BlockStateBoolean.java b/src/main/java/net/minecraft/server/BlockStateBoolean.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockStateBoolean.java @@ -82,3 +50,44 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this == object) { return true; } else if (object instanceof BlockStateInteger && super.equals(object)) { +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> { + 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> { + } + + public boolean equals(Object object) { +- if (this == object) { +- return true; +- } else if (!(object instanceof IBlockState)) { +- return false; +- } else { +- IBlockState iblockstate = (IBlockState) object; +- +- return this.a.equals(iblockstate.a) && this.b.equals(iblockstate.b); +- } ++ return this == object; // Paper - only one instance per configuration + } + ++ private static final java.util.concurrent.atomic.AtomicInteger hashId = new java.util.concurrent.atomic.AtomicInteger(1); // Paper - only one instance per configuration ++ private final int hashCode = 92821 * hashId.getAndIncrement(); // Paper - only one instance per configuration + public final int hashCode() { + if (this.c == null) { + this.c = this.b(); + } + +- return this.c; ++ return this.hashCode; // Paper - only one instance per configuration + } + + public int b() { diff --git a/Spigot-Server-Patches/Optimise-removeQueue.patch b/Spigot-Server-Patches/Optimise-removeQueue.patch index a00af58257..a475831e28 100644 --- a/Spigot-Server-Patches/Optimise-removeQueue.patch +++ b/Spigot-Server-Patches/Optimise-removeQueue.patch @@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class LoginListener implements PacketLoginInListener { - return LoginListener.this.server.Y() && socketaddress instanceof InetSocketAddress ? ((InetSocketAddress) socketaddress).getAddress() : null; + return LoginListener.this.server.U() && socketaddress instanceof InetSocketAddress ? ((InetSocketAddress) socketaddress).getAddress() : null; } - }; - diff --git a/Spigot-Server-Patches/Optimize-ItemStack.isEmpty.patch b/Spigot-Server-Patches/Optimize-ItemStack.isEmpty.patch index f4374a69ce..cb8176d566 100644 --- a/Spigot-Server-Patches/Optimize-ItemStack.isEmpty.patch +++ b/Spigot-Server-Patches/Optimize-ItemStack.isEmpty.patch @@ -13,8 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public boolean isEmpty() { -- return this == ItemStack.a ? true : (this.getItem() != null && this.getItem() != Items.AIR ? this.count <= 0 : true); -+ return this == ItemStack.a || this.item == null || this.item == Items.AIR || this.count <= 0; // Paper +- return this == ItemStack.b ? true : (this.getItem() != null && this.getItem() != Items.AIR ? this.count <= 0 : true); ++ return this == ItemStack.NULL_ITEM || this.item == null || this.item == Items.AIR || this.count <= 0; // Paper } public ItemStack cloneAndSubtract(int i) { diff --git a/Spigot-Server-Patches/Remove-FishingHook-reference-on-Craft-Entity-removal.patch b/Spigot-Server-Patches/Remove-FishingHook-reference-on-Craft-Entity-removal.patch index d99e588e5f..b19c38731a 100644 --- a/Spigot-Server-Patches/Remove-FishingHook-reference-on-Craft-Entity-removal.patch +++ b/Spigot-Server-Patches/Remove-FishingHook-reference-on-Craft-Entity-removal.patch @@ -8,7 +8,7 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java b/sr index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java -@@ -0,0 +0,0 @@ public class CraftFishHook extends AbstractProjectile implements FishHook { +@@ -0,0 +0,0 @@ public class CraftFishHook extends CraftProjectile implements FishHook { Validate.isTrue(chance >= 0 && chance <= 1, "The bite chance must be between 0 and 1."); this.biteChance = chance; } From 4aa79558187e23f95ac550e0ce59782634572904 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 25 Jun 2020 06:11:48 -0700 Subject: [PATCH 08/91] even even more work --- .../Ability-to-apply-mending-to-XP-API.patch | 2 +- ...e-PlayerProfile-in-AsyncPreLoginEven.patch | 2 +- .../Add-PlayerArmorChangeEvent.patch | 28 ++++---- .../Add-PlayerJumpEvent.patch | 4 +- .../Add-UnknownCommandEvent.patch | 4 +- ...-a-custom-authentication-servers-dow.patch | 2 +- .../AsyncTabCompleteEvent.patch | 22 +++--- .../Basic-PlayerProfile-API.patch | 45 +++++++----- .../Do-not-let-armorstands-drown.patch | 8 +-- ...nt-protocol-version-and-virtual-host.patch | 8 --- .../Extend-Player-Interact-cancellation.patch | 17 +++-- .../Fill-Profile-Property-Events.patch | 1 + .../Fix-this-stupid-bullshit.patch | 2 +- ...nt-extended-PaperServerListPingEvent.patch | 12 ++-- .../Implement-getI18NDisplayName.patch | 21 ++++-- .../Improve-the-Saddle-API-for-Horses.patch | 2 +- .../Item-canEntityPickup.patch | 4 +- .../LivingEntity-setKiller.patch | 4 +- ...awns-should-honor-nametags-and-leash.patch | 2 +- ...PlayerAdvancementCriterionGrantEvent.patch | 2 +- .../PlayerNaturallySpawnCreaturesEvent.patch | 10 +-- .../PlayerPickupExperienceEvent.patch | 8 +-- .../PreCreatureSpawnEvent.patch | 69 ++++++++++--------- ...sted-Ice-from-loading-holding-chunks.patch | 33 ++++----- ...rom-being-processed-when-the-player-.patch | 2 +- .../Profile-Lookup-Events.patch | 9 ++- .../ProfileWhitelistVerifyEvent.patch | 9 +-- ...le-async-calls-to-restart-the-server.patch | 6 +- ...dEffects-only-to-players-who-can-see.patch | 4 +- ...oleAppender-for-console-improvements.patch | 22 +++--- .../handle-PacketPlayInKeepAlive-async.patch | 3 +- ...rt-serverside-behavior-of-keepalives.patch | 14 ++-- ...e-implementations-for-captured-block.patch | 2 +- 33 files changed, 200 insertions(+), 183 deletions(-) diff --git a/Spigot-Server-Patches/Ability-to-apply-mending-to-XP-API.patch b/Spigot-Server-Patches/Ability-to-apply-mending-to-XP-API.patch index 61a683e77b..f59cc5e55a 100644 --- a/Spigot-Server-Patches/Ability-to-apply-mending-to-XP-API.patch +++ b/Spigot-Server-Patches/Ability-to-apply-mending-to-XP-API.patch @@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } @Nullable public static Entry b(Enchantment enchantment, EntityLiving entityliving) { - Map map = enchantment.a(entityliving); + return a(enchantment, entityliving, (itemstack) -> { diff --git a/src/main/java/net/minecraft/server/EntityExperienceOrb.java b/src/main/java/net/minecraft/server/EntityExperienceOrb.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java diff --git a/Spigot-Server-Patches/Ability-to-change-PlayerProfile-in-AsyncPreLoginEven.patch b/Spigot-Server-Patches/Ability-to-change-PlayerProfile-in-AsyncPreLoginEven.patch index 2722950169..c3447efd77 100644 --- a/Spigot-Server-Patches/Ability-to-change-PlayerProfile-in-AsyncPreLoginEven.patch +++ b/Spigot-Server-Patches/Ability-to-change-PlayerProfile-in-AsyncPreLoginEven.patch @@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import com.destroystokyo.paper.profile.PlayerProfile; import com.mojang.authlib.GameProfile; import com.mojang.authlib.exceptions.AuthenticationUnavailableException; - import io.netty.channel.ChannelFuture; + import java.math.BigInteger; @@ -0,0 +0,0 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/Spigot-Server-Patches/Add-PlayerArmorChangeEvent.patch b/Spigot-Server-Patches/Add-PlayerArmorChangeEvent.patch index 251ed82155..f78f0cbd97 100644 --- a/Spigot-Server-Patches/Add-PlayerArmorChangeEvent.patch +++ b/Spigot-Server-Patches/Add-PlayerArmorChangeEvent.patch @@ -11,24 +11,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ package net.minecraft.server; -+import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent; ++import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent; // Paper import com.google.common.base.Objects; import com.google.common.collect.ImmutableList; - import com.google.common.collect.ImmutableSet; + import com.google.common.collect.ImmutableMap; @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { - ItemStack itemstack1 = this.getEquipment(enumitemslot); + 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 (!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 + if (map == null) { + map = Maps.newEnumMap(EnumItemSlot.class); + } diff --git a/src/main/java/net/minecraft/server/EnumItemSlot.java b/src/main/java/net/minecraft/server/EnumItemSlot.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EnumItemSlot.java diff --git a/Spigot-Server-Patches/Add-PlayerJumpEvent.patch b/Spigot-Server-Patches/Add-PlayerJumpEvent.patch index 3cb5cd8994..9b7c2491ee 100644 --- a/Spigot-Server-Patches/Add-PlayerJumpEvent.patch +++ b/Spigot-Server-Patches/Add-PlayerJumpEvent.patch @@ -18,9 +18,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit end @@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { - } + boolean flag = d8 > 0.0D; - if (this.player.onGround && !packetplayinflying.b() && d8 > 0.0D) { + if (this.player.isOnGround() && !packetplayinflying.b() && flag) { - this.player.jump(); + // Paper start - Add player jump event + Player player = this.getPlayer(); diff --git a/Spigot-Server-Patches/Add-UnknownCommandEvent.patch b/Spigot-Server-Patches/Add-UnknownCommandEvent.patch index 39dc00d560..d459cb3296 100644 --- a/Spigot-Server-Patches/Add-UnknownCommandEvent.patch +++ b/Spigot-Server-Patches/Add-UnknownCommandEvent.patch @@ -8,9 +8,9 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/ja 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 @@ import net.minecraft.server.WorldServer; +@@ -0,0 +0,0 @@ import net.minecraft.server.WorldNBTStorage; + import net.minecraft.server.WorldServer; import net.minecraft.server.WorldSettings; - import net.minecraft.server.WorldType; import org.apache.commons.lang.Validate; +import org.apache.commons.lang3.StringUtils; import org.bukkit.BanList; diff --git a/Spigot-Server-Patches/Allow-specifying-a-custom-authentication-servers-dow.patch b/Spigot-Server-Patches/Allow-specifying-a-custom-authentication-servers-dow.patch index 7c42041f2a..5d939965c5 100644 --- a/Spigot-Server-Patches/Allow-specifying-a-custom-authentication-servers-dow.patch +++ b/Spigot-Server-Patches/Allow-specifying-a-custom-authentication-servers-dow.patch @@ -38,6 +38,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (com.destroystokyo.paper.PaperConfig.authenticationServersDownKickMessage != null) { + LoginListener.this.disconnect(new ChatComponentText(com.destroystokyo.paper.PaperConfig.authenticationServersDownKickMessage)); + } else // Paper end - LoginListener.this.disconnect(new ChatMessage("multiplayer.disconnect.authservers_down", new Object[0])); + LoginListener.this.disconnect(new ChatMessage("multiplayer.disconnect.authservers_down")); LoginListener.LOGGER.error("Couldn't verify username because servers are unavailable"); } diff --git a/Spigot-Server-Patches/AsyncTabCompleteEvent.patch b/Spigot-Server-Patches/AsyncTabCompleteEvent.patch index 6a34979c0d..5fa430455d 100644 --- a/Spigot-Server-Patches/AsyncTabCompleteEvent.patch +++ b/Spigot-Server-Patches/AsyncTabCompleteEvent.patch @@ -46,19 +46,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // If the event isn't handled, we can assume that we have no completions, and so we'll ask the server + if (!event.isHandled()) { + if (!event.isCancelled()) { -+ // Paper end - async tab completion -+ this.minecraftServer.scheduleOnMain(() -> { // Paper - This needs to be on main -+ ParseResults parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener()); - this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { - if (((Suggestions) suggestions).isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [] from showing for plugins with nothing more to offer -- this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestions)); // CraftBukkit - decompile error +- this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { +- if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [] from showing for plugins with nothing more to offer +- this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestions)); - }); -+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestions)); // CraftBukkit - decompile error -+ }); -+ }); // Paper - This needs to be on main ++ this.minecraftServer.scheduleOnMain(() -> { // Paper - This needs to be on main ++ ParseResults parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener()); ++ ++ this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { ++ if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [] from showing for plugins with nothing more to offer ++ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestions)); ++ }); ++ }); + } -+ // Paper start - async tab completion + } else if (!completions.isEmpty()) { + com.mojang.brigadier.suggestion.SuggestionsBuilder builder = new com.mojang.brigadier.suggestion.SuggestionsBuilder(packetplayintabcomplete.c(), stringreader.getTotalLength()); + @@ -67,7 +68,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + player.playerConnection.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), builder.buildFuture().join())); + } + // Paper end - async tab completion -+ } @Override diff --git a/Spigot-Server-Patches/Basic-PlayerProfile-API.patch b/Spigot-Server-Patches/Basic-PlayerProfile-API.patch index 15df7c9edb..0fa7b80c05 100644 --- a/Spigot-Server-Patches/Basic-PlayerProfile-API.patch +++ b/Spigot-Server-Patches/Basic-PlayerProfile-API.patch @@ -315,17 +315,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ +package com.destroystokyo.paper.profile; + -+import com.mojang.authlib.Agent; -+import com.mojang.authlib.GameProfileRepository; -+import com.mojang.authlib.UserAuthentication; ++import com.mojang.authlib.*; +import com.mojang.authlib.minecraft.MinecraftSessionService; +import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; ++import com.mojang.authlib.yggdrasil.YggdrasilEnvironment; + +import java.net.Proxy; + +public class PaperAuthenticationService extends YggdrasilAuthenticationService { ++ private final Environment environment; + public PaperAuthenticationService(Proxy proxy, String clientToken) { + super(proxy, clientToken); ++ this.environment = (Environment)EnvironmentParser.getEnvironmentFromProperties().orElse(YggdrasilEnvironment.PROD);; + } + + @Override @@ -335,12 +336,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + @Override + public MinecraftSessionService createMinecraftSessionService() { -+ return new PaperMinecraftSessionService(this); ++ return new PaperMinecraftSessionService(this, this.environment); + } + + @Override + public GameProfileRepository createProfileRepository() { -+ return new PaperGameProfileRepository(this); ++ return new PaperGameProfileRepository(this, this.environment); + } +} diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java @@ -352,13 +353,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +package com.destroystokyo.paper.profile; + +import com.mojang.authlib.Agent; ++import com.mojang.authlib.Environment; +import com.mojang.authlib.ProfileLookupCallback; +import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; +import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository; + +public class PaperGameProfileRepository extends YggdrasilGameProfileRepository { -+ public PaperGameProfileRepository(YggdrasilAuthenticationService authenticationService) { -+ super(authenticationService); ++ public PaperGameProfileRepository(YggdrasilAuthenticationService authenticationService, Environment environment) { ++ super(authenticationService, environment); + } + + @Override @@ -374,6 +376,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ +package com.destroystokyo.paper.profile; + ++import com.mojang.authlib.Environment; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; @@ -382,8 +385,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import java.util.Map; + +public class PaperMinecraftSessionService extends YggdrasilMinecraftSessionService { -+ protected PaperMinecraftSessionService(YggdrasilAuthenticationService authenticationService) { -+ super(authenticationService); ++ protected PaperMinecraftSessionService(YggdrasilAuthenticationService authenticationService, Environment environment) { ++ super(authenticationService, environment); + } + + @Override @@ -445,21 +448,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 /** * Calculates distance between 2 entities * @param e1 +diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/Main.java ++++ b/src/main/java/net/minecraft/server/Main.java +@@ -0,0 +0,0 @@ public class Main { + } + + File file = (File) optionset.valueOf("universe"); // CraftBukkit +- YggdrasilAuthenticationService yggdrasilauthenticationservice = new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString()); ++ YggdrasilAuthenticationService yggdrasilauthenticationservice = new com.destroystokyo.paper.profile.PaperAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString()); // Paper + MinecraftSessionService minecraftsessionservice = yggdrasilauthenticationservice.createMinecraftSessionService(); + GameProfileRepository gameprofilerepository = yggdrasilauthenticationservice.createProfileRepository(); + UserCache usercache = new UserCache(gameprofilerepository, new File(file, MinecraftServer.b.getName())); 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= 5000000000L) { - this.Z = i; + if (i - this.T >= 5000000000L) { + this.T = i; this.serverPing.setPlayerSample(new ServerPing.ServerPingPlayerSample(this.getMaxPlayers(), this.getPlayerCount())); - GameProfile[] agameprofile = new GameProfile[Math.min(this.getPlayerCount(), 12)]; + GameProfile[] agameprofile = new GameProfile[Math.min(this.getPlayerCount(), org.spigotmc.SpigotConfig.playerSample)]; // Paper - int j = MathHelper.nextInt(this.q, 0, this.getPlayerCount() - agameprofile.length); + int j = MathHelper.nextInt(this.r, 0, this.getPlayerCount() - agameprofile.length); for (int k = 0; k < agameprofile.length; ++k) { diff --git a/src/main/java/net/minecraft/server/PacketStatusListener.java b/src/main/java/net/minecraft/server/PacketStatusListener.java diff --git a/Spigot-Server-Patches/Implement-getI18NDisplayName.patch b/Spigot-Server-Patches/Implement-getI18NDisplayName.patch index e23ac6ac71..76837e9405 100644 --- a/Spigot-Server-Patches/Implement-getI18NDisplayName.patch +++ b/Spigot-Server-Patches/Implement-getI18NDisplayName.patch @@ -11,19 +11,28 @@ diff --git a/src/main/java/net/minecraft/server/LocaleLanguage.java b/src/main/j index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/LocaleLanguage.java +++ b/src/main/java/net/minecraft/server/LocaleLanguage.java -@@ -0,0 +0,0 @@ public class LocaleLanguage { +@@ -0,0 +0,0 @@ public abstract class LocaleLanguage { + + private static LocaleLanguage c() { + Builder builder = ImmutableMap.builder(); +- BiConsumer biconsumer = builder::put; ++ BiConsumer biconsumer = builder::put; // Paper - decompile fix + + try { + InputStream inputstream = LocaleLanguage.class.getResourceAsStream("/assets/minecraft/lang/en_us.json"); +@@ -0,0 +0,0 @@ public abstract class LocaleLanguage { } + public static LocaleLanguage getInstance() { return a(); } // Paper - OBFHELPER public static LocaleLanguage a() { - return LocaleLanguage.c; + return LocaleLanguage.d; } -+ public synchronized String translateKey(String key) { return a(key); } // Paper - OBFHELPER - public synchronized String a(String s) { - return this.c(s); - } ++ public String translateKey(String key) { return a(key); } // Paper - OBFHELPER + public abstract String a(String s); + + public abstract boolean b(String s); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java diff --git a/Spigot-Server-Patches/Improve-the-Saddle-API-for-Horses.patch b/Spigot-Server-Patches/Improve-the-Saddle-API-for-Horses.patch index 6cc44be4fa..09e1fdb7e5 100644 --- a/Spigot-Server-Patches/Improve-the-Saddle-API-for-Horses.patch +++ b/Spigot-Server-Patches/Improve-the-Saddle-API-for-Horses.patch @@ -10,7 +10,7 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java -@@ -0,0 +0,0 @@ import net.minecraft.server.EntityHorseAbstract; +@@ -0,0 +0,0 @@ import net.minecraft.server.GenericAttributes; import org.apache.commons.lang.Validate; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.inventory.CraftInventoryAbstractHorse; diff --git a/Spigot-Server-Patches/Item-canEntityPickup.patch b/Spigot-Server-Patches/Item-canEntityPickup.patch index 05e3cbe5ed..9df7a8230c 100644 --- a/Spigot-Server-Patches/Item-canEntityPickup.patch +++ b/Spigot-Server-Patches/Item-canEntityPickup.patch @@ -11,13 +11,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class EntityInsentient extends EntityLiving { EntityItem entityitem = (EntityItem) iterator.next(); - if (!entityitem.dead && !entityitem.getItemStack().isEmpty() && !entityitem.p()) { + if (!entityitem.dead && !entityitem.getItemStack().isEmpty() && !entityitem.p() && this.i(entityitem.getItemStack())) { + // Paper Start + if (!entityitem.canMobPickup) { + continue; + } + // Paper End - this.a(entityitem); + this.b(entityitem); } } diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java diff --git a/Spigot-Server-Patches/LivingEntity-setKiller.patch b/Spigot-Server-Patches/LivingEntity-setKiller.patch index c0dbee1b02..4edf41b263 100644 --- a/Spigot-Server-Patches/LivingEntity-setKiller.patch +++ b/Spigot-Server-Patches/LivingEntity-setKiller.patch @@ -10,13 +10,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { public float aL; - public float aM; + @Nullable public EntityHuman killer; - protected int lastDamageByPlayerTime; + public int lastDamageByPlayerTime; // Paper - protected -> public protected boolean killed; protected int ticksFarFromPlayer; - protected float aR; + protected float aQ; 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 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java diff --git a/Spigot-Server-Patches/Ocelot-despawns-should-honor-nametags-and-leash.patch b/Spigot-Server-Patches/Ocelot-despawns-should-honor-nametags-and-leash.patch index b083060b69..a1ab905d58 100644 --- a/Spigot-Server-Patches/Ocelot-despawns-should-honor-nametags-and-leash.patch +++ b/Spigot-Server-Patches/Ocelot-despawns-should-honor-nametags-and-leash.patch @@ -16,4 +16,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return !this.isTrusting() && !this.hasCustomName() && !this.isLeashed() /*&& this.ticksLived > 2400*/; // CraftBukkit // Paper - honor name and leash } - @Override + public static AttributeProvider.Builder eL() { diff --git a/Spigot-Server-Patches/PlayerAdvancementCriterionGrantEvent.patch b/Spigot-Server-Patches/PlayerAdvancementCriterionGrantEvent.patch index cdaae1d3c1..42595d86d6 100644 --- a/Spigot-Server-Patches/PlayerAdvancementCriterionGrantEvent.patch +++ b/Spigot-Server-Patches/PlayerAdvancementCriterionGrantEvent.patch @@ -19,5 +19,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end this.d(advancement); - this.i.add(advancement); + this.j.add(advancement); flag = true; diff --git a/Spigot-Server-Patches/PlayerNaturallySpawnCreaturesEvent.patch b/Spigot-Server-Patches/PlayerNaturallySpawnCreaturesEvent.patch index 7b3e8ec2db..c726713c3b 100644 --- a/Spigot-Server-Patches/PlayerNaturallySpawnCreaturesEvent.patch +++ b/Spigot-Server-Patches/PlayerNaturallySpawnCreaturesEvent.patch @@ -13,20 +13,20 @@ 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 @@ public class ChunkProviderServer extends IChunkProvider { - - this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings this.world.getMethodProfiler().exit(); + //List list = Lists.newArrayList(this.playerChunkMap.f()); // Paper + //Collections.shuffle(list); // Paper + //Paper start - call player naturally spawn event + int chunkRange = world.spigotConfig.mobSpawnRange; + chunkRange = (chunkRange > world.spigotConfig.viewDistance) ? (byte) world.spigotConfig.viewDistance : chunkRange; + chunkRange = Math.min(chunkRange, 8); -+ for (EntityPlayer entityPlayer : this.world.players) { ++ for (EntityPlayer entityPlayer : this.world.getPlayers()) { + entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange); + entityPlayer.playerNaturallySpawnedEvent.callEvent(); + }; + // Paper end - this.playerChunkMap.f().forEach((playerchunk) -> { - Optional optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); + this.playerChunkMap.f().forEach((playerchunk) -> { // Paper - no... just no... + Optional optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/PlayerPickupExperienceEvent.patch b/Spigot-Server-Patches/PlayerPickupExperienceEvent.patch index 608747378c..a98c235140 100644 --- a/Spigot-Server-Patches/PlayerPickupExperienceEvent.patch +++ b/Spigot-Server-Patches/PlayerPickupExperienceEvent.patch @@ -13,8 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void pickup(EntityHuman entityhuman) { if (!this.world.isClientSide) { -- if (this.d == 0 && entityhuman.bC == 0) { -+ if (this.d == 0 && entityhuman.bC == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((EntityPlayer) entityhuman).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - entityhuman.bC = 2; +- if (this.d == 0 && entityhuman.bB == 0) { ++ if (this.d == 0 && entityhuman.bB == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((EntityPlayer) entityhuman).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper + entityhuman.bB = 2; entityhuman.receive(this, 1); - Entry entry = EnchantmentManager.b(Enchantments.MENDING, (EntityLiving) entityhuman); + Entry entry = EnchantmentManager.a(Enchantments.MENDING, (EntityLiving) entityhuman, ItemStack::f); diff --git a/Spigot-Server-Patches/PreCreatureSpawnEvent.patch b/Spigot-Server-Patches/PreCreatureSpawnEvent.patch index dd5fe1dd41..54f268c6aa 100644 --- a/Spigot-Server-Patches/PreCreatureSpawnEvent.patch +++ b/Spigot-Server-Patches/PreCreatureSpawnEvent.patch @@ -21,9 +21,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class MobSpawnerAbstract { double d5 = j >= 3 ? nbttaglist.h(2) : (double) blockposition.getZ() + (world.random.nextDouble() - world.random.nextDouble()) * (double) this.spawnRange + 0.5D; - if (world.a(((EntityTypes) optional.get()).a(d3, d4, d5)) && EntityPositionTypes.a((EntityTypes) optional.get(), world.getMinecraftWorld(), EnumMobSpawn.SPAWNER, new BlockPosition(d3, d4, d5), world.getRandom())) { + if (world.b(((EntityTypes) optional.get()).a(d3, d4, d5)) && EntityPositionTypes.a((EntityTypes) optional.get(), world.getMinecraftWorld(), EnumMobSpawn.SPAWNER, new BlockPosition(d3, d4, d5), world.getRandom())) { + // Paper start -+ EntityTypes entityType = optional.get(); ++ EntityTypes entityType = optional.get(); + String key = EntityTypes.getName(entityType).getKey(); + + org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(key); @@ -51,37 +51,42 @@ 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 { - BiomeBase.BiomeMeta biomebase_biomemeta = null; - GroupDataEntity groupdataentity = null; - int l1 = MathHelper.f(Math.random() * 4.0D); -- int i2 = 0; -+ int i2 = 0; // Paper - force diff on name change - int j2 = 0; + j1 = biomebase_biomemeta.d + worldserver.random.nextInt(1 + biomebase_biomemeta.e - biomebase_biomemeta.d); + } - while (true) { +- if (a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2) && spawnercreature_c.test(biomebase_biomemeta.c, blockposition_mutableblockposition, ichunkaccess)) { ++ // Paper start ++ Boolean doSpawning = a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2); ++ if (doSpawning == null) { ++ return; ++ } ++ if (doSpawning.booleanValue() && spawnercreature_c.test(biomebase_biomemeta.c, blockposition_mutableblockposition, ichunkaccess)) { // Paper end + EntityInsentient entityinsentient = a(worldserver, biomebase_biomemeta.c); + + if (entityinsentient == null) { @@ -0,0 +0,0 @@ public final class SpawnerCreature { - if (a(entitypositiontypes_surface, (IWorldReader) worldserver, (BlockPosition) blockposition_mutableblockposition, entitytypes) && EntityPositionTypes.a(entitytypes, worldserver, EnumMobSpawn.NATURAL, blockposition_mutableblockposition, worldserver.random) && worldserver.a(entitytypes.a((double) f, (double) k, (double) f1))) { - EntityInsentient entityinsentient; + } + } -+ // Paper start -+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event; -+ EntityTypes cls = biomebase_biomemeta.b; -+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityTypes.getName(cls).getKey()); -+ if (type != null) { -+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( -+ MCUtil.toLocation(worldserver, blockposition_mutableblockposition), -+ type, SpawnReason.NATURAL -+ ); -+ if (!event.callEvent()) { -+ if (event.shouldAbortSpawn()) { -+ return; -+ } -+ ++i2; -+ continue; -+ } -+ } -+ // Paper end -+ - try { - Entity entity = entitytypes.a((World) worldserver); +- private static boolean a(WorldServer worldserver, EnumCreatureType enumcreaturetype, StructureManager structuremanager, ChunkGenerator chunkgenerator, BiomeBase.BiomeMeta biomebase_biomemeta, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) { ++ private static Boolean a(WorldServer worldserver, EnumCreatureType enumcreaturetype, StructureManager structuremanager, ChunkGenerator chunkgenerator, BiomeBase.BiomeMeta biomebase_biomemeta, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) { // Paper + EntityTypes entitytypes = biomebase_biomemeta.c; ++ // Paper start ++ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event; ++ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityTypes.getName(entitytypes).getKey()); ++ if (type != null) { ++ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( ++ MCUtil.toLocation(worldserver, blockposition_mutableblockposition), ++ type, SpawnReason.NATURAL ++ ); ++ if (!event.callEvent()) { ++ if (event.shouldAbortSpawn()) { ++ return null; ++ } ++ return false; // TODO is this handled correctly? ++ } ++ } ++ // Paper end + if (entitytypes.e() == EnumCreatureType.MISC) { + return false; diff --git a/Spigot-Server-Patches/Prevent-Frosted-Ice-from-loading-holding-chunks.patch b/Spigot-Server-Patches/Prevent-Frosted-Ice-from-loading-holding-chunks.patch index 28c75edfd3..b065e63281 100644 --- a/Spigot-Server-Patches/Prevent-Frosted-Ice-from-loading-holding-chunks.patch +++ b/Spigot-Server-Patches/Prevent-Frosted-Ice-from-loading-holding-chunks.patch @@ -9,22 +9,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/BlockIceFrost.java +++ b/src/main/java/net/minecraft/server/BlockIceFrost.java @@ -0,0 +0,0 @@ public class BlockIceFrost extends BlockIce { - EnumDirection enumdirection = aenumdirection[j]; + EnumDirection enumdirection = aenumdirection[j]; - blockposition_pooledblockposition.g(blockposition).c(enumdirection); -- IBlockData iblockdata1 = worldserver.getType(blockposition_pooledblockposition); -- -+ IBlockData iblockdata1 = worldserver.getTypeIfLoaded(blockposition_pooledblockposition); // Paper - don't load chunks -+ if (iblockdata1 == null) continue; // Paper - if (iblockdata1.getBlock() == this && !this.e(iblockdata1, (World) worldserver, blockposition_pooledblockposition)) { - worldserver.getBlockTickList().a(blockposition_pooledblockposition, this, MathHelper.nextInt(random, worldserver.paperConfig.frostedIceDelayMin, worldserver.paperConfig.frostedIceDelayMax)); // Paper - use configurable min/max delay - } + blockposition_mutableblockposition.a((BaseBlockPosition) blockposition, enumdirection); +- IBlockData iblockdata1 = worldserver.getType(blockposition_mutableblockposition); ++ IBlockData iblockdata1 = worldserver.getTypeIfLoaded(blockposition_mutableblockposition); // Paper ++ if (iblockdata1 == null) { continue; } // Paper + + if (iblockdata1.a((Block) this) && !this.e(iblockdata1, (World) worldserver, blockposition_mutableblockposition)) { + worldserver.getBlockTickList().a(blockposition_mutableblockposition, this, MathHelper.nextInt(random, worldserver.paperConfig.frostedIceDelayMin, worldserver.paperConfig.frostedIceDelayMax)); // Paper - use configurable min/max delay @@ -0,0 +0,0 @@ public class BlockIceFrost extends BlockIce { - EnumDirection enumdirection = aenumdirection[l]; + EnumDirection enumdirection = aenumdirection[l]; - blockposition_pooledblockposition.g(blockposition).c(enumdirection); -- if (iblockaccess.getType(blockposition_pooledblockposition).getBlock() == this) { -+ if (((World) iblockaccess).getBlockIfLoaded(blockposition_pooledblockposition) == this) { // Paper - don't load chunks - ++j; - if (j >= i) { - boolean flag = false; + blockposition_mutableblockposition.a((BaseBlockPosition) blockposition, enumdirection); +- if (iblockaccess.getType(blockposition_mutableblockposition).a((Block) this)) { ++ // Paper start ++ IBlockData type = iblockaccess.getTypeIfLoaded(blockposition_mutableblockposition); ++ if (type != null && type.a((Block) this)) { // Paper end + ++j; + if (j >= i) { + return false; diff --git a/Spigot-Server-Patches/Prevent-logins-from-being-processed-when-the-player-.patch b/Spigot-Server-Patches/Prevent-logins-from-being-processed-when-the-player-.patch index 66d4779626..f020fa950d 100644 --- a/Spigot-Server-Patches/Prevent-logins-from-being-processed-when-the-player-.patch +++ b/Spigot-Server-Patches/Prevent-logins-from-being-processed-when-the-player-.patch @@ -20,5 +20,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end } else if (this.g == LoginListener.EnumProtocolState.DELAY_ACCEPT) { - EntityPlayer entityplayer = this.server.getPlayerList().a(this.i.getId()); + EntityPlayer entityplayer = this.server.getPlayerList().getPlayer(this.i.getId()); diff --git a/Spigot-Server-Patches/Profile-Lookup-Events.patch b/Spigot-Server-Patches/Profile-Lookup-Events.patch index b76c4776aa..d9b9aff6a5 100644 --- a/Spigot-Server-Patches/Profile-Lookup-Events.patch +++ b/Spigot-Server-Patches/Profile-Lookup-Events.patch @@ -17,18 +17,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import com.destroystokyo.paper.event.profile.PreLookupProfileEvent; +import com.google.common.collect.Sets; import com.mojang.authlib.Agent; + import com.mojang.authlib.Environment; +import com.mojang.authlib.GameProfile; import com.mojang.authlib.ProfileLookupCallback; import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository; +import java.util.Set; -+ public class PaperGameProfileRepository extends YggdrasilGameProfileRepository { -+ - public PaperGameProfileRepository(YggdrasilAuthenticationService authenticationService) { - super(authenticationService); - } + public PaperGameProfileRepository(YggdrasilAuthenticationService authenticationService, Environment environment) { + super(authenticationService, environment); +@@ -0,0 +0,0 @@ public class PaperGameProfileRepository extends YggdrasilGameProfileRepository { @Override public void findProfilesByNames(String[] names, Agent agent, ProfileLookupCallback callback) { diff --git a/Spigot-Server-Patches/ProfileWhitelistVerifyEvent.patch b/Spigot-Server-Patches/ProfileWhitelistVerifyEvent.patch index 508d586486..d9429a8cb8 100644 --- a/Spigot-Server-Patches/ProfileWhitelistVerifyEvent.patch +++ b/Spigot-Server-Patches/ProfileWhitelistVerifyEvent.patch @@ -9,12 +9,9 @@ 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 { - - // return chatmessage; if (!gameprofilebanentry.hasExpired()) event.disallow(PlayerLoginEvent.Result.KICK_BANNED, CraftChatMessage.fromComponent(chatmessage)); // Spigot -- } else if (!this.isWhitelisted(gameprofile)) { -+ } 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 + //event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot // Paper - moved to isWhitelisted } else if (getIPBans().isBanned(socketaddress) && !getIPBans().get(socketaddress).hasExpired()) { @@ -46,4 +43,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end public boolean isOp(GameProfile gameprofile) { - return this.operators.d(gameprofile) || this.server.a(gameprofile) && this.server.getWorldServer(DimensionManager.OVERWORLD).getWorldData().t() || this.u; + return this.operators.d(gameprofile) || this.server.a(gameprofile) && this.server.getSaveData().n() || this.v; diff --git a/Spigot-Server-Patches/Properly-handle-async-calls-to-restart-the-server.patch b/Spigot-Server-Patches/Properly-handle-async-calls-to-restart-the-server.patch index 76ba93d724..8e6af2a1c6 100644 --- a/Spigot-Server-Patches/Properly-handle-async-calls-to-restart-the-server.patch +++ b/Spigot-Server-Patches/Properly-handle-async-calls-to-restart-the-server.patch @@ -34,9 +34,9 @@ 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> worldServer; 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 private boolean isStopped; private int ticks; @@ -77,7 +77,7 @@ 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 { - entityplayer.playerInteractManager.b(generatoraccess.getWorldData().getGameType()); + entityplayer.playerInteractManager.b(worldserver.getMinecraftServer().getSaveData().getGameType()); } + // Paper start - Extract method to allow for restarting flag diff --git a/Spigot-Server-Patches/Send-attack-SoundEffects-only-to-players-who-can-see.patch b/Spigot-Server-Patches/Send-attack-SoundEffects-only-to-players-who-can-see.patch index 6b013310df..7f0ea1018d 100644 --- a/Spigot-Server-Patches/Send-attack-SoundEffects-only-to-players-who-can-see.patch +++ b/Spigot-Server-Patches/Send-attack-SoundEffects-only-to-players-who-can-see.patch @@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end + public void attack(Entity entity) { - if (entity.bA()) { + if (entity.bH()) { if (!entity.t(this)) { @@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving { int i = b0 + EnchantmentManager.b((EntityLiving) this); @@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_PLAYER_ATTACK_SWEEP, this.getSoundCategory(), 1.0F, 1.0F); + sendSoundEffect(this, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_PLAYER_ATTACK_SWEEP, this.getSoundCategory(), 1.0F, 1.0F); // Paper - send while respecting visibility - this.ea(); + this.ew(); } @@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving { diff --git a/Spigot-Server-Patches/Use-TerminalConsoleAppender-for-console-improvements.patch b/Spigot-Server-Patches/Use-TerminalConsoleAppender-for-console-improvements.patch index a42f1c07b0..92c15e858e 100644 --- a/Spigot-Server-Patches/Use-TerminalConsoleAppender-for-console-improvements.patch +++ b/Spigot-Server-Patches/Use-TerminalConsoleAppender-for-console-improvements.patch @@ -194,10 +194,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import org.apache.logging.log4j.Logger; // CraftBukkit start -import jline.console.ConsoleReader; -+import joptsimple.OptionSet; ++// Paper + import joptsimple.OptionSet; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.CraftServer; - import org.bukkit.craftbukkit.Main; @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant { -+ this.disconnect(new ChatMessage("disconnect.timeout")); + this.disconnect(new ChatMessage("disconnect.timeout")); + }); + // Paper end } diff --git a/Spigot-Server-Patches/revert-serverside-behavior-of-keepalives.patch b/Spigot-Server-Patches/revert-serverside-behavior-of-keepalives.patch index 7b6cc63ff7..ac4a543121 100644 --- a/Spigot-Server-Patches/revert-serverside-behavior-of-keepalives.patch +++ b/Spigot-Server-Patches/revert-serverside-behavior-of-keepalives.patch @@ -45,6 +45,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - - if (i - this.lastKeepAlive >= 25000L) { // CraftBukkit - if (this.awaitingKeepAlive) { +- this.disconnect(new ChatMessage("disconnect.timeout")); +- } else { +- this.awaitingKeepAlive = true; +- this.lastKeepAlive = i; +- this.h = i; +- this.sendPacket(new PacketPlayOutKeepAlive(this.h)); + // Paper Start - give clients a longer time to respond to pings as per pre 1.12.2 timings + // This should effectively place the keepalive handling back to "as it was" before 1.12.2 + long currentTime = SystemUtils.getMonotonicMillis(); @@ -53,12 +59,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (this.isPendingPing()) { + if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected + PlayerConnection.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getName()); // more info - this.disconnect(new ChatMessage("disconnect.timeout", new Object[0])); -- } else { -- this.awaitingKeepAlive = true; -- this.lastKeepAlive = i; -- this.h = i; -- this.sendPacket(new PacketPlayOutKeepAlive(this.h)); ++ this.disconnect(new ChatMessage("disconnect.timeout", new Object[0])); + } + } else { + if (elapsedTime >= 15000L) { // 15 seconds @@ -66,7 +67,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.setLastPing(currentTime); + this.setKeepAliveID(currentTime); + this.sendPacket(new PacketPlayOutKeepAlive(this.getKeepAliveID())); -+ } } + // Paper end diff --git a/Spigot-Server-Patches/use-CB-BlockState-implementations-for-captured-block.patch b/Spigot-Server-Patches/use-CB-BlockState-implementations-for-captured-block.patch index 75958afe19..8b4fb45e72 100644 --- a/Spigot-Server-Patches/use-CB-BlockState-implementations-for-captured-block.patch +++ b/Spigot-Server-Patches/use-CB-BlockState-implementations-for-captured-block.patch @@ -31,7 +31,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public List captureDrops; public long ticksPerAnimalSpawns; @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { + public boolean a(BlockPosition blockposition, IBlockData iblockdata, int i, int j) { // CraftBukkit start - tree generation if (this.captureTreeGeneration) { - CapturedBlockState blockstate = capturedBlockStates.get(blockposition); From e943ece469c5f231367417fb333c941014378f84 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Thu, 25 Jun 2020 16:09:55 +0200 Subject: [PATCH 09/91] even even even more work --- SHIT_TO_CHECK.md | 6 + ...ies-option-to-debug-dupe-uuid-issues.patch | 26 +- .../Add-LivingEntity-getTargetEntity.patch | 10 +- .../Add-More-Creeper-API.patch | 4 +- .../Add-PhantomPreSpawnEvent.patch | 2 +- .../Add-PlayerConnectionCloseEvent.patch | 2 +- Spigot-Server-Patches/Add-TNTPrimeEvent.patch | 20 +- .../Add-Velocity-IP-Forwarding-Support.patch | 4 +- ...to-disable-ender-dragon-legacy-check.patch | 20 +- .../Add-hand-to-bucket-events.patch | 101 +- .../Add-more-Witch-API.patch | 86 +- .../Add-more-Zombie-API.patch | 22 +- .../Add-sun-related-API.patch | 8 +- .../Allow-Saving-of-Oversized-Chunks.patch | 6 +- ...Allow-disabling-armour-stand-ticking.patch | 124 +- Spigot-Server-Patches/AnvilDamageEvent.patch | 33 +- .../Avoid-dimension-id-collisions.patch | 22 - ...e-if-stack-size-above-max-stack-size.patch | 2 +- .../Block-Enderpearl-Travel-Exploit.patch | 18 +- Spigot-Server-Patches/BlockDestroyEvent.patch | 8 +- Spigot-Server-Patches/Book-Size-Limits.patch | 4 +- ...oggleEvent-when-whitelist-is-toggled.patch | 2 +- ...arseException-in-Entity-and-TE-names.patch | 19 +- ...owned-for-Villager-Aggression-Config.patch | 19 - .../Chunk-debug-command.patch | 8 +- .../ChunkMapDistance-CME.patch | 2 +- ...le-Alternative-LootPool-Luck-Formula.patch | 18 +- .../Configurable-Bed-Search-Radius.patch | 9 +- ...le-Keep-Spawn-Loaded-range-per-world.patch | 15 +- ...ble-connection-throttle-kick-message.patch | 6 +- ...le-speed-for-water-flowing-over-lava.patch | 6 +- ...t-allow-digging-into-unloaded-chunks.patch | 42 +- ...ge-the-Entity-Random-seed-for-squids.patch | 2 +- ...ConvertSigns-boolean-every-sign-save.patch | 2 +- .../Duplicate-UUID-Resolve-Option.patch | 20 +- .../EnderDragon-Events.patch | 2 +- .../Enderman.teleportRandomly.patch | 8 +- .../EndermanAttackPlayerEvent.patch | 10 +- .../EndermanEscapeEvent.patch | 48 +- .../Entity-getEntitySpawnReason.patch | 4 +- ...ent-consumeArrow-and-getArrowItem-AP.patch | 12 +- .../EntityTransformedEvent.patch | 48 +- ...ld.spawnParticle-API-and-add-Builder.patch | 6 +- ...PI-for-Reason-Source-Triggering-play.patch | 2 +- ...e-attack-cooldown-methods-for-Player.patch | 18 +- ...onRetractEvent-for-all-empty-pistons.patch | 2 +- ...e-EntityShootBowEvent-for-Illusioner.patch | 2 +- .../Fire-event-on-GS4-query.patch | 217 ---- ...isPrimaryThread-and-MinecraftServer-.patch | 2 +- Spigot-Server-Patches/Fix-MC-124320.patch | 12 +- .../Fix-SpongeAbsortEvent-handling.patch | 4 +- ...ient-rendering-skulls-from-same-user.patch | 10 +- ...-allowed-colored-signs-to-be-created.patch | 2 +- ...h-entity-loss-due-to-unloaded-chunks.patch | 36 +- .../Fix-sign-edit-memory-leak.patch | 4 +- ...x-some-generation-concurrency-issues.patch | 223 ---- ...n-item-frames-are-modified-MC-123450.patch | 2 +- ...le-Oversized-Tile-Entities-in-chunks.patch | 4 +- Spigot-Server-Patches/Here-s-Johnny.patch | 38 - .../Hook-into-CB-plugin-rewrites.patch | 26 +- ...ead-Entities-in-entityList-iteration.patch | 23 +- .../Implement-CraftBlockSoundGroup.patch | 40 +- ...lement-EntityTeleportEndGatewayEvent.patch | 2 +- .../Implement-Expanded-ArmorStand-API.patch | 8 +- .../Implement-PlayerPostRespawnEvent.patch | 14 +- ...nt-furnace-cook-speed-multiplier-API.patch | 10 +- .../Improve-BlockPosition-inlining.patch | 204 +-- ...er-Thread-Pool-and-Thread-Priorities.patch | 21 +- .../Improve-death-events.patch | 48 +- .../InventoryCloseEvent-Reason-API.patch | 10 +- .../ItemStack-getMaxItemUseDuration.patch | 2 +- ...-world-storage-in-CraftOfflinePlayer.patch | 62 - ...mit-lightning-strike-effect-distance.patch | 83 -- ...ivingEntity-Hand-Raised-Item-Use-API.patch | 14 +- ...tityAreaEffectCloud-from-going-negat.patch | 2 +- ...6-Experience-should-save-as-Integers.patch | 4 +- ...0-Fix-Whitelist-On-Off-inconsistency.patch | 35 - ...ther-worlds-for-shooter-of-projectil.patch | 37 +- ...Make-player-data-saving-configurable.patch | 6 +- ...e-shield-blocking-delay-configurable.patch | 4 +- ...ault-permission-message-configurable.patch | 2 +- .../Mob-Pathfinding-API.patch | 10 +- ...e-Biome-Mob-Lookups-for-Mob-Spawning.patch | 26 +- ...ptimize-BlockPosition-helper-methods.patch | 2 +- .../Optimize-Captured-TileEntity-Lookup.patch | 2 +- .../Optimize-CraftBlockData-Creation.patch | 59 - ...-Manager-and-add-advanced-packet-sup.patch | 8 +- .../Optimize-RegistryMaterials.patch | 22 +- .../Optimize-Server-World-Map.patch | 62 +- .../Optimize-redstone-algorithm.patch | 1148 ----------------- ...t-armor-stands-from-doing-entity-loo.patch | 9 +- ...layer-View-Distance-API-placeholders.patch | 37 +- .../Player.setPlayerProfile-API.patch | 14 +- .../PlayerElytraBoostEvent.patch | 2 +- .../PlayerReadyArrowEvent.patch | 2 +- ...Prevent-Enderman-from-loading-chunks.patch | 4 +- ...ent-Mob-AI-Rules-from-Loading-Chunks.patch | 16 +- ...revent-Saving-Bad-entities-to-chunks.patch | 4 +- ...wning-from-loading-generating-chunks.patch | 34 +- ...ils-when-failing-to-save-player-data.patch | 4 +- ...nilla-entity-warnings-for-duplicates.patch | 2 +- .../Reset-players-airTicks-on-respawn.patch | 4 +- ...ets-from-world-player-list-not-serve.patch | 82 -- .../Server-Tick-Events.patch | 2 +- ...st-tick-at-start-of-drowning-process.patch | 6 +- .../SkeletonHorse-Additions.patch | 26 +- .../Slime-Pathfinder-Events.patch | 20 +- .../Support-Overriding-World-Seeds.patch | 99 -- Spigot-Server-Patches/Turtle-API.patch | 84 +- ...ed-flag-on-cancel-of-Explosion-Event.patch | 2 +- .../Use-ConcurrentHashMap-in-JsonList.patch | 63 +- ...oleAppender-for-console-improvements.patch | 6 +- .../Use-a-Queue-for-Queueing-Commands.patch | 4 +- ...ength-when-serialising-BungeeCord-te.patch | 4 +- .../Vanished-players-don-t-have-rights.patch | 71 +- .../Vex-getSummoner-API.patch | 4 +- .../WitchConsumePotionEvent.patch | 2 +- .../WitchReadyPotionEvent.patch | 6 +- .../WitchThrowPotionEvent.patch | 2 +- ...vehicle-tracking-issue-on-disconnect.patch | 4 +- ...-more-information-to-Entity.toString.patch | 4 +- ...entity-dismount-during-teleportation.patch | 12 +- .../incremental-chunk-saving.patch | 320 ----- work/Bukkit | 2 +- work/CraftBukkit | 2 +- 125 files changed, 857 insertions(+), 3512 deletions(-) create mode 100644 SHIT_TO_CHECK.md delete mode 100644 Spigot-Server-Patches/Avoid-dimension-id-collisions.patch delete mode 100644 Spigot-Server-Patches/Check-Drowned-for-Villager-Aggression-Config.patch delete mode 100644 Spigot-Server-Patches/Fire-event-on-GS4-query.patch delete mode 100644 Spigot-Server-Patches/Fix-some-generation-concurrency-issues.patch delete mode 100644 Spigot-Server-Patches/Here-s-Johnny.patch delete mode 100644 Spigot-Server-Patches/Lazy-init-world-storage-in-CraftOfflinePlayer.patch delete mode 100644 Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch delete mode 100644 Spigot-Server-Patches/Optimize-CraftBlockData-Creation.patch delete mode 100644 Spigot-Server-Patches/Optimize-redstone-algorithm.patch delete mode 100644 Spigot-Server-Patches/Send-nearby-packets-from-world-player-list-not-serve.patch delete mode 100644 Spigot-Server-Patches/Support-Overriding-World-Seeds.patch delete mode 100644 Spigot-Server-Patches/incremental-chunk-saving.patch 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 From ec7bd6a7c6ce2e2ed308f054ea4d2c7f7725df8e Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 25 Jun 2020 16:38:24 -0700 Subject: [PATCH 10/91] even even even even more work --- SHIT_TO_CHECK.md | 2 + .../Add-effect-to-block-break-naturally.patch | 2 +- ...to-allow-iron-golems-to-spawn-in-air.patch | 2 +- ...d-option-to-disable-pillager-patrols.patch | 4 +- ...n-to-nerf-pigmen-from-nether-portals.patch | 4 +- Spigot-Server-Patches/Anti-Xray.patch | 60 ++-- .../Asynchronous-chunk-IO-and-loading.patch | 320 ++++++++---------- .../Backport-fix-for-MC-167561.patch | 41 --- ...-more-tolerant-of-invalid-attributes.patch | 29 -- ...get-gravity-in-void.-Fixes-MC-167279.patch | 4 +- ...-chance-of-villager-zombie-infection.patch | 11 +- ...gurable-projectile-relative-velocity.patch | 27 +- ...if-we-have-a-custom-Bukkit-generator.patch | 52 ++- ...low-bees-to-load-chunks-for-beehives.patch | 10 +- ...Chunks-from-Hoppers-and-other-things.patch | 7 +- ...re-Entity-is-never-double-registered.patch | 18 +- .../Entity-Activation-Range-2.0.patch | 89 +++-- Spigot-Server-Patches/Entity-Jump-API.patch | 8 +- ...or-when-player-hand-set-to-empty-typ.patch | 20 +- .../Fix-World-isChunkGenerated-calls.patch | 29 +- ...ator-behavior-for-EntityPhanton-goal.patch | 19 -- ...x-items-vanishing-through-end-portal.patch | 8 +- ...k-in-stack-not-having-effects-when-d.patch | 8 +- .../Fix-spawn-radius-being-treated-as-0.patch | 19 -- ...ering-entities-from-unloading-chunks.patch | 2 +- .../Generator-Settings.patch | 82 +++-- ...rializing-mismatching-chunk-coordina.patch | 8 +- ...lement-alternative-item-despawn-rate.patch | 2 +- .../Lag-compensate-eating.patch | 36 +- .../Make-the-GUI-graph-fancier.patch | 8 +- ...-being-ticked-when-notifying-navigat.patch | 4 +- ...al-Spawned-mobs-towards-natural-spaw.patch | 22 +- ...timise-IEntityAccess-getPlayerByUUID.patch | 10 +- ...imise-TickListServer-by-rewriting-it.patch | 76 ++--- .../Optimise-random-block-ticking.patch | 181 +++------- Spigot-Server-Patches/Optimize-Hoppers.patch | 32 +- ...mize-call-to-getFluid-for-explosions.patch | 4 +- ...spawn-settings-and-per-player-option.patch | 5 +- ...layerDeathEvent-shouldDropExperience.patch | 4 +- .../PlayerLaunchProjectileEvent.patch | 58 ++-- ...-PlayerChunkMap-adds-crashing-server.patch | 8 +- ...oading-chunks-checking-hive-position.patch | 2 +- ...revent-consuming-the-wrong-itemstack.patch | 8 +- ...nk-loads-when-villagers-try-to-find-.patch | 16 +- Spigot-Server-Patches/Reduce-sync-loads.patch | 10 +- .../Seed-based-feature-search.patch | 110 ------ ...PaletteBlock-instead-of-ReentrantLoc.patch | 2 +- ...Status-cache-when-saving-protochunks.patch | 25 -- ...etChunkIfLoadedImmediately-in-places.patch | 37 +- ...ement-optional-per-player-mob-spawns.patch | 304 +++++++++-------- .../incremental-chunk-saving.patch | 319 +++++++++++++++++ scripts/importmcdev.sh | 2 +- 52 files changed, 1064 insertions(+), 1106 deletions(-) delete mode 100644 Spigot-Server-Patches/Backport-fix-for-MC-167561.patch delete mode 100644 Spigot-Server-Patches/Be-more-tolerant-of-invalid-attributes.patch delete mode 100644 Spigot-Server-Patches/Fix-comparator-behavior-for-EntityPhanton-goal.patch delete mode 100644 Spigot-Server-Patches/Fix-spawn-radius-being-treated-as-0.patch delete mode 100644 Spigot-Server-Patches/Seed-based-feature-search.patch delete mode 100644 Spigot-Server-Patches/Use-ChunkStatus-cache-when-saving-protochunks.patch create mode 100644 Spigot-Server-Patches/incremental-chunk-saving.patch diff --git a/SHIT_TO_CHECK.md b/SHIT_TO_CHECK.md index 6077d66cd2..024d8cc9af 100644 --- a/SHIT_TO_CHECK.md +++ b/SHIT_TO_CHECK.md @@ -4,3 +4,5 @@ * 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 +* Make sure the flat bedrock setting doesn't do anything stupid +* Check DataBits foreach \ No newline at end of file diff --git a/Spigot-Server-Patches/Add-effect-to-block-break-naturally.patch b/Spigot-Server-Patches/Add-effect-to-block-break-naturally.patch index cf767a46d0..7fbb466ce8 100644 --- a/Spigot-Server-Patches/Add-effect-to-block-break-naturally.patch +++ b/Spigot-Server-Patches/Add-effect-to-block-break-naturally.patch @@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 net.minecraft.server.Block block = iblockdata.getBlock(); @@ -0,0 +0,0 @@ public class CraftBlock implements Block { // Modelled off EntityHuman#hasBlock - if (block != Blocks.AIR && (item == null || iblockdata.getMaterial().isAlwaysDestroyable() || nmsItem.canDestroySpecialBlock(iblockdata))) { + if (block != Blocks.AIR && (item == null || !iblockdata.isAlwaysDestroyable() || nmsItem.canDestroySpecialBlock(iblockdata))) { net.minecraft.server.Block.dropItems(iblockdata, world.getMinecraftWorld(), position, world.getTileEntity(position), null, nmsItem); + if (triggerEffect) world.triggerEffect(org.bukkit.Effect.STEP_SOUND.getId(), position, net.minecraft.server.Block.getCombinedId(block.getBlockData())); // Paper result = true; diff --git a/Spigot-Server-Patches/Add-option-to-allow-iron-golems-to-spawn-in-air.patch b/Spigot-Server-Patches/Add-option-to-allow-iron-golems-to-spawn-in-air.patch index 053bce4c02..c03f830711 100644 --- a/Spigot-Server-Patches/Add-option-to-allow-iron-golems-to-spawn-in-air.patch +++ b/Spigot-Server-Patches/Add-option-to-allow-iron-golems-to-spawn-in-air.patch @@ -24,7 +24,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityIronGolem.java b/src/main/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityIronGolem.java +++ b/src/main/java/net/minecraft/server/EntityIronGolem.java -@@ -0,0 +0,0 @@ public class EntityIronGolem extends EntityGolem { +@@ -0,0 +0,0 @@ public class EntityIronGolem extends EntityGolem implements IEntityAngerable { BlockPosition blockposition1 = blockposition.down(); IBlockData iblockdata = iworldreader.getType(blockposition1); diff --git a/Spigot-Server-Patches/Add-option-to-disable-pillager-patrols.patch b/Spigot-Server-Patches/Add-option-to-disable-pillager-patrols.patch index f4a942a6aa..221bf805c6 100644 --- a/Spigot-Server-Patches/Add-option-to-disable-pillager-patrols.patch +++ b/Spigot-Server-Patches/Add-option-to-disable-pillager-patrols.patch @@ -22,9 +22,9 @@ diff --git a/src/main/java/net/minecraft/server/MobSpawnerPatrol.java b/src/main index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/MobSpawnerPatrol.java +++ b/src/main/java/net/minecraft/server/MobSpawnerPatrol.java -@@ -0,0 +0,0 @@ public class MobSpawnerPatrol { - public MobSpawnerPatrol() {} +@@ -0,0 +0,0 @@ public class MobSpawnerPatrol implements MobSpawner { + @Override public int a(WorldServer worldserver, boolean flag, boolean flag1) { + if (worldserver.paperConfig.disablePillagerPatrols) return 0; // Paper if (!flag) { diff --git a/Spigot-Server-Patches/Add-option-to-nerf-pigmen-from-nether-portals.patch b/Spigot-Server-Patches/Add-option-to-nerf-pigmen-from-nether-portals.patch index e3b65d58fe..f41a39e283 100644 --- a/Spigot-Server-Patches/Add-option-to-nerf-pigmen-from-nether-portals.patch +++ b/Spigot-Server-Patches/Add-option-to-nerf-pigmen-from-nether-portals.patch @@ -23,14 +23,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/BlockPortal.java +++ b/src/main/java/net/minecraft/server/BlockPortal.java @@ -0,0 +0,0 @@ public class BlockPortal extends Block { - Entity entity = EntityTypes.ZOMBIE_PIGMAN.spawnCreature(worldserver, (NBTTagCompound) null, (IChatBaseComponent) null, (EntityHuman) null, blockposition.up(), EnumMobSpawn.STRUCTURE, false, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NETHER_PORTAL); if (entity != null) { + entity.portalCooldown = entity.getDefaultPortalCooldown(); + entity.fromNetherPortal = true; // Paper + if (worldserver.paperConfig.nerfNetherPortalPigmen) ((EntityInsentient) entity).aware = false; // Paper - entity.portalCooldown = entity.ba(); } } + } 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 diff --git a/Spigot-Server-Patches/Anti-Xray.patch b/Spigot-Server-Patches/Anti-Xray.patch index 319edc40a0..73bde20765 100644 --- a/Spigot-Server-Patches/Anti-Xray.patch +++ b/Spigot-Server-Patches/Anti-Xray.patch @@ -1039,6 +1039,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ package net.minecraft.server; + import java.util.function.Predicate; +import com.destroystokyo.paper.antixray.ChunkPacketInfo; // Paper - Anti-Xray - Add chunk packet info import javax.annotation.Nullable; @@ -1065,8 +1066,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.nonEmptyBlockCount = short0; this.tickingBlockCount = short1; this.e = short2; -- this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData()); -+ this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData(), world == null ? null : world.chunkPacketBlockController.getPredefinedBlockData(world, chunk, this, initializeBlocks), initializeBlocks); // Paper - Anti-Xray - Add predefined block data +- this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData()); ++ this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData(), world == null ? null : world.chunkPacketBlockController.getPredefinedBlockData(world, chunk, this, initializeBlocks), initializeBlocks); // Paper - Anti-Xray - Add predefined block data } public final IBlockData getType(int i, int j, int k) { // Paper @@ -1092,10 +1093,10 @@ diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/DataPaletteBlock.java +++ b/src/main/java/net/minecraft/server/DataPaletteBlock.java -@@ -0,0 +0,0 @@ package net.minecraft.server; - import it.unimi.dsi.fastutil.ints.Int2IntMap; +@@ -0,0 +0,0 @@ + package net.minecraft.server; + import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; - import it.unimi.dsi.fastutil.ints.Int2IntMap.Entry; +import com.destroystokyo.paper.antixray.ChunkPacketInfo; // Paper - Anti-Xray - Add chunk packet info import java.util.Arrays; import java.util.Objects; @@ -1195,9 +1196,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public synchronized void a(NBTTagList nbttaglist, long[] along) { // Paper - synchronize this.a(); -- int i = Math.max(4, MathHelper.d(nbttaglist.size())); +- int i = Math.max(4, MathHelper.e(nbttaglist.size())); + // Paper - Anti-Xray - TODO: Should this.predefinedObjects.length just be added here (faster) or should the contents be compared to calculate the size (less RAM)? -+ int i = Math.max(4, MathHelper.d(nbttaglist.size() + (this.predefinedObjects == null ? 0 : this.predefinedObjects.length))); // Paper - Anti-Xray - Calculate the size with predefined objects ++ int i = Math.max(4, MathHelper.e(nbttaglist.size() + (this.predefinedObjects == null ? 0 : this.predefinedObjects.length))); // Paper - Anti-Xray - Calculate the size with predefined objects - if (i != this.i) { + if (true || i != this.i) { // Paper - Anti-Xray - Not initialized yet @@ -1221,13 +1222,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; @@ -0,0 +0,0 @@ public class PacketPlayOutMapChunk implements Packet { - private byte[] f; private byte[] getData() { return this.f; } // Paper - OBFHELPER - private List g; private boolean h; -+ private volatile boolean ready; // Paper - Async-Anti-Xray - Ready flag for the network manager + private boolean i; - public PacketPlayOutMapChunk() {} + // Paper start - Async-Anti-Xray - Set the ready flag to true ++ private volatile boolean ready; // Paper - Async-Anti-Xray - Ready flag for the network manager + public PacketPlayOutMapChunk() { + this.ready = true; + } @@ -1238,7 +1238,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class PacketPlayOutMapChunk implements Packet { } // Paper end - public PacketPlayOutMapChunk(Chunk chunk, int i) { + public PacketPlayOutMapChunk(Chunk chunk, int i, boolean flag) { + ChunkPacketInfo chunkPacketInfo = chunk.world.chunkPacketBlockController.getChunkPacketInfo(this, chunk, i); // Paper - Anti-Xray - Add chunk packet info ChunkCoordIntPair chunkcoordintpair = chunk.getPos(); @@ -1247,12 +1247,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } this.f = new byte[this.a(chunk, i)]; -- this.c = this.a(new PacketDataSerializer(this.j()), chunk, i); +- this.c = this.a(new PacketDataSerializer(this.k()), chunk, i); + // Paper start - Anti-Xray - Add chunk packet info + if (chunkPacketInfo != null) { + chunkPacketInfo.setData(this.getData()); + } -+ this.c = this.writeChunk(new PacketDataSerializer(this.j()), chunk, i, chunkPacketInfo); ++ this.c = this.writeChunk(new PacketDataSerializer(this.k()), chunk, i, chunkPacketInfo); + // Paper end this.g = Lists.newArrayList(); iterator = chunk.getTileEntities().entrySet().iterator(); @@ -1306,9 +1306,9 @@ 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 { - PlayerChunkMap.LOGGER.error("Couldn't load chunk {}", chunkcoordintpair, exception); } + this.g(chunkcoordintpair); - return Either.left(new ProtoChunk(chunkcoordintpair, ChunkConverter.a)); + return Either.left(new ProtoChunk(chunkcoordintpair, ChunkConverter.a, this.world)); // Paper - Anti-Xray - Add parameter }, this.executor); @@ -1403,17 +1403,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public final co.aikar.timings.WorldTimingsHandler timings; // Paper public static BlockPosition lastPhysicsProblem; // Spigot @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - return ((ChunkProviderServer) this.chunkProvider).getChunkAt(x, z, false); + return (CraftServer) Bukkit.getServer(); } -- protected World(WorldData worlddata, DimensionManager dimensionmanager, BiFunction bifunction, GameProfilerFiller gameprofilerfiller, boolean flag, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { -+ protected World(WorldData worlddata, DimensionManager dimensionmanager, java.util.concurrent.Executor executor, BiFunction bifunction, GameProfilerFiller gameprofilerfiller, boolean flag, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { // Paper - executor - this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot - this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(worlddata.getName(), this.spigotConfig); // Paper +- protected World(WorldDataMutable worlddatamutable, ResourceKey resourcekey, ResourceKey resourcekey1, DimensionManager dimensionmanager, Supplier supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { ++ protected World(WorldDataMutable worlddatamutable, ResourceKey resourcekey, ResourceKey resourcekey1, DimensionManager dimensionmanager, Supplier supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env, java.util.concurrent.Executor executor) { + this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot + this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig((((WorldDataServer)worlddatamutable).getName()), this.spigotConfig); // Paper + this.chunkPacketBlockController = this.paperConfig.antiXray ? new ChunkPacketBlockControllerAntiXray(this.paperConfig, executor) : ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray this.generator = gen; - if (dimensionmanager.world == null) dimensionmanager.world = (WorldServer) this; // Paper this.world = new CraftWorld((WorldServer) this, gen, env); + this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { // CraftBukkit end @@ -1426,15 +1426,15 @@ 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 { - - // 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) { -- super(worlddata, dimensionmanager, (world, worldprovider) -> { -+ super(worlddata, dimensionmanager, executor, (world, worldprovider) -> { // Paper - pass executor down - // CraftBukkit start - ChunkGenerator chunkGenerator; +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { + // Add env and gen to constructor, WorldData -> WorldDataServer + public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey resourcekey, ResourceKey resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { +- super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env); ++ super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor + this.pvpMode = minecraftserver.getPVP(); + convertable = convertable_conversionsession; + uuid = WorldUUID.getUUID(convertable_conversionsession.folder.toFile()); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -1452,8 +1452,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 NBTTagCompound data = new NBTTagCompound(); cs[i].getBlocks().a(data, "Palette", "BlockStates"); -- DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData()); // TODO: snapshot whole ChunkSection -+ DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData(), null, false); // TODO: snapshot whole ChunkSection // Paper - Anti-Xray - Add no predefined block data and don't initialize because it's done in the line below internally +- DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData()); // TODO: snapshot whole ChunkSection ++ DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData(), null, false); // TODO: snapshot whole ChunkSection // Paper - Anti-Xray - Add no predefined block data and don't initialize because it's done in the line below internally blockids.a(data.getList("Palette", CraftMagicNumbers.NBT.TAG_COMPOUND), data.getLongArray("BlockStates")); sectionBlockIDs[i] = blockids; diff --git a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch index da0da43621..a1099c9e45 100644 --- a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch @@ -2534,7 +2534,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public static InProgressChunkHolder loadChunk(WorldServer worldserver, DefinedStructureManager definedstructuremanager, VillagePlace villageplace, ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound, boolean distinguish) { + ArrayDeque tasksToExecuteOnMain = new ArrayDeque<>(); + // Paper end - ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator(); + ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator(); WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager(); NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level"); @@ -0,0 +0,0 @@ public class ChunkRegionLoader { @@ -2560,25 +2560,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (flag) { if (nbttagcompound2.hasKeyOfType("BlockLight", 7)) { -- lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("BlockLight"))); +- lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("BlockLight")), true); + // Paper start - delay this task since we're executing off-main + NibbleArray blockLight = new NibbleArray(nbttagcompound2.getByteArray("BlockLight")); -+ // Note: We move the block light nibble array creation here for perf & in case the compound is modified + tasksToExecuteOnMain.add(() -> { -+ lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), blockLight); ++ lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), blockLight, true); + }); -+ // Paper end ++ // Paper end - delay this task since we're executing off-main } if (flag2 && nbttagcompound2.hasKeyOfType("SkyLight", 7)) { -- lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("SkyLight"))); +- lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("SkyLight")), true); + // Paper start - delay this task since we're executing off-main + NibbleArray skyLight = new NibbleArray(nbttagcompound2.getByteArray("SkyLight")); -+ // Note: We move the block light nibble array creation here for perf & in case the compound is modified + tasksToExecuteOnMain.add(() -> { -+ lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), skyLight); ++ lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), skyLight, true); + }); -+ // Paper end ++ // Paper end - delay this task since we're executing off-main } } } @@ -2597,9 +2595,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - return protochunk1; + return new InProgressChunkHolder(protochunk1, tasksToExecuteOnMain); // Paper - Async chunk loading - } - } - ++ } ++ } ++ + // Paper start - async chunk save for unload + public static final class AsyncSaveData { + public final NibbleArray[] blockLight; // null or size of 17 (for indices -1 through 15) @@ -2617,9 +2615,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.blockTickList = blockTickList; + this.fluidTickList = fluidTickList; + this.worldTime = worldTime; -+ } -+ } -+ + } + } + + // must be called sync + public static AsyncSaveData getAsyncSaveData(WorldServer world, IChunkAccess chunk) { + org.spigotmc.AsyncCatcher.catchOp("preparation of chunk data for async save"); @@ -2731,8 +2729,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (ticklist instanceof ProtoChunkTickList) { nbttagcompound1.set("ToBeTicked", ((ProtoChunkTickList) ticklist).b()); } else if (ticklist instanceof TickListChunk) { -- nbttagcompound1.set("TileTicks", ((TickListChunk) ticklist).a(worldserver.getTime())); -+ nbttagcompound1.set("TileTicks", ((TickListChunk) ticklist).a(asyncsavedata != null ? asyncsavedata.worldTime : worldserver.getTime())); // Paper - async chunk unloading + nbttagcompound1.set("TileTicks", ((TickListChunk) ticklist).b()); + // Paper start - async chunk save for unload + } else if (asyncsavedata != null) { + nbttagcompound1.set("TileTicks", asyncsavedata.blockTickList); @@ -2748,15 +2745,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (ticklist1 instanceof ProtoChunkTickList) { nbttagcompound1.set("LiquidsToBeTicked", ((ProtoChunkTickList) ticklist1).b()); } else if (ticklist1 instanceof TickListChunk) { -- nbttagcompound1.set("LiquidTicks", ((TickListChunk) ticklist1).a(worldserver.getTime())); -+ nbttagcompound1.set("LiquidTicks", ((TickListChunk) ticklist1).a(asyncsavedata != null ? asyncsavedata.worldTime : worldserver.getTime())); // Paper - async chunk unloading + nbttagcompound1.set("LiquidTicks", ((TickListChunk) ticklist1).b()); + // Paper start - async chunk save for unload + } else if (asyncsavedata != null) { + nbttagcompound1.set("LiquidTicks", asyncsavedata.fluidTickList); + // Paper end } else { - nbttagcompound1.set("LiquidTicks", worldserver.getFluidTickList().a(chunkcoordintpair)); -+ nbttagcompound1.set("LiquidTicks", worldserver.getFluidTickList().a(chunkcoordintpair)); // Paper - diff on method change (see getAsyncSaveData) ++ nbttagcompound1.set("LiquidTicks", worldserver.getFluidTickList().a(chunkcoordintpair)); // Paper - diff on method change (see getAsyncSaveData) } nbttagcompound1.set("PostProcessing", a(ichunkaccess.l())); @@ -2824,23 +2820,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import java.util.function.Supplier; import javax.annotation.Nullable; --public class IChunkLoader implements AutoCloseable { -+public class IChunkLoader extends RegionFileCache implements AutoCloseable { + public class IChunkLoader implements AutoCloseable { - private final IOWorker a; public IOWorker getIOWorker() { return a; } // Paper - OBFHELPER -+// private final IOWorker a; public IOWorker getIOWorker() { return a; } // Paper - OBFHELPER - nuke IOWorker ++ // Paper - OBFHELPER - nuke IOWorker protected final DataFixer b; @Nullable - private PersistentStructureLegacy c; + private volatile PersistentStructureLegacy c; // Paper - async chunk loading + + private final Object persistentDataLock = new Object(); // Paper ++ protected final RegionFileCache regionFileCache; - public IChunkLoader(File file, DataFixer datafixer) { -+ super(file); + public IChunkLoader(File file, DataFixer datafixer, boolean flag) { ++ this.regionFileCache = new RegionFileCache(file, flag); // Paper - nuke IOWorker this.b = datafixer; -- this.a = new IOWorker(new RegionFileCache(file), "chunk"); -+// this.a = new IOWorker(new RegionFileCache(file), "chunk"); // Paper - nuke IOWorker +- this.a = new IOWorker(file, flag, "chunk"); ++ // Paper - nuke IOWorker } // CraftBukkit start @@ -2881,7 +2877,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) { + synchronized (this.persistentDataLock) { // Paper - Async chunk loading if (this.c == null) { - this.c = PersistentStructureLegacy.a(dimensionmanager.getType(), (WorldPersistentData) supplier.get()); // CraftBukkit - getType + this.c = PersistentStructureLegacy.a(resourcekey, (WorldPersistentData) supplier.get()); } nbttagcompound = this.c.a(nbttagcompound); @@ -2890,49 +2886,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } @@ -0,0 +0,0 @@ public class IChunkLoader implements AutoCloseable { - return nbttagcompound.hasKeyOfType("DataVersion", 99) ? nbttagcompound.getInt("DataVersion") : -1; + + @Nullable + public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException { +- return this.a.a(chunkcoordintpair); ++ return this.regionFileCache.read(chunkcoordintpair); } -- @Nullable -- public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException { -- return this.a.a(chunkcoordintpair); -- } -- - public void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) { - this.a.a(chunkcoordintpair, nbttagcompound); -+// Paper start - nuke IOWorker -+// @Nullable -+// public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException { -+// return this.a.a(chunkcoordintpair); -+// } -+// + public void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { write(chunkcoordintpair, nbttagcompound); } // Paper OBFHELPER + public void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { // Paper - OBFHELPER - (Switched around for safety) -+ super.write(chunkcoordintpair, nbttagcompound); ++ this.regionFileCache.write(chunkcoordintpair, nbttagcompound); if (this.c != null) { -- this.c.a(chunkcoordintpair.pair()); + synchronized (this.persistentDataLock) { // Paper - Async chunk loading -+ this.c.a(chunkcoordintpair.pair()); } // Paper - Async chunk loading} + this.c.a(chunkcoordintpair.pair()); ++ } // Paper - Async chunk loading} } - - } +- +- } - - public void i() { - this.a.a().join(); -- } -- -- public void close() throws IOException { + } + + public void close() throws IOException { - this.a.close(); -- } -+// -+// public void i() { -+// this.a.a().join(); -+// } -+// -+// public void close() throws IOException { -+// this.a.close(); -+// } -+// Paper end ++ this.regionFileCache.close(); + } } diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -2948,6 +2929,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return 33 + ChunkStatus.getTicketLevelOffset(status); + } } +diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/Main.java ++++ b/src/main/java/net/minecraft/server/Main.java +@@ -0,0 +0,0 @@ public class Main { + + convertable_conversionsession.a((IRegistryCustom) iregistrycustom_dimension, (SaveData) object); + */ ++ Class.forName("net.minecraft.server.VillagerTrades");// Paper - load this sync so it won't fail later async + final DedicatedServer dedicatedserver = (DedicatedServer) MinecraftServer.a((thread) -> { + DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, datapackconfiguration1, thread, iregistrycustom_dimension, convertable_conversionsession, resourcepackrepository, datapackresources, null, dedicatedserversettings, DataConverterRegistry.a(), minecraftsessionservice, gameprofilerepository, usercache, WorldLoadListenerLogger::new); + 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 @@ -2956,18 +2949,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.getUserCache().c(false); // Paper } // Spigot end +- + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.close(true, true); // Paper } public String getServerIp() { -@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant executor; - public final ChunkGenerator chunkGenerator; + public final ChunkGenerator chunkGenerator; - private final Supplier l; + private final Supplier l; public final Supplier getWorldPersistentDataSupplier() { return this.l; } // Paper - OBFHELPER private final VillagePlace m; @@ -3083,11 +3069,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private final PlayerMap playerMap; public final Int2ObjectMap trackedEntities; @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getWorldProvider().f(), threadedmailbox1, this.p.a(threadedmailbox1, false)); + this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getDimensionManager().hasSkyLight(), threadedmailbox1, this.p.a(threadedmailbox1, false)); this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler); this.l = supplier; -- this.m = new VillagePlace(new File(this.w, "poi"), datafixer); -+ this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper +- this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag); ++ this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper this.setViewDistance(i); } @@ -3240,15 +3226,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.lightEngine.queueUpdate(); this.worldLoadListener.a(ichunkaccess.getPos(), (ChunkStatus) null); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } } -+ // Paper start - Async chunk io -+ public NBTTagCompound completeChunkData(NBTTagCompound compound, ChunkCoordIntPair chunkcoordintpair) throws IOException { -+ return compound == null ? null : this.getChunkData(this.world.getWorldProvider().getDimensionManager(), this.getWorldPersistentDataSupplier(), compound, chunkcoordintpair, this.world); -+ } -+ // Paper end -+ private CompletableFuture> f(ChunkCoordIntPair chunkcoordintpair) { - return CompletableFuture.supplyAsync(() -> { + // Paper start - Async chunk io @@ -3259,38 +3238,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - try (Timing ignored2 = this.world.timings.chunkIO.startTimingIfSync()) { // Paper start - timings - nbttagcompound = this.readChunkData(chunkcoordintpair); - } // Paper end -- ++ // Paper start ++ if (ioThrowable != null) { ++ com.destroystokyo.paper.util.SneakyThrow.sneaky(ioThrowable); ++ } ++ // Paper end + - if (nbttagcompound != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings - boolean flag = nbttagcompound.hasKeyOfType("Level", 10) && nbttagcompound.getCompound("Level").hasKeyOfType("Status", 8); -+ if (ioThrowable != null) { -+ com.destroystokyo.paper.io.IOUtil.rethrow(ioThrowable); -+ } ++ if (chunkHolder.protoChunk != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings // Paper - chunk is created async - if (flag) { - ProtoChunk protochunk = ChunkRegionLoader.loadChunk(this.world, this.definedStructureManager, this.m, chunkcoordintpair, nbttagcompound); -+ this.getVillagePlace().loadInData(chunkcoordintpair, chunkHolder.poiData); -+ chunkHolder.tasks.forEach(Runnable::run); -+ // Paper - async load completes this -+ // Paper end - -- protochunk.setLastSaved(this.world.getTime()); -- return Either.left(protochunk); -- } -- -- PlayerChunkMap.LOGGER.error("Chunk file at {} is missing level data, skipping", chunkcoordintpair); -- }} // Paper -+ // Paper start - This is done async -+ if (chunkHolder.protoChunk != null) { -+ chunkHolder.protoChunk.setLastSaved(this.world.getTime()); -+ return Either.left(chunkHolder.protoChunk); -+ } -+ // Paper end - } catch (ReportedException reportedexception) { - Throwable throwable = reportedexception.getCause(); ++ if (true) { ++ ProtoChunk protochunk = chunkHolder.protoChunk; + protochunk.setLastSaved(this.world.getTime()); + this.a(chunkcoordintpair, protochunk.getChunkStatus().getType()); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } + this.g(chunkcoordintpair); return Either.left(new ProtoChunk(chunkcoordintpair, ChunkConverter.a, this.world)); // Paper - Anti-Xray - Add parameter - }, this.executor); + // Paper start - Async chunk io @@ -3321,7 +3288,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end } - private CompletableFuture> b(PlayerChunk playerchunk, ChunkStatus chunkstatus) { + private void g(ChunkCoordIntPair chunkcoordintpair) { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } @@ -3330,43 +3297,37 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.m.a(ichunkaccess.getPos()); if (!ichunkaccess.isNeedsSaving()) { return false; - } else { -- try { -- this.world.checkSession(); -- } catch (ExceptionWorldConflict exceptionworldconflict) { -- PlayerChunkMap.LOGGER.error("Couldn't save chunk; already in use by another instance of Minecraft?", exceptionworldconflict); -- com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exceptionworldconflict); // Paper -- return false; -- } -+ // Paper - The save session check is performed on the IO thread - - ichunkaccess.setLastSaved(this.world.getTime()); - ichunkaccess.setNeedsSaving(false); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - NBTTagCompound nbttagcompound; + ChunkStatus chunkstatus = ichunkaccess.getChunkStatus(); if (chunkstatus.getType() != ChunkStatus.Type.LEVELCHUNK) { + try (co.aikar.timings.Timing ignored1 = this.world.timings.chunkSaveOverwriteCheck.startTiming()) { // Paper - // Paper start - Optimize save by using status cache - ChunkStatus statusOnDisk = this.getChunkStatusOnDisk(chunkcoordintpair); - if (statusOnDisk != null && statusOnDisk.getType() == ChunkStatus.Type.LEVELCHUNK) { -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + if (this.h(chunkcoordintpair)) { + return false; } +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + if (chunkstatus == ChunkStatus.EMPTY && ichunkaccess.h().values().stream().noneMatch(StructureStart::e)) { + return false; + } ++ } // Paper } -+ } // Paper this.world.getMethodProfiler().c("chunkSave"); +- NBTTagCompound nbttagcompound = ChunkRegionLoader.saveChunk(this.world, ichunkaccess); ++ NBTTagCompound nbttagcompound; + try (co.aikar.timings.Timing ignored1 = this.world.timings.chunkSaveDataSerialization.startTiming()) { // Paper - nbttagcompound = ChunkRegionLoader.saveChunk(this.world, ichunkaccess); -- this.a(chunkcoordintpair, nbttagcompound); ++ nbttagcompound = ChunkRegionLoader.saveChunk(this.world, ichunkaccess); + } // Paper ++ + +- this.a(chunkcoordintpair, nbttagcompound); + // Paper start - async chunk io + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, chunkcoordintpair.x, chunkcoordintpair.z, + null, nbttagcompound, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY); + // Paper end - async chunk io + this.a(chunkcoordintpair, chunkstatus.getType()); return true; } catch (Exception exception) { - PlayerChunkMap.LOGGER.error("Failed to save chunk {},{}", chunkcoordintpair.x, chunkcoordintpair.z, exception); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { return false; } @@ -3374,7 +3335,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } // Paper } - protected void setViewDistance(int i) { + private boolean h(ChunkCoordIntPair chunkcoordintpair) { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } } @@ -3417,14 +3378,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public ChunkStatus getChunkStatusOnDiskIfCached(ChunkCoordIntPair chunkPos) { - RegionFile regionFile = this.getIOWorker().getRegionFileCache().getRegionFileIfLoaded(chunkPos); + synchronized (this) { // Paper -+ RegionFile regionFile = this.getRegionFileIfLoaded(chunkPos); ++ RegionFile regionFile = this.regionFileCache.getRegionFileIfLoaded(chunkPos); return regionFile == null ? null : regionFile.getStatusIfCached(chunkPos.x, chunkPos.z); + } // Paper } public ChunkStatus getChunkStatusOnDisk(ChunkCoordIntPair chunkPos) throws IOException { -- RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, false); +- RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, true); + // Paper start - async chunk save for unload + IChunkAccess unloadingChunk = this.world.asyncChunkTaskManager.getChunkInSaveProgress(chunkPos.x, chunkPos.z); + if (unloadingChunk != null) { @@ -3435,20 +3396,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + NBTTagCompound inProgressWrite = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE + .getPendingWrite(this.world, chunkPos.x, chunkPos.z, false); -- if (!regionFile.chunkExists(chunkPos)) { +- if (regionFile == null || !regionFile.chunkExists(chunkPos)) { - return null; + if (inProgressWrite != null) { + return ChunkRegionLoader.getStatus(inProgressWrite); } + // Paper end + synchronized (this) { // Paper - async io -+ RegionFile regionFile = this.getFile(chunkPos, false); -+ -+ if (!regionFile.chunkExists(chunkPos)) { -+ return null; -+ } ++ RegionFile regionFile = this.regionFileCache.getFile(chunkPos, true); - ChunkStatus status = regionFile.getStatusIfCached(chunkPos.x, chunkPos.z); ++ if (regionFile == null || !regionFile.chunkExists(chunkPos)) { ++ return null; ++ } ++ + ChunkStatus status = regionFile.getStatusIfCached(chunkPos.x, chunkPos.z); - if (status != null) { @@ -3470,7 +3431,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void updateChunkStatusOnDisk(ChunkCoordIntPair chunkPos, @Nullable NBTTagCompound compound) throws IOException { - RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, false); + synchronized (this) { -+ RegionFile regionFile = this.getFile(chunkPos, false); ++ RegionFile regionFile = this.regionFileCache.getFile(chunkPos, false); - regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkRegionLoader.getStatus(compound)); + regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkRegionLoader.getStatus(compound)); @@ -3506,7 +3467,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + synchronized (world.getChunkProvider().playerChunkMap) { + net.minecraft.server.RegionFile file; + try { -+ file = world.getChunkProvider().playerChunkMap.getFile(chunkPos, false); ++ file = world.getChunkProvider().playerChunkMap.regionFileCache.getFile(chunkPos, false); + } catch (IOException ex) { + throw new RuntimeException(ex); + } @@ -3577,9 +3538,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end this.closed = true; // Paper try { - this.c(); + this.d(); @@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable { - } + this.dataFile.close(); } } + } finally { // Paper start - Prevent regionfiles from being closed during use @@ -3633,7 +3594,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } else { if (this.cache.size() >= com.destroystokyo.paper.PaperConfig.regionFileCacheSize) { // Paper - configurable @@ -0,0 +0,0 @@ public final class RegionFileCache implements AutoCloseable { - RegionFile regionfile1 = new RegionFile(file, this.b); + RegionFile regionfile1 = new RegionFile(file, this.b, this.c); this.cache.putAndMoveToFirst(i, regionfile1); + // Paper start @@ -3686,9 +3647,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - public void close() throws IOException { + public synchronized void close() throws IOException { // Paper -> synchronized + ExceptionSuppressor exceptionsuppressor = new ExceptionSuppressor<>(); ObjectIterator objectiterator = this.cache.values().iterator(); - while (objectiterator.hasNext()) { @@ -0,0 +0,0 @@ public final class RegionFileCache implements AutoCloseable { } @@ -3710,39 +3671,38 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; --public class RegionFileSection implements AutoCloseable { -+public class RegionFileSection extends RegionFileCache implements AutoCloseable { // Paper - nuke IOWorker +-public class RegionFileSection implements AutoCloseable { ++public class RegionFileSection extends RegionFileCache implements AutoCloseable { // Paper - nuke IOWorker private static final Logger LOGGER = LogManager.getLogger(); - private final IOWorker b; -+// private final IOWorker b; ++ // Paper - nuke IOWorker private final Long2ObjectMap> c = new Long2ObjectOpenHashMap(); - private final LongLinkedOpenHashSet d = new LongLinkedOpenHashSet(); + protected final LongLinkedOpenHashSet d = new LongLinkedOpenHashSet(); // Paper - private -> protected - private final BiFunction, R> e; + private final Function> e; private final Function f; private final DataFixer g; private final DataFixTypes h; - public RegionFileSection(File file, BiFunction, R> bifunction, Function function, DataFixer datafixer, DataFixTypes datafixtypes) { -+ super(file); // Paper - nuke IOWorker - this.e = bifunction; - this.f = function; + public RegionFileSection(File file, Function> function, Function function1, DataFixer datafixer, DataFixTypes datafixtypes, boolean flag) { ++ super(file, flag); // Paper - nuke IOWorker + this.e = function; + this.f = function1; this.g = datafixer; this.h = datafixtypes; -- this.b = new IOWorker(new RegionFileCache(file), file.getName()); -+// this.b = new IOWorker(new RegionFileCache(file), file.getName()); // Paper - nuke IOWorker +- this.b = new IOWorker(file, flag, file.getName()); ++ //this.b = new IOWorker(file, flag, file.getName()); // Paper - nuke IOWorker } protected void a(BooleanSupplier booleansupplier) { -- while (!this.d.isEmpty() && booleansupplier.getAsBoolean()) { -- ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).u(); -+ while (!this.d.isEmpty() && booleansupplier.getAsBoolean()) { // Paper - conflict here to avoid obfhelpers -+ ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).u(); // Paper - conflict here to avoid obfhelpers + while (!this.d.isEmpty() && booleansupplier.getAsBoolean()) { +- ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).r(); ++ ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).r(); // Paper - conflict here to avoid obfhelpers this.d(chunkcoordintpair); } -@@ -0,0 +0,0 @@ public class RegionFileSection implements AutoC +@@ -0,0 +0,0 @@ public class RegionFileSection implements AutoCloseable { } private void b(ChunkCoordIntPair chunkcoordintpair) { @@ -3763,7 +3723,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } catch (IOException ioexception) { RegionFileSection.LOGGER.error("Error reading chunk {} data from disk", chunkcoordintpair, ioexception); return null; -@@ -0,0 +0,0 @@ public class RegionFileSection implements AutoC +@@ -0,0 +0,0 @@ public class RegionFileSection implements AutoCloseable { } private void d(ChunkCoordIntPair chunkcoordintpair) { @@ -3797,19 +3757,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private Dynamic a(ChunkCoordIntPair chunkcoordintpair, DynamicOps dynamicops) { Map map = Maps.newHashMap(); -@@ -0,0 +0,0 @@ public class RegionFileSection implements AutoC +@@ -0,0 +0,0 @@ public class RegionFileSection implements AutoCloseable { public void a(ChunkCoordIntPair chunkcoordintpair) { if (!this.d.isEmpty()) { for (int i = 0; i < 16; ++i) { -- long j = SectionPosition.a(chunkcoordintpair, i).v(); -+ long j = SectionPosition.a(chunkcoordintpair, i).v(); // Paper - conflict here to avoid obfhelpers +- long j = SectionPosition.a(chunkcoordintpair, i).s(); ++ long j = SectionPosition.a(chunkcoordintpair, i).s(); // Paper - conflict here to avoid obfhelpers - if (this.d.contains(j)) { + if (this.d.contains(j)) { // Paper - conflict here to avoid obfhelpers this.d(chunkcoordintpair); return; } -@@ -0,0 +0,0 @@ public class RegionFileSection implements AutoC +@@ -0,0 +0,0 @@ public class RegionFileSection implements AutoCloseable { } @@ -3827,7 +3787,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // This is checking if the data exists, then it builds it later in getDataInternal(ChunkCoordIntPair) + if (!this.d.isEmpty()) { + for (int i = 0; i < 16; ++i) { -+ long j = SectionPosition.a(chunkcoordintpair, i).v(); ++ long j = SectionPosition.a(chunkcoordintpair, i).s(); + + if (this.d.contains(j)) { + return this.getDataInternal(chunkcoordintpair); @@ -3860,14 +3820,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private final WorldServer world; // Paper + - public VillagePlace(File file, DataFixer datafixer) { -+ // Paper start -+ this(file, datafixer, null); + public VillagePlace(File file, DataFixer datafixer, boolean flag) { ++ // Paper start - add world parameter ++ this(file, datafixer, flag, null); + } -+ public VillagePlace(File file, DataFixer datafixer, WorldServer world) { -+ // Paper end - super(file, VillagePlaceSection::new, VillagePlaceSection::new, datafixer, DataFixTypes.POI_CHUNK); -+ this.world = world; // Paper ++ public VillagePlace(File file, DataFixer datafixer, boolean flag, WorldServer world) { + super(file, VillagePlaceSection::a, VillagePlaceSection::new, datafixer, DataFixTypes.POI_CHUNK, flag); ++ this.world = world; ++ // Paper end - add world parameter } public void a(BlockPosition blockposition, VillagePlaceType villageplacetype) { @@ -3882,7 +3842,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } else { + //super.a(booleansupplier); // re-implement below + while (!((RegionFileSection)this).d.isEmpty() && booleansupplier.getAsBoolean()) { -+ ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(((RegionFileSection)this).d.firstLong()).u(); ++ ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(((RegionFileSection)this).d.firstLong()).r(); + + NBTTagCompound data; + try (co.aikar.timings.Timing ignored1 = this.world.timings.poiSaveDataSerialization.startTiming()) { @@ -3936,8 +3896,8 @@ 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 { - return new Throwable(entity + " Added to world at " + new java.util.Date()); +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { + return this.chunkProvider.getChunkAt(x, z, false); } + // Paper start - Asynchronous IO @@ -3993,7 +3953,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + RegionFile file; + + try { -+ file = WorldServer.this.getChunkProvider().playerChunkMap.getFile(new ChunkCoordIntPair(chunkX, chunkZ), false); ++ file = WorldServer.this.getChunkProvider().playerChunkMap.regionFileCache.getFile(new ChunkCoordIntPair(chunkX, chunkZ), false); + } catch (java.io.IOException ex) { + throw new RuntimeException(ex); + } @@ -4005,7 +3965,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override + public T computeForRegionFileIfLoaded(int chunkX, int chunkZ, java.util.function.Function function) { + synchronized (WorldServer.this.getChunkProvider().playerChunkMap) { -+ RegionFile file = WorldServer.this.getChunkProvider().playerChunkMap.getRegionFileIfLoaded(new ChunkCoordIntPair(chunkX, chunkZ)); ++ RegionFile file = WorldServer.this.getChunkProvider().playerChunkMap.regionFileCache.getRegionFileIfLoaded(new ChunkCoordIntPair(chunkX, chunkZ)); + return function.apply(file); + } + } @@ -4013,19 +3973,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager; + // Paper end + - // 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) { - super(worlddata, dimensionmanager, executor, (world, worldprovider) -> { // Paper - pass executor down -@@ -0,0 +0,0 @@ public class WorldServer extends World { - - this.mobSpawnerTrader = this.worldProvider.getDimensionManager().getType() == DimensionManager.OVERWORLD ? new MobSpawnerTrader(this) : null; // CraftBukkit - getType() + // Add env and gen to constructor, WorldData -> WorldDataServer + public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey resourcekey, ResourceKey resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { + super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { + this.dragonBattle = null; + } this.getServer().addWorld(this.getWorld()); // CraftBukkit + + this.asyncChunkTaskManager = new com.destroystokyo.paper.io.chunk.ChunkTaskManager(this); // Paper } // CraftBukkit start -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { } MCUtil.getSpiralOutChunks(spawn, radiusInBlocks >> 4).forEach(pair -> { @@ -4082,8 +4042,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // fall through to load // we do this so we do not re-read the chunk data on disk @@ -0,0 +0,0 @@ public class CraftWorld implements World { - - return new CraftDragonBattle(worldProvider.o()); // PAIL rename getDragonBattle + public DragonBattle getEnderDragonBattle() { + return (getHandle().getDragonBattle() == null) ? null : new CraftDragonBattle(getHandle().getDragonBattle()); } + // Paper start + @Override diff --git a/Spigot-Server-Patches/Backport-fix-for-MC-167561.patch b/Spigot-Server-Patches/Backport-fix-for-MC-167561.patch deleted file mode 100644 index ead80ed47a..0000000000 --- a/Spigot-Server-Patches/Backport-fix-for-MC-167561.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Shane Freeder -Date: Fri, 21 Feb 2020 18:44:28 +0000 -Subject: [PATCH] Backport fix for MC-167561 - - -diff --git a/src/main/java/net/minecraft/server/EntityWolf.java b/src/main/java/net/minecraft/server/EntityWolf.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/EntityWolf.java -+++ b/src/main/java/net/minecraft/server/EntityWolf.java -@@ -0,0 +0,0 @@ public class EntityWolf extends EntityTameableAnimal { - boolean flag = super.a(entityhuman, enumhand); - - if (!flag || this.isBaby()) { -- this.goalSit.setSitting(!this.isSitting()); -+ //this.goalSit.setSitting(!this.isSitting()); // Paper start - copied from below -+ if (this.i((EntityLiving) entityhuman) && !this.i(itemstack)) { -+ this.goalSit.setSitting(!this.isSitting()); -+ this.jumping = false; -+ this.navigation.o(); -+ this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason -+ } -+ // Paper end - copied from below - } - - return flag; -@@ -0,0 +0,0 @@ public class EntityWolf extends EntityTameableAnimal { - return true; - } - -+ /* Paper start - Move into above - if (this.i((EntityLiving) entityhuman) && !this.i(itemstack)) { - this.goalSit.setSitting(!this.isSitting()); - this.jumping = false; - this.navigation.o(); - this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason - } -+ */ // Paper end - } else if (item == Items.BONE && !this.isAngry()) { - if (!entityhuman.abilities.canInstantlyBuild) { - itemstack.subtract(1); diff --git a/Spigot-Server-Patches/Be-more-tolerant-of-invalid-attributes.patch b/Spigot-Server-Patches/Be-more-tolerant-of-invalid-attributes.patch deleted file mode 100644 index abd4ca0d76..0000000000 --- a/Spigot-Server-Patches/Be-more-tolerant-of-invalid-attributes.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zach Brown <1254957+zachbr@users.noreply.github.com> -Date: Thu, 6 Feb 2020 19:20:27 -0600 -Subject: [PATCH] Be more tolerant of invalid attributes - -Prior to this commit, the player would be disconnected if they ever encountered an attribute with a name that did -not match Bukkit's expected vanilla scheme. It appears that datapacks can set whatever attribute name they want, -ignoring vanilla's typical scheme. - -In a more perfect world the API would expose some way to interact with these attributes, however Bukkit is not -particularly flexible in this area. Perhaps this is an area for future expansion at a later time. - -diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java -+++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java -@@ -0,0 +0,0 @@ public class CraftAttributeMap implements Attributable { - public static Attribute fromMinecraft(String nms) { - String[] split = nms.split("\\.", 2); - -+ // Paper start - Datapacks can set their own attributes that may not match our expectations, ignore them -+ if (split.length != 2) { -+ return null; -+ } -+ // Paper end -+ - String generic = split[0]; - String descriptor = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, split[1]); // movementSpeed -> MOVEMENT_SPEED - String fin = generic + "_" + descriptor; diff --git a/Spigot-Server-Patches/Bees-get-gravity-in-void.-Fixes-MC-167279.patch b/Spigot-Server-Patches/Bees-get-gravity-in-void.-Fixes-MC-167279.patch index 20495b198f..8044f1f126 100644 --- a/Spigot-Server-Patches/Bees-get-gravity-in-void.-Fixes-MC-167279.patch +++ b/Spigot-Server-Patches/Bees-get-gravity-in-void.-Fixes-MC-167279.patch @@ -34,7 +34,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/n index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityBee.java +++ b/src/main/java/net/minecraft/server/EntityBee.java -@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements EntityBird { +@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB public EntityBee(EntityTypes entitytypes, World world) { super(entitytypes, world); @@ -51,5 +51,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + }; + // Paper end this.lookController = new EntityBee.j(this); + this.a(PathType.DANGER_FIRE, -1.0F); this.a(PathType.WATER, -1.0F); - this.a(PathType.COCOA, -1.0F); diff --git a/Spigot-Server-Patches/Configurable-chance-of-villager-zombie-infection.patch b/Spigot-Server-Patches/Configurable-chance-of-villager-zombie-infection.patch index 582937fb04..c816903f2b 100644 --- a/Spigot-Server-Patches/Configurable-chance-of-villager-zombie-infection.patch +++ b/Spigot-Server-Patches/Configurable-chance-of-villager-zombie-infection.patch @@ -27,18 +27,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/EntityZombie.java @@ -0,0 +0,0 @@ public class EntityZombie extends EntityMonster { @Override - public void b(EntityLiving entityliving) { - super.b(entityliving); + public void a_(EntityLiving entityliving) { + super.a_(entityliving); - if ((this.world.getDifficulty() == EnumDifficulty.NORMAL || this.world.getDifficulty() == EnumDifficulty.HARD) && entityliving instanceof EntityVillager) { - if (this.world.getDifficulty() != EnumDifficulty.HARD && this.random.nextBoolean()) { + // Paper start + if (world.paperConfig.zombieVillagerInfectionChance != 0.0 && (world.paperConfig.zombieVillagerInfectionChance != -1.0 || this.world.getDifficulty() == EnumDifficulty.NORMAL || this.world.getDifficulty() == EnumDifficulty.HARD) && entityliving instanceof EntityVillager) { + if (world.paperConfig.zombieVillagerInfectionChance == -1.0 && this.world.getDifficulty() != EnumDifficulty.HARD && this.random.nextBoolean()) { -+ return; -+ } -+ if (world.paperConfig.zombieVillagerInfectionChance != -1.0 && (this.random.nextDouble() * 100.0) > world.paperConfig.zombieVillagerInfectionChance) { return; -- } + } ++ if (world.paperConfig.zombieVillagerInfectionChance != -1.0 && (this.random.nextDouble() * 100.0) > world.paperConfig.zombieVillagerInfectionChance) { ++ return; + } // Paper end EntityVillager entityvillager = (EntityVillager) entityliving; diff --git a/Spigot-Server-Patches/Configurable-projectile-relative-velocity.patch b/Spigot-Server-Patches/Configurable-projectile-relative-velocity.patch index 6b7741d337..fdef2c3315 100644 --- a/Spigot-Server-Patches/Configurable-projectile-relative-velocity.patch +++ b/Spigot-Server-Patches/Configurable-projectile-relative-velocity.patch @@ -38,29 +38,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + disableRelativeProjectileVelocity = getBoolean("game-mechanics.disable-relative-projectile-velocity", false); + } } -diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.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/EntityArrow.java -+++ b/src/main/java/net/minecraft/server/EntityArrow.java -@@ -0,0 +0,0 @@ public abstract class EntityArrow extends Entity implements IProjectile { - float f7 = MathHelper.cos(f1 * 0.017453292F) * MathHelper.cos(f * 0.017453292F); - - this.shoot((double) f5, (double) f6, (double) f7, f3, f4); -- this.setMot(this.getMot().add(entity.getMot().x, entity.onGround ? 0.0D : entity.getMot().y, entity.getMot().z)); -+ if (!entity.world.paperConfig.disableRelativeProjectileVelocity) this.setMot(this.getMot().add(entity.getMot().x, entity.onGround ? 0.0D : entity.getMot().y, entity.getMot().z)); // Paper - allow disabling relative velocity - } - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityProjectile.java b/src/main/java/net/minecraft/server/EntityProjectile.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 { +--- 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 { this.shoot((double) f5, (double) f6, (double) f7, f3, f4); Vec3D vec3d = entity.getMot(); -- this.setMot(this.getMot().add(vec3d.x, entity.onGround ? 0.0D : vec3d.y, vec3d.z)); -+ if (!entity.world.paperConfig.disableRelativeProjectileVelocity) this.setMot(this.getMot().add(vec3d.x, entity.onGround ? 0.0D : vec3d.y, vec3d.z)); // Paper - allow disabling relative velocity +- this.setMot(this.getMot().add(vec3d.x, entity.isOnGround() ? 0.0D : vec3d.y, vec3d.z)); ++ if (!entity.world.paperConfig.disableRelativeProjectileVelocity) this.setMot(this.getMot().add(vec3d.x, entity.isOnGround() ? 0.0D : vec3d.y, vec3d.z)); // Paper - allow disabling relative velocity } - @Override + protected void a(MovingObjectPosition movingobjectposition) { diff --git a/Spigot-Server-Patches/Do-less-work-if-we-have-a-custom-Bukkit-generator.patch b/Spigot-Server-Patches/Do-less-work-if-we-have-a-custom-Bukkit-generator.patch index 1f4ea0475e..6fd63597f2 100644 --- a/Spigot-Server-Patches/Do-less-work-if-we-have-a-custom-Bukkit-generator.patch +++ b/Spigot-Server-Patches/Do-less-work-if-we-have-a-custom-Bukkit-generator.patch @@ -6,41 +6,35 @@ Subject: [PATCH] Do less work if we have a custom Bukkit generator If the Bukkit generator already has a spawn, use it immediately instead of spending time generating one that we won't use -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +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/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { - } else if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { - this.worldData.setSpawn(BlockPosition.ZERO.up()); +--- 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 list = worldchunkmanager.a(); -- Random random = new Random(this.getSeed()); -- BlockPosition blockposition = worldchunkmanager.a(0, this.getSeaLevel(), 0, 256, list, random); +- WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager(); +- List list = worldchunkmanager.b(); +- Random random = new Random(worldserver.getSeed()); +- BlockPosition blockposition = worldchunkmanager.a(0, worldserver.getSeaLevel(), 0, 256, list, random); - ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition); -- -+// Paper start - moved down -+// WorldChunkManager worldchunkmanager = this.getChunkProvider().getChunkGenerator().getWorldChunkManager(); -+// List list = worldchunkmanager.a(); -+// Random random = new Random(this.getSeed()); -+// BlockPosition blockposition = worldchunkmanager.a(0, this.getSeaLevel(), 0, 256, list, random); -+// ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition); -+// Paper end ++ // Paper start - moved down // CraftBukkit start - if (this.generator != null) { - Random rand = new Random(this.getSeed()); -@@ -0,0 +0,0 @@ public class WorldServer extends World { + if (worldserver.generator != null) { + Random rand = new Random(worldserver.getSeed()); +@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant list = worldchunkmanager.a(); -+ Random random = new Random(this.getSeed()); -+ BlockPosition blockposition = worldchunkmanager.a(0, this.getSeaLevel(), 0, 256, list, random); ++ // Paper start - if the generator created a spawn for us, then there is no need for us to also create a spawn - ++ // only do it if the generator did not ++ WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager(); ++ List list = worldchunkmanager.b(); ++ Random random = new Random(worldserver.getSeed()); ++ BlockPosition blockposition = worldchunkmanager.a(0, worldserver.getSeaLevel(), 0, 256, list, random); + ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition); + // Paper end + if (blockposition == null) { - WorldServer.LOGGER.warn("Unable to find spawn biome"); - } + MinecraftServer.LOGGER.warn("Unable to find spawn biome"); diff --git a/Spigot-Server-Patches/Do-not-allow-bees-to-load-chunks-for-beehives.patch b/Spigot-Server-Patches/Do-not-allow-bees-to-load-chunks-for-beehives.patch index 0073903ee7..521514d73d 100644 --- a/Spigot-Server-Patches/Do-not-allow-bees-to-load-chunks-for-beehives.patch +++ b/Spigot-Server-Patches/Do-not-allow-bees-to-load-chunks-for-beehives.patch @@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/n index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityBee.java +++ b/src/main/java/net/minecraft/server/EntityBee.java -@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements EntityBird { +@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB if (this.hivePos == null) { return false; } else { @@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 TileEntity tileentity = this.world.getTileEntity(this.hivePos); return tileentity instanceof TileEntityBeehive && ((TileEntityBeehive) tileentity).d(); -@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements EntityBird { +@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB } private boolean i(BlockPosition blockposition) { @@ -24,15 +24,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 TileEntity tileentity = this.world.getTileEntity(blockposition); return tileentity instanceof TileEntityBeehive ? !((TileEntityBeehive) tileentity).isFull() : false; -@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements EntityBird { +@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB @Override public boolean g() { - if (EntityBee.this.hasHivePos() && EntityBee.this.eI() && EntityBee.this.hivePos.a((IPosition) EntityBee.this.getPositionVector(), 2.0D)) { + if (EntityBee.this.hasHivePos() && EntityBee.this.fe() && EntityBee.this.hivePos.a((IPosition) EntityBee.this.getPositionVector(), 2.0D)) { + if (!EntityBee.this.world.isLoadedAndInBounds(EntityBee.this.hivePos)) return false; // Paper TileEntity tileentity = EntityBee.this.world.getTileEntity(EntityBee.this.hivePos); if (tileentity instanceof TileEntityBeehive) { -@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements EntityBird { +@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB @Override public void c() { diff --git a/Spigot-Server-Patches/Don-t-load-Chunks-from-Hoppers-and-other-things.patch b/Spigot-Server-Patches/Don-t-load-Chunks-from-Hoppers-and-other-things.patch index 9e65c17c06..f9461e3223 100644 --- a/Spigot-Server-Patches/Don-t-load-Chunks-from-Hoppers-and-other-things.patch +++ b/Spigot-Server-Patches/Don-t-load-Chunks-from-Hoppers-and-other-things.patch @@ -21,13 +21,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } else { BlockPosition blockposition1 = blockposition.shift((EnumDirection) function1.apply(iblockdata)); - IBlockData iblockdata1 = generatoraccess.getType(blockposition1); -- -+ // Paper start - don't load chunks if the other side of the chest is in unloaded chunk ++ // Paper start + IBlockData iblockdata1 = generatoraccess.getTypeIfLoaded(blockposition1); + if (iblockdata1 == null) { + return new DoubleBlockFinder.Result.Single<>(s0); + } + // Paper end - if (iblockdata1.getBlock() == iblockdata.getBlock()) { - DoubleBlockFinder.BlockType doubleblockfinder_blocktype1 = (DoubleBlockFinder.BlockType) function.apply(iblockdata1); + if (iblockdata1.a(iblockdata.getBlock())) { + DoubleBlockFinder.BlockType doubleblockfinder_blocktype1 = (DoubleBlockFinder.BlockType) function.apply(iblockdata1); diff --git a/Spigot-Server-Patches/Ensure-Entity-is-never-double-registered.patch b/Spigot-Server-Patches/Ensure-Entity-is-never-double-registered.patch index b524f88631..5247e488c2 100644 --- a/Spigot-Server-Patches/Ensure-Entity-is-never-double-registered.patch +++ b/Spigot-Server-Patches/Ensure-Entity-is-never-double-registered.patch @@ -26,15 +26,15 @@ 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 { + Entity entity2; - try (co.aikar.timings.Timing ignored = this.timings.newEntities.startTiming()) { // Paper - timings - while ((entity = (Entity) this.entitiesToAdd.poll()) != null) { -+ if (!entity.isQueuedForRegister) continue; // Paper - ignore cancelled registers - this.registerEntity(entity); + while ((entity2 = (Entity) this.entitiesToAdd.poll()) != null) { ++ if (!entity2.isQueuedForRegister) continue; // Paper - ignore cancelled registers + this.registerEntity(entity2); } - } // Paper - timings -@@ -0,0 +0,0 @@ public class WorldServer extends World { + +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { public void unregisterEntity(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot @@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Spigot start if ( entity instanceof EntityHuman ) { -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { private void registerEntity(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot @@ -76,4 +76,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + entity.isQueuedForRegister = false; // Paper this.entitiesById.put(entity.getId(), entity); if (entity instanceof EntityEnderDragon) { - EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon) entity).eo(); + EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon) entity).eK(); diff --git a/Spigot-Server-Patches/Entity-Activation-Range-2.0.patch b/Spigot-Server-Patches/Entity-Activation-Range-2.0.patch index f1dee1b612..b854d7156d 100644 --- a/Spigot-Server-Patches/Entity-Activation-Range-2.0.patch +++ b/Spigot-Server-Patches/Entity-Activation-Range-2.0.patch @@ -17,13 +17,13 @@ diff --git a/src/main/java/net/minecraft/server/BehaviorController.java b/src/ma 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 implements MinecraftSeri - }); +@@ -0,0 +0,0 @@ public class BehaviorController { + } + public boolean hasActivity(Activity activity) { return c(activity); } // Paper - OBFHELPER public boolean c(Activity activity) { - return this.g.contains(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 @@ -46,7 +46,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (vec3d.equals(Vec3D.a)) { return; @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - this.y = Vec3D.a; + this.x = Vec3D.a; this.setMot(Vec3D.a); } + // Paper start - ignore movement changes while inactive. @@ -58,13 +58,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end vec3d = this.a(vec3d, enummovetype); - Vec3D vec3d1 = this.e(vec3d); + Vec3D vec3d1 = this.f(vec3d); @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - return this.am; + return this.al; } -+ public boolean isPushedByWater() { return this.bM(); } // Paper - OBFHELPER - the below is not an obfhelper, don't use it! - public boolean bM() { ++ public boolean isPushedByWater() { return this.bU(); } // Paper - OBFHELPER - the below is not an obfhelper, don't use it! + public boolean bU() { // Paper start return this.pushedByWater(); diff --git a/src/main/java/net/minecraft/server/EntityCreature.java b/src/main/java/net/minecraft/server/EntityCreature.java @@ -88,10 +88,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public long lootTableSeed; @Nullable - private Entity leashHolder; -+ public Entity leashHolder; // Paper - private int bF; ++ public Entity leashHolder; // Paper - private -> public + private int bE; @Nullable - private NBTTagCompound bG; + private NBTTagCompound bF; @@ -0,0 +0,0 @@ public abstract class EntityInsentient extends EntityLiving { return this.lookController; } @@ -115,25 +115,25 @@ 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 { - protected float aV; - protected int aW; protected int getKillCount() { return this.aW; } // Paper - OBFHELPER + protected float aU; + protected int aV; protected int getKillCount() { return this.aV; } // Paper - OBFHELPER public float lastDamage; - protected boolean jumping; -+ public boolean jumping; // Paper ++ public boolean jumping; // Paper protected -> public + public float aY; public float aZ; public float ba; - public float bb; diff --git a/src/main/java/net/minecraft/server/EntityLlama.java b/src/main/java/net/minecraft/server/EntityLlama.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityLlama.java +++ b/src/main/java/net/minecraft/server/EntityLlama.java @@ -0,0 +0,0 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn - return this.bK != null; + return this.bJ != null; } -+ public boolean inCaravan() { return this.fd(); } // Paper - OBFHELPER - public boolean fd() { - return this.bJ != null; ++ public final boolean inCaravan() { return this.fD(); } // Paper - OBFHELPER + public boolean fD() { + return this.bI != null; } diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -148,14 +148,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start + if (this.getUnhappy() > 0) { + this.setUnhappy(this.getUnhappy() - 1); -+ } + } + if (this.doAITick()) { + if (world.spigotConfig.tickInactiveVillagers) { + this.mobTick(); + } else { + this.mobTick(true); + } - } ++ } + doReputationTick(); + // Paper end + @@ -163,30 +163,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // Spigot End -- @Override + @Override - protected void mobTick() { -+ @Override // Paper start - tick trades while inactive + protected void mobTick() { mobTick(false); } + protected void mobTick(boolean inactive) { -+ // Paper end - this.world.getMethodProfiler().enter("brain"); + this.world.getMethodProfiler().enter("villagerBrain"); - this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error +- this.world.getMethodProfiler().exit(); + if (!inactive) this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error // Paper - this.world.getMethodProfiler().exit(); - if (!this.et() && this.bB > 0) { - --this.bB; + if (this.bM) { + this.bM = false; + } @@ -0,0 +0,0 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - this.bD = null; + this.bC = null; } - if (!this.isNoAI() && this.random.nextInt(100) == 0) { + if (!inactive && !this.isNoAI() && this.random.nextInt(100) == 0) { // Paper - Raid raid = ((WorldServer) this.world).c_(new BlockPosition(this)); + Raid raid = ((WorldServer) this.world).c_(this.getChunkCoordinates()); if (raid != null && raid.v() && !raid.a()) { @@ -0,0 +0,0 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.et()) { - this.ey(); + if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.eO()) { + this.eT(); } + if (inactive) return; // Paper @@ -196,8 +195,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } -+ private void doReputationTick() { fa(); } // Paper - OBFHELPER - private void fa() { ++ private void doReputationTick() { fv(); } // Paper - OBFHELPER + private void fv() { long i = this.world.getTime(); diff --git a/src/main/java/net/minecraft/server/EntityVillagerAbstract.java b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java @@ -208,14 +207,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, (GroupDataEntity) groupdataentity, nbttagcompound); } -+ public final int getUnhappy() { return eq(); } // Paper - OBFHELPER - public int eq() { - return (Integer) this.datawatcher.get(EntityVillagerAbstract.bx); ++ public final int getUnhappy() { return eL(); } // Paper - OBFHELPER + public int eL() { + return (Integer) this.datawatcher.get(EntityVillagerAbstract.bw); } + public final void setUnhappy(int i) { s(i); } // Paper - OBFHELPER public void s(int i) { - this.datawatcher.set(EntityVillagerAbstract.bx, i); + this.datawatcher.set(EntityVillagerAbstract.bw, i); } diff --git a/src/main/java/net/minecraft/server/PathfinderGoal.java b/src/main/java/net/minecraft/server/PathfinderGoal.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -267,7 +266,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public PathfinderGoalGotoTarget(EntityCreature entitycreature, double d0, int i, int j) { this.e = BlockPosition.ZERO; @@ -0,0 +0,0 @@ public abstract class PathfinderGoalGotoTarget extends PathfinderGoal { - blockposition_mutableblockposition.g(blockposition).e(i1, k - 1, j1); + blockposition_mutableblockposition.a((BaseBlockPosition) blockposition, i1, k - 1, j1); if (this.a.a((BlockPosition) blockposition_mutableblockposition) && this.a(this.a.world, blockposition_mutableblockposition)) { this.e = blockposition_mutableblockposition; + setTarget(blockposition_mutableblockposition.immutableCopy()); // Paper @@ -283,15 +282,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 }; private final Map c = new EnumMap(PathfinderGoal.Type.class); - private final Set d = Sets.newLinkedHashSet(); -+ private final Set d = Sets.newLinkedHashSet();private Set getTasks() { return d; }// Paper - OBFHELPER - private final GameProfilerFiller e; ++ private final Set d = Sets.newLinkedHashSet(); private Set getTasks() { return d; }// Paper - OBFHELPER + private final Supplier e; private final EnumSet f = EnumSet.noneOf(PathfinderGoal.Type.class); - private int g = 3; + private int g = 3;private int getTickRate() { return g; } // Paper - OBFHELPER + private int curRate;private int getCurRate() { return curRate; } private void incRate() { this.curRate++; } // Paper TODO - public PathfinderGoalSelector(GameProfilerFiller gameprofilerfiller) { - this.e = gameprofilerfiller; + public PathfinderGoalSelector(Supplier supplier) { + this.e = supplier; @@ -0,0 +0,0 @@ public class PathfinderGoalSelector { this.d.add(new PathfinderGoalWrapped(i, pathfindergoal)); } @@ -593,8 +592,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } if ( !( entity instanceof EntityArrow ) ) { -- if ( !entity.onGround || !entity.passengers.isEmpty() || entity.isPassenger() ) -+ if ( (!entity.onGround && !(entity instanceof EntityFlying)) || !entity.passengers.isEmpty() || entity.isPassenger() ) // Paper +- if ( !entity.isOnGround() || !entity.passengers.isEmpty() || entity.isPassenger() ) ++ if ( (!entity.isOnGround() && !(entity instanceof EntityFlying)) || !entity.passengers.isEmpty() || entity.isPassenger() ) { - return true; + return 10; // Paper diff --git a/Spigot-Server-Patches/Entity-Jump-API.patch b/Spigot-Server-Patches/Entity-Jump-API.patch index ff7424a411..da44758b6a 100644 --- a/Spigot-Server-Patches/Entity-Jump-API.patch +++ b/Spigot-Server-Patches/Entity-Jump-API.patch @@ -9,9 +9,9 @@ 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 { - } else if (this.aH()) { - this.c(TagsFluid.LAVA); - } else if ((this.onGround || this.N > 0.0D && this.N <= 0.4D) && this.jumpTicks == 0) { + } else if (this.aN() && (!this.onGround || d7 > d8)) { + this.c((Tag) TagsFluid.LAVA); + } else if ((this.onGround || flag && d7 <= d8) && this.jumpTicks == 0) { + if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper this.jump(); this.jumpTicks = 10; @@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class EntityPanda extends EntityAnimal { EntityPanda entitypanda = (EntityPanda) iterator.next(); - if (!entitypanda.isBaby() && entitypanda.onGround && !entitypanda.isInWater() && entitypanda.eL()) { + if (!entitypanda.isBaby() && entitypanda.onGround && !entitypanda.isInWater() && entitypanda.fi()) { + if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper entitypanda.jump(); + } else { this.setJumping(false); } // Paper - setJumping(false) stops a potential loop diff --git a/Spigot-Server-Patches/Fix-AssertionError-when-player-hand-set-to-empty-typ.patch b/Spigot-Server-Patches/Fix-AssertionError-when-player-hand-set-to-empty-typ.patch index 2fc174550e..4422b90b90 100644 --- a/Spigot-Server-Patches/Fix-AssertionError-when-player-hand-set-to-empty-typ.patch +++ b/Spigot-Server-Patches/Fix-AssertionError-when-player-hand-set-to-empty-typ.patch @@ -11,10 +11,10 @@ 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 this.getEquipment(EnumItemSlot.OFFHAND); + return predicate.test(this.getItemInMainHand().getItem()) || predicate.test(this.getItemInOffHand().getItem()); } -+ public ItemStack getItemInHand(EnumHand enumhand) { return this.b(enumhand); } // Paper - OBFHELPER ++ public final ItemStack getItemInHand(EnumHand enumhand) { return this.b(enumhand); } // Paper - OBFHELPER public ItemStack b(EnumHand enumhand) { if (enumhand == EnumHand.MAIN_HAND) { return this.getEquipment(EnumItemSlot.MAINHAND); @@ -23,13 +23,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { - if (cancelled) { this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524 - } else { -+ // Paper start -+ itemstack = this.player.getItemInHand(enumhand); -+ if (itemstack.isEmpty()) return; -+ // Paper end - this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand); + return; } - // CraftBukkit end ++ // Paper start ++ itemstack = this.player.getItemInHand(enumhand); ++ if (itemstack.isEmpty()) return; ++ // Paper end + EnumInteractionResult enuminteractionresult = this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand); + + if (enuminteractionresult.b()) { diff --git a/Spigot-Server-Patches/Fix-World-isChunkGenerated-calls.patch b/Spigot-Server-Patches/Fix-World-isChunkGenerated-calls.patch index f0403a6f11..e4af25853b 100644 --- a/Spigot-Server-Patches/Fix-World-isChunkGenerated-calls.patch +++ b/Spigot-Server-Patches/Fix-World-isChunkGenerated-calls.patch @@ -142,14 +142,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - private NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException { + public NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException { // Paper - private -> public NBTTagCompound nbttagcompound = this.read(chunkcoordintpair); - -- return nbttagcompound == null ? null : this.getChunkData(this.world.getWorldProvider().getDimensionManager(), this.l, nbttagcompound, chunkcoordintpair, world); // CraftBukkit + // Paper start - Cache chunk status on disk + if (nbttagcompound == null) { + return null; + } + -+ nbttagcompound = this.getChunkData(this.world.getWorldProvider().getDimensionManager(), this.l, nbttagcompound, chunkcoordintpair, world); // CraftBukkit ++ nbttagcompound = this.getChunkData(this.world.getTypeKey(), this.l, nbttagcompound, chunkcoordintpair, world); // CraftBukkit + if (nbttagcompound == null) { + return null; + } @@ -165,12 +163,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + RegionFile regionFile = this.getIOWorker().getRegionFileCache().getRegionFileIfLoaded(chunkPos); + + return regionFile == null ? null : regionFile.getStatusIfCached(chunkPos.x, chunkPos.z); - } - -+ public ChunkStatus getChunkStatusOnDisk(ChunkCoordIntPair chunkPos) throws IOException { -+ RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, false); ++ } + -+ if (!regionFile.chunkExists(chunkPos)) { ++ public ChunkStatus getChunkStatusOnDisk(ChunkCoordIntPair chunkPos) throws IOException { ++ RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, true); ++ ++ if (regionFile == null || !regionFile.chunkExists(chunkPos)) { + return null; + } + @@ -181,10 +179,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + this.readChunkData(chunkPos); -+ + +- return nbttagcompound == null ? null : this.getChunkData(this.world.getTypeKey(), this.l, nbttagcompound, chunkcoordintpair, world); // CraftBukkit + return regionFile.getStatusIfCached(chunkPos.x, chunkPos.z); -+ } -+ + } + + public void updateChunkStatusOnDisk(ChunkCoordIntPair chunkPos, @Nullable NBTTagCompound compound) throws IOException { + RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, false); + @@ -232,8 +231,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end + - 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); } @@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable { return this.getOffset(chunkcoordintpair) != 0; @@ -247,14 +246,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void close() throws IOException { + this.closed = true; // Paper try { - this.c(); + this.d(); } finally { diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/RegionFileCache.java +++ b/src/main/java/net/minecraft/server/RegionFileCache.java @@ -0,0 +0,0 @@ public final class RegionFileCache implements AutoCloseable { - this.b = file; + this.c = flag; } - private RegionFile getFile(ChunkCoordIntPair chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit diff --git a/Spigot-Server-Patches/Fix-comparator-behavior-for-EntityPhanton-goal.patch b/Spigot-Server-Patches/Fix-comparator-behavior-for-EntityPhanton-goal.patch deleted file mode 100644 index 012659b1c0..0000000000 --- a/Spigot-Server-Patches/Fix-comparator-behavior-for-EntityPhanton-goal.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Shane Freeder -Date: Wed, 22 Jan 2020 21:00:21 +0000 -Subject: [PATCH] Fix comparator behavior for EntityPhanton goal - - -diff --git a/src/main/java/net/minecraft/server/EntityPhantom.java b/src/main/java/net/minecraft/server/EntityPhantom.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/EntityPhantom.java -+++ b/src/main/java/net/minecraft/server/EntityPhantom.java -@@ -0,0 +0,0 @@ public class EntityPhantom extends EntityFlying implements IMonster { - - if (!list.isEmpty()) { - list.sort((entityhuman, entityhuman1) -> { -- return entityhuman.locY() > entityhuman1.locY() ? -1 : 1; -+ return Double.compare(entityhuman1.locY(), entityhuman.locY()); // Paper - }); - Iterator iterator = list.iterator(); - diff --git a/Spigot-Server-Patches/Fix-items-vanishing-through-end-portal.patch b/Spigot-Server-Patches/Fix-items-vanishing-through-end-portal.patch index 66c5006093..2892b633b8 100644 --- a/Spigot-Server-Patches/Fix-items-vanishing-through-end-portal.patch +++ b/Spigot-Server-Patches/Fix-items-vanishing-through-end-portal.patch @@ -19,12 +19,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke if (blockposition == null) { // CraftBukkit - if (dimensionmanager1.getType() == DimensionManager.THE_END && dimensionmanager == DimensionManager.OVERWORLD) { // CraftBukkit + if (this.world.getDimensionKey() == World.THE_END && worldserver.getDimensionKey() == World.OVERWORLD) { + // Paper start - Ensure spawn chunk is always loaded before calculating Y coordinate -+ if (!worldserver1.isLoaded(worldserver1.getSpawn())) { -+ worldserver1.getChunkAtWorldCoords(worldserver1.getSpawn()); -+ } ++ this.world.getChunkAtWorldCoords(this.world.getSpawn()); + // Paper end // CraftBukkit start - EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent(this, worldserver1, worldserver1.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver1.getSpawn()), 0); + EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent(this, worldserver, worldserver.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver.getSpawn()), 0); if (event == null) { diff --git a/Spigot-Server-Patches/Fix-last-firework-in-stack-not-having-effects-when-d.patch b/Spigot-Server-Patches/Fix-last-firework-in-stack-not-having-effects-when-d.patch index 892826de01..43ba0c661f 100644 --- a/Spigot-Server-Patches/Fix-last-firework-in-stack-not-having-effects-when-d.patch +++ b/Spigot-Server-Patches/Fix-last-firework-in-stack-not-having-effects-when-d.patch @@ -16,8 +16,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); -- EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), itemstack, d3, d4, d5, true); -+ EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), itemstack1, d3, d4, d5, true); // Paper - GH-2871 - fix last firework in stack having no effects when dispensed +- EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), itemstack, isourceblock.getX(), isourceblock.getY(), isourceblock.getX(), true); ++ EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), itemstack1, isourceblock.getX(), isourceblock.getY(), isourceblock.getX(), true); // Paper - GH-2871 - fix last firework in stack having no effects when dispensed - entityfireworks.shoot(d0, d1, d2, 0.5F, 1.0F); - isourceblock.getWorld().addEntity(entityfireworks); + IDispenseBehavior.a(isourceblock, entityfireworks, enumdirection); + entityfireworks.shoot((double) enumdirection.getAdjacentX(), (double) enumdirection.getAdjacentY(), (double) enumdirection.getAdjacentZ(), 0.5F, 1.0F); diff --git a/Spigot-Server-Patches/Fix-spawn-radius-being-treated-as-0.patch b/Spigot-Server-Patches/Fix-spawn-radius-being-treated-as-0.patch deleted file mode 100644 index eb029b9908..0000000000 --- a/Spigot-Server-Patches/Fix-spawn-radius-being-treated-as-0.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Shane Freeder -Date: Sun, 15 Dec 2019 19:41:28 +0000 -Subject: [PATCH] Fix spawn radius being treated as 0 - - -diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- 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 final BlockPosition getSpawnPoint(WorldServer worldserver) { - BlockPosition blockposition = worldserver.getSpawn(); - -- if (worldserver.worldProvider.g() && worldserver.getWorldData().getGameType() != EnumGamemode.ADVENTURE) { -+ if (worldserver.worldProvider.f() && worldserver.getWorldData().getGameType() != EnumGamemode.ADVENTURE) { // Paper - int i = Math.max(0, this.server.a(worldserver)); - int j = MathHelper.floor(worldserver.getWorldBorder().b((double) blockposition.getX(), (double) blockposition.getZ())); - diff --git a/Spigot-Server-Patches/Fix-unregistering-entities-from-unloading-chunks.patch b/Spigot-Server-Patches/Fix-unregistering-entities-from-unloading-chunks.patch index 2134d29148..e753c5fa81 100644 --- a/Spigot-Server-Patches/Fix-unregistering-entities-from-unloading-chunks.patch +++ b/Spigot-Server-Patches/Fix-unregistering-entities-from-unloading-chunks.patch @@ -18,7 +18,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 { } private void removeEntityFromChunk(Entity entity) { diff --git a/Spigot-Server-Patches/Generator-Settings.patch b/Spigot-Server-Patches/Generator-Settings.patch index 596865d130..f4cda5030d 100644 --- a/Spigot-Server-Patches/Generator-Settings.patch +++ b/Spigot-Server-Patches/Generator-Settings.patch @@ -22,32 +22,68 @@ diff --git a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java b/sr index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java +++ b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java -@@ -0,0 +0,0 @@ public abstract class ChunkGeneratorAbstract +@@ -0,0 +0,0 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); int i = ichunkaccess.getPos().d(); int j = ichunkaccess.getPos().e(); - T t0 = this.getSettings(); -- int k = t0.u(); -- int l = t0.t(); -+ int k = t0.u(); final int floorHeight = k; // Paper -+ int l = t0.t(); final int roofHeight = l; // Paper - Iterator iterator = BlockPosition.b(i, 0, j, i + 15, 0, j + 15).iterator(); +- int k = this.h.f(); +- int l = this.x - 1 - this.h.e(); ++ int k = this.h.f(); final int floorHeight = k; // Paper ++ int l = this.x - 1 - this.h.e(); final int roofHeight = l; // Paper + boolean flag = true; + boolean flag1 = l + 4 >= 0 && l < this.x; + boolean flag2 = k + 4 >= 0 && k < this.x; +@@ -0,0 +0,0 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator { - while (iterator.hasNext()) { -@@ -0,0 +0,0 @@ public abstract class ChunkGeneratorAbstract - - if (l > 0) { - for (i1 = l; i1 >= l - 4; --i1) { -- if (i1 >= l - random.nextInt(5)) { -+ if (i1 >= (getWorld().paperConfig.generateFlatBedrock ? roofHeight : l - random.nextInt(5))) { // Paper - Configurable flat bedrock roof - ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false); + if (flag1) { + for (i1 = 0; i1 < 5; ++i1) { +- if (i1 <= random.nextInt(5)) { ++ if (i1 <= (ichunkaccess.generateFlatBedrock() ? roofHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock roof + ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), l - i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false); + } } - } -@@ -0,0 +0,0 @@ public abstract class ChunkGeneratorAbstract +@@ -0,0 +0,0 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator { - if (k < 256) { - for (i1 = k + 4; i1 >= k; --i1) { -- if (i1 <= k + random.nextInt(5)) { -+ if (i1 <= (getWorld().paperConfig.generateFlatBedrock ? floorHeight : k + random.nextInt(5))) { // Paper - Configurable flat bedrock floor - ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false); + if (flag2) { + for (i1 = 4; i1 >= 0; --i1) { +- if (i1 <= random.nextInt(5)) { ++ if (i1 <= (ichunkaccess.generateFlatBedrock() ? floorHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock floor + ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), k + i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false); + } } - } +diff --git a/src/main/java/net/minecraft/server/IChunkAccess.java b/src/main/java/net/minecraft/server/IChunkAccess.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/IChunkAccess.java ++++ b/src/main/java/net/minecraft/server/IChunkAccess.java +@@ -0,0 +0,0 @@ import org.apache.logging.log4j.LogManager; + + public interface IChunkAccess extends IBlockAccess, IStructureAccess { + ++ // Paper start ++ default boolean generateFlatBedrock() { ++ if (this instanceof ProtoChunk) { ++ return ((ProtoChunk)this).world.paperConfig.generateFlatBedrock; ++ } else if (this instanceof Chunk) { ++ return ((Chunk)this).world.paperConfig.generateFlatBedrock; ++ } else { ++ return false; ++ } ++ } ++ // Paper end ++ + IBlockData getType(final int x, final int y, final int z); // Paper + @Nullable + IBlockData setType(BlockPosition blockposition, IBlockData iblockdata, boolean flag); +diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/ProtoChunk.java ++++ b/src/main/java/net/minecraft/server/ProtoChunk.java +@@ -0,0 +0,0 @@ public class ProtoChunk implements IChunkAccess { + private long s; + private final Map t; + private volatile boolean u; +- private final World world; // Paper - Anti-Xray - Add world ++ final World world; // Paper - Anti-Xray - Add world // Paper - private -> default + + // Paper start - Anti-Xray - Add world + @Deprecated public ProtoChunk(ChunkCoordIntPair chunkcoordintpair, ChunkConverter chunkconverter) { this(chunkcoordintpair, chunkconverter, null); } // Notice for updates: Please make sure this constructor isn't used anywhere diff --git a/Spigot-Server-Patches/Guard-against-serializing-mismatching-chunk-coordina.patch b/Spigot-Server-Patches/Guard-against-serializing-mismatching-chunk-coordina.patch index fe3aa5408a..26c0d59940 100644 --- a/Spigot-Server-Patches/Guard-against-serializing-mismatching-chunk-coordina.patch +++ b/Spigot-Server-Patches/Guard-against-serializing-mismatching-chunk-coordina.patch @@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ChunkRegionLoader { // Paper end - ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator(); + ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator(); WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager(); - NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level"); - ChunkCoordIntPair chunkcoordintpair1 = new ChunkCoordIntPair(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos")); @@ -38,8 +38,8 @@ diff --git a/src/main/java/net/minecraft/server/IChunkLoader.java b/src/main/jav index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/IChunkLoader.java +++ b/src/main/java/net/minecraft/server/IChunkLoader.java -@@ -0,0 +0,0 @@ public class IChunkLoader extends RegionFileCache implements AutoCloseable { - // +@@ -0,0 +0,0 @@ public class IChunkLoader implements AutoCloseable { + public void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { write(chunkcoordintpair, nbttagcompound); } // Paper OBFHELPER public void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { // Paper - OBFHELPER - (Switched around for safety) + // Paper start @@ -49,6 +49,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + " but compound says coordinate is " + ChunkRegionLoader.getChunkCoordinate(nbttagcompound).toString() + (world == null ? " for an unknown world" : (" for world: " + world))); + } + // Paper end - super.write(chunkcoordintpair, nbttagcompound); + this.regionFileCache.write(chunkcoordintpair, nbttagcompound); if (this.c != null) { synchronized (this.persistentDataLock) { // Paper - Async chunk loading diff --git a/Spigot-Server-Patches/Implement-alternative-item-despawn-rate.patch b/Spigot-Server-Patches/Implement-alternative-item-despawn-rate.patch index 1e55afffde..37a7771eb3 100644 --- a/Spigot-Server-Patches/Implement-alternative-item-despawn-rate.patch +++ b/Spigot-Server-Patches/Implement-alternative-item-despawn-rate.patch @@ -123,5 +123,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end + @Override - public Packet L() { + public Packet O() { return new PacketPlayOutSpawnEntity(this); diff --git a/Spigot-Server-Patches/Lag-compensate-eating.patch b/Spigot-Server-Patches/Lag-compensate-eating.patch index 3ad9bccb61..7d85ea46e9 100644 --- a/Spigot-Server-Patches/Lag-compensate-eating.patch +++ b/Spigot-Server-Patches/Lag-compensate-eating.patch @@ -14,45 +14,45 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private int jumpTicks; private float bD; public ItemStack activeItem; // Paper - public -- protected int bl; -+ protected int bl; protected final int getEatTimeTicks() { return this.bl; } protected final void setEatTimeTicks(int value) { this.bl = value; } // Paper - OBFHELPER - protected int bm; +- protected int bk; ++ protected int bk; protected final int getEatTimeTicks() { return this.bk; } protected final void setEatTimeTicks(int value) { this.bk = value; } // Paper - OBFHELPER + protected int bl; private BlockPosition bE; - private DamageSource bF; + private Optional bF; @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { - return ((Byte) this.datawatcher.get(EntityLiving.ao) & 2) > 0 ? EnumHand.OFF_HAND : EnumHand.MAIN_HAND; + return ((Byte) this.datawatcher.get(EntityLiving.an) & 2) > 0 ? EnumHand.OFF_HAND : EnumHand.MAIN_HAND; } + // Paper start - lag compensate eating + protected long eatStartTime; + protected int totalEatTimeTicks; + // Paper end - private void o() { ++ + private void u() { if (this.isHandRaised()) { if (ItemStack.d(this.b(this.getRaisedHand()), this.activeItem)) { @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { this.b(this.activeItem, 5); } -- if (--this.bl == 0 && !this.world.isClientSide && !this.activeItem.m()) { -+ +- if (--this.bk == 0 && !this.world.isClientSide && !this.activeItem.m()) { + // Paper start - lag compensate eating + // we add 1 to the expected time to avoid lag compensating when we should not + boolean shouldLagCompensate + = this.activeItem.getItem().isFood() && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1 + this.totalEatTimeTicks) * 50 * (1000 * 1000)); -+ if ((--this.bl == 0 || shouldLagCompensate) && !this.world.isClientSide && !this.activeItem.m()) { ++ if ((--this.bk == 0 || shouldLagCompensate) && !this.world.isClientSide && !this.activeItem.m()) { + this.setEatTimeTicks(0); + // Paper end - this.q(); + this.s(); } } else { @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { if (!itemstack.isEmpty() && !this.isHandRaised() || forceUpdate) { // Paper use override flag this.activeItem = itemstack; -- this.bl = itemstack.k(); +- this.bk = itemstack.k(); + // Paper start - lag compensate eating -+ this.bl = this.totalEatTimeTicks = itemstack.k(); ++ this.bk = this.totalEatTimeTicks = itemstack.k(); + this.eatStartTime = System.nanoTime(); + // Paper end if (!this.world.isClientSide) { @@ -61,10 +61,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { } } else if (!this.isHandRaised() && !this.activeItem.isEmpty()) { - this.activeItem = ItemStack.a; -- this.bl = 0; + this.activeItem = ItemStack.b; +- this.bk = 0; + // Paper start - lag compensate eating -+ this.bl = this.totalEatTimeTicks = 0; ++ this.bk = this.totalEatTimeTicks = 0; + this.eatStartTime = -1L; + // Paper end } @@ -73,10 +73,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { } - this.activeItem = ItemStack.a; -- this.bl = 0; + this.activeItem = ItemStack.b; +- this.bk = 0; + // Paper start - lag compensate eating -+ this.bl = this.totalEatTimeTicks = 0; ++ this.bk = this.totalEatTimeTicks = 0; + this.eatStartTime = -1L; + // Paper end } diff --git a/Spigot-Server-Patches/Make-the-GUI-graph-fancier.patch b/Spigot-Server-Patches/Make-the-GUI-graph-fancier.patch index acbd7a72f7..10da4ae409 100644 --- a/Spigot-Server-Patches/Make-the-GUI-graph-fancier.patch +++ b/Spigot-Server-Patches/Make-the-GUI-graph-fancier.patch @@ -403,12 +403,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant> 4, blockposition.getZ() >> 4); + diff --git a/Spigot-Server-Patches/Optimise-IEntityAccess-getPlayerByUUID.patch b/Spigot-Server-Patches/Optimise-IEntityAccess-getPlayerByUUID.patch index 2479f49a74..bc43aa1dc9 100644 --- a/Spigot-Server-Patches/Optimise-IEntityAccess-getPlayerByUUID.patch +++ b/Spigot-Server-Patches/Optimise-IEntityAccess-getPlayerByUUID.patch @@ -26,9 +26,9 @@ 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 { - return new Throwable(entity + " Added to world at " + new java.util.Date()); +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { } + // Paper end + // Paper start - optimise getPlayerByUUID + @Nullable @@ -39,6 +39,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end + - // Paper start - Asynchronous IO - public final com.destroystokyo.paper.io.PaperFileIOThread.ChunkDataController poiDataController = new com.destroystokyo.paper.io.PaperFileIOThread.ChunkDataController() { - @Override + // Add env and gen to constructor, WorldData -> WorldDataServer + public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey resourcekey, ResourceKey resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { + super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor diff --git a/Spigot-Server-Patches/Optimise-TickListServer-by-rewriting-it.patch b/Spigot-Server-Patches/Optimise-TickListServer-by-rewriting-it.patch index 18a7ee2092..6b665f255b 100644 --- a/Spigot-Server-Patches/Optimise-TickListServer-by-rewriting-it.patch +++ b/Spigot-Server-Patches/Optimise-TickListServer-by-rewriting-it.patch @@ -113,7 +113,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private final WorldServer world; + private final Predicate excludeFromScheduling; + private final Function getMinecraftKeyFrom; -+ private final Function getObjectFronMinecraftKey; ++ //private final Function getObjectFronMinecraftKey; + private final Consumer> tickFunction; + + private final co.aikar.timings.Timing timingCleanup; // Paper @@ -156,12 +156,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + public PaperTickList(final WorldServer world, final Predicate excludeFromScheduling, final Function getMinecraftKeyFrom, -+ final Function getObjectFronMinecraftKey, final Consumer> tickFunction, final String timingsType) { -+ super(world, excludeFromScheduling, getMinecraftKeyFrom, getObjectFronMinecraftKey, tickFunction, timingsType); ++ final Consumer> tickFunction, final String timingsType) { ++ super(world, excludeFromScheduling, getMinecraftKeyFrom, tickFunction, timingsType); + this.world = world; + this.excludeFromScheduling = excludeFromScheduling; + this.getMinecraftKeyFrom = getMinecraftKeyFrom; -+ this.getObjectFronMinecraftKey = getObjectFronMinecraftKey; + this.tickFunction = tickFunction; + this.timingCleanup = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Cleanup"); // Paper + this.timingTicking = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Ticking"); // Paper @@ -521,10 +520,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.addToSchedule(entry); + } + -+ @Override -+ public void scheduleAll(final Stream> stream) { -+ this.scheduleAll(stream.iterator()); -+ } + public void scheduleAll(final Iterator> iterator) { + while (iterator.hasNext()) { + this.schedule(iterator.next()); @@ -886,7 +881,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 { return i == 0 && j == 0 && k == 0 ? this : new BlockPosition(this.getX() + i, this.getY() + j, this.getZ() + k); } @@ -909,9 +904,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - rewrite ticklistserver + - - public ChunkProviderServer(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator chunkgenerator, int i, WorldLoadListener worldloadlistener, Supplier supplier) { + public ChunkProviderServer(WorldServer worldserver, Convertable.ConversionSession convertable_conversionsession, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator chunkgenerator, int i, boolean flag, WorldLoadListener worldloadlistener, Supplier supplier) { this.world = worldserver; + this.serverThreadQueue = new ChunkProviderServer.a(worldserver); diff --git a/src/main/java/net/minecraft/server/NextTickListEntry.java b/src/main/java/net/minecraft/server/NextTickListEntry.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/NextTickListEntry.java @@ -1030,7 +1025,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return this.d >= structureboundingbox.a && this.a <= structureboundingbox.d && this.f >= structureboundingbox.c && this.c <= structureboundingbox.f && this.e >= structureboundingbox.b && this.b <= structureboundingbox.e; } @@ -0,0 +0,0 @@ public class StructureBoundingBox { - return new StructureBoundingBox(this.a + i, this.b + j, this.c + k, this.d + i, this.e + j, this.f + k); + this.a(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ()); } + public final boolean hasPoint(BaseBlockPosition baseblockposition) { return this.b(baseblockposition); } // Paper - OBFHELPER @@ -1062,17 +1057,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + public boolean isPendingTickThisTick(BlockPosition blockposition, T t0) { + // Paper end - return this.g.contains(new NextTickListEntry<>(blockposition, t0)); - } - - @Override - public void a(Stream> stream) { -+ // Paper start - allow overriding -+ this.scheduleAll(stream); -+ } -+ public void scheduleAll(Stream> stream) { -+ // Paper end - stream.forEach(this::a); + return this.f.contains(new NextTickListEntry<>(blockposition, t0)); } public List> a(ChunkCoordIntPair chunkcoordintpair, boolean flag, boolean flag1) { @@ -1119,11 +1104,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end List> list = this.a(chunkcoordintpair, false, true); - return a(this.b, list, this.f.getTime()); + return a(this.b, list, this.e.getTime()); } + public static NBTTagList serialize(Function function, Iterable> iterable, long i) { return TickListServer.a(function, iterable, i); } // Paper - OBFHELPER - public static NBTTagList a(Function function, Iterable> iterable, long i) { + private static NBTTagList a(Function function, Iterable> iterable, long i) { NBTTagList nbttaglist = new NBTTagList(); Iterator iterator = iterable.iterator(); @@ -0,0 +0,0 @@ public class TickListServer implements TickList { @@ -1146,7 +1131,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public void schedule(BlockPosition blockposition, T t0, int i, TickListPriority ticklistpriority) { + // Paper end if (!this.a.test(t0)) { - this.a(new NextTickListEntry<>(blockposition, t0, (long) i + this.f.getTime(), ticklistpriority)); + this.a(new NextTickListEntry<>(blockposition, t0, (long) i + this.e.getTime(), ticklistpriority)); } @@ -0,0 +0,0 @@ public class TickListServer implements TickList { } @@ -1164,7 +1149,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 { } // Paper end @@ -1177,35 +1162,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - rewrite ticklistserver + - // 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) { - super(worlddata, dimensionmanager, executor, (world, worldprovider) -> { // Paper - pass executor down -@@ -0,0 +0,0 @@ public class WorldServer extends World { - this.pvpMode = minecraftserver.getPVP(); - worlddata.world = this; + // Add env and gen to constructor, WorldData -> WorldDataServer + public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey resourcekey, ResourceKey resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { + super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { + convertable = convertable_conversionsession; + uuid = WorldUUID.getUUID(convertable_conversionsession.folder.toFile()); // CraftBukkit end - this.nextTickListBlock = new TickListServer<>(this, (block) -> { - return block == null || block.getBlockData().isAir(); -- }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b, "Blocks"); // Paper - Timings +- }, IRegistry.BLOCK::getKey, this::b, "Blocks"); // Paper - Timings - this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> { - return fluidtype == null || fluidtype == FluidTypes.EMPTY; -- }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a, "Fluids"); // Paper - Timings +- }, IRegistry.FLUID::getKey, this::a, "Fluids"); // Paper - Timings + if (com.destroystokyo.paper.PaperConfig.useOptimizedTickList) { -+ this.nextTickListBlock = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> { // Paper - optimise TickListServer ++ this.nextTickListBlock = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> { + return block == null || block.getBlockData().isAir(); -+ }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b, "Blocks"); // Paper - Timings -+ this.nextTickListFluid = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (fluidtype) -> { // Paper - optimise TickListServer ++ }, IRegistry.BLOCK::getKey, this::b, "Blocks"); // Paper - Timings ++ this.nextTickListFluid = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (fluidtype) -> { + return fluidtype == null || fluidtype == FluidTypes.EMPTY; -+ }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a, "Fluids"); // Paper - Timings ++ }, IRegistry.FLUID::getKey, this::a, "Fluids"); // Paper - Timings + } else { -+ this.nextTickListBlock = new TickListServer<>(this, (block) -> { // Paper - optimise TickListServer ++ this.nextTickListBlock = new TickListServer<>(this, (block) -> { + return block == null || block.getBlockData().isAir(); -+ }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b, "Blocks"); // Paper - Timings -+ this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> { // Paper - optimise TickListServer ++ }, IRegistry.BLOCK::getKey, this::b, "Blocks"); // Paper - Timings ++ this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> { + return fluidtype == null || fluidtype == FluidTypes.EMPTY; -+ }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a, "Fluids"); // Paper - Timings ++ }, IRegistry.FLUID::getKey, this::a, "Fluids"); // Paper - Timings + } -+ this.navigators = Sets.newHashSet(); - this.I = new ObjectLinkedOpenHashSet(); - this.dataManager = worldnbtstorage; + this.L = new ObjectLinkedOpenHashSet(); + this.Q = flag1; diff --git a/Spigot-Server-Patches/Optimise-random-block-ticking.patch b/Spigot-Server-Patches/Optimise-random-block-ticking.patch index 28e598f7b2..23a930b1be 100644 --- a/Spigot-Server-Patches/Optimise-random-block-ticking.patch +++ b/Spigot-Server-Patches/Optimise-random-block-ticking.patch @@ -70,39 +70,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return fastRandomBounded(this.next(32) & 0xFFFFFFFFL, bound); + } +} -diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java -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 iblockdata.d(iblockaccess, blockposition, EnumDirection.UP) && this.n < 14; - } - -- @Deprecated -- public boolean d(IBlockData iblockdata) { -+ public final boolean isAir(IBlockData iblockdata) { return this.d(iblockdata); } // Paper - OBFHELPER -+ @Deprecated public boolean d(IBlockData iblockdata) { // Paper - OBFHELPER - return false; - } - -diff --git a/src/main/java/net/minecraft/server/BlockFluids.java b/src/main/java/net/minecraft/server/BlockFluids.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BlockFluids.java -+++ b/src/main/java/net/minecraft/server/BlockFluids.java -@@ -0,0 +0,0 @@ public class BlockFluids extends Block implements IFluidSource { - - @Override - public void b(IBlockData iblockdata, WorldServer worldserver, BlockPosition blockposition, Random random) { -- worldserver.getFluid(blockposition).b(worldserver, blockposition, random); -+ iblockdata.getFluid().b(worldserver, blockposition, random); // Paper - avoid getType call - } - - @Override 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 +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { return this.d(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); } @@ -119,9 +91,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } - @Override -- public int a(HeightMap.Type heightmap_type, int i, int j) { -+ public int getHighestBlockY(HeightMap.Type heightmap_type, int i, int j) { return this.a(heightmap_type, i, j) + 1; } // Paper - sort of an obfhelper, but without -1 -+ @Override public int a(HeightMap.Type heightmap_type, int i, int j) { // Paper +- public int getHighestBlock(HeightMap.Type heightmap_type, int i, int j) { ++ public final int getHighestBlockY(HeightMap.Type heightmap_type, int i, int j) { return this.getHighestBlock(heightmap_type, i, j) + 1; } // Paper - sort of an obfhelper, but without -1 ++ @Override public int getHighestBlock(HeightMap.Type heightmap_type, int i, int j) { // Paper return ((HeightMap) this.heightMap.get(heightmap_type)).a(i & 15, j & 15) - 1; } @@ -148,7 +120,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public ChunkSection(int i, IChunkAccess chunk, World world, boolean initializeBlocks) { @@ -0,0 +0,0 @@ public class ChunkSection { --this.nonEmptyBlockCount; - if (iblockdata1.q()) { + if (iblockdata1.isTicking()) { --this.tickingBlockCount; + // Paper start + this.tickingList.remove(i, j, k); @@ -158,7 +130,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ChunkSection { ++this.nonEmptyBlockCount; - if (iblockdata.q()) { + if (iblockdata.isTicking()) { ++this.tickingBlockCount; + // Paper start + this.tickingList.add(i, j, k, iblockdata); @@ -182,10 +154,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!iblockdata.isAir()) { - this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i); -+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); // Paper - if (iblockdata.q()) { ++ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); + if (iblockdata.isTicking()) { - this.tickingBlockCount = (short) (this.tickingBlockCount + i); -+ this.tickingBlockCount = (short) (this.tickingBlockCount + 1); // Paper ++ this.tickingBlockCount = (short) (this.tickingBlockCount + 1); + // Paper start + this.tickingList.add(location, iblockdata); + // Paper end @@ -194,10 +166,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!fluid.isEmpty()) { - this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i); -+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); // Paper - if (fluid.h()) { ++ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); + if (fluid.f()) { - this.e = (short) (this.e + i); -+ this.e = (short) (this.e + 1); // Paper ++ this.e = (short) (this.e + 1); } } @@ -206,41 +178,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/DataBits.java +++ b/src/main/java/net/minecraft/server/DataBits.java @@ -0,0 +0,0 @@ public class DataBits { - } + } + + // Paper start + public final void forEach(DataBitConsumer consumer) { -+ // Note: copied from above -+ int i = this.a.length; ++ int i = 0; ++ long[] along = this.b; ++ int j = along.length; + -+ if (i != 0) { -+ int j = 0; -+ long k = this.a[0]; -+ long l = i > 1 ? this.a[1] : 0L; ++ for (int k = 0; k < j; ++k) { ++ long l = along[k]; + -+ for (int i1 = 0; i1 < this.d; ++i1) { -+ int j1 = i1 * this.b; -+ int k1 = j1 >> 6; -+ int l1 = (i1 + 1) * this.b - 1 >> 6; -+ int i2 = j1 ^ k1 << 6; -+ -+ if (k1 != j) { -+ k = l; -+ l = k1 + 1 < i ? this.a[k1 + 1] : 0L; -+ j = k1; -+ } -+ -+ if (k1 == l1) { -+ consumer.accept(i1, (int) (k >>> i2 & this.c)); -+ } else { -+ int j2 = 64 - i2; -+ -+ consumer.accept(i1, (int) ((k >>> i2 | l << j2) & this.c)); ++ for (int i1 = 0; i1 < this.f; ++i1) { ++ consumer.accept(i, (int) (l & this.d)); ++ l >>= this.c; ++ ++i; ++ if (i >= this.e) { ++ return; + } + } -+ + } + } + @@ -277,72 +235,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/EntityTurtle.java @@ -0,0 +0,0 @@ public class EntityTurtle extends EntityAnimal { - public final void setHome(BlockPosition pos) { g(pos); } // Paper - OBFHELPER - public void g(BlockPosition blockposition) { -- this.datawatcher.set(EntityTurtle.bx, blockposition); -+ this.datawatcher.set(EntityTurtle.bx, blockposition.immutableCopy()); // Paper - make sure home position can't change + public final void setHome(BlockPosition pos) { setHomePos(pos); } // Paper - OBFHELPER + public void setHomePos(BlockPosition blockposition) { +- this.datawatcher.set(EntityTurtle.bw, blockposition); ++ this.datawatcher.set(EntityTurtle.bw, blockposition.immutableCopy()); // Paper - called with mutablepos... } - - public final BlockPosition getHome() { return this.es(); } // Paper - OBFHELPER -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 - private IBlockData.a c; - private final int d; - private final boolean e; -+ private final boolean isAir; // Paper -+ private final boolean isTicking; // Paper - - public IBlockData(Block block, ImmutableMap, Comparable> immutablemap) { - super(block, immutablemap); - this.d = block.a(this); - this.e = block.o(this); -+ this.isAir = this.getBlock().isAir(this); // Paper -+ this.isTicking = this.getBlock().isTicking(this); // Paper - } - - public void c() { -@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements - return this.d; - } - -- public boolean isAir() { -- return this.getBlock().d(this); -+ public final boolean isAir() { // Paper - compile fail if the impl changes -+ return this.isAir; // Paper - improve inlining of isAir - } - - public MaterialMapColor c(IBlockAccess iblockaccess, BlockPosition blockposition) { -@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements - return this.getBlock().a(tag); - } - -+ private Fluid fluidData; // Paper - cache result - public Fluid getFluid() { -- return this.getBlock().a_(this); -+ // Paper start -+ // This can't be done during the constructor, order issues -+ if (this.fluidData != null) { -+ return this.fluidData; -+ } -+ return this.fluidData = this.getBlock().a_(this); -+ // Paper end - } - - public boolean q() { -- return this.getBlock().isTicking(this); -+ return this.isTicking; // Paper - } - - public final SoundEffectType getStepSound() { return this.r(); } // Paper - OBFHELPER + // TODO Paper: Obf helpers here can prolly be removed? check that no newer patches use them + public final BlockPosition getHome() { return this.getHomePos(); } // Paper - OBFHELPER 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 abstract TagRegistry t(); + public abstract TagRegistry p(); public BlockPosition a(int i, int j, int k, int l) { + // Paper start - allow use of mutable pos @@ -350,11 +255,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.getRandomBlockPosition(i, j, k, l, ret); + return ret.immutableCopy(); + } -+ + public final BlockPosition.MutableBlockPosition getRandomBlockPosition(int i, int j, int k, int l, BlockPosition.MutableBlockPosition out) { + // Paper end - this.i = this.i * 3 + 1013904223; - int i1 = this.i >> 2; + this.n = this.n * 3 + 1013904223; + int i1 = this.n >> 2; - return new BlockPosition(i + (i1 & 15), j + (i1 >> 16 & l), k + (i1 >> 8 & 15)); + out.setValues(i + (i1 & 15), j + (i1 >> 16 & l), k + (i1 >> 8 & 15)); // Paper - change to setValues call @@ -366,7 +270,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 { }); } @@ -380,21 +284,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 ChunkCoordIntPair chunkcoordintpair = chunk.getPos(); boolean flag = this.isRaining(); int j = chunkcoordintpair.d(); -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { GameProfilerFiller gameprofilerfiller = this.getMethodProfiler(); gameprofilerfiller.enter("thunder"); - BlockPosition blockposition; + final BlockPosition.MutableBlockPosition blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change -- if (!this.paperConfig.disableThunder && flag && this.U() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder + if (!this.paperConfig.disableThunder && flag && this.T() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder - blockposition = this.a(this.a(j, 0, k, 15)); -+ if (!this.paperConfig.disableThunder && flag && this.U() && this.randomTickRandom.nextInt(100000) == 0) { // Paper - Disable thunder // Paper - optimise random ticking -+ blockposition.setValues(this.a(this.getRandomBlockPosition(j, 0, k, 15, blockposition))); // Paper ++ blockposition.setValues(this.a(this.a(j, 0, k, 15))); // Paper if (this.isRainingAt(blockposition)) { DifficultyDamageScaler difficultydamagescaler = this.getDamageScaler(blockposition); boolean flag1 = this.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.b() * paperConfig.skeleHorseSpawnChance; // Paper -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { } gameprofilerfiller.exitEnter("iceandsnow"); @@ -469,10 +372,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + continue; + } -- if (iblockdata.q()) { -- iblockdata.getBlock().randomTick = true; // Paper - fix MC-113809 +- if (iblockdata.isTicking()) { - iblockdata.b(this, blockposition2, this.random); -- iblockdata.getBlock().randomTick = false; // Paper - fix MC-113809 - } + long raw = section.tickingList.getRaw(index); + int location = com.destroystokyo.paper.util.maplist.IBlockDataList.getLocationFromRaw(raw); @@ -484,12 +385,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + BlockPosition blockposition2 = blockposition.setValues(j + randomX, randomY, k + randomZ); + IBlockData iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw); -- if (fluid.h()) { +- if (fluid.f()) { - fluid.b(this, blockposition2, this.random); - } -+ iblockdata.getBlock().randomTick = true; // Paper - fix MC-113809 + iblockdata.b(this, blockposition2, this.randomTickRandom); -+ iblockdata.getBlock().randomTick = false; // Paper - fix MC-113809 - gameprofilerfiller.exit(); - } diff --git a/Spigot-Server-Patches/Optimize-Hoppers.patch b/Spigot-Server-Patches/Optimize-Hoppers.patch index 9bed81874a..47ee597893 100644 --- a/Spigot-Server-Patches/Optimize-Hoppers.patch +++ b/Spigot-Server-Patches/Optimize-Hoppers.patch @@ -43,14 +43,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 World getWorld(); + default BlockPosition getBlockPosition() { return new BlockPosition(getX(), getY(), getZ()); } // Paper +- double x(); ++ double x(); default double getX() { return this.x(); } // Paper - OBFHELPER + - double z(); -+ double z();default double getX() { return z(); } // Paper - OBFHELPER ++ double z(); default double getY() { return this.z(); } // Paper - OBFHELPER - double A(); -+ double A();default double getY() { return A(); } // Paper - OBFHELPER - -- double B(); -+ double B();default double getZ() { return B(); } // Paper - OBFHELPER ++ double A(); default double getZ() { return this.A(); } // Paper - OBFHELPER } diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -65,25 +65,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public ItemStack cloneItemStack() { return cloneItemStack(false); } // Paper + public ItemStack cloneItemStack(boolean origItem) { // Paper + if (!origItem && this.isEmpty()) { // Paper - return ItemStack.a; + return ItemStack.b; } else { - ItemStack itemstack = new ItemStack(this.getItem(), this.count); + ItemStack itemstack = new ItemStack(origItem ? this.item : this.getItem(), this.count); // Paper - itemstack.d(this.C()); + itemstack.d(this.D()); if (this.tag != null) { 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 0; // Paper + TileEntityHopper.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - if (true || worldserver.worldProvider.getDimensionManager() == DimensionManager.OVERWORLD || this.getAllowNether()) { // CraftBukkit - this.methodProfiler.a(() -> { - return worldserver.getWorldData().getName() + " " + IRegistry.DIMENSION_TYPE.getKey(worldserver.worldProvider.getDimensionManager()); + + this.methodProfiler.a(() -> { + return worldserver + " " + worldserver.getDimensionKey().a(); diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/TileEntity.java @@ -266,8 +266,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end + - private boolean j() { - IInventory iinventory = this.k(); + private boolean k() { + IInventory iinventory = this.l(); @@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi if (this.b(iinventory, enumdirection)) { @@ -412,15 +412,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + IGNORE_TILE_UPDATES = true; // Paper iinventory1.setItem(i, itemstack); + IGNORE_TILE_UPDATES = false; // Paper - itemstack = ItemStack.a; + itemstack = ItemStack.b; flag = true; } else if (a(itemstack1, itemstack)) { @@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi } public static List c(IHopper ihopper) { -- return (List) ihopper.P_().d().stream().flatMap((axisalignedbb) -> { -- return ihopper.getWorld().a(EntityItem.class, axisalignedbb.d(ihopper.z() - 0.5D, ihopper.A() - 0.5D, ihopper.B() - 0.5D), IEntitySelector.a).stream(); +- return (List) ihopper.ac_().d().stream().flatMap((axisalignedbb) -> { +- return ihopper.getWorld().a(EntityItem.class, axisalignedbb.d(ihopper.x() - 0.5D, ihopper.z() - 0.5D, ihopper.A() - 0.5D), IEntitySelector.a).stream(); - }).collect(Collectors.toList()); + // Paper start - Optimize item suck in. remove streams, restore 1.12 checks. Seriously checking the bowl?! + World world = ihopper.getWorld(); diff --git a/Spigot-Server-Patches/Optimize-call-to-getFluid-for-explosions.patch b/Spigot-Server-Patches/Optimize-call-to-getFluid-for-explosions.patch index 72644f1c98..5e9e7cb003 100644 --- a/Spigot-Server-Patches/Optimize-call-to-getFluid-for-explosions.patch +++ b/Spigot-Server-Patches/Optimize-call-to-getFluid-for-explosions.patch @@ -14,6 +14,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 IBlockData iblockdata = this.world.getType(blockposition); - Fluid fluid = this.world.getFluid(blockposition); + Fluid fluid = iblockdata.getFluid(); // Paper + Optional optional = this.k.a(this, this.world, blockposition, iblockdata, fluid); - if (!iblockdata.isAir() || !fluid.isEmpty()) { - float f2 = Math.max(iblockdata.getBlock().getDurability(), fluid.k()); + if (optional.isPresent()) { diff --git a/Spigot-Server-Patches/Pillager-patrol-spawn-settings-and-per-player-option.patch b/Spigot-Server-Patches/Pillager-patrol-spawn-settings-and-per-player-option.patch index b3a0997d20..bad4373f6b 100644 --- a/Spigot-Server-Patches/Pillager-patrol-spawn-settings-and-per-player-option.patch +++ b/Spigot-Server-Patches/Pillager-patrol-spawn-settings-and-per-player-option.patch @@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/MobSpawnerPatrol.java @@ -0,0 +0,0 @@ import java.util.Random; - public class MobSpawnerPatrol { + public class MobSpawnerPatrol implements MobSpawner { + private int getSpawnDelay() { return a; } // Paper - OBFHELPER + private void setSpawnDelay(int spawnDelay) { this.a = spawnDelay; } // Paper - OBFHELPER @@ -61,13 +61,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public MobSpawnerPatrol() {} + @Override public int a(WorldServer worldserver, boolean flag, boolean flag1) { - if (worldserver.paperConfig.disablePillagerPatrols) return 0; // Paper + if (worldserver.paperConfig.disablePillagerPatrols || worldserver.paperConfig.patrolSpawnChance == 0) return 0; // Paper if (!flag) { return 0; } else if (!worldserver.getGameRules().getBoolean(GameRules.DO_PATROL_SPAWNING)) { -@@ -0,0 +0,0 @@ public class MobSpawnerPatrol { +@@ -0,0 +0,0 @@ public class MobSpawnerPatrol implements MobSpawner { } else { Random random = worldserver.random; diff --git a/Spigot-Server-Patches/PlayerDeathEvent-shouldDropExperience.patch b/Spigot-Server-Patches/PlayerDeathEvent-shouldDropExperience.patch index 0c8021baf9..dc279458f3 100644 --- a/Spigot-Server-Patches/PlayerDeathEvent-shouldDropExperience.patch +++ b/Spigot-Server-Patches/PlayerDeathEvent-shouldDropExperience.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 { - - this.releaseShoulderEntities(); + this.eW(); + } // SPIGOT-5478 must be called manually now - this.dropExperience(); + if (event.shouldDropExperience()) this.dropExperience(); // Paper - tie to event diff --git a/Spigot-Server-Patches/PlayerLaunchProjectileEvent.patch b/Spigot-Server-Patches/PlayerLaunchProjectileEvent.patch index 8f81dd5b77..0e9d0ac723 100644 --- a/Spigot-Server-Patches/PlayerLaunchProjectileEvent.patch +++ b/Spigot-Server-Patches/PlayerLaunchProjectileEvent.patch @@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + } - world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemEgg.i.nextFloat() * 0.4F + 0.8F)); // CraftBukkit - from above + world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemEgg.RANDOM.nextFloat() * 0.4F + 0.8F)); // CraftBukkit - from above + /* // Paper start - moved up entityhuman.b(StatisticList.ITEM_USED.b(this)); @@ -58,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + */ // Paper end - return InteractionResultWrapper.success(itemstack); + return InteractionResultWrapper.a(itemstack, world.s_()); } diff --git a/src/main/java/net/minecraft/server/ItemEnderPearl.java b/src/main/java/net/minecraft/server/ItemEnderPearl.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -91,7 +91,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } -- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.i.nextFloat() * 0.4F + 0.8F)); +- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.RANDOM.nextFloat() * 0.4F + 0.8F)); - entityhuman.getCooldownTracker().setCooldown(this, 20); - // CraftBukkit end - @@ -100,7 +100,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - itemstack.subtract(1); - } + // Paper start - moved up -+// world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.i.nextFloat() * 0.4F + 0.8F)); ++// world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.RANDOM.nextFloat() * 0.4F + 0.8F)); +// entityhuman.getCooldownTracker().setCooldown(this, 20); +// // CraftBukkit end +// @@ -108,9 +108,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +// if (!entityhuman.abilities.canInstantlyBuild) { +// itemstack.subtract(1); +// } -+ // Paper end ++ // Paper end - moved up - return InteractionResultWrapper.success(itemstack); + return InteractionResultWrapper.a(itemstack, world.s_()); } diff --git a/src/main/java/net/minecraft/server/ItemExpBottle.java b/src/main/java/net/minecraft/server/ItemExpBottle.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -120,8 +120,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); -- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.i.nextFloat() * 0.4F + 0.8F)); -+// world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.i.nextFloat() * 0.4F + 0.8F)); // Paper - moved down +- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.RANDOM.nextFloat() * 0.4F + 0.8F)); ++ //world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.RANDOM.nextFloat() * 0.4F + 0.8F)); // Paper - moved down if (!world.isClientSide) { EntityThrownExpBottle entitythrownexpbottle = new EntityThrownExpBottle(world, entityhuman); @@ -155,7 +155,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + */ // Paper end - return InteractionResultWrapper.success(itemstack); + return InteractionResultWrapper.a(itemstack, world.s_()); } diff --git a/src/main/java/net/minecraft/server/ItemLingeringPotion.java b/src/main/java/net/minecraft/server/ItemLingeringPotion.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -165,12 +165,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { -- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.i.nextFloat() * 0.4F + 0.8F)); +- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.RANDOM.nextFloat() * 0.4F + 0.8F)); - return super.a(world, entityhuman, enumhand); + // Paper start + InteractionResultWrapper wrapper = super.a(world, entityhuman, enumhand); -+ if (wrapper.getResult() != EnumInteractionResult.FAIL) -+ world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.i.nextFloat() * 0.4F + 0.8F)); ++ if (wrapper.getResult() != EnumInteractionResult.FAIL) { ++ world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.RANDOM.nextFloat() * 0.4F + 0.8F)); ++ } + return wrapper; + // Paper end } @@ -210,7 +211,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + */ // Paper end - return InteractionResultWrapper.success(itemstack); + return InteractionResultWrapper.a(itemstack, world.s_()); } diff --git a/src/main/java/net/minecraft/server/ItemSnowball.java b/src/main/java/net/minecraft/server/ItemSnowball.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -226,30 +227,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity()); + if (event.callEvent() && world.addEntity(entitysnowball)) { + if (event.shouldConsume() && !entityhuman.abilities.canInstantlyBuild) { ++ // Paper end itemstack.subtract(1); -+ } else if (entityhuman instanceof EntityPlayer) { -+ ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); ++ } else if (entityhuman instanceof EntityPlayer) { // Paper ++ ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); // Paper } -- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemSnowball.i.nextFloat() * 0.4F + 0.8F)); + world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemSnowball.RANDOM.nextFloat() * 0.4F + 0.8F)); - } else if (entityhuman instanceof EntityPlayer) { - ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); -+ world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); -+ entityhuman.b(StatisticList.ITEM_USED.b(this)); -+ } else { -+ if (entityhuman instanceof EntityPlayer) { -+ ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); -+ } -+ return new InteractionResultWrapper(EnumInteractionResult.FAIL, itemstack); ++ } else { // Paper ++ if (entityhuman instanceof EntityPlayer) ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); // Paper ++ return new InteractionResultWrapper(EnumInteractionResult.FAIL, itemstack); // Paper } } // CraftBukkit end - -- entityhuman.b(StatisticList.ITEM_USED.b(this)); -+// entityhuman.b(StatisticList.ITEM_USED.b(this)); // Paper - moved up - // CraftBukkit start - moved up - /* - if (!entityhuman.abilities.canInstantlyBuild) { diff --git a/src/main/java/net/minecraft/server/ItemSplashPotion.java b/src/main/java/net/minecraft/server/ItemSplashPotion.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ItemSplashPotion.java @@ -258,12 +250,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { -- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemSplashPotion.i.nextFloat() * 0.4F + 0.8F)); -- return super.a(world, entityhuman, enumhand); + // Paper start + InteractionResultWrapper wrapper = super.a(world, entityhuman, enumhand); -+ if (wrapper.getResult() != EnumInteractionResult.FAIL) -+ world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemSplashPotion.i.nextFloat() * 0.4F + 0.8F)); ++ if (wrapper.getResult() != EnumInteractionResult.FAIL) { + world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemSplashPotion.RANDOM.nextFloat() * 0.4F + 0.8F)); +- return super.a(world, entityhuman, enumhand); ++ } + return wrapper; + // Paper end } diff --git a/Spigot-Server-Patches/Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/Spigot-Server-Patches/Prevent-Double-PlayerChunkMap-adds-crashing-server.patch index 3a3cd7a3c4..9b69cf36ed 100644 --- a/Spigot-Server-Patches/Prevent-Double-PlayerChunkMap-adds-crashing-server.patch +++ b/Spigot-Server-Patches/Prevent-Double-PlayerChunkMap-adds-crashing-server.patch @@ -23,13 +23,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end if (!(entity instanceof EntityComplexPart)) { - if (!(entity instanceof EntityLightning)) { - EntityTypes entitytypes = entity.getEntityType(); + EntityTypes entitytypes = entity.getEntityType(); + int i = entitytypes.getChunkRange() * 16; 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 { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { } } @@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit start - SPIGOT-5278 if (entity instanceof EntityDrowned) { this.navigators.add(((EntityDrowned) entity).navigationWater); -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.navigators.add(((EntityInsentient) entity).getNavigation()); } entity.valid = true; // CraftBukkit diff --git a/Spigot-Server-Patches/Prevent-bees-loading-chunks-checking-hive-position.patch b/Spigot-Server-Patches/Prevent-bees-loading-chunks-checking-hive-position.patch index 82bb02aa0d..98f76a5752 100644 --- a/Spigot-Server-Patches/Prevent-bees-loading-chunks-checking-hive-position.patch +++ b/Spigot-Server-Patches/Prevent-bees-loading-chunks-checking-hive-position.patch @@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/n index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityBee.java +++ b/src/main/java/net/minecraft/server/EntityBee.java -@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements EntityBird { +@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB if (!this.hasHivePos()) { return false; } else { diff --git a/Spigot-Server-Patches/Prevent-consuming-the-wrong-itemstack.patch b/Spigot-Server-Patches/Prevent-consuming-the-wrong-itemstack.patch index f93da9e66e..1104879e50 100644 --- a/Spigot-Server-Patches/Prevent-consuming-the-wrong-itemstack.patch +++ b/Spigot-Server-Patches/Prevent-consuming-the-wrong-itemstack.patch @@ -9,7 +9,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 { - this.datawatcher.set(EntityLiving.ao, (byte) j); + this.datawatcher.set(EntityLiving.an, (byte) j); } - public void c(EnumHand enumhand) { @@ -22,10 +22,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - if (!itemstack.isEmpty() && !this.isHandRaised()) { + if (!itemstack.isEmpty() && !this.isHandRaised() || forceUpdate) { // Paper use override flag this.activeItem = itemstack; - this.bl = itemstack.k(); + this.bk = itemstack.k(); if (!this.world.isClientSide) { @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { - this.clearActiveItem(); + this.releaseActiveItem(); } else { if (!this.activeItem.isEmpty() && this.isHandRaised()) { + this.updateActiveItem(this.getRaisedHand(), true); // Paper @@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { this.a(this.getRaisedHand(), itemstack); // CraftBukkit end - this.dH(); + this.clearActiveItem(); - // Paper start - if the replacement is anything but the default, update the client inventory - if (this instanceof EntityPlayer && !com.google.common.base.Objects.equal(defaultReplacement, itemstack)) { + // Paper start diff --git a/Spigot-Server-Patches/Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch b/Spigot-Server-Patches/Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch index 18f6d0f99b..78f68b2fd3 100644 --- a/Spigot-Server-Patches/Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch +++ b/Spigot-Server-Patches/Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch @@ -9,12 +9,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/BehaviorSleep.java +++ b/src/main/java/net/minecraft/server/BehaviorSleep.java @@ -0,0 +0,0 @@ public class BehaviorSleep extends Behavior { - if (optional.isPresent() && worldserver.getTime() - ((MinecraftSerializableLong) optional.get()).a() < 100L) { - return false; - } else { -- IBlockData iblockdata = worldserver.getType(globalpos.getBlockPosition()); -+ IBlockData iblockdata = worldserver.getTypeIfLoaded(globalpos.getBlockPosition()); // Paper -+ if(iblockdata == null) return false; // Paper - - return globalpos.getBlockPosition().a((IPosition) entityliving.getPositionVector(), 2.0D) && iblockdata.getBlock().a(TagsBlock.BEDS) && !(Boolean) iblockdata.get(BlockBed.OCCUPIED); + } } + +- IBlockData iblockdata = worldserver.getType(globalpos.getBlockPosition()); ++ IBlockData iblockdata = worldserver.getTypeIfLoaded(globalpos.getBlockPosition()); // Paper ++ if (iblockdata == null) { return false; } // Paper + + return globalpos.getBlockPosition().a((IPosition) entityliving.getPositionVector(), 2.0D) && iblockdata.getBlock().a((Tag) TagsBlock.BEDS) && !(Boolean) iblockdata.get(BlockBed.OCCUPIED); + } diff --git a/Spigot-Server-Patches/Reduce-sync-loads.patch b/Spigot-Server-Patches/Reduce-sync-loads.patch index 6ba707db51..e2d7b7693f 100644 --- a/Spigot-Server-Patches/Reduce-sync-loads.patch +++ b/Spigot-Server-Patches/Reduce-sync-loads.patch @@ -267,7 +267,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final ThrowableWithEquals other = (ThrowableWithEquals)obj; + final StackTraceElement[] otherStackTrace = other.stacktrace; + -+ if (this.stacktrace.length != otherStackTrace.length) { ++ if (this.stacktrace.length != otherStackTrace.length || this.hash != other.hash) { + return false; + } + @@ -305,7 +305,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 for (int i1 = i; i1 <= j; ++i1) { for (int j1 = k; j1 <= l; ++j1) { -- Chunk chunk = this.getChunkProvider().getChunkAt(i1, j1, false); +- Chunk chunk = ichunkprovider.getChunkAt(i1, j1, false); + Chunk chunk = (Chunk)this.getChunkIfLoadedImmediately(i1, j1); // Paper if (chunk != null) { @@ -332,7 +332,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 { }; public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager; // Paper end @@ -343,5 +343,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - // 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) { + // Add env and gen to constructor, WorldData -> WorldDataServer + public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey resourcekey, ResourceKey resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { diff --git a/Spigot-Server-Patches/Seed-based-feature-search.patch b/Spigot-Server-Patches/Seed-based-feature-search.patch deleted file mode 100644 index 30c0ee0347..0000000000 --- a/Spigot-Server-Patches/Seed-based-feature-search.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Phoenix616 -Date: Mon, 13 Jan 2020 15:40:32 +0100 -Subject: [PATCH] Seed based feature search - -This fixes the issue where the server will load surrounding chunks up to -a radius of 100 chunks in order to search for features e.g. when running -the /locate command or for treasure maps (issue #2312). -This is done by using the same seed checking functionality that is used -by the server when generating these features before actually attempting -to load the chunk to check if a feature is available in it. - -The only downside of this is that it breaks once the seed or generator -changes but this should usually not happen. A config option to disable -this improvement is added though in case that should ever be necessary. - -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 boolean seedBasedFeatureSearch = true; -+ private void seedBasedFeatureSearch() { -+ seedBasedFeatureSearch = getBoolean("seed-based-feature-search", seedBasedFeatureSearch); -+ log("Feature search is based on seed: " + seedBasedFeatureSearch); -+ } -+ - public int maxCollisionsPerEntity; - private void maxEntityCollision() { - maxCollisionsPerEntity = getInt( "max-entity-collisions", this.spigotConfig.getInt("max-entity-collisions", 8) ); -diff --git a/src/main/java/net/minecraft/server/BiomeManager.java b/src/main/java/net/minecraft/server/BiomeManager.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BiomeManager.java -+++ b/src/main/java/net/minecraft/server/BiomeManager.java -@@ -0,0 +0,0 @@ public class BiomeManager { - this.c = genlayerzoomer; - } - -+ public BiomeManager withProvider(WorldChunkManager worldchunkmanager) { return a(worldchunkmanager); } // Paper - OBFHELPER - public BiomeManager a(WorldChunkManager worldchunkmanager) { - return new BiomeManager(worldchunkmanager, this.b, this.c); - } - -+ public BiomeBase getBiome(BlockPosition blockposition) { return a(blockposition); } // Paper - OBFHELPER - public BiomeBase a(BlockPosition blockposition) { - return this.c.a(this.b, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.a); - } -diff --git a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java -+++ b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java -@@ -0,0 +0,0 @@ public class ChunkCoordIntPair { - } - } - -+ public int getBlockX() { return d(); } // Paper - OBFHELPER - public int d() { - return this.x << 4; - } - -+ public int getBlockZ() { return e(); } // Paper - OBFHELPER - public int e() { - return this.z << 4; - } -diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/StructureGenerator.java -+++ b/src/main/java/net/minecraft/server/StructureGenerator.java -@@ -0,0 +0,0 @@ public abstract class StructureGenerator - if (flag1 || flag2) { - ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, seededrandom, j, k, i1, j1); - if (!world.getWorldBorder().isChunkInBounds(chunkcoordintpair.x, chunkcoordintpair.z)) { continue; } // Paper -+ // Paper start - seed based feature search -+ if (world.paperConfig.seedBasedFeatureSearch) { -+ BiomeManager biomeManager = world.getBiomeManager().withProvider(chunkgenerator.getWorldChunkManager()); -+ BiomeBase biomeBase = biomeManager.getBiome(new BlockPosition(chunkcoordintpair.getBlockX() + 9, 0, chunkcoordintpair.getBlockZ() + 9)); -+ if (!shouldGenerate(biomeManager, chunkgenerator, seededrandom, chunkcoordintpair.x, chunkcoordintpair.z, biomeBase)) { -+ continue; -+ } -+ } -+ // Paper end - StructureStart structurestart = world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, ChunkStatus.STRUCTURE_STARTS).a(this.b()); - - if (structurestart != null && structurestart.e()) { -@@ -0,0 +0,0 @@ public abstract class StructureGenerator - return new ChunkCoordIntPair(i + k, j + l); - } - -+ public boolean shouldGenerate(BiomeManager biomemanager, ChunkGenerator chunkgenerator, Random random, int chunkX, int chunkZ, BiomeBase biomebase) { return a(biomemanager, chunkgenerator, random, chunkX, chunkZ, biomebase); } // Paper - OBFHELPER - public abstract boolean a(BiomeManager biomemanager, ChunkGenerator chunkgenerator, Random random, int i, int j, BiomeBase biomebase); - - public abstract StructureGenerator.a a(); -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 { - return this.methodProfiler; - } - -- @Override -- public BiomeManager d() { -+ public BiomeManager getBiomeManager() { return d(); } // Paper - OBFHELPER -+ @Override public BiomeManager d() { - return this.biomeManager; - } - } diff --git a/Spigot-Server-Patches/Synchronize-DataPaletteBlock-instead-of-ReentrantLoc.patch b/Spigot-Server-Patches/Synchronize-DataPaletteBlock-instead-of-ReentrantLoc.patch index 548f86bdf4..6599ac8f3e 100644 --- a/Spigot-Server-Patches/Synchronize-DataPaletteBlock-instead-of-ReentrantLoc.patch +++ b/Spigot-Server-Patches/Synchronize-DataPaletteBlock-instead-of-ReentrantLoc.patch @@ -88,7 +88,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - public void a(NBTTagList nbttaglist, long[] along) { + public synchronized void a(NBTTagList nbttaglist, long[] along) { // Paper - synchronize this.a(); - int i = Math.max(4, MathHelper.d(nbttaglist.size())); + int i = Math.max(4, MathHelper.e(nbttaglist.size())); @@ -0,0 +0,0 @@ public class DataPaletteBlock implements DataPaletteExpandable { this.b(); diff --git a/Spigot-Server-Patches/Use-ChunkStatus-cache-when-saving-protochunks.patch b/Spigot-Server-Patches/Use-ChunkStatus-cache-when-saving-protochunks.patch deleted file mode 100644 index 0b162327c6..0000000000 --- a/Spigot-Server-Patches/Use-ChunkStatus-cache-when-saving-protochunks.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Sat, 22 Jun 2019 04:20:47 -0700 -Subject: [PATCH] Use ChunkStatus cache when saving protochunks - -The cache should contain the chunk status when saving. If not it -will load it. - -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 { - NBTTagCompound nbttagcompound; - - if (chunkstatus.getType() != ChunkStatus.Type.LEVELCHUNK) { -- nbttagcompound = this.readChunkData(chunkcoordintpair); -- if (nbttagcompound != null && ChunkRegionLoader.a(nbttagcompound) == ChunkStatus.Type.LEVELCHUNK) { -+ // Paper start - Optimize save by using status cache -+ ChunkStatus statusOnDisk = this.getChunkStatusOnDisk(chunkcoordintpair); -+ if (statusOnDisk != null && statusOnDisk.getType() == ChunkStatus.Type.LEVELCHUNK) { -+ // Paper end - return false; - } - diff --git a/Spigot-Server-Patches/Use-getChunkIfLoadedImmediately-in-places.patch b/Spigot-Server-Patches/Use-getChunkIfLoadedImmediately-in-places.patch index 48fd517b67..553fb38569 100644 --- a/Spigot-Server-Patches/Use-getChunkIfLoadedImmediately-in-places.patch +++ b/Spigot-Server-Patches/Use-getChunkIfLoadedImmediately-in-places.patch @@ -25,39 +25,35 @@ 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 { + return (CraftServer) Bukkit.getServer(); } - public Chunk getChunkIfLoaded(int x, int z) { -- return ((ChunkProviderServer) this.chunkProvider).getChunkAt(x, z, false); -+ return ((ChunkProviderServer) this.chunkProvider).getChunkAtIfLoadedImmediately(x, z); // Paper - } + // Paper start + @Override + public boolean isChunkLoaded(int x, int z) { -+ return getChunkIfLoaded(x, z) != null; ++ return ((WorldServer)this).getChunkIfLoaded(x, z) != null; + } -+ -+ + // Paper end - - protected World(WorldData worlddata, DimensionManager dimensionmanager, java.util.concurrent.Executor executor, BiFunction bifunction, GameProfilerFiller gameprofilerfiller, boolean flag, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { // Paper - executor - this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot ++ + protected World(WorldDataMutable worlddatamutable, ResourceKey resourcekey, ResourceKey resourcekey1, DimensionManager dimensionmanager, Supplier supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env, java.util.concurrent.Executor executor) { + this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot + this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig((((WorldDataServer)worlddatamutable).getName()), this.spigotConfig); // Paper @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { } - public boolean n(BlockPosition blockposition) { -- return isOutsideWorld(blockposition) ? false : this.chunkProvider.b(blockposition.getX() >> 4, blockposition.getZ() >> 4); + public boolean p(BlockPosition blockposition) { +- return isOutsideWorld(blockposition) ? false : this.getChunkProvider().b(blockposition.getX() >> 4, blockposition.getZ() >> 4); + return isOutsideWorld(blockposition) ? false : isChunkLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); // Paper } - public boolean a(BlockPosition blockposition, Entity entity) { + public boolean a(BlockPosition blockposition, Entity entity, EnumDirection enumdirection) { if (isOutsideWorld(blockposition)) { return false; } else { - IChunkAccess ichunkaccess = this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4, ChunkStatus.FULL, false); + IChunkAccess ichunkaccess = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); // Paper - return ichunkaccess == null ? false : ichunkaccess.getType(blockposition).a((IBlockAccess) this, blockposition, entity); + return ichunkaccess == null ? false : ichunkaccess.getType(blockposition).a((IBlockAccess) this, blockposition, entity, enumdirection); } @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { @@ -68,6 +64,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (chunk != null) { chunk.a(oclass, axisalignedbb, list, predicate); +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 Chunk getChunkIfLoaded(int x, int z) { +- return this.chunkProvider.getChunkAt(x, z, false); ++ return this.chunkProvider.getChunkAtIfLoadedImmediately(x, z); // Paper + } + + // Paper start - Asynchronous IO diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java diff --git a/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch b/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch index ba76ab638e..f3e456e258 100644 --- a/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch +++ b/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch @@ -549,12 +549,12 @@ 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 @@ public class ChunkProviderServer extends IChunkProvider { + this.world.getMethodProfiler().enter("naturalSpawnCount"); this.world.timings.countNaturalMobs.startTiming(); // Paper - timings int l = this.chunkMapDistance.b(); - EnumCreatureType[] aenumcreaturetype = EnumCreatureType.values(); -- Object2IntMap object2intmap = this.world.l(); +- SpawnerCreature.d spawnercreature_d = SpawnerCreature.a(l, this.world.z(), this::a); + // Paper start - per player mob spawning -+ int[] worldMobCount; ++ SpawnerCreature.d spawnercreature_d; // moved down + if (this.playerChunkMap.playerMobDistanceMap != null) { + // update distance map + this.world.timings.playerMobDistanceMapUpdate.startTiming(); @@ -564,40 +564,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + for (EntityPlayer player : this.world.players) { + Arrays.fill(player.mobCounts, 0); + } -+ worldMobCount = this.world.countMobs(true); ++ spawnercreature_d = SpawnerCreature.countMobs(l, this.world.z(), this::a, true); + } else { -+ worldMobCount = this.world.countMobs(false); ++ spawnercreature_d = SpawnerCreature.countMobs(l, this.world.z(), this::a, false); + } + // Paper end - this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings - this.world.getMethodProfiler().exit(); -@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - if (enumcreaturetype != EnumCreatureType.MISC && (!enumcreaturetype.c() || this.allowAnimals) && (enumcreaturetype.c() || this.allowMonsters) && (!enumcreaturetype.d() || flag2)) { - int k1 = limit * l / ChunkProviderServer.b; // CraftBukkit - use per-world limits -- if (object2intmap.getInt(enumcreaturetype) <= k1) { -- SpawnerCreature.a(enumcreaturetype, this.world, chunk, blockposition); -+ // Paper start - only allow spawns upto the limit per chunk and update count afterwards -+ int currEntityCount = worldMobCount[enumcreaturetype.ordinal()]; -+ int difference = k1 - currEntityCount; -+ -+ if (this.world.paperConfig.perPlayerMobSpawns) { -+ int minDiff = Integer.MAX_VALUE; -+ for (EntityPlayer entityplayer : this.playerChunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) { -+ minDiff = Math.min(limit - this.playerChunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff); -+ } -+ difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff; -+ } -+ -+ if (difference > 0) { -+ int spawnCount = SpawnerCreature.spawnMobs(enumcreaturetype, this.world, chunk, blockposition, difference, -+ this.world.paperConfig.perPlayerMobSpawns ? this.playerChunkMap::updatePlayerMobTypeMap : null); -+ worldMobCount[enumcreaturetype.ordinal()] += spawnCount; -+ // Paper end - } - } - } + this.p = spawnercreature_d; diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java @@ -626,30 +600,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } -+ public SectionPosition getPlayerMapSection() { return this.K(); } // Paper - OBFHELPER - public SectionPosition K() { - return this.cs; ++ public final SectionPosition getPlayerMapSection() { return this.N(); } // Paper - OBFHELPER + public SectionPosition N() { + return this.cq; } diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityTypes.java +++ b/src/main/java/net/minecraft/server/EntityTypes.java @@ -0,0 +0,0 @@ public class EntityTypes { - return this.bf; + return this.bk; } -+ public EnumCreatureType getEnumCreatureType() { return this.e(); } // Paper - OBFHELPER ++ public final EnumCreatureType getEnumCreatureType() { return this.e(); } // Paper - OBFHELPER public EnumCreatureType e() { - return this.bb; + return this.bf; } 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 { - private final PlayerMap playerMap; public final Int2ObjectMap trackedEntities; - private final Queue z; + private final Long2ByteMap z; + private final Queue A; private final Queue getUnloadQueueTasks() { return this.A; } // Paper - OBFHELPER - private int viewDistance; + int viewDistance; // Paper - private -> package private + public final com.destroystokyo.paper.util.PlayerMobDistanceMap playerMobDistanceMap; // Paper @@ -658,7 +632,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public final CallbackExecutor callbackExecutor = new CallbackExecutor(); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.l = supplier; - this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper + this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper this.setViewDistance(i); + this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper + } @@ -685,117 +659,167 @@ diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/SpawnerCreature.java +++ b/src/main/java/net/minecraft/server/SpawnerCreature.java -@@ -0,0 +0,0 @@ package net.minecraft.server; - import java.util.List; - import java.util.Objects; - import java.util.Random; -+import java.util.function.Consumer; // Paper - import javax.annotation.Nullable; - import org.apache.logging.log4j.LogManager; - import org.apache.logging.log4j.Logger; @@ -0,0 +0,0 @@ public final class SpawnerCreature { + }); - private static final Logger LOGGER = LogManager.getLogger(); - -+ // Paper start - add maxSpawns parameter and return spawned mobs - public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, BlockPosition blockposition) { -+ spawnMobs(enumcreaturetype, worldserver, chunk, blockposition, Integer.MAX_VALUE, null); + public static SpawnerCreature.d a(int i, Iterable iterable, SpawnerCreature.b spawnercreature_b) { ++ // Paper start - add countMobs parameter ++ return countMobs(i, iterable, spawnercreature_b, false); + } -+ public static int spawnMobs(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, BlockPosition blockposition, int maxSpawns, Consumer trackEntity) { -+ // Paper end - ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator(); -- int i = 0; -+ int i = 0; // Paper - force diff on name change - BlockPosition blockposition1 = getRandomPosition(worldserver, chunk); - int j = blockposition1.getX(); - int k = blockposition1.getY(); -@@ -0,0 +0,0 @@ public final class SpawnerCreature { - ); - if (!event.callEvent()) { - if (event.shouldAbortSpawn()) { -- return; -+ return i; // Paper - } - ++i2; - continue; -@@ -0,0 +0,0 @@ public final class SpawnerCreature { - } catch (Exception exception) { - SpawnerCreature.LOGGER.warn("Failed to create mob", exception); - ServerInternalException.reportInternalException(exception); // Paper -- return; -+ return i; // Paper - } - - entityinsentient.setPositionRotation((double) f, (double) k, (double) f1, worldserver.random.nextFloat() * 360.0F, 0.0F); -@@ -0,0 +0,0 @@ public final class SpawnerCreature { - groupdataentity = entityinsentient.prepare(worldserver, worldserver.getDamageScaler(new BlockPosition(entityinsentient)), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null); - // CraftBukkit start - if (worldserver.addEntity(entityinsentient, SpawnReason.NATURAL)) { -- ++i; -+ ++i; // Paper - force diff on name change - ++i2; -+ if (trackEntity != null) { -+ trackEntity.accept(entityinsentient); // Paper -+ } - } -+ if (i >= maxSpawns) { return i; } // Paper - // CraftBukkit end - if (i >= entityinsentient.getMaxSpawnGroup()) { -- return; -+ return i; // Paper - } - - if (entityinsentient.c(i2)) { ++ public static SpawnerCreature.d countMobs(int i, Iterable iterable, SpawnerCreature.b spawnercreature_b, boolean countMobs) { ++ // Paper end - add countMobs parameter + SpawnerCreatureProbabilities spawnercreatureprobabilities = new SpawnerCreatureProbabilities(); + Object2IntOpenHashMap object2intopenhashmap = new Object2IntOpenHashMap(); + Iterator iterator = iterable.iterator(); @@ -0,0 +0,0 @@ public final class SpawnerCreature { + } + object2intopenhashmap.addTo(enumcreaturetype, 1); ++ // Paper start ++ if (countMobs) { ++ ((WorldServer)chunk.world).getChunkProvider().playerChunkMap.updatePlayerMobTypeMap(entity); ++ } ++ // Paper end + }); } } -+ return i; // Paper - } +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + continue; + } - @Nullable -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 { - } - - public Object2IntMap l() { -- Object2IntMap object2intmap = new Object2IntOpenHashMap(); -+ // Paper start -+ int[] values = this.countMobs(false); -+ EnumCreatureType[] byId = EnumCreatureType.values(); -+ Object2IntMap ret = new Object2IntOpenHashMap<>(); ++ // Paper start - only allow spawns upto the limit per chunk and update count afterwards ++ int currEntityCount = spawnercreature_d.getEntityCountsByType().getInt(enumcreaturetype); ++ int k1 = limit * spawnercreature_d.getSpawnerChunks() / SpawnerCreature.b; ++ int difference = k1 - currEntityCount; + -+ for (int i = 0, len = values.length; i < len; ++i) { -+ ret.put(byId[i], values[i]); -+ } -+ -+ return ret; -+ } -+ public int[] countMobs(boolean updatePlayerCounts) { -+ int[] ret = new int[EntityPlayer.ENUMCREATURETYPE_TOTAL_ENUMS]; -+ // Paper end - ObjectIterator objectiterator = this.entitiesById.values().iterator(); - - while (objectiterator.hasNext()) { -@@ -0,0 +0,0 @@ public class WorldServer extends World { - continue; - } - // Paper end -- object2intmap.mergeInt(enumcreaturetype, 1, Integer::sum); -+ // Paper start - rework mob spawning -+ if (updatePlayerCounts) { -+ this.getChunkProvider().playerChunkMap.updatePlayerMobTypeMap(entity); ++ if (worldserver.paperConfig.perPlayerMobSpawns) { ++ int minDiff = Integer.MAX_VALUE; ++ for (EntityPlayer entityplayer : worldserver.getChunkProvider().playerChunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) { ++ minDiff = Math.min(limit - worldserver.getChunkProvider().playerChunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff); + } -+ ++ret[enumcreaturetype.ordinal()]; -+ // Paper end ++ difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff; ++ } ++ // Paper end ++ ++ if (difference > 0) { // Paper + if ((flag || !enumcreaturetype.d()) && (flag1 || enumcreaturetype.d()) && (flag2 || !enumcreaturetype.e()) && spawnercreature_d.a(enumcreaturetype, limit)) { + // CraftBukkit end +- a(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> { ++ int spawnCount = spawnMobs(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> { + return spawnercreature_d.a(entitytypes, blockposition, ichunkaccess); + }, (entityinsentient, ichunkaccess) -> { + spawnercreature_d.a(entityinsentient, ichunkaccess); ++ }, ++ limit, worldserver.paperConfig.perPlayerMobSpawns ? worldserver.getChunkProvider().playerChunkMap::updatePlayerMobTypeMap : null); ++ spawnercreature_d.getEntityCountsByType().mergeInt(enumcreaturetype, 0, (keyInMap, valueInMap) -> { ++ return Integer.valueOf(spawnCount + valueInMap.intValue()); + }); ++ } // Paper } } -- return object2intmap; -+ return ret; +@@ -0,0 +0,0 @@ public final class SpawnerCreature { } - @Override + public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a) { ++ // Paper start - add parameters and int ret type ++ spawnMobs(enumcreaturetype, worldserver, chunk, spawnercreature_c, spawnercreature_a, Integer.MAX_VALUE, null); ++ } ++ public static int spawnMobs(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a, int maxSpawns, Consumer trackEntity) { ++ // Paper end - add parameters and int ret type + BlockPosition blockposition = getRandomPosition(worldserver, chunk); + + if (blockposition.getY() >= 1) { +- a(enumcreaturetype, worldserver, (IChunkAccess) chunk, blockposition, spawnercreature_c, spawnercreature_a); ++ return spawnMobsInternal(enumcreaturetype, worldserver, (IChunkAccess) chunk, blockposition, spawnercreature_c, spawnercreature_a, maxSpawns, trackEntity); + } ++ return 0; // Paper + } + + public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition blockposition, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a) { ++ // Paper start - add maxSpawns parameter and return spawned mobs ++ spawnMobsInternal(enumcreaturetype, worldserver, ichunkaccess, blockposition, spawnercreature_c, spawnercreature_a, Integer.MAX_VALUE, null); ++ } ++ public static int spawnMobsInternal(EnumCreatureType enumcreaturetype, WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition blockposition, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a, int maxSpawns, Consumer trackEntity) { ++ // Paper end - add maxSpawns parameter and return spawned mobs + StructureManager structuremanager = worldserver.getStructureManager(); + ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator(); + int i = blockposition.getY(); + IBlockData iblockdata = worldserver.getTypeIfLoadedAndInBounds(blockposition); // Paper - don't load chunks for mob spawn ++ int j = 0; // Paper - moved up + + 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; ++ // Paper - moved up + int k = 0; + + while (k < 3) { +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + // Paper start + Boolean doSpawning = a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2); + if (doSpawning == null) { +- return; ++ return j; // Paper + } + if (doSpawning.booleanValue() && spawnercreature_c.test(biomebase_biomemeta.c, blockposition_mutableblockposition, ichunkaccess)) { // Paper end + EntityInsentient entityinsentient = a(worldserver, biomebase_biomemeta.c); + + if (entityinsentient == null) { +- return; ++ return j; // Paper + } + + entityinsentient.setPositionRotation(d0, (double) i, d1, worldserver.random.nextFloat() * 360.0F, 0.0F); +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + groupdataentity = entityinsentient.prepare(worldserver, worldserver.getDamageScaler(entityinsentient.getChunkCoordinates()), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null); + // CraftBukkit start + if (worldserver.addEntity(entityinsentient, SpawnReason.NATURAL)) { +- ++j; ++ ++j; // Paper - force diff on name change - we expect this to be the total amount spawned + ++k1; + spawnercreature_a.run(entityinsentient, ichunkaccess); ++ // Paper start ++ if (trackEntity != null) { ++ trackEntity.accept(entityinsentient); ++ } ++ // Paper end + } + // CraftBukkit end +- if (j >= entityinsentient.getMaxSpawnGroup()) { +- return; ++ if (j >= entityinsentient.getMaxSpawnGroup() || j >= maxSpawns) { // Paper ++ return j; // Paper + } + + if (entityinsentient.c(k1)) { +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + } + + } ++ return j; // Paper + } + + private static boolean a(WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) { +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + + public static class d { + +- private final int a; ++ private final int a; final int getSpawnerChunks() { return this.a; } // Paper - OBFHELPER + private final Object2IntOpenHashMap b; + private final SpawnerCreatureProbabilities c; +- private final Object2IntMap d; ++ private final Object2IntMap d; final Object2IntMap getEntityCountsByType() { return this.d; } // Paper - OBFHELPER + @Nullable + private BlockPosition e; + @Nullable +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + + // CraftBukkit start + private boolean a(EnumCreatureType enumcreaturetype, int limit) { +- int i = limit * this.a / SpawnerCreature.b; ++ int i = limit * this.a / SpawnerCreature.b; // Paper - diff on change, needed in the spawn method + // CraftBukkit end + + return this.b.getInt(enumcreaturetype) < i; diff --git a/Spigot-Server-Patches/incremental-chunk-saving.patch b/Spigot-Server-Patches/incremental-chunk-saving.patch new file mode 100644 index 0000000000..56e383a305 --- /dev/null +++ b/Spigot-Server-Patches/incremental-chunk-saving.patch @@ -0,0 +1,319 @@ +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 java.util.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 implements GeneratorAccessSeed { + return !this.server.a(this, blockposition, entityhuman) && this.getWorldBorder().a(blockposition); + } + ++ // Paper start - derived from below ++ public void saveIncrementally(boolean doFull) { ++ 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 ++ ++ ++ // Copied from save() ++ // CraftBukkit start - moved from MinecraftServer.saveChunks ++ if (doFull) { // Paper ++ WorldServer worldserver1 = this; ++ ++ worldDataServer.a(worldserver1.getWorldBorder().t()); ++ worldDataServer.setCustomBossEvents(this.server.getBossBattleCustomData().save()); ++ convertable.a(this.server.f, this.worldDataServer, this.server.getPlayerList().save()); ++ } ++ // CraftBukkit end ++ } ++ } ++ // Paper end ++ + public void save(@Nullable IProgressUpdate iprogressupdate, boolean flag, boolean flag1) { + 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 // Paper + try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper + if (iprogressupdate != null) { + iprogressupdate.a(new ChatMessage("menu.savingLevel")); +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { + // CraftBukkit end + } + ++ private void saveData() { this.ag(); } // Paper - OBFHELPER + private void ag() { + if (this.dragonBattle != null) { + this.server.getSaveData().a(this.dragonBattle.a()); diff --git a/scripts/importmcdev.sh b/scripts/importmcdev.sh index 6fd55da94e..06ad7ab9b9 100755 --- a/scripts/importmcdev.sh +++ b/scripts/importmcdev.sh @@ -94,7 +94,7 @@ done # import FileName - +import VoxelShapeSpliterator ######################################################## ######################################################## From cfd598512a66aff5056bdd00cdb13169c5d5279d Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 25 Jun 2020 18:53:21 -0700 Subject: [PATCH 11/91] even even even even even even more work --- SHIT_TO_CHECK.md | 3 +- ...PlayerAttackEntityCooldownResetEvent.patch | 3 +- ...ntom-creative-and-insomniac-controls.patch | 12 +- .../Add-tick-times-API-and-mspt-command.patch | 12 +- .../Allow-sleeping-players-to-float.patch | 23 ---- .../Broadcast-join-message-to-console.patch | 2 +- ...ions-until-after-entity-ticking-is-d.patch | 10 +- ...layer-is-attempted-to-be-removed-fro.patch | 6 +- ...t-fire-BlockFade-on-worldgen-threads.patch | 15 ++- ...move-existing-players-to-world-spawn.patch | 25 ++-- .../Don-t-tick-dead-players.patch | 4 +- ...-Chunk-Post-Processing-deadlock-risk.patch | 4 +- ...g-Broken-behavior-of-PlayerJoinEvent.patch | 2 +- ...m-duplication-issues-and-teleport-is.patch | 12 +- .../Implement-Brigadier-Mojang-API.patch | 30 ++--- .../Implement-Mob-Goal-API.patch | 14 +- .../Implement-Player-Client-Options-API.patch | 44 +++---- .../Improved-Watchdog-Support.patch | 57 ++++---- .../Increase-Light-Queue-Size.patch | 2 +- ...Load-Chunks-for-Login-Asynchronously.patch | 51 ++++++-- ...asks-Speed-up-processing-of-chunk-lo.patch | 52 ++++---- ...pawn-point-if-spawn-in-unloaded-worl.patch | 10 +- ...No-Tick-view-distance-implementation.patch | 40 +++--- ...imise-entity-hard-collision-checking.patch | 58 +++++---- ...oviderServer-s-chunk-level-checking-.patch | 17 +-- ...ptimize-Collision-to-not-load-chunks.patch | 122 +++++++++++------- .../Optimize-Pathfinding.patch | 2 +- ...hunkMap-memory-use-for-visibleChunks.patch | 8 +- ...-isOutsideRange-to-use-distance-maps.patch | 65 +++++----- .../Remove-streams-from-MinecraftKey.patch | 47 ------- .../Remove-streams-from-Mob-AI-System.patch | 24 ++-- ...-teleport-command-to-valid-locations.patch | 8 +- ...tance-map-to-optimise-entity-tracker.patch | 42 ++++-- .../Villager-Restocks-API.patch | 2 +- 34 files changed, 420 insertions(+), 408 deletions(-) delete mode 100644 Spigot-Server-Patches/Allow-sleeping-players-to-float.patch delete mode 100644 Spigot-Server-Patches/Remove-streams-from-MinecraftKey.patch diff --git a/SHIT_TO_CHECK.md b/SHIT_TO_CHECK.md index 024d8cc9af..98771cea37 100644 --- a/SHIT_TO_CHECK.md +++ b/SHIT_TO_CHECK.md @@ -5,4 +5,5 @@ * 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 * Make sure the flat bedrock setting doesn't do anything stupid -* Check DataBits foreach \ No newline at end of file +* Check DataBits foreach +* Update MobGoalHelper \ No newline at end of file diff --git a/Spigot-Server-Patches/Add-PlayerAttackEntityCooldownResetEvent.patch b/Spigot-Server-Patches/Add-PlayerAttackEntityCooldownResetEvent.patch index 356defd044..436e2e8ff6 100644 --- a/Spigot-Server-Patches/Add-PlayerAttackEntityCooldownResetEvent.patch +++ b/Spigot-Server-Patches/Add-PlayerAttackEntityCooldownResetEvent.patch @@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, hardHatModifier, blockingModifier, armorModifier, resistanceModifier, magicModifier, absorptionModifier, hardHat, blocking, armor, resistance, magic, absorption); if (damagesource.getEntity() instanceof EntityHuman) { -- ((EntityHuman) damagesource.getEntity()).ey(); // Moved from EntityHuman in order to make the cooldown reset get called after the damage event is fired +- ((EntityHuman) damagesource.getEntity()).resetAttackCooldown(); // Moved from EntityHuman in order to make the cooldown reset get called after the damage event is fired + // Paper start - PlayerAttackEntityCooldownResetEvent + if (damagesource.getEntity() instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer) damagesource.getEntity(); @@ -23,7 +23,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + ((EntityHuman) damagesource.getEntity()).resetCooldown(); + } + // Paper end -+ } if (event.isCancelled()) { return false; diff --git a/Spigot-Server-Patches/Add-phantom-creative-and-insomniac-controls.patch b/Spigot-Server-Patches/Add-phantom-creative-and-insomniac-controls.patch index e5523e2267..1d2990ac34 100644 --- a/Spigot-Server-Patches/Add-phantom-creative-and-insomniac-controls.patch +++ b/Spigot-Server-Patches/Add-phantom-creative-and-insomniac-controls.patch @@ -37,23 +37,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/IEntitySelector.java +++ b/src/main/java/net/minecraft/server/IEntitySelector.java @@ -0,0 +0,0 @@ public final class IEntitySelector { - public static final Predicate f = (entity) -> { + public static final Predicate g = (entity) -> { return !entity.isSpectator(); }; + public static Predicate isInsomniac = (player) -> MathHelper.clamp(((EntityPlayer) player).getStatisticManager().getStatisticValue(StatisticList.CUSTOM.get(StatisticList.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper - public static Predicate a(double d0, double d1, double d2, double d3) { - double d4 = d3 * d3; + // Paper start + public static final Predicate affectsSpawning = (entity) -> { diff --git a/src/main/java/net/minecraft/server/MobSpawnerPhantom.java b/src/main/java/net/minecraft/server/MobSpawnerPhantom.java 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 { while (iterator.hasNext()) { EntityHuman entityhuman = (EntityHuman) iterator.next(); - if (!entityhuman.isSpectator()) { + if (!entityhuman.isSpectator() && (!worldserver.paperConfig.phantomIgnoreCreative || !entityhuman.isCreative())) { // Paper - BlockPosition blockposition = new BlockPosition(entityhuman); + BlockPosition blockposition = entityhuman.getChunkCoordinates(); - if (!worldserver.worldProvider.f() || blockposition.getY() >= worldserver.getSeaLevel() && worldserver.f(blockposition)) { + if (!worldserver.getDimensionManager().hasSkyLight() || blockposition.getY() >= worldserver.getSeaLevel() && worldserver.f(blockposition)) { diff --git a/Spigot-Server-Patches/Add-tick-times-API-and-mspt-command.patch b/Spigot-Server-Patches/Add-tick-times-API-and-mspt-command.patch index ef2016f31a..b070d28109 100644 --- a/Spigot-Server-Patches/Add-tick-times-API-and-mspt-command.patch +++ b/Spigot-Server-Patches/Add-tick-times-API-and-mspt-command.patch @@ -91,19 +91,19 @@ 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 -Date: Sun, 19 Apr 2020 12:25:20 +0200 -Subject: [PATCH] Allow sleeping players to float - -This change lets players who are in their bed have a position which is above -ground for a longer period of time. This is because of the server not setting -their position to the ground/exit location when entering the bed, resulting in -the server believing they're still in the air. - -diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -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 @@ public class PlayerConnection implements PacketListenerPlayIn { - this.player.setLocation(this.l, this.m, this.n, this.player.yaw, this.player.pitch); - ++this.e; - this.processedMovePackets = this.receivedMovePackets; -- if (this.B) { -+ if (this.B && !this.player.isSleeping()) { // Paper - #3176 Allow sleeping players to float - if (++this.C > 80) { - PlayerConnection.LOGGER.warn("{} was kicked for floating too long!", this.player.getDisplayName().getString()); - this.disconnect(com.destroystokyo.paper.PaperConfig.flyingKickPlayerMessage); // Paper - use configurable kick message diff --git a/Spigot-Server-Patches/Broadcast-join-message-to-console.patch b/Spigot-Server-Patches/Broadcast-join-message-to-console.patch index 9ca906ecdf..58ea9674fd 100644 --- a/Spigot-Server-Patches/Broadcast-join-message-to-console.patch +++ b/Spigot-Server-Patches/Broadcast-join-message-to-console.patch @@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (joinMessage != null && joinMessage.length() > 0) { - for (IChatBaseComponent line : org.bukkit.craftbukkit.util.CraftChatMessage.fromString(joinMessage)) { -- server.getPlayerList().sendAll(new PacketPlayOutChat(line)); +- server.getPlayerList().sendAll(new PacketPlayOutChat(line, ChatMessageType.SYSTEM, SystemUtils.b)); - } + // Paper start - Removed sendAll for loop and broadcasted to console also + server.getPlayerList().sendMessage(CraftChatMessage.fromString(joinMessage)); diff --git a/Spigot-Server-Patches/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch b/Spigot-Server-Patches/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch index 4abf658465..533cad8881 100644 --- a/Spigot-Server-Patches/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch +++ b/Spigot-Server-Patches/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch @@ -9,9 +9,9 @@ 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 { - private final Queue entitiesToAdd = Queues.newArrayDeque(); +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { public final List players = Lists.newArrayList(); // Paper - private -> public + public final ChunkProviderServer chunkProvider; // Paper - public boolean tickingEntities; + // Paper start + List afterEntityTickingTasks = Lists.newArrayList(); @@ -24,9 +24,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end private final MinecraftServer server; - private final WorldNBTStorage dataManager; + public final WorldDataServer worldDataServer; // CraftBukkit - type public boolean savingDisabled; -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { timings.entityTick.stopTiming(); // Spigot this.tickingEntities = false; @@ -42,4 +42,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end this.getMinecraftServer().midTickLoadChunks(); // Paper - try (co.aikar.timings.Timing ignored = this.timings.newEntities.startTiming()) { // Paper - timings + Entity entity2; diff --git a/Spigot-Server-Patches/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch b/Spigot-Server-Patches/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch index b79282d73a..9ad6a06d86 100644 --- a/Spigot-Server-Patches/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch +++ b/Spigot-Server-Patches/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch @@ -11,7 +11,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 { - long i = sectionposition.u().pair(); + long i = sectionposition.r().pair(); ObjectSet objectset = (ObjectSet) this.c.get(i); - objectset.remove(entityplayer); @@ -19,5 +19,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (objectset != null) objectset.remove(entityplayer); // Paper - some state corruption happens here, don't crash, clean up gracefully. + if (objectset == null || objectset.isEmpty()) { // Paper this.c.remove(i); - this.f.b(i, Integer.MAX_VALUE, false); - this.g.b(i, Integer.MAX_VALUE, false); + this.f.update(i, Integer.MAX_VALUE, false); + this.g.update(i, Integer.MAX_VALUE, false); diff --git a/Spigot-Server-Patches/Don-t-fire-BlockFade-on-worldgen-threads.patch b/Spigot-Server-Patches/Don-t-fire-BlockFade-on-worldgen-threads.patch index 124b393bf1..da24b21125 100644 --- a/Spigot-Server-Patches/Don-t-fire-BlockFade-on-worldgen-threads.patch +++ b/Spigot-Server-Patches/Don-t-fire-BlockFade-on-worldgen-threads.patch @@ -9,11 +9,20 @@ diff --git a/src/main/java/net/minecraft/server/BlockFire.java b/src/main/java/n index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockFire.java +++ b/src/main/java/net/minecraft/server/BlockFire.java -@@ -0,0 +0,0 @@ public class BlockFire extends Block { +@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { // CraftBukkit start -+ if (!(generatoraccess instanceof WorldServer)) return this.canPlace(iblockdata, generatoraccess, blockposition) ? (IBlockData) this.a((IBlockAccess) generatoraccess, blockposition).set(BlockFire.AGE, iblockdata.get(BlockFire.AGE)) : Blocks.AIR.getBlockData(); // Paper - don't fire events in world generation - if (!iblockdata.canPlace(generatoraccess, blockposition)) { ++ if (!(generatoraccess instanceof WorldServer)) return this.canPlace(iblockdata, generatoraccess, blockposition) ? (IBlockData) this.a(generatoraccess, blockposition, (Integer) iblockdata.get(BlockFire.AGE)) : Blocks.AIR.getBlockData(); // Paper - don't fire events in world generation + if (!this.canPlace(iblockdata, generatoraccess, blockposition)) { CraftBlockState blockState = CraftBlockState.getBlockState(generatoraccess, blockposition); blockState.setData(Blocks.AIR.getBlockData()); +@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { + return blockState.getHandle(); + } + } +- return this.a(generatoraccess, blockposition, (Integer) iblockdata.get(BlockFire.AGE)); ++ return this.a(generatoraccess, blockposition, (Integer) iblockdata.get(BlockFire.AGE)); // Paper - diff on change, see "don't fire events in world generation" + // CraftBukkit end + } + diff --git a/Spigot-Server-Patches/Don-t-move-existing-players-to-world-spawn.patch b/Spigot-Server-Patches/Don-t-move-existing-players-to-world-spawn.patch index 33a19ad581..875b09ea4f 100644 --- a/Spigot-Server-Patches/Don-t-move-existing-players-to-world-spawn.patch +++ b/Spigot-Server-Patches/Don-t-move-existing-players-to-world-spawn.patch @@ -16,9 +16,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.serverStatisticManager = minecraftserver.getPlayerList().getStatisticManager(this); this.advancementDataPlayer = minecraftserver.getPlayerList().f(this); - this.H = 1.0F; -- this.a(worldserver); -+ //this.a(worldserver); // Paper - don't move to spawn on login, only first join + this.G = 1.0F; +- this.b(worldserver); ++ //this.b(worldserver); // Paper - don't move to spawn on login, only first join this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper @@ -26,28 +26,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // CraftBukkit end -+ public void moveToSpawn(WorldServer worldserver) { a(worldserver); } // Paper - OBFHELPER - private void a(WorldServer worldserver) { ++ public final void moveToSpawn(WorldServer worldserver) { b(worldserver); } // Paper - OBFHELPER + private void b(WorldServer worldserver) { BlockPosition blockposition = worldserver.getSpawn(); @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - position = new Vec3D(world.getSpawn()); + position = Vec3D.a(((WorldServer) world).getSpawn()); } this.world = world; - this.setPosition(position.getX(), position.getY(), position.getZ()); + this.setPositionRaw(position.getX(), position.getY(), position.getZ()); // Paper - don't register to chunks yet } - this.dimension = ((WorldServer) this.world).getWorldProvider().getDimensionManager(); this.playerInteractManager.a((WorldServer) world); + } 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 { - NBTTagCompound bukkit = nbttagcompound.getCompound("bukkit"); - s = bukkit.hasKeyOfType("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s; + worldserver1 = worldserver; } -+ if (nbttagcompound == null) entityplayer.moveToSpawn(worldserver); // Paper - only move to spawn on first login, otherwise, stay where you are.... - // CraftBukkit end - entityplayer.spawnIn(worldserver); ++ if (nbttagcompound == null) entityplayer.moveToSpawn(worldserver1); // Paper - only move to spawn on first login, otherwise, stay where you are.... ++ + entityplayer.spawnIn(worldserver1); + entityplayer.playerInteractManager.a((WorldServer) entityplayer.world); + String s1 = "local"; diff --git a/Spigot-Server-Patches/Don-t-tick-dead-players.patch b/Spigot-Server-Patches/Don-t-tick-dead-players.patch index 01acdc680e..b9e63c162d 100644 --- a/Spigot-Server-Patches/Don-t-tick-dead-players.patch +++ b/Spigot-Server-Patches/Don-t-tick-dead-players.patch @@ -14,8 +14,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void playerTick() { try { -- if (!this.isSpectator() || this.world.isLoaded(new BlockPosition(this))) { -+ if (valid && (!this.isSpectator() || this.world.isLoaded(new BlockPosition(this)))) { // Paper - don't tick dead players that are not in the world currently (pending respawn) +- if (!this.isSpectator() || this.world.isLoaded(this.getChunkCoordinates())) { ++ if (valid && !this.isSpectator() || this.world.isLoaded(this.getChunkCoordinates())) { // Paper - don't tick dead players that are not in the world currently (pending respawn) super.tick(); } diff --git a/Spigot-Server-Patches/Fix-Chunk-Post-Processing-deadlock-risk.patch b/Spigot-Server-Patches/Fix-Chunk-Post-Processing-deadlock-risk.patch index 0d34b04899..2251aae288 100644 --- a/Spigot-Server-Patches/Fix-Chunk-Post-Processing-deadlock-risk.patch +++ b/Spigot-Server-Patches/Fix-Chunk-Post-Processing-deadlock-risk.patch @@ -53,8 +53,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return Either.left(chunk); }); }, (runnable) -> { -- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error -+ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, () -> PlayerChunkMap.this.chunkLoadConversionCallbackExecutor.execute(runnable))); // CraftBukkit - decompile error // Paper - delay running Chunk post processing until outside of the sorter to prevent a deadlock scenario when post processing causes another chunk request. +- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); ++ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, () -> PlayerChunkMap.this.chunkLoadConversionCallbackExecutor.execute(runnable))); // Paper - delay running Chunk post processing until outside of the sorter to prevent a deadlock scenario when post processing causes another chunk request. }); completablefuture1.thenAcceptAsync((either) -> { diff --git a/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch b/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch index ab15c7d976..74b6d19d14 100644 --- a/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch +++ b/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch @@ -50,7 +50,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (entity instanceof EntityPlayer && ((EntityPlayer) entity).supressTrackerForLogin) return; // Delay adding to tracker until after list packets // Paper end if (!(entity instanceof EntityComplexPart)) { - if (!(entity instanceof EntityLightning)) { + EntityTypes entitytypes = entity.getEntityType(); 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 diff --git a/Spigot-Server-Patches/Fix-numerous-item-duplication-issues-and-teleport-is.patch b/Spigot-Server-Patches/Fix-numerous-item-duplication-issues-and-teleport-is.patch index b9b0c35c5a..b302e074b9 100644 --- a/Spigot-Server-Patches/Fix-numerous-item-duplication-issues-and-teleport-is.patch +++ b/Spigot-Server-Patches/Fix-numerous-item-duplication-issues-and-teleport-is.patch @@ -36,17 +36,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit start @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke @Nullable - public Entity teleportTo(DimensionManager dimensionmanager, BlockPosition location) { + public Entity teleportTo(WorldServer worldserver, BlockPosition location) { // CraftBukkit end + // Paper start - fix bad state entities causing dupes + if (!isAlive() || !valid) { -+ LOGGER.warn("Illegal Entity Teleport " + this + " to " + dimensionmanager + ":" + location, new Throwable()); ++ LOGGER.warn("Illegal Entity Teleport " + this + " to " + worldserver + ":" + location, new Throwable()); + return null; + } + // Paper end - if (!this.world.isClientSide && !this.dead) { + if (this.world instanceof WorldServer && !this.dead) { this.world.getMethodProfiler().enter("changeDimension"); - MinecraftServer minecraftserver = this.getMinecraftServer(); + // CraftBukkit start @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke entity.bukkitEntity = this.getBukkitEntity(); @@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!itemstack.isEmpty()) { - drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops + drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe - this.handItems.set(i, ItemStack.a); + this.handItems.set(i, ItemStack.b); } } @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { @@ -84,7 +84,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!itemstack.isEmpty()) { - drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops + drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe - this.armorItems.set(i, ItemStack.a); + this.armorItems.set(i, ItemStack.b); } } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java diff --git a/Spigot-Server-Patches/Implement-Brigadier-Mojang-API.patch b/Spigot-Server-Patches/Implement-Brigadier-Mojang-API.patch index c59d66e274..62fecb8ad1 100644 --- a/Spigot-Server-Patches/Implement-Brigadier-Mojang-API.patch +++ b/Spigot-Server-Patches/Implement-Brigadier-Mojang-API.patch @@ -40,8 +40,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 -public class CommandListenerWrapper implements ICompletionProvider { +public class CommandListenerWrapper implements ICompletionProvider, com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource { // Paper - public static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.player", new Object[0])); - public static final SimpleCommandExceptionType b = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.entity", new Object[0])); + public static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.player")); + public static final SimpleCommandExceptionType b = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.entity")); @@ -0,0 +0,0 @@ public class CommandListenerWrapper implements ICompletionProvider { return this.g; } @@ -73,19 +73,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { - ParseResults parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener()); + ParseResults parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener()); - this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { -- if (((Suggestions) suggestions).isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [] from showing for plugins with nothing more to offer -- this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestions)); // CraftBukkit - decompile error -+ // Paper start -+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer); -+ suggestEvent.setCancelled(suggestions.isEmpty()); -+ if (!suggestEvent.callEvent()) return; -+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper -+ // Paper end - }); - }); // Paper - This needs to be on main + this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { +- if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [] from showing for plugins with nothing more to offer +- this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestions)); ++ // Paper start ++ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer); ++ suggestEvent.setCancelled(suggestions.isEmpty()); ++ if (!suggestEvent.callEvent()) return; ++ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper ++ // Paper end + }); + }); } @@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { @@ -99,7 +99,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestEvent.getSuggestions())); } // Paper end - async tab completion - + } diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java diff --git a/Spigot-Server-Patches/Implement-Mob-Goal-API.patch b/Spigot-Server-Patches/Implement-Mob-Goal-API.patch index 355a7d356a..95d0b0363c 100644 --- a/Spigot-Server-Patches/Implement-Mob-Goal-API.patch +++ b/Spigot-Server-Patches/Implement-Mob-Goal-API.patch @@ -787,13 +787,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } }; private final Map c = new EnumMap(PathfinderGoal.Type.class); -- private final Set d = Sets.newLinkedHashSet();private Set getTasks() { return d; }// Paper - OBFHELPER -+ private final Set d = Sets.newLinkedHashSet();public Set getTasks() { return d; }// Paper - OBFHELPER - private final GameProfilerFiller e; +- private final Set d = Sets.newLinkedHashSet(); private Set getTasks() { return d; }// Paper - OBFHELPER ++ private final Set d = Sets.newLinkedHashSet(); public final Set getTasks() { return d; }// Paper - OBFHELPER // Paper - private -> public + private final Supplier e; private final EnumSet f = EnumSet.noneOf(PathfinderGoal.Type.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. private final OptimizedSmallEnumSet goalTypes = new OptimizedSmallEnumSet<>(PathfinderGoal.Type.class); // Paper - remove streams from pathfindergoalselector @@ -0,0 +0,0 @@ public class PathfinderGoalSelector { - this.e = gameprofilerfiller; + this.e = supplier; } - public void a(int i, PathfinderGoal pathfindergoal) { @@ -811,11 +811,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 for (Iterator iterator = this.d.iterator(); iterator.hasNext();) { PathfinderGoalWrapped goalWrapped = iterator.next(); @@ -0,0 +0,0 @@ public class PathfinderGoalSelector { - this.e.exit(); + gameprofilerfiller.exit(); } -+ public Stream getExecutingGoals() {return c();} // Paper - OBFHELPER - public Stream c() { ++ public final Stream getExecutingGoals() { return d(); } // Paper - OBFHELPER + public Stream d() { return this.d.stream().filter(PathfinderGoalWrapped::g); } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java diff --git a/Spigot-Server-Patches/Implement-Player-Client-Options-API.patch b/Spigot-Server-Patches/Implement-Player-Client-Options-API.patch index c27a59fd82..eac1cd199c 100644 --- a/Spigot-Server-Patches/Implement-Player-Client-Options-API.patch +++ b/Spigot-Server-Patches/Implement-Player-Client-Options-API.patch @@ -89,14 +89,14 @@ 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 { - private static final Map b = ImmutableMap.builder().put(EntityPose.STANDING, EntityHuman.bp).put(EntityPose.SLEEPING, EntityHuman.ap).put(EntityPose.FALL_FLYING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SWIMMING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SPIN_ATTACK, EntitySize.b(0.6F, 0.6F)).put(EntityPose.CROUCHING, EntitySize.b(0.6F, 1.5F)).put(EntityPose.DYING, EntitySize.c(0.2F, 0.2F)).build(); + private static final Map b = ImmutableMap.builder().put(EntityPose.STANDING, EntityHuman.bo).put(EntityPose.SLEEPING, EntityHuman.ao).put(EntityPose.FALL_FLYING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SWIMMING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SPIN_ATTACK, EntitySize.b(0.6F, 0.6F)).put(EntityPose.CROUCHING, EntitySize.b(0.6F, 1.5F)).put(EntityPose.DYING, EntitySize.c(0.2F, 0.2F)).build(); private static final DataWatcherObject c = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.c); private static final DataWatcherObject d = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.b); -- protected static final DataWatcherObject bq = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); -+ protected static final DataWatcherObject bq = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); public static DataWatcherObject getSkinPartsWatcher() { return bq; } // Paper - OBFHELPER - protected static final DataWatcherObject br = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); +- protected static final DataWatcherObject bp = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); ++ protected static final DataWatcherObject bp = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); public static DataWatcherObject getSkinPartsWatcher() { return bp; } // Paper - OBFHELPER + protected static final DataWatcherObject bq = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); + protected static final DataWatcherObject br = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p); protected static final DataWatcherObject bs = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p); - protected static final DataWatcherObject bt = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p); diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java @@ -108,19 +108,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent; // Paper import com.mojang.authlib.GameProfile; import com.mojang.datafixers.util.Either; - import io.netty.util.concurrent.Future; + import com.mojang.serialization.DataResult; @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { public int lastSentExp = -99999999; public int invulnerableTicks = 60; - private EnumChatVisibility ch; -- private boolean ci = true; -+ private boolean ci = true; public boolean hasChatColorsEnabled() { return this.ci; } // Paper - OBFHELPER - private long cj = SystemUtils.getMonotonicMillis(); + private EnumChatVisibility cf; +- private boolean cg = true; ++ private boolean cg = true; public boolean hasChatColorsEnabled() { return this.cg; } // Paper - OBFHELPER + private long ch = SystemUtils.getMonotonicMillis(); private Entity spectatedEntity; public boolean worldChangeInvuln; @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - } + public String locale = null; // CraftBukkit - lowercase // Paper - default to null public void a(PacketPlayInSettings packetplayinsettings) { + new PlayerClientOptionsChangeEvent(getBukkitEntity(), packetplayinsettings.getLocale(), packetplayinsettings.viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(packetplayinsettings.getChatVisibility().name()), packetplayinsettings.hasChatColorsEnabled(), new com.destroystokyo.paper.PaperSkinParts(packetplayinsettings.getSkinParts()), packetplayinsettings.getMainHand() == EnumMainHand.LEFT ? MainHand.LEFT : MainHand.RIGHT).callEvent(); // Paper - settings event // CraftBukkit start @@ -130,15 +130,19 @@ diff --git a/src/main/java/net/minecraft/server/PacketPlayInSettings.java b/src/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PacketPlayInSettings.java +++ b/src/main/java/net/minecraft/server/PacketPlayInSettings.java +@@ -0,0 +0,0 @@ import java.io.IOException; + + public class PacketPlayInSettings implements Packet { + +- public String locale; ++ public String locale; public String getLocale() { return this.locale; } // Paper - OBFHELPER + public int viewDistance; + private EnumChatVisibility c; + private boolean d; @@ -0,0 +0,0 @@ public class PacketPlayInSettings implements Packet { packetlistenerplayin.a(this); } -+ public String getLocale() { return b(); } // Paper - OBFHELPER - public String b() { - return this.a; - } - + public EnumChatVisibility getChatVisibility() { return d(); } // Paper - OBFHELPER public EnumChatVisibility d() { return this.c; @@ -166,14 +170,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import com.destroystokyo.paper.Title; import com.destroystokyo.paper.profile.CraftPlayerProfile; import com.destroystokyo.paper.profile.PlayerProfile; -@@ -0,0 +0,0 @@ import net.minecraft.server.BlockPosition; - import net.minecraft.server.ChatComponentText; - import net.minecraft.server.Container; - import net.minecraft.server.Entity; -+import net.minecraft.server.EntityHuman; - import net.minecraft.server.EntityLiving; - import net.minecraft.server.EntityPlayer; - import net.minecraft.server.EnumColor; @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void setViewDistance(int viewDistance) { throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO diff --git a/Spigot-Server-Patches/Improved-Watchdog-Support.patch b/Spigot-Server-Patches/Improved-Watchdog-Support.patch index 1486a45c9f..d22f25f743 100644 --- a/Spigot-Server-Patches/Improved-Watchdog-Support.patch +++ b/Spigot-Server-Patches/Improved-Watchdog-Support.patch @@ -71,11 +71,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/DedicatedServer.java @@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer - long l = SystemUtils.getMonotonicNanos() - i; - String s2 = String.format(Locale.ROOT, "%.3fs", (double) l / 1.0E9D); + long j = SystemUtils.getMonotonicNanos() - i; + String s = String.format(Locale.ROOT, "%.3fs", (double) j / 1.0E9D); -- DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s2); -+ //DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s2); // Paper moved to after init +- DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s); ++ //DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s); // Paper moved to after init if (dedicatedserverproperties.announcePlayerAchievements != null) { ((GameRules.GameRuleBoolean) this.getGameRules().get(GameRules.ANNOUNCE_ADVANCEMENTS)).a(dedicatedserverproperties.announcePlayerAchievements, (MinecraftServer) this); } @@ -91,8 +91,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void stop() { super.stop(); -- SystemUtils.f(); -+ //SystemUtils.f(); // Paper - moved into super +- SystemUtils.h(); ++ //SystemUtils.h(); // Paper - moved into super } @Override @@ -105,21 +105,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 r0.run(); } catch (Exception exception) { + if (exception.getCause() instanceof ThreadDeath) throw exception; // Paper - IAsyncTaskHandler.LOGGER.fatal("Error executing task on {}", this.bi(), exception); + IAsyncTaskHandler.LOGGER.fatal("Error executing task on {}", this.bh(), exception); } 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 resourcePackRepository; - @Nullable - private ResourcePackSourceFolder resourcePackFolder; -+ public volatile Thread shutdownThread; // Paper - public CommandDispatcher commandDispatcher; - private final CraftingManager craftingManager; - private final TagRegistry tagRegistry; @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant S a(Function function) { + AtomicReference atomicreference = new AtomicReference(); + Thread thread = new Thread(() -> { +@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant public + boolean flag = this.chunkMapDistance.a(this.playerChunkMap); + boolean flag1 = this.playerChunkMap.b(); + 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 @@ -12,18 +25,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.pitch = MathHelper.a(f1, -90.0F, 90.0F) % 360.0F; this.lastYaw = this.yaw; this.lastPitch = this.pitch; -- world.getChunkAt((int) Math.floor(this.locX) >> 4, (int) Math.floor(this.locZ) >> 4); // CraftBukkit -+ if (valid) world.getChunkAt((int) Math.floor(this.locX) >> 4, (int) Math.floor(this.locZ) >> 4); // CraftBukkit // Paper +- world.getChunkAt((int) Math.floor(this.locX()) >> 4, (int) Math.floor(this.locZ()) >> 4); // CraftBukkit ++ if (valid) world.getChunkAt((int) Math.floor(this.locX()) >> 4, (int) Math.floor(this.locZ()) >> 4); // CraftBukkit // Paper } - public void setPositionRotation(BlockPosition blockposition, float f, float f1) { + public void c(Vec3D vec3d) { diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- 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 { + private static final Logger LOGGER = LogManager.getLogger(); - public String locale = null; // CraftBukkit - lowercase // Paper - default to null public PlayerConnection playerConnection; + public NetworkManager networkManager; // Paper public final MinecraftServer server; @@ -45,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // Paper end } else if (this.g == LoginListener.EnumProtocolState.DELAY_ACCEPT) { -- EntityPlayer entityplayer = this.server.getPlayerList().a(this.i.getId()); +- EntityPlayer entityplayer = this.server.getPlayerList().getPlayer(this.i.getId()); + EntityPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.i.getId()); // Paper if (entityplayer == null) { @@ -54,7 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } this.networkManager.sendPacket(new PacketLoginOutSuccess(this.i)); -- EntityPlayer entityplayer = this.server.getPlayerList().a(this.i.getId()); +- EntityPlayer entityplayer = this.server.getPlayerList().getPlayer(this.i.getId()); + EntityPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.i.getId()); // Paper if (entityplayer != null) { @@ -140,15 +153,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 s = bukkit.hasKeyOfType("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s; - } + }String lastKnownName = s; // Paper - if (nbttagcompound == null) entityplayer.moveToSpawn(worldserver); // Paper - only move to spawn on first login, otherwise, stay where you are.... // CraftBukkit end + if (nbttagcompound != null) { @@ -0,0 +0,0 @@ public abstract class PlayerList { entityplayer.B().a(entityplayer); - this.sendScoreboard(worldserver.getScoreboard(), entityplayer); + this.sendScoreboard(worldserver1.getScoreboard(), entityplayer); this.server.invalidatePingSample(); + // Paper start - async load spawn in chunk + WorldServer finalWorldserver = worldserver; ++ WorldServer finalWorldserver1 = worldserver1; + int chunkX = loc.getBlockX() >> 4; + int chunkZ = loc.getBlockZ() >> 4; + final ChunkCoordIntPair pos = new ChunkCoordIntPair(chunkX, chunkZ); @@ -165,7 +179,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + }).thenAccept(chunk -> { + playerconnection.playerJoinReady = () -> { + postChunkLoadJoin( -+ entityplayer, finalWorldserver, networkmanager, playerconnection, ++ entityplayer, finalWorldserver, finalWorldserver1, networkmanager, playerconnection, + nbttagcompound, networkmanager.getSocketAddress().toString(), lastKnownName + ); + //playerChunkMap.chunkDistanceManager.removeTicketAtLevel(TicketType.LOGIN, pos, 31, pos.pair()); @@ -186,7 +200,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + }); + } + -+ private void postChunkLoadJoin(EntityPlayer entityplayer, WorldServer worldserver, NetworkManager networkmanager, PlayerConnection playerconnection, NBTTagCompound nbttagcompound, String s1, String s) { ++ private void postChunkLoadJoin(EntityPlayer entityplayer, WorldServer worldserver, WorldServer worldserver1, NetworkManager networkmanager, PlayerConnection playerconnection, NBTTagCompound nbttagcompound, String s1, String s) { + pendingPlayers.remove(entityplayer.getUniqueID(), entityplayer); + if (!networkmanager.isConnected()) { + return; @@ -196,6 +210,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 ChatMessage chatmessage; if (entityplayer.getProfile().getName().equalsIgnoreCase(s)) { +@@ -0,0 +0,0 @@ public abstract class PlayerList { + entityplayer.supressTrackerForLogin = true; + worldserver.addPlayerJoin(entityplayer); + this.server.getBossBattleCustomData().a(entityplayer); // see commented out section below worldserver.addPlayerJoin(entityplayer); +- mountSavedVehicle(entityplayer, worldserver, nbttagcompound); ++ mountSavedVehicle(entityplayer, worldserver, worldserver1, nbttagcompound); + // Paper end + // CraftBukkit start + PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(cserver.getPlayer(entityplayer), joinMessage); @@ -0,0 +0,0 @@ public abstract class PlayerList { } entityplayer.sentListPacket = true; @@ -211,7 +234,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + ((WorldServer)entityplayer.world).getChunkProvider().playerChunkMap.addEntity(entityplayer); // track entity now onPlayerJoinFinish(entityplayer, worldserver, s1); } - private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver, NBTTagCompound nbttagcompound) { +- private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver, NBTTagCompound nbttagcompound) { ++ private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver, WorldServer worldserver1, NBTTagCompound nbttagcompound) { + // Paper end + if (nbttagcompound != null && nbttagcompound.hasKeyOfType("RootVehicle", 10)) { + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("RootVehicle"); @@ -0,0 +0,0 @@ public abstract class PlayerList { protected void savePlayerFile(EntityPlayer entityplayer) { @@ -242,7 +269,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end // CraftBukkit start - // this.sendAll(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer})); + // this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer})); @@ -0,0 +0,0 @@ public abstract class PlayerList { cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity()); // CraftBukkit end diff --git a/Spigot-Server-Patches/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch b/Spigot-Server-Patches/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch index 8c4e734e65..cf1ca82dd3 100644 --- a/Spigot-Server-Patches/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch +++ b/Spigot-Server-Patches/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch @@ -81,17 +81,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Paper end - this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping + final int[] chunksTicked = {0}; this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping - Optional optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); + Optional optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); if (optional.isPresent()) { @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - this.world.timings.chunkTicks.startTiming(); // Spigot // Paper - this.world.a(chunk, k); - this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper -+ if (chunksTicked[0]++ % 10 == 0) this.world.getMinecraftServer().midTickLoadChunks(); // Paper + this.world.timings.chunkTicks.startTiming(); // Spigot // Paper + this.world.a(chunk, k); + this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper ++ if (chunksTicked[0]++ % 10 == 0) this.world.getMinecraftServer().midTickLoadChunks(); // Paper + } } } - }); @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { super.executeTask(runnable); } @@ -154,7 +154,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public boolean canSleepForTick() { // Paper // CraftBukkit start if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken - return this.forceTicks || this.isEntered() || SystemUtils.getMonotonicMillis() < (this.ac ? this.ab : this.nextTick); + return this.forceTicks || this.isEntered() || SystemUtils.getMonotonicMillis() < (this.X ? this.W : this.nextTick); @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant ticket = new Ticket<>(TicketType.PLAYER, 33, new ChunkCoordIntPair(i)); // Paper - no-tick view distance if (flag1) { - ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error + ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java @@ -125,8 +125,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + boolean needsChunkCenterUpdate; // Paper - no-tick view distance + public EntityPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) { - super((World) worldserver, gameprofile); - playerinteractmanager.player = this; + super(worldserver, worldserver.getSpawn(), gameprofile); + this.spawnDimension = World.OVERWORLD; 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 @@ -306,7 +306,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + player.needsChunkCenterUpdate = false; + // Paper end - no-tick view distance } - + // Paper end @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } @@ -367,18 +367,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return Either.left(chunk); }); }, (runnable) -> { -- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error -+ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error // Paper - diff on change, this is the scheduling method copied in Chunk used to schedule chunk broadcasts (on change it needs to be copied again) +- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); ++ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // Paper - diff on change, this is the scheduling method copied in Chunk used to schedule chunk broadcasts (on change it needs to be copied again) }); return completablefuture1; } @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } // Paper } -- protected void setViewDistance(int i) { + protected void setViewDistance(int i) { - int j = MathHelper.clamp(i + 1, 3, 33); -+ public final void setViewDistance(int i) { // Paper - public + int j = MathHelper.clamp(i + 1, 3, 33); // Paper - diff on change, these make the lower view distance limit 2 and the upper 32 if (j != this.viewDistance) { @@ -501,7 +499,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return Stream.empty(); + } + // all current cases are inlined so we wont hit this code, it's just in case plugins or future updates use it -+ List players = new ArrayList<>(); ++ List players = new java.util.ArrayList<>(); + Object[] backingSet = inRange.getBackingSet(); + + if (flag) { // flag -> border only @@ -542,7 +540,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final void sendChunk(EntityPlayer entityplayer, Packet[] apacket, Chunk chunk) { this.a(entityplayer, apacket, chunk); } // Paper - OBFHELPER private void a(EntityPlayer entityplayer, Packet[] apacket, Chunk chunk) { if (apacket[0] == null) { - apacket[0] = new PacketPlayOutMapChunk(chunk, 65535); + apacket[0] = new PacketPlayOutMapChunk(chunk, 65535, true); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(this.tracker.chunkX, this.tracker.chunkZ); PlayerChunk playerchunk = PlayerChunkMap.this.getVisibleChunk(chunkcoordintpair.pair()); @@ -557,23 +555,23 @@ 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 { - // 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(), WorldData.c(worlddata.getSeed()), worlddata.isHardcore(), worldserver.worldProvider.getDimensionManager().getType(), this.getMaxPlayers(), worlddata.getType(), worldserver.getChunkProvider().playerChunkMap.getLoadViewDistance(), flag1, !flag)); // Paper - no-tick view distance +- 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())); ++ 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(), worldserver1.getChunkProvider().playerChunkMap.getLoadViewDistance(), flag1, !flag, worldserver1.isDebugWorld(), worldserver1.isFlatWorld())); // Paper - no-tick view distance entityplayer.getBukkitEntity().sendSupportedChannels(); // CraftBukkit playerconnection.sendPacket(new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.a, (new PacketDataSerializer(Unpooled.buffer())).a(this.getServer().getServerModName()))); playerconnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); @@ -0,0 +0,0 @@ public abstract class PlayerList { - WorldData worlddata = worldserver.getWorldData(); - - entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver.worldProvider.getDimensionManager().getType(), WorldData.c(worldserver.getWorldData().getSeed()), worldserver.getWorldData().getType(), entityplayer1.playerInteractManager.getGameMode())); -- entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver.spigotConfig.viewDistance)); // Spigot -+ entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver.getChunkProvider().playerChunkMap.getLoadViewDistance())); // Paper - no-tick view distance - entityplayer1.spawnIn(worldserver); + // CraftBukkit start + WorldData worlddata = worldserver1.getWorldData(); + entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver1.getTypeKey(), worldserver1.getDimensionKey(), BiomeManager.a(worldserver1.getSeed()), entityplayer1.playerInteractManager.getGameMode(), entityplayer1.playerInteractManager.c(), worldserver1.isDebugWorld(), worldserver1.isFlatWorld(), flag)); +- entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver1.spigotConfig.viewDistance)); // Spigot ++ entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver1.getChunkProvider().playerChunkMap.getLoadViewDistance())); // Spigot // Paper - no-tick view distance + entityplayer1.spawnIn(worldserver1); entityplayer1.dead = false; - entityplayer1.playerConnection.teleport(new Location(worldserver.getWorld(), entityplayer1.locX(), entityplayer1.locY(), entityplayer1.locZ(), entityplayer1.yaw, entityplayer1.pitch)); + entityplayer1.playerConnection.teleport(new Location(worldserver1.getWorld(), entityplayer1.locX(), entityplayer1.locY(), entityplayer1.locZ(), entityplayer1.yaw, entityplayer1.pitch)); @@ -0,0 +0,0 @@ public abstract class PlayerList { public void a(int i) { diff --git a/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch b/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch index 12459568c9..e809bb7285 100644 --- a/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch +++ b/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch @@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + -+ public final void getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List into) { ++ public final void getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List into, Predicate predicate) { + // copied from getEntities + int min = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); + int max = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D); @@ -43,7 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Entity entity1 = entities[i]; + if (entity1.shouldBeRemoved) continue; // Paper + -+ if (entity1 != entity && entity1.getBoundingBox().intersects(axisalignedbb)) { ++ if (entity1 != entity && entity1.getBoundingBox().intersects(axisalignedbb) && (predicate == null || predicate.test(entity1))) { + into.add(entity1); + + if (!(entity1 instanceof EntityEnderDragon)) { @@ -56,7 +56,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + for (int i1 = 0; i1 < l; ++i1) { + EntityComplexPart entitycomplexpart = aentitycomplexpart[i1]; + -+ if (entitycomplexpart != entity && entitycomplexpart.getBoundingBox().intersects(axisalignedbb)) { ++ if (entitycomplexpart != entity && entitycomplexpart.getBoundingBox().intersects(axisalignedbb) && (predicate == null || predicate.test(entitycomplexpart))) { + into.add(entitycomplexpart); + } + } @@ -106,9 +106,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Boolean hardCollides = cachedOverrides.get(this.getClass()); + if (hardCollides == null) { + try { -+ Object getHardCollisionBoxMethod = Entity.class.getMethod("au"); ++ Object getHardCollisionBoxMethod = Entity.class.getMethod("ay"); + Object getHardCollisionBoxEntityMethod = Entity.class.getMethod("j", Entity.class); -+ if (!this.getClass().getMethod("au").equals(getHardCollisionBoxMethod)) { ++ if (!this.getClass().getMethod("ay").equals(getHardCollisionBoxMethod)) { + hardCollides = Boolean.TRUE; + } else if (!this.getClass().getMethod("j", Entity.class).equals(getHardCollisionBoxEntityMethod)) { + hardCollides = Boolean.TRUE; @@ -140,8 +140,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void checkDespawn() {} -+ public final EntityComplexPart[] getComplexParts() { return this.eo(); } // Paper - OBFHELPER - public EntityComplexPart[] eo() { ++ public final EntityComplexPart[] getComplexParts() { return this.eK(); } // Paper - OBFHELPER + public EntityComplexPart[] eK() { return this.children; } diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java @@ -149,34 +149,46 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/IEntityAccess.java +++ b/src/main/java/net/minecraft/server/IEntityAccess.java @@ -0,0 +0,0 @@ public interface IEntityAccess { - return this.b(oclass, axisalignedbb, IEntitySelector.f); + return this.b(oclass, axisalignedbb, IEntitySelector.g); } + // Paper start - optimise hard collision + /** + * Not guaranteed to only return hard colliding entites + */ -+ default List getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb) { ++ default List getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate) { + return this.getEntities(entity, axisalignedbb); + } + // Paper end - optimise hard collision + - default Stream b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { + default Stream c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate) { if (axisalignedbb.a() < 1.0E-7D) { return Stream.empty(); } else { AxisAlignedBB axisalignedbb1 = axisalignedbb.g(1.0E-7D); -- Stream stream = this.getEntities(entity, axisalignedbb1).stream().filter((entity1) -> { // Paper - decompile fix -+ Stream stream = ((entity != null && entity.hardCollides()) ? this.getEntities(entity, axisalignedbb) : this.getHardCollidingEntities(entity, axisalignedbb1)).stream().filter((entity1) -> { // Paper - decompile fix // Paper - optimise hard collision - return !set.contains(entity1); - }).filter((entity1) -> { - return entity == null || !entity.isSameVehicle(entity1); - }).flatMap((entity1) -> { -- return Stream.of(entity1.au(), entity == null ? null : entity.j(entity1)); -+ return Stream.of(entity1.au(), entity == null ? null : entity.j(entity1)); // Paper - optimise hard collision - diff on change, these are the methods that only hard colliding entities override - }).filter(Objects::nonNull); - return stream.filter(axisalignedbb1::c).map(VoxelShapes::a); +- return this.getEntities(entity, axisalignedbb1, predicate.and((entity1) -> { ++ // Paper start ++ Predicate effectivePredicate = predicate.and((entity1) -> { + return entity == null || !entity.isSameVehicle(entity1); +- })).stream().flatMap((entity1) -> { ++ }); ++ ++ return ((entity != null && entity.hardCollides()) ? this.getEntities(entity, axisalignedbb, effectivePredicate) : this.getHardCollidingEntities(entity, axisalignedbb1, effectivePredicate)).stream().flatMap((entity1) -> { + if (entity != null) { +- AxisAlignedBB axisalignedbb2 = entity.j(entity1); ++ AxisAlignedBB axisalignedbb2 = entity.j(entity1); // Paper - diff on change, hard collision box method + + if (axisalignedbb2 != null && axisalignedbb2.c(axisalignedbb1)) { + return Stream.of(entity1.ay(), axisalignedbb2); + } + } + +- return Stream.of(entity1.ay()); ++ return Stream.of(entity1.ay()); // Paper - diff on change, hard collision box method + }).filter(Objects::nonNull).map(VoxelShapes::a); + } + } 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 @@ -187,7 +199,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - optimise hard collision handling + @Override -+ public List getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb) { ++ public List getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate) { + // copied from below + List list = Lists.newArrayList(); + int i = MathHelper.floor((axisalignedbb.minX - 2.0D) / 16.0D); @@ -195,14 +207,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + int k = MathHelper.floor((axisalignedbb.minZ - 2.0D) / 16.0D); + int l = MathHelper.floor((axisalignedbb.maxZ + 2.0D) / 16.0D); + -+ ChunkProviderServer chunkProvider = ((ChunkProviderServer)this.chunkProvider); ++ ChunkProviderServer chunkProvider = ((WorldServer)this).getChunkProvider(); + + for (int i1 = i; i1 <= j; ++i1) { + for (int j1 = k; j1 <= l; ++j1) { + Chunk chunk = chunkProvider.getChunkAtIfLoadedMainThread(i1, j1); + + if (chunk != null) { -+ chunk.getHardCollidingEntities(entity, axisalignedbb, list); ++ chunk.getHardCollidingEntities(entity, axisalignedbb, list, predicate); + } + } + } diff --git a/Spigot-Server-Patches/Optimize-ChunkProviderServer-s-chunk-level-checking-.patch b/Spigot-Server-Patches/Optimize-ChunkProviderServer-s-chunk-level-checking-.patch index 7fd7aa4d5d..0f3108799f 100644 --- a/Spigot-Server-Patches/Optimize-ChunkProviderServer-s-chunk-level-checking-.patch +++ b/Spigot-Server-Patches/Optimize-ChunkProviderServer-s-chunk-level-checking-.patch @@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public boolean a(Entity entity) { - long i = ChunkCoordIntPair.pair(MathHelper.floor(entity.locX()) >> 4, MathHelper.floor(entity.locZ()) >> 4); - -- return this.a(i, PlayerChunk::b); +- return this.a(i, (Function>>) PlayerChunk::b); // CraftBukkit - decompile error + // Paper start - optimize is ticking ready type functions + // entity ticking + PlayerChunk playerChunk = this.getChunk(MCUtil.getCoordinateKey(entity)); @@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public final boolean isEntityTickingChunk(ChunkCoordIntPair chunkcoordintpair) { return this.a(chunkcoordintpair); } // Paper - OBFHELPER @Override public boolean a(ChunkCoordIntPair chunkcoordintpair) { -- return this.a(chunkcoordintpair.pair(), PlayerChunk::b); +- return this.a(chunkcoordintpair.pair(), (Function>>) PlayerChunk::b); // CraftBukkit - decompile error + // Paper start - optimize is ticking ready type functions + // is entity ticking ready + PlayerChunk playerChunk = this.getChunk(MCUtil.getCoordinateKey(chunkcoordintpair)); @@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public boolean a(BlockPosition blockposition) { - long i = ChunkCoordIntPair.pair(blockposition.getX() >> 4, blockposition.getZ() >> 4); - -- return this.a(i, PlayerChunk::a); +- return this.a(i, (Function>>) PlayerChunk::a); // CraftBukkit - decompile error + // Paper start - optimize is ticking ready type functions + // is ticking ready + PlayerChunk playerChunk = this.getChunk(MCUtil.getCoordinateKey(blockposition)); @@ -48,15 +48,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - optimize is ticking ready type functions } - public boolean b(Entity entity) { -- long i = ChunkCoordIntPair.pair(MathHelper.floor(entity.locX()) >> 4, MathHelper.floor(entity.locZ()) >> 4); -- -- return this.a(i, PlayerChunk::c); -+ // Paper start - optimize is ticking ready type functions -+ // is full chunk ready -+ PlayerChunk playerChunk = this.getChunk(MCUtil.getCoordinateKey(entity)); -+ return playerChunk != null && playerChunk.isFullChunkReady(); -+ // Paper end - optimize is ticking ready type functions - } - private boolean a(long i, Function>> function) { diff --git a/Spigot-Server-Patches/Optimize-Collision-to-not-load-chunks.patch b/Spigot-Server-Patches/Optimize-Collision-to-not-load-chunks.patch index 2cd9d1192c..570df4963f 100644 --- a/Spigot-Server-Patches/Optimize-Collision-to-not-load-chunks.patch +++ b/Spigot-Server-Patches/Optimize-Collision-to-not-load-chunks.patch @@ -32,57 +32,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess { } - default boolean a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { + default boolean b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate) { + try { if (entity != null) entity.collisionLoadChunks = true; // Paper - return this.c(entity, axisalignedbb, set).allMatch(VoxelShape::isEmpty); + return this.d(entity, axisalignedbb, predicate).allMatch(VoxelShape::isEmpty); + } finally { if (entity != null) entity.collisionLoadChunks = false; } // Paper } - default Stream b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { -@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess { - } - - while (cursorposition.a()) { -- int k1 = cursorposition.b(); -- int l1 = cursorposition.c(); -- int i2 = cursorposition.d(); -+ int k1 = cursorposition.b();int x = k1; // Paper -+ int l1 = cursorposition.c();int y = l1; // Paper -+ int i2 = cursorposition.d();int z = i2; // Paper - int j2 = cursorposition.e(); - - if (j2 != 3) { -- int k2 = k1 >> 4; -- int l2 = i2 >> 4; -- IBlockAccess iblockaccess = ICollisionAccess.this.c(k2, l2); -- -- if (iblockaccess != null) { -- blockposition_mutableblockposition.d(k1, l1, i2); -- IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); -+ // Paper start - ensure we don't load chunks -+ //int k2 = k1 >> 4; -+ //int l2 = i2 >> 4; -+ boolean far = entity != null && MCUtil.distanceSq(entity.locX(), y, entity.locZ(), x, y, z) > 14; -+ blockposition_mutableblockposition.setValues(x, y, z); -+ -+ boolean isRegionLimited = ICollisionAccess.this instanceof RegionLimitedWorldAccess; -+ IBlockData iblockdata = isRegionLimited ? Blocks.VOID_AIR.getBlockData() : ((!far && entity instanceof EntityPlayer) || (entity != null && entity.collisionLoadChunks) -+ ? ICollisionAccess.this.getType(blockposition_mutableblockposition) -+ : ICollisionAccess.this.getTypeIfLoaded(blockposition_mutableblockposition) -+ ); -+ if (iblockdata == null) { -+ if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) { -+ VoxelShape voxelshape3 = VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z))); -+ consumer.accept(voxelshape3); -+ return true; -+ } -+ } else { -+ //blockposition_mutableblockposition.d(k1, l1, i2); // moved up -+ //IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); // moved up -+ // Paper end - - if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { - VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision); + Stream c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate); 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 @@ -92,9 +48,77 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit end + worldserver.getChunkProvider().addTicket(TicketType.POST_TELEPORT, new ChunkCoordIntPair(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper - while (avoidSuffocation && !worldserver.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) { + while (avoidSuffocation && !worldserver1.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) { entityplayer1.setPosition(entityplayer1.locX(), entityplayer1.locY() + 1.0D, entityplayer1.locZ()); } +diff --git a/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java b/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java ++++ b/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java +@@ -0,0 +0,0 @@ import javax.annotation.Nullable; + public class VoxelShapeSpliterator extends AbstractSpliterator { + + @Nullable +- private final Entity a; ++ private final Entity a; final Entity getEntity() { return this.a; } // Paper - OBFHELPER + private final AxisAlignedBB b; + private final VoxelShapeCollision c; + private final CursorPosition d; +- private final BlockPosition.MutableBlockPosition e; ++ private final BlockPosition.MutableBlockPosition e; final BlockPosition.MutableBlockPosition getMutablePos() { return this.e; } // Paper - OBFHELPER + private final VoxelShape f; +- private final ICollisionAccess g; ++ private final ICollisionAccess g; final ICollisionAccess getCollisionAccess() { return this.g; } // Paper - OBFHELPER + private boolean h; + private final BiPredicate i; + +@@ -0,0 +0,0 @@ public class VoxelShapeSpliterator extends AbstractSpliterator { + boolean a(Consumer consumer) { + while (true) { + if (this.d.a()) { +- int i = this.d.b(); +- int j = this.d.c(); +- int k = this.d.d(); ++ int i = this.d.b(); final int x = i; ++ int j = this.d.c(); final int y = j; ++ int k = this.d.d(); final int z = k; + int l = this.d.e(); + + if (l == 3) { + continue; + } + +- IBlockAccess iblockaccess = this.a(i, k); +- +- if (iblockaccess == null) { ++ // Paper start - ensure we don't load chunks ++ Entity entity = this.getEntity(); ++ BlockPosition.MutableBlockPosition blockposition_mutableblockposition = this.getMutablePos(); ++ boolean far = entity != null && MCUtil.distanceSq(entity.locX(), y, entity.locZ(), x, y, z) > 14; ++ blockposition_mutableblockposition.setValues(x, y, z); ++ ++ boolean isRegionLimited = this.getCollisionAccess() instanceof RegionLimitedWorldAccess; ++ IBlockData iblockdata = isRegionLimited ? Blocks.VOID_AIR.getBlockData() : ((!far && entity instanceof EntityPlayer) || (entity != null && entity.collisionLoadChunks) ++ ? this.getCollisionAccess().getType(blockposition_mutableblockposition) ++ : this.getCollisionAccess().getTypeIfLoaded(blockposition_mutableblockposition) ++ ); ++ ++ if (iblockdata == null) { ++ if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) { ++ VoxelShape voxelshape3 = VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z))); ++ consumer.accept(voxelshape3); ++ return true; ++ } + continue; + } +- +- this.e.d(i, j, k); +- IBlockData iblockdata = iblockaccess.getType(this.e); ++ // Paper - moved up ++ // Paper end + + if (!this.i.test(iblockdata, this.e) || l == 1 && !iblockdata.d() || l == 2 && !iblockdata.a(Blocks.MOVING_PISTON)) { + continue; diff --git a/src/main/java/net/minecraft/server/VoxelShapes.java b/src/main/java/net/minecraft/server/VoxelShapes.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/VoxelShapes.java @@ -107,5 +131,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + IBlockData iblockdata = iworldreader.getTypeIfLoaded(blockposition_mutableblockposition); // Paper + if (iblockdata == null) return 0.0D; // Paper - if ((k2 != 1 || iblockdata.f()) && (k2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { + if ((k2 != 1 || iblockdata.d()) && (k2 != 2 || iblockdata.a(Blocks.MOVING_PISTON))) { d0 = iblockdata.b((IBlockAccess) iworldreader, blockposition_mutableblockposition, voxelshapecollision).a(enumdirection_enumaxis2, axisalignedbb.d((double) (-blockposition_mutableblockposition.getX()), (double) (-blockposition_mutableblockposition.getY()), (double) (-blockposition_mutableblockposition.getZ())), d0); diff --git a/Spigot-Server-Patches/Optimize-Pathfinding.patch b/Spigot-Server-Patches/Optimize-Pathfinding.patch index 94c11c7eea..d35d9e3aad 100644 --- a/Spigot-Server-Patches/Optimize-Pathfinding.patch +++ b/Spigot-Server-Patches/Optimize-Pathfinding.patch @@ -17,8 +17,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - protected PathEntity c; + protected PathEntity c; protected final PathEntity getCurrentPath() { return this.c; } // Paper - OBFHELPER protected double d; - private final AttributeInstance p; protected int e; + protected int f; @@ -0,0 +0,0 @@ public abstract class NavigationAbstract { return this.a(this.a(d0, d1, d2, 1), d3); } diff --git a/Spigot-Server-Patches/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch b/Spigot-Server-Patches/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch index 1bc10e94de..7525f11629 100644 --- a/Spigot-Server-Patches/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch +++ b/Spigot-Server-Patches/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch @@ -64,9 +64,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 entityPlayer.playerNaturallySpawnedEvent.callEvent(); }; // Paper end -- this.playerChunkMap.f().forEach((playerchunk) -> { +- this.playerChunkMap.f().forEach((playerchunk) -> { // Paper - no... just no... + this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping - Optional optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); + Optional optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); if (optional.isPresent()) { diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java @@ -124,8 +124,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public final WorldServer world; @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - public PlayerChunkMap(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator chunkgenerator, WorldLoadListener worldloadlistener, Supplier supplier, int i) { - super(new File(worldserver.getWorldProvider().getDimensionManager().a(file), "region"), datafixer); + public PlayerChunkMap(WorldServer worldserver, Convertable.ConversionSession convertable_conversionsession, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator chunkgenerator, WorldLoadListener worldloadlistener, Supplier supplier, int i, boolean flag) { + super(new File(convertable_conversionsession.a(worldserver.getDimensionKey()), "region"), datafixer, flag); - this.visibleChunks = this.updatingChunks.clone(); + //this.visibleChunks = this.updatingChunks.clone(); // Paper - no more cloning this.pendingUnload = new Long2ObjectLinkedOpenHashMap(); diff --git a/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch b/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch index 44fdb9491f..a536028223 100644 --- a/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch +++ b/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch @@ -12,9 +12,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { private final Long2ObjectMap> c = new Long2ObjectOpenHashMap(); public final Long2ObjectOpenHashMap>> tickets = new Long2ObjectOpenHashMap(); - 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); -+ public static final int MOB_SPAWN_RANGE = 8; //private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); // Paper - no longer used ++ public static final int MOB_SPAWN_RANGE = 8; // private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); // Paper - no longer used private final ChunkMapDistance.c g = new ChunkMapDistance.c(33); // Paper start use a queue, but still keep unique requirement public final java.util.Queue pendingChunkUpdates = new java.util.ArrayDeque() { @@ -34,24 +34,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.f.a(); + //this.f.a(); // Paper - no longer used this.g.a(); - int i = Integer.MAX_VALUE - this.e.a(Integer.MAX_VALUE); + int i = Integer.MAX_VALUE - this.ticketLevelTracker.a(Integer.MAX_VALUE); boolean flag = i != 0; @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { ((ObjectSet) this.c.computeIfAbsent(i, (j) -> { return new ObjectOpenHashSet(); })).add(entityplayer); -- this.f.b(i, 0, true); -+ //this.f.b(i, 0, true); // Paper - no longer used - this.g.b(i, 0, true); +- this.f.update(i, 0, true); ++ //this.f.update(i, 0, true); // Paper - no longer used + this.g.update(i, 0, true); } @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { if (objectset != null) objectset.remove(entityplayer); // Paper - some state corruption happens here, don't crash, clean up gracefully. if (objectset == null || objectset.isEmpty()) { // Paper this.c.remove(i); -- this.f.b(i, Integer.MAX_VALUE, false); -+ //this.f.b(i, Integer.MAX_VALUE, false); // Paper - no longer used - this.g.b(i, Integer.MAX_VALUE, false); +- this.f.update(i, Integer.MAX_VALUE, false); ++ //this.f.update(i, Integer.MAX_VALUE, false); // Paper - no longer used + this.g.update(i, Integer.MAX_VALUE, false); } @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { @@ -116,37 +116,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - optimize isOutisdeRange this.world.getMethodProfiler().enter("pollingChunks"); int k = this.world.getGameRules().getInt(GameRules.RANDOM_TICK_SPEED); - BlockPosition blockposition = this.world.getSpawn(); + boolean flag2 = world.ticksPerAnimalSpawns != 0L && worlddata.getTime() % world.ticksPerAnimalSpawns == 0L; // CraftBukkit @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - - this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings this.world.getMethodProfiler().exit(); + //List list = Lists.newArrayList(this.playerChunkMap.f()); // Paper + //Collections.shuffle(list); // Paper - //Paper start - call player naturally spawn event - int chunkRange = world.spigotConfig.mobSpawnRange; - chunkRange = (chunkRange > world.spigotConfig.viewDistance) ? (byte) world.spigotConfig.viewDistance : chunkRange; - chunkRange = Math.min(chunkRange, 8); -- for (EntityPlayer entityPlayer : this.world.players) { +- for (EntityPlayer entityPlayer : this.world.getPlayers()) { - entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange); - entityPlayer.playerNaturallySpawnedEvent.callEvent(); - }; - // Paper end -+ // Paper - replaced by above ++ // Paper - moved up final int[] chunksTicked = {0}; this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping - Optional optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); + Optional optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - this.world.getMethodProfiler().exit(); - ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); + Chunk chunk = (Chunk) optional1.get(); + ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); + +- if (!this.playerChunkMap.isOutsideOfRange(chunkcoordintpair)) { ++ if (!this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, false)) { // Paper - optimise isOutsideOfRange + chunk.setInhabitedTime(chunk.getInhabitedTime() + j); +- if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(chunkcoordintpair, true)) { // Spigot ++ if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, true)) { // Spigot // Paper - optimise isOutsideOfRange + SpawnerCreature.a(this.world, chunk, spawnercreature_d, this.allowAnimals, this.allowMonsters, flag2); + } -- if (!this.playerChunkMap.isOutsideOfRange(chunkcoordintpair)) { -+ if (!this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, false)) { // Paper - optimise isOutsideOfRange - // Paper end - chunk.setInhabitedTime(chunk.getInhabitedTime() + j); -- if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(chunkcoordintpair, true)) { // Spigot -+ if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, true)) { // Spigot // Paper - optimise isOutsideOfRange - this.world.getMethodProfiler().enter("spawner"); - this.world.timings.mobSpawn.startTiming(); // Spigot - EnumCreatureType[] aenumcreaturetype1 = aenumcreaturetype; diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java @@ -158,8 +157,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + double lastEntitySpawnRadiusSquared; // Paper - optimise isOutsideRange, this field is in blocks + public EntityPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) { - super((World) worldserver, gameprofile); - playerinteractmanager.player = this; + super(worldserver, worldserver.getSpawn(), gameprofile); + this.spawnDimension = World.OVERWORLD; 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 @@ -196,8 +195,8 @@ 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 { - final com.destroystokyo.paper.util.misc.PlayerAreaMap[] playerEntityTrackerTrackMaps; - final int[] entityTrackerTrackRanges; + return MinecraftServer.getServer().applyTrackingRangeScale(vanilla); + } // Paper end - use distance map to optimise tracker + // Paper start - optimise PlayerChunkMap#isOutsideRange + // A note about the naming used here: @@ -242,16 +241,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, ChunkMapDistance.MOB_SPAWN_RANGE); + // Paper end - optimise PlayerChunkMap#isOutsideRange } - + // Paper end @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.mailboxWorldGen = this.p.a(threadedmailbox, false); this.mailboxMain = this.p.a(mailbox, false); - this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getWorldProvider().f(), threadedmailbox1, this.p.a(threadedmailbox1, false)); + this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getDimensionManager().hasSkyLight(), threadedmailbox1, this.p.a(threadedmailbox1, false)); - this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler); + this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler); this.chunkDistanceManager.chunkMap = this; // Paper this.l = supplier; - this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper + this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper this.setViewDistance(i); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.playerEntityTrackerTrackMaps[ordinal] = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets); diff --git a/Spigot-Server-Patches/Remove-streams-from-MinecraftKey.patch b/Spigot-Server-Patches/Remove-streams-from-MinecraftKey.patch deleted file mode 100644 index cdccb6f235..0000000000 --- a/Spigot-Server-Patches/Remove-streams-from-MinecraftKey.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Mon, 6 Apr 2020 18:06:24 -0700 -Subject: [PATCH] Remove streams from MinecraftKey - -They produce a lot of garbage. - -diff --git a/src/main/java/net/minecraft/server/MinecraftKey.java b/src/main/java/net/minecraft/server/MinecraftKey.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/MinecraftKey.java -+++ b/src/main/java/net/minecraft/server/MinecraftKey.java -@@ -0,0 +0,0 @@ public class MinecraftKey implements Comparable { - } - - private static boolean c(String s) { -- return s.chars().allMatch((i) -> { -- return i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 47 || i == 46; -- }); -+ // Paper start - remove streams -+ for (int index = 0, len = s.length(); index < len; ++index) { -+ int i = (int)s.charAt(index); -+ boolean condition = i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 47 || i == 46; // this is copied from the replaced code. -+ if (!condition) { -+ return false; -+ } -+ } -+ return true; -+ // Paper end - remove streams - } - - private static boolean d(String s) { -- return s.chars().allMatch((i) -> { -- return i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 46; -- }); -+ // Paper start - remove streams -+ for (int index = 0, len = s.length(); index < len; ++index) { -+ int i = (int)s.charAt(index); -+ boolean condition = i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 46; // this is copied from the replaced code. -+ if (!condition) { -+ return false; -+ } -+ } -+ return true; -+ // Paper end - remove streams - } - - public static class a implements JsonDeserializer, JsonSerializer { diff --git a/Spigot-Server-Patches/Remove-streams-from-Mob-AI-System.patch b/Spigot-Server-Patches/Remove-streams-from-Mob-AI-System.patch index 40aaee3299..00a42bae81 100644 --- a/Spigot-Server-Patches/Remove-streams-from-Mob-AI-System.patch +++ b/Spigot-Server-Patches/Remove-streams-from-Mob-AI-System.patch @@ -66,11 +66,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import java.util.Iterator; // Paper - remove streams from pathfindergoalselector import java.util.Map; import java.util.Set; - import java.util.stream.Stream; + import java.util.function.Supplier; @@ -0,0 +0,0 @@ public class PathfinderGoalSelector { private final Map c = new EnumMap(PathfinderGoal.Type.class); - private final Set d = Sets.newLinkedHashSet();private Set getTasks() { return d; }// Paper - OBFHELPER - private final GameProfilerFiller e; + private final Set d = Sets.newLinkedHashSet(); private Set getTasks() { return d; }// Paper - OBFHELPER + private final Supplier e; - private final EnumSet f = EnumSet.noneOf(PathfinderGoal.Type.class); + private final EnumSet f = EnumSet.noneOf(PathfinderGoal.Type.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. + private final OptimizedSmallEnumSet goalTypes = new OptimizedSmallEnumSet<>(PathfinderGoal.Type.class); // Paper - remove streams from pathfindergoalselector @@ -104,8 +104,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private static final PathfinderGoal.Type[] PATHFINDER_GOAL_TYPES = PathfinderGoal.Type.values(); // Paper - remove streams from pathfindergoalselector + public void doTick() { - this.e.enter("goalCleanup"); -- this.c().filter((pathfindergoalwrapped) -> { + GameProfilerFiller gameprofilerfiller = (GameProfilerFiller) this.e.get(); + + gameprofilerfiller.enter("goalCleanup"); +- this.d().filter((pathfindergoalwrapped) -> { - boolean flag; - - if (pathfindergoalwrapped.g()) { @@ -138,8 +140,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.c.remove(pathfindergoal_type); @@ -0,0 +0,0 @@ public class PathfinderGoalSelector { }); - this.e.exit(); - this.e.enter("goalUpdate"); + gameprofilerfiller.exit(); + gameprofilerfiller.enter("goalUpdate"); - this.d.stream().filter((pathfindergoalwrapped) -> { - return !pathfindergoalwrapped.g(); - }).filter((pathfindergoalwrapped) -> { @@ -203,9 +205,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + wrappedGoal.c(); + } + // Paper end - remove streams from pathfindergoalselector - this.e.exit(); - this.e.enter("goalTick"); -- this.c().forEach(PathfinderGoalWrapped::e); + gameprofilerfiller.exit(); + gameprofilerfiller.enter("goalTick"); +- this.d().forEach(PathfinderGoalWrapped::e); + // Paper start - remove streams from pathfindergoalselector + for (Iterator iterator = this.d.iterator(); iterator.hasNext();) { + PathfinderGoalWrapped wrappedGoal = iterator.next(); @@ -214,7 +216,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + // Paper end - remove streams from pathfindergoalselector - this.e.exit(); + gameprofilerfiller.exit(); } @@ -0,0 +0,0 @@ public class PathfinderGoalSelector { diff --git a/Spigot-Server-Patches/Restrict-vanilla-teleport-command-to-valid-locations.patch b/Spigot-Server-Patches/Restrict-vanilla-teleport-command-to-valid-locations.patch index b6c4f8b6da..691c930c1b 100644 --- a/Spigot-Server-Patches/Restrict-vanilla-teleport-command-to-valid-locations.patch +++ b/Spigot-Server-Patches/Restrict-vanilla-teleport-command-to-valid-locations.patch @@ -10,15 +10,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/CommandTeleport.java +++ b/src/main/java/net/minecraft/server/CommandTeleport.java @@ -0,0 +0,0 @@ public class CommandTeleport { - } - private static void a(CommandListenerWrapper commandlistenerwrapper, Entity entity, WorldServer worldserver, double d0, double d1, double d2, Set set, float f, float f1, @Nullable CommandTeleport.a commandteleport_a) { + private static void a(CommandListenerWrapper commandlistenerwrapper, Entity entity, WorldServer worldserver, double d0, double d1, double d2, Set set, float f, float f1, @Nullable CommandTeleport.a commandteleport_a) throws CommandSyntaxException { + BlockPosition blockposition = new BlockPosition(d0, d1, d2); + // Paper start - Don't allow teleport command to invalid locations + if (d0 <= -30000000 || d2 <= -30000000 || d0 > 30000000 || d2 > 30000000 || d1 > 30000000 || d1 <= -30000000) { // Copy/pasta from BaseBlockPosition#isValidLocation + org.bukkit.Bukkit.getLogger().warning("Refused to teleport " + entity.getName() + " to " + d0 + ", " + d1 + ", " + d2); + return; + } + // Paper end - if (entity instanceof EntityPlayer) { - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(new BlockPosition(d0, d1, d2)); + if (!World.k(blockposition)) { + throw CommandTeleport.a.create(); 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 b5c1702cd6..15817fc888 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 @@ -36,13 +36,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java +++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java @@ -0,0 +0,0 @@ public class EntityTrackerEntry { - this.r = entity.onGround; + this.r = entity.isOnGround(); } + public final void tick() { this.a(); } // Paper - OBFHELPER public void a() { List list = this.tracker.getPassengers(); +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>> 4) + ((configuredSpigotValue & 15) != 0 ? 1 : 0); + this.entityTrackerTrackRanges[ordinal] = trackRange; @@ -166,12 +183,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 int j = MathHelper.floor(entityplayer.locZ()) >> 4; @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker - this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker); -- playerchunkmap_entitytracker.track(this.world.getPlayers()); -+ playerchunkmap_entitytracker.updatePlayers(entity.getPlayersInTrackRange()); // Paper - don't search all players - if (entity instanceof EntityPlayer) { - EntityPlayer entityplayer = (EntityPlayer) entity; + entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker + this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker); +- playerchunkmap_entitytracker.track(this.world.getPlayers()); ++ playerchunkmap_entitytracker.updatePlayers(entity.getPlayersInTrackRange()); // Paper - don't search all players + if (entity instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entity; @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { entity.tracker = null; // Paper - We're no longer tracked @@ -321,6 +338,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/spigotmc/TrackingRange.java +++ b/src/main/java/org/spigotmc/TrackingRange.java @@ -0,0 +0,0 @@ public class TrackingRange + return config.miscTrackingRange; + } else + { +- if (entity instanceof EntityEnderDragon) return ((WorldServer)(entity.getWorld())).getChunkProvider().playerChunkMap.getLoadViewDistance(); // Paper - enderdragon is exempt ++ if (entity instanceof EntityEnderDragon) return defaultRange; // Paper - enderdragon is exempt return config.otherTrackingRange; } } @@ -337,8 +359,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + switch (entity.activationType) { + case RAIDER: + case MONSTER: ++ case FLYING_MONSTER: + return TrackingRangeType.MONSTER; + case WATER: ++ case VILLAGER: + case ANIMAL: + return TrackingRangeType.ANIMAL; + case MISC: diff --git a/Spigot-Server-Patches/Villager-Restocks-API.patch b/Spigot-Server-Patches/Villager-Restocks-API.patch index 5a828d88f9..3bc317aec4 100644 --- a/Spigot-Server-Patches/Villager-Restocks-API.patch +++ b/Spigot-Server-Patches/Villager-Restocks-API.patch @@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/EntityVillager.java @@ -0,0 +0,0 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - return optional.isPresent() && optional1.isPresent() ? i - ((MinecraftSerializableLong) optional.get()).a() < 24000L && i - ((MinecraftSerializableLong) optional1.get()).a() < 36000L : false; + return optional.isPresent() ? i - (Long) optional.get() < 24000L : false; } + + // Paper start From bc5acdddad21d004e590510d1da20d2dee58ed76 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 25 Jun 2020 21:58:00 -0400 Subject: [PATCH 12/91] Current non compilable status of all patches - THIS IS NOT READY THERE IS STILL NO ETA. GOBLINS WILL EAT YOU. --- Paper-MojangAPI/pom.xml | 2 +- .../Add-ProjectileCollideEvent.patch | 5 - ...dd-configurable-portal-search-radius.patch | 4 +- .../Add-permission-for-command-blocks.patch | 79 ----- .../Add-villager-reputation-API.patch | 8 +- ...unk-Unloads-based-on-Player-Movement.patch | 6 - ...sure-Entity-AABB-s-are-never-invalid.patch | 55 ---- ...der-respects-game-and-entity-rules-f.patch | 5 +- .../Ensure-safe-gateway-teleport.patch | 17 +- ...ent-consumeArrow-and-getArrowItem-AP.patch | 8 - .../Expose-Arrow-getItemStack.patch | 2 +- .../Fix-CraftServer.unloadWorld-Leak.patch | 124 -------- Spigot-Server-Patches/Fix-Light-Command.patch | 2 +- .../Fix-enderdragon-exp-dupe.patch | 21 +- ...x-items-vanishing-through-end-portal.patch | 2 +- ...ston-physics-inconsistency-MC-188840.patch | 9 +- .../Fix-this-stupid-bullshit.patch | 2 +- ...k-Priority-Urgency-System-for-Chunks.patch | 89 ++++-- ...quid-s-Entity-Collision-optimisation.patch | 101 ------- .../Implement-PlayerLocaleChangeEvent.patch | 1 + ...mprove-Chunk-Status-Transition-Speed.patch | 26 +- ...generate-Carving-Masks-BitSet-unless.patch | 43 --- .../Optimize-Bit-Operations-by-inlining.patch | 97 ++----- .../Optimize-Light-Engine.patch | 268 +++++++---------- ...ze-NibbleArray-to-use-pooled-buffers.patch | 12 +- ...der-Remove-Streams-Optimized-collect.patch | 162 ----------- .../Optimize-Villagers.patch | 273 ------------------ ...WorldBorder-collision-checks-and-air.patch | 61 ---- ...-packets-to-nearby-locations-sounds-.patch | 66 ++--- Spigot-Server-Patches/POM-Changes.patch | 2 +- Spigot-Server-Patches/Potential-bed-API.patch | 17 +- ...vent-opening-inventories-when-frozen.patch | 8 +- ...-desync-in-playerconnection-causing-.patch | 2 +- ...and-End-Portal-Frames-from-being-des.patch | 69 ++--- ...llocation-of-Vec3D-by-entity-tracker.patch | 2 +- ...me-Streams-usage-in-Entity-Collision.patch | 178 ------------ ...ient-crashes-server-lists-and-Mojang.patch | 2 +- ...ookup-for-Treasure-Maps-Fixes-lag-fr.patch | 5 +- ...Wait-for-Async-Tasks-during-shutdown.patch | 2 +- ...ound-for-Client-Lag-Spikes-MC-162253.patch | 6 +- work/Bukkit | 2 +- work/CraftBukkit | 2 +- work/Spigot | 2 +- 43 files changed, 316 insertions(+), 1533 deletions(-) delete mode 100644 Spigot-Server-Patches/Add-permission-for-command-blocks.patch delete mode 100644 Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch delete mode 100644 Spigot-Server-Patches/Fix-CraftServer.unloadWorld-Leak.patch delete mode 100644 Spigot-Server-Patches/Implement-JellySquid-s-Entity-Collision-optimisation.patch delete mode 100644 Spigot-Server-Patches/MC-183249-Don-t-generate-Carving-Masks-BitSet-unless.patch delete mode 100644 Spigot-Server-Patches/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch delete mode 100644 Spigot-Server-Patches/Optimize-Villagers.patch delete mode 100644 Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch delete mode 100644 Spigot-Server-Patches/Remove-some-Streams-usage-in-Entity-Collision.patch diff --git a/Paper-MojangAPI/pom.xml b/Paper-MojangAPI/pom.xml index d0da7daf4e..4c7c62c787 100644 --- a/Paper-MojangAPI/pom.xml +++ b/Paper-MojangAPI/pom.xml @@ -10,7 +10,7 @@ com.destroystokyo.paper paper-mojangapi - 1.15.2-R0.1-SNAPSHOT + 1.16.1-R0.1-SNAPSHOT jar Paper-MojangAPI diff --git a/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch b/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch index bec046d55f..46d33f3603 100644 --- a/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch +++ b/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch @@ -66,11 +66,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (movingobjectposition != null) { + // Paper end this.a(movingobjectposition); - // CraftBukkit start - if (this.dead) { - org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition); - } - // CraftBukkit end + } // Paper } diff --git a/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch b/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch index f5aaed2731..ed9e673a98 100644 --- a/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch +++ b/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch @@ -41,8 +41,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit start Location enter = this.getBukkitEntity().getLocation(); Location exit = (worldserver == null) ? null : new Location(worldserver.getWorld(), d0, d1, d2, f1, f); -- PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, resourcekey == World.THE_END ? 0 : 16); -+ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, worldserver.paperConfig.portalSearchRadius, true, resourcekey == World.THE_END ? 0 : worldserver.paperConfig.portalCreateRadius); +- PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, resourcekey == DimensionManager.THE_END ? 0 : 16); ++ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, worldserver.paperConfig.portalSearchRadius, true, resourcekey == DimensionManager.THE_END ? 0 : worldserver.paperConfig.portalCreateRadius); Bukkit.getServer().getPluginManager().callEvent(event); if (event.isCancelled() || event.getTo() == null) { return null; diff --git a/Spigot-Server-Patches/Add-permission-for-command-blocks.patch b/Spigot-Server-Patches/Add-permission-for-command-blocks.patch deleted file mode 100644 index 5dd95643b7..0000000000 --- a/Spigot-Server-Patches/Add-permission-for-command-blocks.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mariell Hoversholm -Date: Sat, 16 May 2020 10:05:30 +0200 -Subject: [PATCH] Add permission for command blocks - - -diff --git a/src/main/java/net/minecraft/server/BlockCommand.java b/src/main/java/net/minecraft/server/BlockCommand.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BlockCommand.java -+++ b/src/main/java/net/minecraft/server/BlockCommand.java -@@ -0,0 +0,0 @@ public class BlockCommand extends BlockTileEntity { - public EnumInteractionResult interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { - TileEntity tileentity = world.getTileEntity(blockposition); - -- if (tileentity instanceof TileEntityCommand && entityhuman.isCreativeAndOp()) { -+ if (tileentity instanceof TileEntityCommand && (entityhuman.isCreativeAndOp() || (entityhuman.isCreative() && entityhuman.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission - entityhuman.a((TileEntityCommand) tileentity); - return EnumInteractionResult.SUCCESS; - } else { -diff --git a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java -+++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java -@@ -0,0 +0,0 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener { - } - - public boolean a(EntityHuman entityhuman) { -- if (!entityhuman.isCreativeAndOp()) { -+ if (!entityhuman.isCreativeAndOp() && !entityhuman.isCreative() && !entityhuman.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission - return false; - } else { - if (entityhuman.getWorld().isClientSide) { -diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -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 @@ public class PlayerConnection implements PacketListenerPlayIn { - PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandblock, this, this.player.getWorldServer()); - if (!this.minecraftServer.getEnableCommandBlock()) { - this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0])); -- } else if (!this.player.isCreativeAndOp()) { -+ } else if (!this.player.isCreativeAndOp() && !this.player.isCreative() && !this.player.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission - this.player.sendMessage(new ChatMessage("advMode.notAllowed", new Object[0])); - } else { - CommandBlockListenerAbstract commandblocklistenerabstract = null; -@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { - PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandminecart, this, this.player.getWorldServer()); - if (!this.minecraftServer.getEnableCommandBlock()) { - this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0])); -- } else if (!this.player.isCreativeAndOp()) { -+ } else if (!this.player.isCreativeAndOp() && !this.player.isCreative() && !this.player.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission - this.player.sendMessage(new ChatMessage("advMode.notAllowed", new Object[0])); - } else { - CommandBlockListenerAbstract commandblocklistenerabstract = packetplayinsetcommandminecart.a(this.player.world); -diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/PlayerInteractManager.java -+++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java -@@ -0,0 +0,0 @@ public class PlayerInteractManager { - TileEntity tileentity = this.world.getTileEntity(blockposition); - Block block = iblockdata.getBlock(); - -- if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp()) { -+ if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp() && !(block instanceof BlockCommand && (this.player.isCreative() && this.player.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission - this.world.notify(blockposition, iblockdata, iblockdata, 3); - return false; - } else if (this.player.a((World) this.world, blockposition, this.gamemode)) { -diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java -@@ -0,0 +0,0 @@ public final class CraftDefaultPermissions { - DefaultPermissions.registerPermission(ROOT + ".nbt.copy", "Gives the user the ability to copy NBT in creative", org.bukkit.permissions.PermissionDefault.TRUE, parent); - DefaultPermissions.registerPermission(ROOT + ".debugstick", "Gives the user the ability to use the debug stick in creative", org.bukkit.permissions.PermissionDefault.OP, parent); - DefaultPermissions.registerPermission(ROOT + ".debugstick.always", "Gives the user the ability to use the debug stick in all game modes", org.bukkit.permissions.PermissionDefault.FALSE, parent); -+ DefaultPermissions.registerPermission(ROOT + ".commandblock", "Gives the user the ability to use command blocks.", org.bukkit.permissions.PermissionDefault.OP, parent); // Paper - // Spigot end - parent.recalculatePermissibles(); - } diff --git a/Spigot-Server-Patches/Add-villager-reputation-API.patch b/Spigot-Server-Patches/Add-villager-reputation-API.patch index d37d07d188..46409b3cdb 100644 --- a/Spigot-Server-Patches/Add-villager-reputation-API.patch +++ b/Spigot-Server-Patches/Add-villager-reputation-API.patch @@ -24,12 +24,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- 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 - this.bL = 0; + this.bK = 0; } -+ public Reputation getReputation() { return this.eN(); } // Paper - OBFHELPER - public Reputation eN() { - return this.bG; ++ public Reputation getReputation() { return this.fj(); } // Paper - OBFHELPER + public Reputation fj() { + return this.bF; } diff --git a/src/main/java/net/minecraft/server/Reputation.java b/src/main/java/net/minecraft/server/Reputation.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/Delay-Chunk-Unloads-based-on-Player-Movement.patch b/Spigot-Server-Patches/Delay-Chunk-Unloads-based-on-Player-Movement.patch index 9f68c91343..11429dfed7 100644 --- a/Spigot-Server-Patches/Delay-Chunk-Unloads-based-on-Player-Movement.patch +++ b/Spigot-Server-Patches/Delay-Chunk-Unloads-based-on-Player-Movement.patch @@ -85,12 +85,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public int compareTo(Ticket ticket) { @@ -0,0 +0,0 @@ public final class Ticket implements Comparable> { - return this.b; - } - -+ protected void setCurrentTick(long i) { a(i); } // Paper - OBFHELPER - protected void a(long i) { - this.d = i; } protected boolean b(long i) { diff --git a/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch b/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch deleted file mode 100644 index df47863da2..0000000000 --- a/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sun, 10 May 2020 22:12:46 -0400 -Subject: [PATCH] Ensure Entity AABB's are never invalid - -If anything used setPositionRaw, it left potential for an AABB -to be left stale at their old location, which could cause massive -AABB boxes if movement ever then got called on the new position. - -This guarantees any time we set the entities position, we also -update their AABB. - -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 - - public void setPosition(double d0, double d1, double d2) { - this.setPositionRaw(d0, d1, d2); -- float f = this.size.width / 2.0F; -- float f1 = this.size.height; -- -- this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f)); -+ // Paper start - move into setPositionRaw -+ //float f = this.size.width / 2.0F; -+ //float f1 = this.size.height; -+ //this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f)); -+ // Paper end - if (valid) ((WorldServer) world).chunkCheck(this); // CraftBukkit - } - -@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - return new AxisAlignedBB(vec3d, vec3d1); - } - -+ public final void setBoundingBox(AxisAlignedBB axisalignedbb) { a(axisalignedbb); } // Paper - OBFHELPER - public void a(AxisAlignedBB axisalignedbb) { - // CraftBukkit start - block invalid bounding boxes - double minX = axisalignedbb.minX, -@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - } - - public void setPositionRaw(double d0, double d1, double d2) { -+ // Paper start - never allow AABB to become desynced from position -+ // hanging has its own special logic -+ if (!(this instanceof EntityHanging) && (locX != d0 || locY != d1 || locZ != d2)) { -+ float f = this.size.width / 2.0F; -+ float f1 = this.size.height; -+ this.setBoundingBox(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f)); -+ } -+ // Paper end - this.locX = d0; - this.locY = d1; - this.locZ = d2; diff --git a/Spigot-Server-Patches/Ensure-EntityRaider-respects-game-and-entity-rules-f.patch b/Spigot-Server-Patches/Ensure-EntityRaider-respects-game-and-entity-rules-f.patch index a28cbb2327..18a1927e0b 100644 --- a/Spigot-Server-Patches/Ensure-EntityRaider-respects-game-and-entity-rules-f.patch +++ b/Spigot-Server-Patches/Ensure-EntityRaider-respects-game-and-entity-rules-f.patch @@ -23,7 +23,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public boolean a() { + if (!getRaider().world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) || !getRaider().canPickupLoot()) return false; // Paper - respect game and entity rules for picking up items -+ - Raid raid = this.b.eE(); + Raid raid = this.b.fb(); - if (this.b.eF() && !this.b.eE().a() && this.b.es() && !ItemStack.matches(this.b.getEquipment(EnumItemSlot.HEAD), Raid.s())) { + if (this.b.fc() && !this.b.fb().a() && this.b.eO() && !ItemStack.matches(this.b.getEquipment(EnumItemSlot.HEAD), Raid.s())) { diff --git a/Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch b/Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch index f350339dd9..1d08fe4d31 100644 --- a/Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch +++ b/Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch @@ -14,16 +14,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 List list = this.world.a(Entity.class, new AxisAlignedBB(this.getPosition())); - - if (!list.isEmpty()) { -- this.a(((Entity) list.get(0)).getRootVehicle()); -- } -+ // Paper start -+ for (Entity entity : list) { -+ if (!entity.isPassenger() && !entity.isVehicle() && entity.canPortal()) { -+ this.a(entity); -+ break; -+ } +- this.a((Entity) list.get(this.world.random.nextInt(list.size()))); ++ // Paper start ++ for (Entity entity : list) { ++ if (!entity.isPassenger() && !entity.isVehicle() && entity.canPortal()) { ++ this.a(entity); ++ break; + } -+ // Paper end + } ++ // Paper end if (this.age % 2400L == 0L) { this.h(); diff --git a/Spigot-Server-Patches/EntityShootBowEvent-consumeArrow-and-getArrowItem-AP.patch b/Spigot-Server-Patches/EntityShootBowEvent-consumeArrow-and-getArrowItem-AP.patch index 89ac9db8d9..2daa038477 100644 --- a/Spigot-Server-Patches/EntityShootBowEvent-consumeArrow-and-getArrowItem-AP.patch +++ b/Spigot-Server-Patches/EntityShootBowEvent-consumeArrow-and-getArrowItem-AP.patch @@ -75,14 +75,6 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b 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 @@ import net.minecraft.server.GeneratorAccess; - import net.minecraft.server.IBlockData; - import net.minecraft.server.IChatBaseComponent; - import net.minecraft.server.IInventory; -+import net.minecraft.server.IProjectile; - import net.minecraft.server.ItemActionContext; - import net.minecraft.server.ItemStack; - import net.minecraft.server.Items; @@ -0,0 +0,0 @@ public class CraftEventFactory { /** * EntityShootBowEvent diff --git a/Spigot-Server-Patches/Expose-Arrow-getItemStack.patch b/Spigot-Server-Patches/Expose-Arrow-getItemStack.patch index d08a9ac7a2..374b7dc20c 100644 --- a/Spigot-Server-Patches/Expose-Arrow-getItemStack.patch +++ b/Spigot-Server-Patches/Expose-Arrow-getItemStack.patch @@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityArrow.java +++ b/src/main/java/net/minecraft/server/EntityArrow.java -@@ -0,0 +0,0 @@ public abstract class EntityArrow extends Entity implements IProjectile { +@@ -0,0 +0,0 @@ public abstract class EntityArrow extends IProjectile { } } diff --git a/Spigot-Server-Patches/Fix-CraftServer.unloadWorld-Leak.patch b/Spigot-Server-Patches/Fix-CraftServer.unloadWorld-Leak.patch deleted file mode 100644 index 6226dbf047..0000000000 --- a/Spigot-Server-Patches/Fix-CraftServer.unloadWorld-Leak.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Fri, 8 May 2020 20:30:58 -0400 -Subject: [PATCH] Fix CraftServer.unloadWorld Leak - -The dimension manager was still registered which leaked the entire World - -diff --git a/src/main/java/net/minecraft/server/DimensionManager.java b/src/main/java/net/minecraft/server/DimensionManager.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/DimensionManager.java -+++ b/src/main/java/net/minecraft/server/DimensionManager.java -@@ -0,0 +0,0 @@ public class DimensionManager implements MinecraftSerializable { - private final boolean hasSkyLight; - private final GenLayerZoomer genLayerZoomer; - -+ // Paper start -+ public static void unregister(String s, DimensionManager dimensionmanager) { -+ if (dimensionmanager == OVERWORLD || dimensionmanager == NETHER || dimensionmanager == THE_END) { return; } // do not unregister the default worlds -+ MCUtil.MAIN_EXECUTOR.execute(() -> { -+ RegistryMaterials registry = (RegistryMaterials) IRegistry.DIMENSION_TYPE; -+ registry.deleteValue(new MinecraftKey(s), dimensionmanager); -+ }); -+ } -+ // Paper end - public static DimensionManager register(String s, DimensionManager dimensionmanager) { - return (DimensionManager) IRegistry.a(IRegistry.DIMENSION_TYPE, dimensionmanager.id, s, dimensionmanager); - } -diff --git a/src/main/java/net/minecraft/server/RegistryID.java b/src/main/java/net/minecraft/server/RegistryID.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/RegistryID.java -+++ b/src/main/java/net/minecraft/server/RegistryID.java -@@ -0,0 +0,0 @@ import javax.annotation.Nullable; - public class RegistryID implements Registry { - - private static final Object a = null; -- private K[] b; -+ private K[] b; // Paper - diff below - private int[] c; -- private K[] d; -+ private K[] d; // Paper - diff below - private int e; - private int f; - private java.util.BitSet usedIds; // Paper -+ // Paper start -+ public void removeValue(K value) { -+ removeValue(value, this.b); -+ removeValue(value, this.d); -+ rehash(this.b.length); -+ } -+ public void removeValue(K value, K[] arr) { -+ for (int i = 0; i < arr.length; i++) { -+ K k = arr[i]; -+ if (k == value) { -+ arr[i] = null; -+ } -+ } -+ } - - public RegistryID(int i) { - i = (int) ((float) i / 0.8F); -@@ -0,0 +0,0 @@ public class RegistryID implements Registry { - return this.e; - } - -+ private void rehash(int i) { d(i); } // Paper - OBFHELPER - private void d(int i) { - K[] ak = this.b; - int[] aint = this.c; -diff --git a/src/main/java/net/minecraft/server/RegistryMaterials.java b/src/main/java/net/minecraft/server/RegistryMaterials.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/RegistryMaterials.java -+++ b/src/main/java/net/minecraft/server/RegistryMaterials.java -@@ -0,0 +0,0 @@ public class RegistryMaterials extends IRegistryWritable { - private int V; - - public RegistryMaterials() {} -+ public T deleteValue(MinecraftKey minecraftkey, T value) { -+ this.b.removeValue(value); // Diff 1 -+ this.d = null; // Diff 2 -+ return this.c.remove(minecraftkey); // Diff 3 -+ } - - @Override - public V a(int i, MinecraftKey minecraftkey, V v0) { -- this.b.a(v0, i); -+ this.b.a(v0, i); // Paper - diff above 1 - Validate.notNull(minecraftkey); - Validate.notNull(v0); -- this.d = null; -+ this.d = null; // Diff 2 - if (this.c.containsKey(minecraftkey)) { - RegistryMaterials.LOGGER.debug("Adding duplicate key '{}' to registry", minecraftkey); - } - -- this.c.put(minecraftkey, v0); -+ this.c.put(minecraftkey, v0); // Paper - diff3 - if (this.V <= i) { - this.V = i + 1; - } -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 @@ import net.minecraft.server.EntityPlayer; - import net.minecraft.server.EnumDifficulty; - import net.minecraft.server.EnumGamemode; - import net.minecraft.server.IRecipe; -+import net.minecraft.server.IRegistry; - import net.minecraft.server.Item; - import net.minecraft.server.ItemWorldMap; - import net.minecraft.server.Items; -@@ -0,0 +0,0 @@ public final class CraftServer implements Server { - } - - worlds.remove(world.getName().toLowerCase(java.util.Locale.ENGLISH)); -- console.worldServer.remove(handle.getWorldProvider().getDimensionManager()); -+ // Paper start -+ DimensionManager dimensionManager = handle.getWorldProvider().getDimensionManager(); -+ DimensionManager.unregister(world.getName().toLowerCase(java.util.Locale.ENGLISH), dimensionManager); -+ console.worldServer.remove(dimensionManager); -+ // Paper end - return true; - } - diff --git a/Spigot-Server-Patches/Fix-Light-Command.patch b/Spigot-Server-Patches/Fix-Light-Command.patch index 098b71e7c8..2fbdef8430 100644 --- a/Spigot-Server-Patches/Fix-Light-Command.patch +++ b/Spigot-Server-Patches/Fix-Light-Command.patch @@ -161,6 +161,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.mailboxWorldGen = this.p.a(threadedmailbox, false); this.mailboxMain = this.p.a(mailbox, false); + this.mailboxLight = this.p.a(lightthreaded, false);// Paper - this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getWorldProvider().f(), threadedmailbox1, this.p.a(threadedmailbox1, false)); + this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getDimensionManager().hasSkyLight(), threadedmailbox1, this.p.a(threadedmailbox1, false)); this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler); this.chunkDistanceManager.chunkMap = this; // Paper this.l = supplier; diff --git a/Spigot-Server-Patches/Fix-enderdragon-exp-dupe.patch b/Spigot-Server-Patches/Fix-enderdragon-exp-dupe.patch index e854d69013..f986ea7e3c 100644 --- a/Spigot-Server-Patches/Fix-enderdragon-exp-dupe.patch +++ b/Spigot-Server-Patches/Fix-enderdragon-exp-dupe.patch @@ -11,27 +11,18 @@ 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 { - public float bx; - public float by; - public boolean bz; -- public int bA; -+ public int bA; public final int getDeathTicks() { return this.bA; } public final void setDeathTicks(final int value) { this.bA = value; } // Paper - public float bB; - @Nullable - public EntityEnderCrystal currentEnderCrystal; -@@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - public void b(NBTTagCompound nbttagcompound) { - super.b(nbttagcompound); - nbttagcompound.setInt("DragonPhase", this.bO.a().getControllerPhase().b()); -+ nbttagcompound.setInt("Paper.DeathTick", this.getDeathTicks()); // Paper + public void saveData(NBTTagCompound nbttagcompound) { + super.saveData(nbttagcompound); + nbttagcompound.setInt("DragonPhase", this.bN.a().getControllerPhase().b()); ++ nbttagcompound.setInt("Paper.DeathTick", this.deathAnimationTicks); // Paper } @Override @@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { if (nbttagcompound.hasKey("DragonPhase")) { - this.bO.setControllerPhase(DragonControllerPhase.getById(nbttagcompound.getInt("DragonPhase"))); + this.bN.setControllerPhase(DragonControllerPhase.getById(nbttagcompound.getInt("DragonPhase"))); } -+ this.setDeathTicks(nbttagcompound.getInt("Paper.DeathTick")); // Paper ++ this.deathAnimationTicks = nbttagcompound.getInt("Paper.DeathTick"); // Paper } diff --git a/Spigot-Server-Patches/Fix-items-vanishing-through-end-portal.patch b/Spigot-Server-Patches/Fix-items-vanishing-through-end-portal.patch index 2892b633b8..6001012c5c 100644 --- a/Spigot-Server-Patches/Fix-items-vanishing-through-end-portal.patch +++ b/Spigot-Server-Patches/Fix-items-vanishing-through-end-portal.patch @@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke if (blockposition == null) { // CraftBukkit - if (this.world.getDimensionKey() == World.THE_END && worldserver.getDimensionKey() == World.OVERWORLD) { + if (this.world.getTypeKey() == DimensionManager.THE_END && worldserver.getTypeKey() == DimensionManager.OVERWORLD) { // CraftBukkit + // Paper start - Ensure spawn chunk is always loaded before calculating Y coordinate + this.world.getChunkAtWorldCoords(this.world.getSpawn()); + // Paper end diff --git a/Spigot-Server-Patches/Fix-piston-physics-inconsistency-MC-188840.patch b/Spigot-Server-Patches/Fix-piston-physics-inconsistency-MC-188840.patch index 4e5bd971a2..665a490241 100644 --- a/Spigot-Server-Patches/Fix-piston-physics-inconsistency-MC-188840.patch +++ b/Spigot-Server-Patches/Fix-piston-physics-inconsistency-MC-188840.patch @@ -63,20 +63,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 blockposition3 = blockposition3.shift(enumdirection1); map.remove(blockposition3); world.setTypeAndData(blockposition3, (IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPiston.FACING, enumdirection), 68); -- world.setTileEntity(blockposition3, BlockPistonMoving.a((IBlockData) list1.get(k), enumdirection, flag, false)); + // Paper start - fix a variety of piston desync dupes + if (!allowDesync) { + iblockdata1 = world.getType(oldPos); + map.replace(oldPos, iblockdata1); + } -+ world.setTileEntity(blockposition3, BlockPistonMoving.a(allowDesync ? list1.get(k) : iblockdata1, enumdirection, flag, false)); + world.setTileEntity(blockposition3, BlockPistonMoving.a((IBlockData) list1.get(k), enumdirection, flag, false)); + if (!allowDesync) { + world.setTypeAndData(oldPos, Blocks.AIR.getBlockData(), 2 | 4 | 16 | 1024); // set air to prevent later physics updates from seeing this block + } + // Paper end - fix a variety of piston desync dupes - --j; - aiblockdata[j] = iblockdata1; + aiblockdata[j++] = iblockdata1; } + diff --git a/src/main/java/net/minecraft/server/TileEntityPiston.java b/src/main/java/net/minecraft/server/TileEntityPiston.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/TileEntityPiston.java @@ -89,4 +88,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.world.setTypeAndData(this.position, this.a, com.destroystokyo.paper.PaperConfig.allowPistonDuplication ? 84 : (84 | 2)); // Paper - force notify (flag 2), it's possible the set type by the piston block (which doesn't notify) set this block to air Block.a(this.a, iblockdata, this.world, this.position, 3); } else { - if (iblockdata.b((IBlockState) BlockProperties.C) && (Boolean) iblockdata.get(BlockProperties.C)) { + if (iblockdata.b(BlockProperties.C) && (Boolean) iblockdata.get(BlockProperties.C)) { diff --git a/Spigot-Server-Patches/Fix-this-stupid-bullshit.patch b/Spigot-Server-Patches/Fix-this-stupid-bullshit.patch index df33fd65b8..d3df7489ae 100644 --- a/Spigot-Server-Patches/Fix-this-stupid-bullshit.patch +++ b/Spigot-Server-Patches/Fix-this-stupid-bullshit.patch @@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -0,0 +0,0 @@ public class Main { Calendar deadline = Calendar.getInstance(); - deadline.add(Calendar.DAY_OF_YEAR, -3); + deadline.add(Calendar.DAY_OF_YEAR, -1); if (buildDate.before(deadline.getTime())) { - System.err.println("*** Error, this build is outdated ***"); + // Paper start - This is some stupid bullshit diff --git a/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch b/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch index 582ad169ef..ee4cbb798c 100644 --- a/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch +++ b/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch @@ -87,7 +87,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public final BlockPosition asPosition() { return l(); } // Paper - OBFHELPER public BlockPosition l() { - return new BlockPosition(this.x << 4, 0, this.z << 4); + return new BlockPosition(this.d(), 0, this.e()); } diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -113,8 +113,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { } - private static int a(ArraySetSorted> arraysetsorted) { -+ AsyncCatcher.catchOp("ChunkMapDistance::getHighestTicketLevel"); // Paper + private static int getLowestTicketLevel(ArraySetSorted> arraysetsorted) { ++ AsyncCatcher.catchOp("ChunkMapDistance::getLowestTicketLevel"); // Paper return !arraysetsorted.isEmpty() ? ((Ticket) arraysetsorted.b()).b() : PlayerChunkMap.GOLDEN_TICKET + 1; } @@ -122,9 +122,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public boolean a(PlayerChunkMap playerchunkmap) { //this.f.a(); // Paper - no longer used -+ AsyncCatcher.catchOp("DistanceManagerTick"); ++ AsyncCatcher.catchOp("DistanceManagerTick"); // Paper this.g.a(); - int i = Integer.MAX_VALUE - this.e.a(Integer.MAX_VALUE); + int i = Integer.MAX_VALUE - this.ticketLevelTracker.a(Integer.MAX_VALUE); boolean flag = i != 0; @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { @@ -149,7 +149,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private boolean addTicket(long i, Ticket ticket) { // CraftBukkit - void -> boolean + AsyncCatcher.catchOp("ChunkMapDistance::addTicket"); // Paper ArraySetSorted> arraysetsorted = this.e(i); - int j = a(arraysetsorted); + int j = getLowestTicketLevel(arraysetsorted); Ticket ticket1 = (Ticket) arraysetsorted.a(ticket); // CraftBukkit - decompile error @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { } @@ -157,18 +157,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private boolean removeTicket(long i, Ticket ticket) { // CraftBukkit - void -> boolean + AsyncCatcher.catchOp("ChunkMapDistance::removeTicket"); // Paper ArraySetSorted> arraysetsorted = this.e(i); -+ int oldLevel = a(arraysetsorted); // Paper ++ int oldLevel = getLowestTicketLevel(arraysetsorted); // Paper boolean removed = false; // CraftBukkit if (arraysetsorted.remove(ticket)) { @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { - if (arraysetsorted.isEmpty()) { this.tickets.remove(i); } -- -- this.e.b(i, a(arraysetsorted), false); -+ int newLevel = a(arraysetsorted); // Paper -+ if (newLevel > oldLevel) this.e.b(i, newLevel, false); // Paper + +- this.ticketLevelTracker.update(i, getLowestTicketLevel(arraysetsorted), false); ++ int newLevel = getLowestTicketLevel(arraysetsorted); // Paper ++ if (newLevel > oldLevel) this.ticketLevelTracker.update(i, newLevel, false); // Paper return removed; // CraftBukkit } @@ -317,6 +316,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Ticket ticket = new Ticket<>(TicketType.PLAYER, 33, coords); // Paper - no-tick view distance if (flag1) { +- ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { + scheduleChunkLoad(i, MinecraftServer.currentTick, j, (priority) -> { // Paper - smarter ticket delay based on frustum and distance + // Paper start - recheck its still valid if not cancel + if (!isChunkInRange(i)) { @@ -337,16 +337,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return; + } + // Paper end - ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error ++ ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error ChunkMapDistance.this.m.execute(() -> { - if (this.c(this.c(i))) { + if (isChunkInRange(i)) { if (!hasPlayerTicket(coords, 33)) { // Paper - high priority might of already added it ChunkMapDistance.this.addTicket(i, ticket); ChunkMapDistance.this.l.add(i); - } else { -+ } -+ } else { // Paper - ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error +- ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { ++ }} else { // Paper ++ ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error }, i, false)); } @@ -357,7 +357,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 })); + }); // Paper } else { - ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error + ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { ChunkMapDistance.this.m.execute(() -> { ChunkMapDistance.this.removeTicket(i, ticket); + ChunkMapDistance.this.clearPriorityTickets(coords); // Paper @@ -562,11 +562,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private boolean a(@Nullable PlayerChunk playerchunk, int i) { @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - return this.serverThreadQueue.executeNext(); } -- private boolean tickDistanceManager() { -+ public boolean tickDistanceManager() { // Paper - public + public boolean tickDistanceManager() { // Paper - private -> public + if (chunkMapDistance.delayDistanceManagerTick) return false; // Paper boolean flag = this.chunkMapDistance.a(this.playerChunkMap); boolean flag1 = this.playerChunkMap.b(); @@ -611,7 +609,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Yes, this doesn't match Vanilla, but it's the best we can do for now. // If this is an issue, PRs are welcome @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - if (valid && (!this.isSpectator() || this.world.isLoaded(new BlockPosition(this)))) { // Paper - don't tick dead players that are not in the world currently (pending respawn) + if (valid && !this.isSpectator() || this.world.isLoaded(this.getChunkCoordinates())) { // Paper - don't tick dead players that are not in the world currently (pending respawn) super.tick(); } + if (valid && isAlive() && playerConnection != null) ((WorldServer)world).getChunkProvider().playerChunkMap.checkHighPriorityChunks(this); // Paper @@ -844,11 +842,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // note: Here is a very good place to add callbacks to logic waiting on this. Chunk entityTickingChunk = either.left().get(); @@ -0,0 +0,0 @@ public class PlayerChunk { - this.entityTickingFuture.complete(PlayerChunk.UNLOADED_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage this.entityTickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE; } -- -- this.w.a(this.location, this::k, this.ticketLevel, this::d); + +- this.v.a(this.location, this::k, this.ticketLevel, this::d); + // Paper start - raise IO/load priority if priority changes, use our preferred priority + priorityBoost = chunkMap.chunkDistanceManager.getChunkPriority(location); + int priority = getDemandedPriority(); @@ -862,7 +859,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + chunkMap.world.asyncChunkTaskManager.raisePriority(location.x, location.z, ioPriority); + } + if (getCurrentPriority() != priority) { -+ this.w.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority ++ this.v.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority + int neighborsPriority = getNeighborsPriority(); + this.neighbors.forEach((neighbor, neighborDesired) -> neighbor.setNeighborPriority(this, neighborsPriority)); + } @@ -896,6 +893,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + public final WorldServer world; + private final LightEngineThreaded lightEngine; + private final IAsyncTaskHandler executor; ++ final java.util.concurrent.Executor mainInvokingExecutor; // Paper + public final ChunkGenerator chunkGenerator; + private final Supplier l; public final Supplier getWorldPersistentDataSupplier() { return this.l; } // Paper - OBFHELPER + private final VillagePlace m; @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @Override @@ -912,6 +917,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (queued == null) { return; } +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + this.world = worldserver; + this.chunkGenerator = chunkgenerator; + this.executor = iasynctaskhandler; ++ // Paper start ++ this.mainInvokingExecutor = (run) -> { ++ if (MCUtil.isMainThread()) { ++ run.run(); ++ } else { ++ iasynctaskhandler.execute(run); ++ } ++ }; ++ // Paper end + ThreadedMailbox threadedmailbox = ThreadedMailbox.a(executor, "worldgen"); + + iasynctaskhandler.getClass(); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.playerViewDistanceTickMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets, (EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ, @@ -1105,8 +1126,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 long i = playerchunk.i().pair(); playerchunk.getClass(); -- mailbox.a(ChunkTaskQueueSorter.a(runnable, i, playerchunk::getTicketLevel)); // CraftBukkit - decompile error -+ mailbox.a(ChunkTaskQueueSorter.a(runnable, i, () -> 1)); // CraftBukkit - decompile error // Paper - final loads are always urgent! +- mailbox.a(ChunkTaskQueueSorter.a(runnable, i, playerchunk::getTicketLevel)); ++ mailbox.a(ChunkTaskQueueSorter.a(runnable, i, () -> 1)); // Paper - final loads are always urgent! }); } @@ -1138,7 +1159,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (updatingChunk != null) { return updatingChunk.getEntityTickingFuture(); @@ -0,0 +0,0 @@ public abstract class PlayerList { - entityplayer, finalWorldserver, networkmanager, playerconnection, + entityplayer, finalWorldserver, finalWorldserver1, networkmanager, playerconnection, nbttagcompound, networkmanager.getSocketAddress().toString(), lastKnownName ); - //playerChunkMap.chunkDistanceManager.removeTicketAtLevel(TicketType.LOGIN, pos, 31, pos.pair()); @@ -1148,7 +1169,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class PlayerList { SocketAddress socketaddress = loginlistener.networkManager.getSocketAddress(); - EntityPlayer entity = new EntityPlayer(this.server, this.server.getWorldServer(DimensionManager.OVERWORLD), gameprofile, new PlayerInteractManager(this.server.getWorldServer(DimensionManager.OVERWORLD))); + EntityPlayer entity = new EntityPlayer(this.server, this.server.getWorldServer(World.OVERWORLD), gameprofile, new PlayerInteractManager(this.server.getWorldServer(World.OVERWORLD))); + entity.isRealPlayer = true; // Paper Player player = entity.getBukkitEntity(); PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.networkManager.getRawAddress()).getAddress()); @@ -1158,7 +1179,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 worldserver.getChunkProvider().addTicket(TicketType.POST_TELEPORT, new ChunkCoordIntPair(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper + entityplayer1.forceCheckHighPriority(); // Player - while (avoidSuffocation && !worldserver.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) { + while (avoidSuffocation && !worldserver1.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) { entityplayer1.setPosition(entityplayer1.locX(), entityplayer1.locY() + 1.0D, entityplayer1.locZ()); } diff --git a/src/main/java/net/minecraft/server/Ticket.java b/src/main/java/net/minecraft/server/Ticket.java @@ -1173,6 +1194,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected Ticket(TicketType tickettype, int i, T t0) { this.a = tickettype; +@@ -0,0 +0,0 @@ public final class Ticket implements Comparable> { + return this.b; + } + ++ public final void setCurrentTick(long i) { this.a(i); } // Paper - OBFHELPER + protected void a(long i) { + this.d = i; + } diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/TicketType.java diff --git a/Spigot-Server-Patches/Implement-JellySquid-s-Entity-Collision-optimisation.patch b/Spigot-Server-Patches/Implement-JellySquid-s-Entity-Collision-optimisation.patch deleted file mode 100644 index afa783e784..0000000000 --- a/Spigot-Server-Patches/Implement-JellySquid-s-Entity-Collision-optimisation.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: JellySquid -Date: Sat, 9 May 2020 16:25:21 -0400 -Subject: [PATCH] Implement JellySquid's Entity Collision optimisations patch - -Optimizes Full Block voxel collisions, and removes streams from Entity collisions - -Original code by JellySquid, licensed under GNU Lesser General Public License v3.0 -you can find the original code on https://github.com/jellysquid3/lithium-fabric/tree/1.15.x/fabric (Yarn mappings) - -diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/ICollisionAccess.java -+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java -@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess { - - if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { - VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision); -- VoxelShape voxelshape3 = voxelshape2.a((double) k1, (double) l1, (double) i2); - -- if (VoxelShapes.c(voxelshape, voxelshape3, OperatorBoolean.AND)) { -- consumer.accept(voxelshape3); -- return true; -+ // Paper start - Lithium Collision Optimizations -+ if (voxelshape2 == VoxelShapes.empty()) { -+ continue; -+ } -+ -+ if (voxelshape2 == VoxelShapes.fullCube()) { -+ if (axisalignedbb.intersects(x, y, z, x + 1.0D, y + 1.0D, z + 1.0D)) { -+ consumer.accept(voxelshape2.offset(x, y, z)); -+ return true; -+ } -+ } else { -+ VoxelShape shape = voxelshape2.offset(x, y, z); -+ if (VoxelShapes.applyOperation(shape, voxelshape, OperatorBoolean.AND)) { -+ consumer.accept(shape); -+ return true; -+ } -+ // Paper end - } - } - } -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 -+++ b/src/main/java/net/minecraft/server/IEntityAccess.java -@@ -0,0 +0,0 @@ public interface IEntityAccess { - // Paper end - optimise hard collision - - default Stream b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { -- if (axisalignedbb.a() < 1.0E-7D) { -+ // Paper start - remove streams from entity collision -+ if (axisalignedbb.getAverageSideLength() < 1.0E-7D) { - return Stream.empty(); -- } else { -- AxisAlignedBB axisalignedbb1 = axisalignedbb.g(1.0E-7D); -- Stream stream = ((entity != null && entity.hardCollides()) ? this.getEntities(entity, axisalignedbb) : this.getHardCollidingEntities(entity, axisalignedbb1)).stream().filter((entity1) -> { // Paper - decompile fix // Paper - optimise hard collision -- return !set.contains(entity1); -- }).filter((entity1) -> { -- return entity == null || !entity.isSameVehicle(entity1); -- }).flatMap((entity1) -> { -- return Stream.of(entity1.au(), entity == null ? null : entity.j(entity1)); // Paper - optimise hard collision - diff on change, these are the methods that only hard colliding entities override -- }).filter(Objects::nonNull); -- -- return stream.filter(axisalignedbb1::c).map(VoxelShapes::a); -+ - } -+ AxisAlignedBB selection = axisalignedbb.grow(1.0E-7D); -+ List entities = entity != null && entity.hardCollides() ? getEntities(entity, selection) : getHardCollidingEntities(entity, selection); -+ List shapes = new java.util.ArrayList<>(); -+ -+ for (Entity otherEntity : entities) { -+ if (!set.isEmpty() && set.contains(otherEntity)) { -+ continue; -+ } -+ -+ if (entity != null && entity.isSameVehicle(otherEntity)) { -+ continue; -+ } -+ -+ AxisAlignedBB otherEntityBox = otherEntity.getCollisionBox(); -+ -+ if (otherEntityBox != null && selection.intersects(otherEntityBox)) { -+ shapes.add(VoxelShapes.of(otherEntityBox)); -+ } -+ -+ if (entity != null) { -+ AxisAlignedBB otherEntityHardBox = entity.getHardCollisionBox(otherEntity); -+ -+ if (otherEntityHardBox != null && selection.intersects(otherEntityHardBox)) { -+ shapes.add(VoxelShapes.of(otherEntityHardBox)); -+ } -+ } -+ } -+ -+ return shapes.stream(); -+ // Paper end - } - - @Nullable diff --git a/Spigot-Server-Patches/Implement-PlayerLocaleChangeEvent.patch b/Spigot-Server-Patches/Implement-PlayerLocaleChangeEvent.patch index 3d44288fc9..731e33773e 100644 --- a/Spigot-Server-Patches/Implement-PlayerLocaleChangeEvent.patch +++ b/Spigot-Server-Patches/Implement-PlayerLocaleChangeEvent.patch @@ -25,6 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 PlayerLocaleChangeEvent event = new PlayerLocaleChangeEvent(getBukkitEntity(), packetplayinsettings.locale); this.server.server.getPluginManager().callEvent(event); } + this.locale = packetplayinsettings.locale; this.clientViewDistance = packetplayinsettings.viewDistance; // CraftBukkit end + // Paper start - add PlayerLocaleChangeEvent diff --git a/Spigot-Server-Patches/Improve-Chunk-Status-Transition-Speed.patch b/Spigot-Server-Patches/Improve-Chunk-Status-Transition-Speed.patch index 2fa7eecbdf..b18c0d5013 100644 --- a/Spigot-Server-Patches/Improve-Chunk-Status-Transition-Speed.patch +++ b/Spigot-Server-Patches/Improve-Chunk-Status-Transition-Speed.patch @@ -57,30 +57,6 @@ diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/j 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 { - public final WorldServer world; - private final LightEngineThreaded lightEngine; - private final IAsyncTaskHandler executor; -+ final java.util.concurrent.Executor mainInvokingExecutor; // Paper - public final ChunkGenerator chunkGenerator; - private final Supplier l; public final Supplier getWorldPersistentDataSupplier() { return this.l; } // Paper - OBFHELPER - private final VillagePlace m; -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - this.world = worldserver; - this.chunkGenerator = chunkgenerator; - this.executor = iasynctaskhandler; -+ // Paper start - optimize chunk status progression without jumping through thread pool -+ this.mainInvokingExecutor = (run) -> { -+ if (MCUtil.isMainThread()) { -+ run.run(); -+ } else { -+ iasynctaskhandler.execute(run); -+ } -+ }; -+ // Paper end - ThreadedMailbox threadedmailbox = ThreadedMailbox.a(executor, "worldgen"); - - iasynctaskhandler.getClass(); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { return either.mapLeft((list) -> { return (Chunk) list.get(list.size() / 2); @@ -118,6 +94,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return; + } + // Paper end - this.mailboxWorldGen.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error + this.mailboxWorldGen.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); }); } diff --git a/Spigot-Server-Patches/MC-183249-Don-t-generate-Carving-Masks-BitSet-unless.patch b/Spigot-Server-Patches/MC-183249-Don-t-generate-Carving-Masks-BitSet-unless.patch deleted file mode 100644 index 8b6545fd60..0000000000 --- a/Spigot-Server-Patches/MC-183249-Don-t-generate-Carving-Masks-BitSet-unless.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sat, 9 May 2020 12:11:47 -0400 -Subject: [PATCH] MC-183249: Don't generate Carving Masks BitSet unless needed - -This was using SIGNIFICANT amounts of memory allocating many -long[]'s for BitSets for every ProtoChunk in the cache that had -been unloaded and reloaded. - -This will result in a nice memory reduction. - -diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java -+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -@@ -0,0 +0,0 @@ public class ChunkRegionLoader { - for (int l = 0; l < k; ++l) { - WorldGenStage.Features worldgenstage_features = aworldgenstage_features[l]; - -- nbttagcompound3.setByteArray(worldgenstage_features.toString(), ichunkaccess.a(worldgenstage_features).toByteArray()); -+ // Paper start - don't create carving mask bitsets if not even at that chunk status yet -+ BitSet mask = protochunk.getCarvingMaskIfSet(worldgenstage_features); -+ if (mask != null) { -+ nbttagcompound3.setByteArray(worldgenstage_features.toString(), mask.toByteArray()); -+ } -+ // Paper end - } - - nbttagcompound1.set("CarvingMasks", nbttagcompound3); -diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/ProtoChunk.java -+++ b/src/main/java/net/minecraft/server/ProtoChunk.java -@@ -0,0 +0,0 @@ public class ProtoChunk implements IChunkAccess { - private final ProtoChunkTickList q; - private final ProtoChunkTickList r; - private long s; -- private final Map t; -+ private final Map t;public BitSet getCarvingMaskIfSet(WorldGenStage.Features worldgenstage_features) { return this.t.get(worldgenstage_features); } // Paper -+ // Paper end - private volatile boolean u; - private final World world; // Paper - Anti-Xray - Add world - diff --git a/Spigot-Server-Patches/Optimize-Bit-Operations-by-inlining.patch b/Spigot-Server-Patches/Optimize-Bit-Operations-by-inlining.patch index 5dfc5efb24..5a84de14ae 100644 --- a/Spigot-Server-Patches/Optimize-Bit-Operations-by-inlining.patch +++ b/Spigot-Server-Patches/Optimize-Bit-Operations-by-inlining.patch @@ -10,8 +10,8 @@ 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 - return dynamicops.createIntList(IntStream.of(new int[]{this.getX(), this.getY(), this.getZ()})); +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { + this(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ()); } + public static long getAdjacent(int baseX, int baseY, int baseZ, EnumDirection enumdirection) { return asLong(baseX + enumdirection.getAdjacentX(), baseY + enumdirection.getAdjacentY(), baseZ + enumdirection.getAdjacentZ()); } // Paper @@ -25,17 +25,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public static int b(long i) { -- return (int) (i << 64 - BlockPosition.k - BlockPosition.c >> 64 - BlockPosition.c); +- return (int) (i << 64 - BlockPosition.m - BlockPosition.f >> 64 - BlockPosition.f); + return (int) (i >> 38); // Paper - simplify/inline } public static int c(long i) { -- return (int) (i << 64 - BlockPosition.f >> 64 - BlockPosition.f); -+ return (int) ((i << 52) >> 52); // Paper - simplify/inline +- return (int) (i << 64 - BlockPosition.h >> 64 - BlockPosition.h); ++ return (int) ((i << 26) >> 38); // Paper - simplify/inline } public static int d(long i) { -- return (int) (i << 64 - BlockPosition.j - BlockPosition.d >> 64 - BlockPosition.d); +- return (int) (i << 64 - BlockPosition.l - BlockPosition.g >> 64 - BlockPosition.g); + return (int) ((i << 26) >> 38); // Paper - simplify/inline } @@ -44,13 +44,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return new BlockPosition((int) (i >> 38), (int) ((i << 52) >> 52), (int) ((i << 26) >> 38)); // Paper - simplify/inline } + public long asLong() { +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { + 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; - -- l |= ((long) i & BlockPosition.g) << BlockPosition.k; -- l |= ((long) j & BlockPosition.h) << 0; -- l |= ((long) k & BlockPosition.i) << BlockPosition.j; +- l |= ((long) i & BlockPosition.i) << BlockPosition.m; +- l |= ((long) j & BlockPosition.j) << 0; +- l |= ((long) k & BlockPosition.k) << BlockPosition.l; - return l; + return (((long) i & (long) 67108863) << 38) | (((long) j & (long) 4095)) | (((long) k & (long) 67108863) << 12); // Paper - inline constants and simplify } @@ -104,75 +107,35 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - int k = b(blockposition.getZ()); - - return (short) (i << 8 | k << 4 | j); -+ return (short) ((blockposition.x & 15) << 8 | (blockposition.z & 15) << 4 | blockposition.y & 15); // Paper - simplify/inline ++ return (short) ((blockposition.getX() & 15) << 8 | (blockposition.getZ() & 15) << 4 | blockposition.getY() & 15); // Paper - simplify/inline } public static int c(int i) { @@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition { - } - - public static int b(long i) { -- return (int) (i << 0 >> 42); -+ return (int) (i >> 42); // Paper - } - - public static int c(long i) { -@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition { - return (int) (i << 22 >> 42); - } - -- public int a() { -- return this.getX(); -+ public final int a() { // Paper -+ return x; // Paper - } - -- public int b() { -- return this.getY(); -+ public final int b() { // Paper -+ return y; // Paper - } - -- public int c() { -- return this.getZ(); -+ public final int c() { // Paper -+ return z; // Paper + return this.getZ(); } - public int d() { - return this.a() << 4; + public final int d() { // Paper -+ return x << 4; // Paper ++ return this.getX() << 4; // Paper } - public int e() { - return this.b() << 4; + public final int e() { // Paper -+ return y << 4; // Paper ++ return this.getY() << 4; // Paper } - public int f() { - return this.c() << 4; + public final int f() { // Paper -+ return z << 4; // Paper ++ return this.getZ() << 4; // Paper } -- public int g() { -- return (this.a() << 4) + 15; -+ public final int g() { // Paper -+ return (x << 4) + 15; // Paper - } - -- public int h() { -- return (this.b() << 4) + 15; -+ public final int h() { // Paper -+ return (y << 4) + 15; // Paper - } - -- public int r() { -- return (this.c() << 4) + 15; -+ public final int r() { // Paper -+ return (z << 4) + 15; // Paper + public int g() { +@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition { + return (this.c() << 4) + 15; } + public static long blockToSection(long i) { return e(i); } // Paper - OBFHELPER @@ -183,15 +146,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public static long f(long i) { -@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition { - } - - public BlockPosition s() { -- return new BlockPosition(c(this.a()), c(this.b()), c(this.c())); -+ return new BlockPosition(x << 4, y << 4, z << 4); // Paper - } - - public BlockPosition t() { @@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition { return new ChunkCoordIntPair(this.a(), this.c()); } @@ -212,14 +166,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return (((long) i & 4194303L) << 42) | (((long) j & 1048575L)) | (((long) k & 4194303L) << 20); // Paper - Simplify to reduce instruction count } - public long v() { + public long s() { - return b(this.a(), this.b(), this.c()); -+ return (((long) x & 4194303L) << 42) | (((long) y & 1048575L)) | (((long) z & 4194303L) << 20); // Paper - Simplify to reduce instruction count ++ return (((long) getX() & 4194303L) << 42) | (((long) getY() & 1048575L)) | (((long) getZ() & 4194303L) << 20); // Paper - Simplify to reduce instruction count } - public Stream w() { -- return BlockPosition.a(this.d(), this.e(), this.f(), this.g(), this.h(), this.r()); -+ return BlockPosition.a(x << 4, y << 4, z << 4, (x << 4) + 15, (y << 4) + 15, (z << 4) + 15); // Paper - simplify/inline + public Stream t() { +@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition { } public static Stream a(SectionPosition sectionposition, int i) { @@ -228,7 +181,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - int l = sectionposition.c(); - - return a(j - i, k - i, l - i, j + i, k + i, l + i); -+ return a(sectionposition.x - i, sectionposition.y - i, sectionposition.z - i, sectionposition.x + i, sectionposition.y + i, sectionposition.z + i); // Paper - simplify/inline ++ return a(sectionposition.getX() - i, sectionposition.getY() - i, sectionposition.getZ() - i, sectionposition.getX() + i, sectionposition.getY() + i, sectionposition.getZ() + i); // Paper - simplify/inline } public static Stream b(ChunkCoordIntPair chunkcoordintpair, int i) { diff --git a/Spigot-Server-Patches/Optimize-Light-Engine.patch b/Spigot-Server-Patches/Optimize-Light-Engine.patch index 6cf38f1f3d..fb85cb52b1 100644 --- a/Spigot-Server-Patches/Optimize-Light-Engine.patch +++ b/Spigot-Server-Patches/Optimize-Light-Engine.patch @@ -24,19 +24,6 @@ Massive update to light to improve performance and chunk loading/generation. 7) Buffer non urgent tasks even if queueUpdate is called multiple times to improve efficiency. 8) Fix NPE risk that crashes server in getting nibble data -diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java -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 false; - } - -- @Deprecated -+ public final boolean canOcclude(IBlockData blockData) { return n(blockData); } @Deprecated // Paper - OBFHELPER - public final boolean n(IBlockData iblockdata) { - return this.j; - } 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 @@ -50,46 +37,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return super.executeNext() || execChunkTask; // Paper } } finally { -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 - private final boolean e; - private final boolean isAir; // Paper - private final boolean isTicking; // Paper -+ private final boolean canOcclude; // Paper - - public IBlockData(Block block, ImmutableMap, Comparable> immutablemap) { - super(block, immutablemap); -@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements - this.e = block.o(this); - this.isAir = this.getBlock().isAir(this); // Paper - this.isTicking = this.getBlock().isTicking(this); // Paper -+ this.canOcclude = this.getBlock().canOcclude(this); // Paper - } - - public void c() { -@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements - return this.c == null || this.c.h; - } - -- public boolean g() { -+ public final boolean g() { // Paper - return this.e; - } - -@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements - return this.c != null ? this.c.c : this.getBlock().k(this, iblockaccess, blockposition); - } - -- public boolean o() { -- return this.c != null ? this.c.b : this.getBlock().n(this); -+ public final boolean o() { // Paper -+ return canOcclude; // Paper - } - - public VoxelShape getShape(IBlockAccess iblockaccess, BlockPosition blockposition) { diff --git a/src/main/java/net/minecraft/server/LightEngineBlock.java b/src/main/java/net/minecraft/server/LightEngineBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/LightEngineBlock.java @@ -277,8 +224,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - private final IBlockAccess[] h = new IBlockAccess[2]; + private final IChunkAccess[] h = new IChunkAccess[2]; // Paper ++ // Paper start - see fully commented out method below (look for Bedrock) ++ // optimized method with less branching for when scenarios arent needed. ++ // avoid using mutable version if can ++ protected final IBlockData getBlockOptimized(int x, int y, int z, MutableInt mutableint) { ++ IChunkAccess iblockaccess = this.a(x >> 4, z >> 4); ++ ++ if (iblockaccess == null) { ++ mutableint.setValue(16); ++ return Blocks.BEDROCK.getBlockData(); ++ } else { ++ this.pos.setValues(x, y, z); ++ IBlockData iblockdata = iblockaccess.getType(x, y, z); ++ mutableint.setValue(iblockdata.b(this.a.getWorld(), this.pos)); ++ return iblockdata.l() && iblockdata.e() ? iblockdata : Blocks.AIR.getBlockData(); ++ } ++ } ++ protected final IBlockData getBlockOptimized(int x, int y, int z) { ++ IChunkAccess iblockaccess = this.a(x >> 4, z >> 4); ++ ++ if (iblockaccess == null) { ++ return Blocks.BEDROCK.getBlockData(); ++ } else { ++ IBlockData iblockdata = iblockaccess.getType(x, y, z); ++ return iblockdata.l() && iblockdata.e() ? iblockdata : Blocks.AIR.getBlockData(); ++ } ++ } ++ // Paper end public LightEngineLayer(ILightAccess ilightaccess, EnumSkyBlock enumskyblock, S s0) { super(16, 256, 8192); + this.a = ilightaccess; @@ -0,0 +0,0 @@ public abstract class LightEngineLayer, S e } @@ -308,7 +283,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - } - - return Blocks.AIR.getBlockData(); -+ // Paper start - unused, optimized versions below, comment out to detect changes +- } else { +- int j = SectionPosition.a(BlockPosition.b(i)); +- int k = SectionPosition.a(BlockPosition.d(i)); +- IBlockAccess iblockaccess = this.a(j, k); +- +- if (iblockaccess == null) { +- if (mutableint != null) { +- mutableint.setValue(16); +- } +- +- return Blocks.BEDROCK.getBlockData(); +- } else { +- this.d.g(i); +- IBlockData iblockdata = iblockaccess.getType(this.d); +- boolean flag = iblockdata.l() && iblockdata.e(); +- +- if (mutableint != null) { +- mutableint.setValue(iblockdata.b(this.a.getWorld(), (BlockPosition) this.d)); +- } +- +- return flag ? iblockdata : Blocks.AIR.getBlockData(); +- } +- } +- } ++ // Paper start - comment out, see getBlockOptimized +// protected IBlockData a(long i, @Nullable MutableInt mutableint) { +// if (i == Long.MAX_VALUE) { +// if (mutableint != null) { @@ -330,7 +329,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +// } else { +// this.d.g(i); +// IBlockData iblockdata = iblockaccess.getType(this.d); -+// boolean flag = iblockdata.o() && iblockdata.g(); ++// boolean flag = iblockdata.l() && iblockdata.e(); +// +// if (mutableint != null) { +// mutableint.setValue(iblockdata.b(this.a.getWorld(), (BlockPosition) this.d)); @@ -340,55 +339,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +// } +// } +// } -+ // optimized method with less branching for when scenarios arent needed. -+ // avoid using mutable version if can -+ protected final IBlockData getBlockOptimized(int x, int y, int z, MutableInt mutableint) { -+ IChunkAccess iblockaccess = this.a(x >> 4, z >> 4); -+ -+ if (iblockaccess == null) { -+ mutableint.setValue(16); -+ return Blocks.BEDROCK.getBlockData(); - } else { -- int j = SectionPosition.a(BlockPosition.b(i)); -- int k = SectionPosition.a(BlockPosition.d(i)); -- IBlockAccess iblockaccess = this.a(j, k); -- -- if (iblockaccess == null) { -- if (mutableint != null) { -- mutableint.setValue(16); -- } -- -- return Blocks.BEDROCK.getBlockData(); -- } else { -- this.d.g(i); -- IBlockData iblockdata = iblockaccess.getType(this.d); -- boolean flag = iblockdata.o() && iblockdata.g(); -- -- if (mutableint != null) { -- mutableint.setValue(iblockdata.b(this.a.getWorld(), (BlockPosition) this.d)); -- } -+ this.pos.setValues(x, y, z); -+ IBlockData iblockdata = iblockaccess.getType(x, y, z); -+ mutableint.setValue(iblockdata.b(this.a.getWorld(), this.pos)); -+ return iblockdata.o() && iblockdata.g() ? iblockdata : Blocks.AIR.getBlockData(); -+ } -+ } -+ protected final IBlockData getBlockOptimized(int x, int y, int z) { -+ IChunkAccess iblockaccess = this.a(x >> 4, z >> 4); - -- return flag ? iblockdata : Blocks.AIR.getBlockData(); -- } -+ if (iblockaccess == null) { -+ return Blocks.BEDROCK.getBlockData(); -+ } else { -+ IBlockData iblockdata = iblockaccess.getType(x, y, z); -+ return iblockdata.o() && iblockdata.g() ? iblockdata : Blocks.AIR.getBlockData(); - } - } + // Paper end protected VoxelShape a(IBlockData iblockdata, long i, EnumDirection enumdirection) { - return iblockdata.o() ? iblockdata.a(this.a.getWorld(), this.d.g(i), enumdirection) : VoxelShapes.a(); + return iblockdata.l() ? iblockdata.a(this.a.getWorld(), this.d.g(i), enumdirection) : VoxelShapes.a(); @@ -0,0 +0,0 @@ public abstract class LightEngineLayer, S e return i == Long.MAX_VALUE ? 0 : 15 - this.c.i(i); } @@ -583,6 +537,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected final Long2ObjectMap i = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap()); private final LongSet n = new LongOpenHashSet(); private final LongSet o = new LongOpenHashSet(); +@@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e protected volatile boolean j; protected LightEngineStorage(EnumSkyBlock enumskyblock, ILightAccess ilightaccess, M m0) { @@ -696,12 +651,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } if (k >= 2 && j != 2) { -- if (this.o.contains(i)) { -- this.o.remove(i); +- if (this.p.contains(i)) { +- this.p.remove(i); - } else { -+ if (!this.o.remove(i)) { // Paper - remove useless contains - credit to JellySquid -+ //this.o.remove(i); // Paper -+ //} else { // Pape ++ if (!this.p.remove(i)) { // Paper - remove useless contains - credit to JellySquid ++ //this.p.remove(i); // Paper ++ //} else { // Paper this.f.a(i, this.j(i)); this.g.add(i); this.k(i); @@ -746,7 +701,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 NibbleArray nibblearray1 = (NibbleArray) this.i.remove(i); @@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e - longiterator = this.o.iterator(); + longiterator = this.p.iterator(); while (longiterator.hasNext()) { - i = (Long) longiterator.next(); @@ -754,16 +709,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.l(i); } - this.o.clear(); - this.j = false; -- ObjectIterator objectiterator = this.i.long2ObjectEntrySet().iterator(); -+ ObjectIterator> objectiterator = Long2ObjectMaps.fastIterator(this.i); // Paper - +@@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e Entry entry; long j; + NibbleArray test = null; // Paper -+ LongSet propagating = new LongOpenHashSet(); // Paper - credit JellySquid for idea to move this up while (objectiterator.hasNext()) { entry = (Entry) objectiterator.next(); j = entry.getLongKey(); @@ -775,66 +725,48 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.a(lightenginelayer, j); this.f.a(j, nibblearray); this.g.add(j); - } -+ if (!flag1) propagating.add(j); // Paper -+ objectiterator.remove(); // Paper - } - } - - this.f.c(); -- if (!flag1) { -- longiterator = this.i.keySet().iterator(); -+ if (!flag1) {// Paper - diff on change, change propagating add a few lines up -+ longiterator = propagating.iterator(); // Paper +@@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e + longiterator = this.i.keySet().iterator(); while (longiterator.hasNext()) { - i = (Long) longiterator.next(); -- if (this.g(i)) { -- int k = SectionPosition.c(SectionPosition.b(i)); -- int l = SectionPosition.c(SectionPosition.c(i)); -- int i1 = SectionPosition.c(SectionPosition.d(i)); -+ // Paper start -+ i = longiterator.nextLong(); -+ if (true) { // don't check hasLight, this iterator is filtered already -+ int secX = (int) (i >> 42); -+ int secY = (int) (i << 44 >> 44); -+ int secZ = (int) (i << 22 >> 42); -+ int k = secX << 4; // baseX -+ int l = secY << 4; // baseY -+ int i1 = secZ << 4; // baseZ -+ // Paper end - EnumDirection[] aenumdirection = LightEngineStorage.k; - int j1 = aenumdirection.length; ++ i = longiterator.nextLong(); // Paper + this.b(lightenginelayer, i); + } + } else { + longiterator = this.n.iterator(); - for (int k1 = 0; k1 < j1; ++k1) { - EnumDirection enumdirection = aenumdirection[k1]; -- long l1 = SectionPosition.a(i, enumdirection); -- -- if (!this.i.containsKey(l1) && this.g(l1)) { -+ long l1 = SectionPosition.getAdjacentFromSectionPos(secX, secY, secZ, enumdirection); // Paper - avoid extra unpacking -+ if (!propagating.contains(l1) && this.g(l1)) { // Paper - use propagating - for (int i2 = 0; i2 < 16; ++i2) { - for (int j2 = 0; j2 < 16; ++j2) { - long k2; -@@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e + while (longiterator.hasNext()) { +- i = (Long) longiterator.next(); ++ i = longiterator.nextLong(); // Paper + this.b(lightenginelayer, i); } } - -+ // Paper start - moved above - Credit JellySquid for idea -+ /* - objectiterator = this.i.long2ObjectEntrySet().iterator(); - - while (objectiterator.hasNext()) { @@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e - if (this.g(j)) { - objectiterator.remove(); - } -- } -+ }*/ -+ // Paper end - } - } + private void b(LightEngineLayer lightenginelayer, long i) { + if (this.g(i)) { +- int j = SectionPosition.c(SectionPosition.b(i)); +- int k = SectionPosition.c(SectionPosition.c(i)); +- int l = SectionPosition.c(SectionPosition.d(i)); ++ // Paper start ++ int secX = (int) (i >> 42); ++ int secY = (int) (i << 44 >> 44); ++ int secZ = (int) (i << 22 >> 42); ++ int j = secX << 4; // baseX ++ int k = secY << 4; // baseY ++ int l = secZ << 4; // baseZ ++ // Paper end + EnumDirection[] aenumdirection = LightEngineStorage.k; + int i1 = aenumdirection.length; + + for (int j1 = 0; j1 < i1; ++j1) { + EnumDirection enumdirection = aenumdirection[j1]; +- long k1 = SectionPosition.a(i, enumdirection); ++ long k1 = SectionPosition.getAdjacentFromSectionPos(secX, secY, secZ, enumdirection); // Paper - avoid extra unpacking + + if (!this.i.containsKey(k1) && this.g(k1)) { + for (int l1 = 0; l1 < 16; ++l1) { diff --git a/src/main/java/net/minecraft/server/LightEngineStorageArray.java b/src/main/java/net/minecraft/server/LightEngineStorageArray.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/LightEngineStorageArray.java @@ -1211,7 +1143,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { private void a(int i, int j, IntSupplier intsupplier, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable) { - this.e.a(ChunkTaskQueueSorter.a(() -> { // Paper - decompile error + this.e.a(ChunkTaskQueueSorter.a(() -> { - this.c.add(Pair.of(lightenginethreaded_update, runnable)); - if (this.c.size() >= this.f) { + // Paper start @@ -1347,7 +1279,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + chunkMap.world.getChunkProvider().getLightEngine().changePriority(location.pair(), getCurrentPriority(), priority); } if (getCurrentPriority() != priority) { - this.w.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority + this.v.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority 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 @@ -1378,7 +1310,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 { } gameprofilerfiller.exit(); timings.chunkTicksBlocks.stopTiming(); // Paper 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 807f67ee00..b3b2dca4eb 100644 --- a/Spigot-Server-Patches/Optimize-NibbleArray-to-use-pooled-buffers.patch +++ b/Spigot-Server-Patches/Optimize-NibbleArray-to-use-pooled-buffers.patch @@ -41,10 +41,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected void a(LightEngineLayer lightenginelayer, long i) { @@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e - protected void a(long i, @Nullable NibbleArray nibblearray) { + protected void a(long i, @Nullable NibbleArray nibblearray, boolean flag) { if (nibblearray != null) { - this.i.put(i, nibblearray); + NibbleArray remove = this.i.put(i, nibblearray); if (remove != null && remove.cleaner != null) remove.cleaner.run(); // Paper - clean up when removed + if (!flag) { + this.n.add(i); + } } else { - this.i.remove(i); + NibbleArray remove = this.i.remove(i); if (remove != null && remove.cleaner != null) remove.cleaner.run(); // Paper - clean up when removed @@ -248,8 +251,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java @@ -0,0 +0,0 @@ public class PacketPlayOutLightUpdate implements Packet { - private List g; private List h; + private boolean i; + // Paper start + java.lang.Runnable cleaner1; @@ -282,9 +285,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end public PacketPlayOutLightUpdate() {} - public PacketPlayOutLightUpdate(ChunkCoordIntPair chunkcoordintpair, LightEngine lightengine) { + public PacketPlayOutLightUpdate(ChunkCoordIntPair chunkcoordintpair, LightEngine lightengine, boolean flag) { this.a = chunkcoordintpair.x; this.b = chunkcoordintpair.z; + this.i = flag; - this.g = Lists.newArrayList(); - this.h = Lists.newArrayList(); + this.g = Lists.newArrayList();cleaner1 = MCUtil.registerListCleaner(this, this.g, NibbleArray::releaseBytes); // Paper @@ -311,7 +315,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } @@ -0,0 +0,0 @@ public class PacketPlayOutLightUpdate implements Packet { - this.b = chunkcoordintpair.z; + this.i = flag; this.c = i; this.d = j; - this.g = Lists.newArrayList(); diff --git a/Spigot-Server-Patches/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/Spigot-Server-Patches/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch deleted file mode 100644 index a4f5fc72c8..0000000000 --- a/Spigot-Server-Patches/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Mon, 11 May 2020 04:18:54 -0400 -Subject: [PATCH] Optimize Pathfinder - Remove Streams / Optimized collections - -I utilized the IDE to convert streams to non streams code, so shouldn't -be any risk of behavior change. Only did minor optimization of the -generated code set to remove unnecessary things. - -I expect us to just drop this patch on next major update and re-apply -it with the IDE again and re-apply the collections optimization. - -Optimize collection by creating a list instead of a set of the key and value. - -This lets us get faster foreach iteration, as well as avoids map lookups on -the values when needed. - -diff --git a/src/main/java/net/minecraft/server/Pathfinder.java b/src/main/java/net/minecraft/server/Pathfinder.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/Pathfinder.java -+++ b/src/main/java/net/minecraft/server/Pathfinder.java -@@ -0,0 +0,0 @@ public class Pathfinder { - this.a.a(); - this.e.a(chunkcache, entityinsentient); - PathPoint pathpoint = this.e.b(); -- Map map = (Map) set.stream().collect(Collectors.toMap((blockposition) -> { -- return this.e.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); -- }, Function.identity())); -+ // Paper start - remove streams - and optimize collection -+ List> map = new java.util.ArrayList<>(); -+ for (BlockPosition blockposition : set) { -+ // cast is important -+ //noinspection RedundantCast -+ PathDestination path = this.e.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); -+ map.add(new java.util.AbstractMap.SimpleEntry<>(path, blockposition)); -+ } -+ // Paper end - PathEntity pathentity = this.a(pathpoint, map, f, i, f1); - - this.e.a(); -@@ -0,0 +0,0 @@ public class Pathfinder { - } - - @Nullable -- private PathEntity a(PathPoint pathpoint, Map map, float f, int i, float f1) { -- Set set = map.keySet(); -+ private PathEntity a(PathPoint pathpoint, java.util.List> list, float f, int i, float f1) { // Paper - list instead of set -+ //Set set = map.keySet(); // Paper - - pathpoint.e = 0.0F; -- pathpoint.f = this.a(pathpoint, set); -+ pathpoint.f = this.a(pathpoint, list); // Paper - list instead of map - pathpoint.g = pathpoint.f; - this.a.a(); - this.b.clear(); -@@ -0,0 +0,0 @@ public class Pathfinder { - PathPoint pathpoint1 = this.a.c(); - - pathpoint1.i = true; -- set.stream().filter((pathdestination) -> { -- return pathpoint1.c((PathPoint) pathdestination) <= (float) i; -- }).forEach(PathDestination::e); -- if (set.stream().anyMatch(PathDestination::f)) { -+ // Paper start - remove streams -+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) { -+ PathDestination pathdestination = list.get(i1).getKey(); -+ if (pathpoint1.c(pathdestination) <= (float) i) { -+ pathdestination.e(); -+ } -+ } -+ boolean result = false; -+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) { -+ PathDestination pathdestination = list.get(i1).getKey(); -+ if (pathdestination.f()) { -+ result = true; -+ break; -+ } -+ } -+ if (result) { -+ // Paper end - break; - } - -@@ -0,0 +0,0 @@ public class Pathfinder { - if (pathpoint2.j < f && (!pathpoint2.c() || f3 < pathpoint2.e)) { - pathpoint2.h = pathpoint1; - pathpoint2.e = f3; -- pathpoint2.f = this.a(pathpoint2, set) * 1.5F; -+ pathpoint2.f = this.a(pathpoint2, list) * 1.5F; // Paper - use list instead of map - if (pathpoint2.c()) { - this.a.a(pathpoint2, pathpoint2.e + pathpoint2.f); - } else { -@@ -0,0 +0,0 @@ public class Pathfinder { - } - } - -- Stream stream; - -- if (set.stream().anyMatch(PathDestination::f)) { -- stream = set.stream().filter(PathDestination::f).map((pathdestination) -> { -- return this.a(pathdestination.d(), (BlockPosition) map.get(pathdestination), true); -- }).sorted(Comparator.comparingInt(PathEntity::e)); -- } else { -- stream = set.stream().map((pathdestination) -> { -- return this.a(pathdestination.d(), (BlockPosition) map.get(pathdestination), false); -- }).sorted(Comparator.comparingDouble(PathEntity::l).thenComparingInt(PathEntity::e)); -+ // Paper start - remove streams -+ boolean result = false; -+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) { -+ PathDestination pathDestination = list.get(i1).getKey(); // Paper -+ if (pathDestination.f()) { -+ result = true; -+ break; -+ } - } -- -- Optional optional = stream.findFirst(); -- -- if (!optional.isPresent()) { -- return null; -+ List candidates = new java.util.ArrayList<>(); -+ if (result) { -+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) { -+ Map.Entry entry = list.get(i1); -+ PathDestination pathdestination = entry.getKey(); -+ if (pathdestination.f()) { -+ PathEntity pathEntity = this.a(pathdestination.d(), entry.getValue(), true); -+ candidates.add(pathEntity); -+ } -+ } -+ if (candidates.isEmpty()) return null; -+ candidates.sort(Comparator.comparingInt(PathEntity::e)); - } else { -- PathEntity pathentity = (PathEntity) optional.get(); -- -- return pathentity; -+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) { -+ Map.Entry entry = list.get(i1); -+ PathDestination pathdestination = entry.getKey(); -+ PathEntity pathEntity = this.a(pathdestination.d(), entry.getValue(), false); -+ candidates.add(pathEntity); -+ } -+ if (candidates.isEmpty()) return null; -+ candidates.sort(Comparator.comparingDouble(PathEntity::l).thenComparingInt(PathEntity::e)); - } -+ return candidates.get(0); -+ // Paper end - } - -- private float a(PathPoint pathpoint, Set set) { -+ private float a(PathPoint pathpoint, java.util.List> list) { - float f = Float.MAX_VALUE; - - float f1; - -- for (Iterator iterator = set.iterator(); iterator.hasNext(); f = Math.min(f1, f)) { -- PathDestination pathdestination = (PathDestination) iterator.next(); -+ for (int i = 0, listSize = list.size(); i < listSize; f = Math.min(f1, f), i++) { // Paper -+ PathDestination pathdestination = list.get(i).getKey(); // Paper - - f1 = pathpoint.a(pathdestination); - pathdestination.a(f1, pathpoint); diff --git a/Spigot-Server-Patches/Optimize-Villagers.patch b/Spigot-Server-Patches/Optimize-Villagers.patch deleted file mode 100644 index 28c23761a5..0000000000 --- a/Spigot-Server-Patches/Optimize-Villagers.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Tue, 26 May 2020 21:32:05 -0400 -Subject: [PATCH] Optimize Villagers - -This change reimplements the entire BehaviorFindPosition method to -get rid of all of the streams, and implement the logic in a more sane way. - -We keep vanilla behavior 100% the same with this change, just wrote more -optimal, as we can abort iterating POI's as soon as we find a match.... - -One slight change is that Minecraft adds a random delay before a POI is -attempted again. I've increased the amount of that delay based on the distance -to said POI, so farther POI's will not be attempted as often. - -Additionally, we spiral out, so we favor local POI's before we ever favor farther POI's. - -We also try to pathfind 1 POI at a time instead of collecting multiple POI's then tossing them -all to the pathfinder, so that once we get a match we can return before even looking at other -POI's. - -This benefits us in that ideally, a villager will constantly find the near POI's and -not even try to pathfind to the farther POI. Trying to pathfind to distant POI's is -what causes significant lag. - -Other improvements here is to stop spamming the POI manager with empty nullables. -Vanilla used them to represent if they needed to load POI data off disk or not. - -Well, we load POI data async on chunk load, so we have it, and we surely do not ever -want to load POI data sync either for unloaded chunks! - -So this massively reduces object count in the POI hashmaps, resulting in less hash collions, -and also less memory use. - -Additionally, unemployed villagers were using significant time due to major ineffeciency in -the code rebuilding data that is static every single invocation for every POI type... - -So we cache that and only rebuild it if professions change, which should be never unless -a plugin manipulates and adds custom professions, which it will handle by rebuilding. - -diff --git a/src/main/java/net/minecraft/server/BehaviorFindPosition.java b/src/main/java/net/minecraft/server/BehaviorFindPosition.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BehaviorFindPosition.java -+++ b/src/main/java/net/minecraft/server/BehaviorFindPosition.java -@@ -0,0 +0,0 @@ public class BehaviorFindPosition extends Behavior { - - protected void a(WorldServer worldserver, EntityCreature entitycreature, long i) { - this.f = 0; -- this.d = worldserver.getTime() + (long) worldserver.getRandom().nextInt(20); -+ this.d = worldserver.getTime() + (long) java.util.concurrent.ThreadLocalRandom.current().nextInt(20); // Paper - VillagePlace villageplace = worldserver.B(); -+ -+ // Paper start - replace implementation completely -+ BlockPosition blockposition2 = new BlockPosition(entitycreature); -+ int dist = 48; -+ int requiredDist = dist * dist; -+ int cdist = Math.floorDiv(dist, 16); -+ Predicate predicate = this.a.c(); -+ int maxPoiAttempts = 4; -+ int poiAttempts = 0; -+ OUT: -+ for (ChunkCoordIntPair chunkcoordintpair : MCUtil.getSpiralOutChunks(blockposition2, cdist)) { -+ for (int i1 = 0; i1 < 16; i1++) { -+ java.util.Optional section = villageplace.getSection(SectionPosition.a(chunkcoordintpair, i1).v()); -+ if (section == null || !section.isPresent()) continue; -+ for (java.util.Map.Entry> e : section.get().getRecords().entrySet()) { -+ if (!predicate.test(e.getKey())) continue; -+ for (VillagePlaceRecord record : e.getValue()) { -+ if (!record.hasVacancy()) continue; -+ -+ BlockPosition pos = record.getPosition(); -+ long key = pos.asLong(); -+ if (this.e.containsKey(key)) { -+ continue; -+ } -+ double poiDist = pos.distanceSquared(blockposition2); -+ if (poiDist <= (double) requiredDist) { -+ this.e.put(key, (long) (this.d + Math.sqrt(poiDist) * 4)); // use dist instead of 40 to blacklist longer if farther distance -+ ++poiAttempts; -+ PathEntity pathentity = entitycreature.getNavigation().a(com.google.common.collect.ImmutableSet.of(pos), 8, false, this.a.d()); -+ -+ if (pathentity != null && pathentity.h()) { -+ record.decreaseVacancy(); -+ GlobalPos globalPos = GlobalPos.create(worldserver.getWorldProvider().getDimensionManager(), pos); -+ entitycreature.getBehaviorController().setMemory(this.b, globalPos); -+ break OUT; -+ } -+ if (poiAttempts >= maxPoiAttempts) { -+ break OUT; -+ } -+ } -+ } -+ } -+ } -+ } -+ // Clean up - vanilla does this only when it runs out, but that would push it to try farther POI's... -+ this.e.long2LongEntrySet().removeIf((entry) -> entry.getLongValue() < this.d); -+ /* - Predicate predicate = (blockposition) -> { - long j = blockposition.asLong(); - -@@ -0,0 +0,0 @@ public class BehaviorFindPosition extends Behavior { - return entry.getLongValue() < this.d; - }); - } -- -+ */ // Paper end - } - } -diff --git a/src/main/java/net/minecraft/server/RegionFileSection.java b/src/main/java/net/minecraft/server/RegionFileSection.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/RegionFileSection.java -+++ b/src/main/java/net/minecraft/server/RegionFileSection.java -@@ -0,0 +0,0 @@ public class RegionFileSection extends RegionFi - - @Nullable - protected Optional c(long i) { -- return (Optional) this.c.get(i); -+ return this.c.getOrDefault(i, Optional.empty()); // Paper - } - -+ protected final Optional getSection(long i) { return d(i); } // Paper - OBFHELPER - protected Optional d(long i) { -- SectionPosition sectionposition = SectionPosition.a(i); -- -- if (this.b(sectionposition)) { -- return Optional.empty(); -- } else { -- Optional optional = this.c(i); -- -- if (optional != null) { -- return optional; -- } else { -- this.b(sectionposition.u()); -- optional = this.c(i); -- if (optional == null) { -- throw (IllegalStateException) SystemUtils.c(new IllegalStateException()); -- } else { -- return optional; -- } -- } -- } -+ // Paper start - replace method - never load POI data sync, we load this in chunk load already, reduce ops -+ // If it's an unloaded chunk, well too bad. -+ return this.c(i); -+ // Paper end - } - - protected boolean b(SectionPosition sectionposition) { -@@ -0,0 +0,0 @@ public class RegionFileSection extends RegionFi - private void a(ChunkCoordIntPair chunkcoordintpair, DynamicOps dynamicops, @Nullable T t0) { - if (t0 == null) { - for (int i = 0; i < 16; ++i) { -- this.c.put(SectionPosition.a(chunkcoordintpair, i).v(), Optional.empty()); -+ //this.c.put(SectionPosition.a(chunkcoordintpair, i).v(), Optional.empty()); // Paper - NO!!! - } - } else { - Dynamic dynamic = new Dynamic(dynamicops, t0); -@@ -0,0 +0,0 @@ public class RegionFileSection extends RegionFi - }, dynamic2); - }); - -- this.c.put(i1, optional); -+ if (optional.isPresent()) this.c.put(i1, optional); // Paper - NO!!! - optional.ifPresent((minecraftserializable) -> { - this.b(i1); - if (flag) { -@@ -0,0 +0,0 @@ public class RegionFileSection extends RegionFi - if (optional != null && optional.isPresent()) { - this.d.add(i); - } else { -- RegionFileSection.LOGGER.warn("No data for position: {}", SectionPosition.a(i)); -+ //RegionFileSection.LOGGER.warn("No data for position: {}", SectionPosition.a(i)); // Paper - hush - } - } - -diff --git a/src/main/java/net/minecraft/server/VillagePlaceRecord.java b/src/main/java/net/minecraft/server/VillagePlaceRecord.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/VillagePlaceRecord.java -+++ b/src/main/java/net/minecraft/server/VillagePlaceRecord.java -@@ -0,0 +0,0 @@ public class VillagePlaceRecord implements MinecraftSerializable { - return dynamicops.createMap(ImmutableMap.of(dynamicops.createString("pos"), this.a.a(dynamicops), dynamicops.createString("type"), dynamicops.createString(IRegistry.POINT_OF_INTEREST_TYPE.getKey(this.b).toString()), dynamicops.createString("free_tickets"), dynamicops.createInt(this.c))); - } - -+ protected final boolean decreaseVacancy() { return b(); } // Paper - OBFHELPER - protected boolean b() { - if (this.c <= 0) { - return false; -@@ -0,0 +0,0 @@ public class VillagePlaceRecord implements MinecraftSerializable { - } - } - -+ protected final boolean increaseVacancy() { return c(); } // Paper - OBFHELPER - protected boolean c() { - if (this.c >= this.b.b()) { - return false; -@@ -0,0 +0,0 @@ public class VillagePlaceRecord implements MinecraftSerializable { - } - } - -+ public final boolean hasVacancy() { return d(); } // Paper - OBFHELPER - public boolean d() { - return this.c > 0; - } - -+ public final boolean isOccupied() { return e(); } // Paper - OBFHELPER - public boolean e() { - return this.c != this.b.b(); - } - -+ public final BlockPosition getPosition() { return f(); } // Paper - public BlockPosition f() { - return this.a; - } -diff --git a/src/main/java/net/minecraft/server/VillagePlaceSection.java b/src/main/java/net/minecraft/server/VillagePlaceSection.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/VillagePlaceSection.java -+++ b/src/main/java/net/minecraft/server/VillagePlaceSection.java -@@ -0,0 +0,0 @@ public class VillagePlaceSection implements MinecraftSerializable { - - private static final Logger LOGGER = LogManager.getLogger(); - private final Short2ObjectMap b = new Short2ObjectOpenHashMap(); -- private final Map> c = Maps.newHashMap(); -+ private final Map> c = Maps.newHashMap(); public final Map> getRecords() { return c; } // Paper - OBFHELPER - private final Runnable d; - private boolean e; - -diff --git a/src/main/java/net/minecraft/server/VillagePlaceType.java b/src/main/java/net/minecraft/server/VillagePlaceType.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/VillagePlaceType.java -+++ b/src/main/java/net/minecraft/server/VillagePlaceType.java -@@ -0,0 +0,0 @@ import java.util.stream.Stream; - - public class VillagePlaceType { - -+ static Set professionCache; // Paper - private static final Predicate v = (villageplacetype) -> { -- return ((Set) IRegistry.VILLAGER_PROFESSION.d().map(VillagerProfession::b).collect(Collectors.toSet())).contains(villageplacetype); -+ // Paper start -+ if (professionCache == null) { -+ professionCache = IRegistry.VILLAGER_PROFESSION.d().map(VillagerProfession::b).collect(Collectors.toSet()); -+ } -+ return professionCache.contains(villageplacetype); -+ // Paper end - }; - public static final Predicate a = (villageplacetype) -> { - return true; -@@ -0,0 +0,0 @@ public class VillagePlaceType { - } - - private static VillagePlaceType a(String s, Set set, int i, int j) { -- return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (Object) (new VillagePlaceType(s, set, i, j)))); -+ return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (new VillagePlaceType(s, set, i, j)))); // Paper - decompile error - } - - private static VillagePlaceType a(String s, Set set, int i, Predicate predicate, int j) { -- return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (Object) (new VillagePlaceType(s, set, i, predicate, j)))); -+ return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (new VillagePlaceType(s, set, i, predicate, j)))); // Paper - decompile error - } - - private static VillagePlaceType a(VillagePlaceType villageplacetype) { -diff --git a/src/main/java/net/minecraft/server/VillagerProfession.java b/src/main/java/net/minecraft/server/VillagerProfession.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/VillagerProfession.java -+++ b/src/main/java/net/minecraft/server/VillagerProfession.java -@@ -0,0 +0,0 @@ public class VillagerProfession { - } - - static VillagerProfession a(String s, VillagePlaceType villageplacetype, ImmutableSet immutableset, ImmutableSet immutableset1, @Nullable SoundEffect soundeffect) { -+ VillagePlaceType.professionCache = null; // Paper - return (VillagerProfession) IRegistry.a((IRegistry) IRegistry.VILLAGER_PROFESSION, new MinecraftKey(s), (Object) (new VillagerProfession(s, villageplacetype, immutableset, immutableset1, soundeffect))); - } - } diff --git a/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch b/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch deleted file mode 100644 index a56e8b94c7..0000000000 --- a/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Sun, 10 May 2020 22:49:05 -0400 -Subject: [PATCH] Optimize WorldBorder collision checks and air - - -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 - AxisAlignedBB axisalignedbb = this.getBoundingBox(); - VoxelShapeCollision voxelshapecollision = VoxelShapeCollision.a(this); - VoxelShape voxelshape = this.world.getWorldBorder().a(); -- Stream stream = VoxelShapes.c(voxelshape, VoxelShapes.a(axisalignedbb.shrink(1.0E-7D)), OperatorBoolean.AND) ? Stream.empty() : Stream.of(voxelshape); -+ Stream stream = !this.world.getWorldBorder().isInBounds(axisalignedbb) ? Stream.empty() : Stream.of(this.world.getWorldBorder().a()); // Paper - Stream stream1 = this.world.b(this, axisalignedbb.a(vec3d), (Set) ImmutableSet.of()); - StreamAccumulator streamaccumulator = new StreamAccumulator<>(Stream.concat(stream1, stream)); - Vec3D vec3d1 = vec3d.g() == 0.0D ? vec3d : a(this, vec3d, axisalignedbb, this.world, voxelshapecollision, streamaccumulator); -diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/ICollisionAccess.java -+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java -@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess { - if (true) { //public boolean tryAdvance(Consumer consumer) {*/ // Paper - if (entity != null) { - // Paper end -- VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a(); -- boolean flag = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().shrink(1.0E-7D)), OperatorBoolean.AND); -- boolean flag1 = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().g(1.0E-7D)), OperatorBoolean.AND); -+ //VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a(); // Paper - only make if collides -+ boolean flag = !ICollisionAccess.this.getWorldBorder().isInBounds(entity.getBoundingBox().shrink(1.0E-7D)); // Paper -+ boolean flag1 = !ICollisionAccess.this.getWorldBorder().isInBounds(entity.getBoundingBox().g(1.0E-7D)); // Paper - - if (!flag && flag1) { -- collisions.add(voxelshape1);// Paper -+ collisions.add(ICollisionAccess.this.getWorldBorder().a());// Paper - if (returnFast) return collisions; - } - } -@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess { - //IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); // moved up - // Paper end - -- if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { -+ if (!iblockdata.isAir() && (j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { // Paper - fast track air - VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision); - - // Paper start - Lithium Collision Optimizations -diff --git a/src/main/java/net/minecraft/server/WorldBorder.java b/src/main/java/net/minecraft/server/WorldBorder.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/WorldBorder.java -+++ b/src/main/java/net/minecraft/server/WorldBorder.java -@@ -0,0 +0,0 @@ public class WorldBorder { - return (double) chunkcoordintpair.f() > this.c() && (double) chunkcoordintpair.d() < this.e() && (double) chunkcoordintpair.g() > this.d() && (double) chunkcoordintpair.e() < this.f(); - } - -+ public final boolean isInBounds(AxisAlignedBB aabb) { return this.a(aabb); } // Paper - OBFHELPER - public boolean a(AxisAlignedBB axisalignedbb) { - return axisalignedbb.maxX > this.c() && axisalignedbb.minX < this.e() && axisalignedbb.maxZ > this.d() && axisalignedbb.minZ < this.f(); - } diff --git a/Spigot-Server-Patches/Optimize-sending-packets-to-nearby-locations-sounds-.patch b/Spigot-Server-Patches/Optimize-sending-packets-to-nearby-locations-sounds-.patch index 7ea3613afe..134174dfab 100644 --- a/Spigot-Server-Patches/Optimize-sending-packets-to-nearby-locations-sounds-.patch +++ b/Spigot-Server-Patches/Optimize-sending-packets-to-nearby-locations-sounds-.patch @@ -15,59 +15,49 @@ 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 { - 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; + public void sendPacketNearby(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, double d3, ResourceKey resourcekey, Packet packet) { +- for (int i = 0; i < this.players.size(); ++i) { +- EntityPlayer entityplayer = (EntityPlayer) this.players.get(i); ++ WorldServer world = null; ++ if (entityhuman != null && entityhuman.world instanceof WorldServer) { ++ world = (WorldServer) entityhuman.world; ++ } + +- // 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())) { +- continue; + // Paper start -+ if ((world == null || world.chunkProvider == null) && dimensionmanager != null) { -+ world = dimensionmanager.world; -+ } + if (world == null) { -+ LOGGER.error("Sending packet to invalid world" + entityhuman + " " + dimensionmanager + " - " + packet.getClass().getName(), new Throwable()); -+ return; // ??? shouldn't happen... ++ world = server.getWorldServer(resourcekey); + } -+ PlayerChunkMap chunkMap = world.chunkMap; ++ PlayerChunkMap chunkMap = world != null ? world.getChunkProvider().playerChunkMap : null; + Object[] backingSet; + if (chunkMap == null) { + // Really shouldn't happen... -+ backingSet = world.players.toArray(); ++ backingSet = world != null ? world.players.toArray() : players.toArray(); + } else { + com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet nearbyPlayers = chunkMap.playerViewDistanceBroadcastMap.getObjectsInRange(MCUtil.fastFloor(d0) >> 4, MCUtil.fastFloor(d2) >> 4); + if (nearbyPlayers == null) { + return; -+ } + } + backingSet = nearbyPlayers.getBackingSet(); + } + + for (Object object : backingSet) { + if (!(object instanceof EntityPlayer)) continue; + EntityPlayer entityplayer = (EntityPlayer) object; - // Paper end ++ // 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())) { // Paper ++ //continue; // Paper ++ //} // Paper + // CraftBukkit end - // CraftBukkit start - Test if player receiving packet can see the source of the packet -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 { - } - } - // Paper end -+ public final PlayerChunkMap chunkMap; // Paper - private final MinecraftServer server; - private final WorldNBTStorage dataManager; - public boolean savingDisabled; -@@ -0,0 +0,0 @@ public class WorldServer extends World { - }, gameprofilerfiller, false, gen, env); - this.pvpMode = minecraftserver.getPVP(); - worlddata.world = this; -+ if (chunkProvider == null) { chunkMap = null; new Throwable("World created without a ChunkProvider!").printStackTrace(); } // Paper - figure out if something weird happened here -+ else chunkMap = ((ChunkProviderServer) chunkProvider).playerChunkMap; - // CraftBukkit end - if (com.destroystokyo.paper.PaperConfig.useOptimizedTickList) { - this.nextTickListBlock = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> { // Paper - optimise TickListServer +- if (entityplayer != entityhuman && entityplayer.world.getDimensionKey() == resourcekey) { ++ if (entityplayer != entityhuman && entityplayer.world.getDimensionKey() == resourcekey && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { // Paper + double d4 = d0 - entityplayer.locX(); + double d5 = d1 - entityplayer.locY(); + double d6 = d2 - entityplayer.locZ(); diff --git a/Spigot-Server-Patches/POM-Changes.patch b/Spigot-Server-Patches/POM-Changes.patch index ee23f17e5b..6be7b50705 100644 --- a/Spigot-Server-Patches/POM-Changes.patch +++ b/Spigot-Server-Patches/POM-Changes.patch @@ -201,7 +201,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Date buildDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(Main.class.getPackage().getImplementationVendor()); // Paper Calendar deadline = Calendar.getInstance(); - deadline.add(Calendar.DAY_OF_YEAR, -3); + deadline.add(Calendar.DAY_OF_YEAR, -1); diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java diff --git a/Spigot-Server-Patches/Potential-bed-API.patch b/Spigot-Server-Patches/Potential-bed-API.patch index a7c6bebe2f..e99bfb9b92 100644 --- a/Spigot-Server-Patches/Potential-bed-API.patch +++ b/Spigot-Server-Patches/Potential-bed-API.patch @@ -12,20 +12,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { - return null; + return getHandle().sleepTicks; } + // Paper start - Potential bed api + @Override + public Location getPotentialBedLocation() { -+ BlockPosition bed = getHandle().getBed(); ++ EntityPlayer handle = (EntityPlayer) getHandle(); ++ BlockPosition bed = handle.getSpawn(); + if (bed == null) { + return null; + } -+ return new Location(getServer().getWorld(getHandle().spawnWorld), bed.getX(), bed.getY(), bed.getZ()); ++ ++ net.minecraft.server.WorldServer worldServer = handle.server.getWorldServer(handle.getSpawnDimension()); ++ if (worldServer == null) { ++ return null; ++ } ++ return new Location(worldServer.getWorld(), bed.getX(), bed.getY(), bed.getZ()); + } + // Paper end -+ @Override - public void setBedSpawnLocation(Location location) { - setBedSpawnLocation(location, false); + public boolean sleep(Location location, boolean force) { + Preconditions.checkArgument(location != null, "Location cannot be null"); diff --git a/Spigot-Server-Patches/Prevent-opening-inventories-when-frozen.patch b/Spigot-Server-Patches/Prevent-opening-inventories-when-frozen.patch index 53a56729a9..aaf34a5dd0 100644 --- a/Spigot-Server-Patches/Prevent-opening-inventories-when-frozen.patch +++ b/Spigot-Server-Patches/Prevent-opening-inventories-when-frozen.patch @@ -43,8 +43,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 String title = container.getBukkitView().getTitle(); -- player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title))); -+ if (!player.isFrozen()) player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title))); // Paper +- player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); ++ if (!player.isFrozen()) player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper getHandle().activeContainer = container; getHandle().activeContainer.addSlotListener(player); } @@ -52,8 +52,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Now open the window Containers windowType = CraftContainer.getNotchInventoryType(inventory.getTopInventory()); String title = inventory.getTitle(); -- player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title))); -+ if (!player.isFrozen()) player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title))); // Paper +- player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); ++ if (!player.isFrozen()) player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper player.activeContainer = container; player.activeContainer.addSlotListener(player); } diff --git a/Spigot-Server-Patches/Prevent-position-desync-in-playerconnection-causing-.patch b/Spigot-Server-Patches/Prevent-position-desync-in-playerconnection-causing-.patch index 11e7c2b77b..a503eadde2 100644 --- a/Spigot-Server-Patches/Prevent-position-desync-in-playerconnection-causing-.patch +++ b/Spigot-Server-Patches/Prevent-position-desync-in-playerconnection-causing-.patch @@ -26,6 +26,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return; // ... thanks Mojang for letting move calls teleport across dimensions. + } + // Paper end - prevent position desync - this.player.onGround = packetplayinflying.b(); double d12 = d8; + d7 = d4 - this.player.locX(); diff --git a/Spigot-Server-Patches/Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch b/Spigot-Server-Patches/Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch index d5f31067f6..22866d1f23 100644 --- a/Spigot-Server-Patches/Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch +++ b/Spigot-Server-Patches/Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch @@ -31,9 +31,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 { - protected final SoundEffectType stepSound; - protected final Material material; +@@ -0,0 +0,0 @@ public class Block extends BlockBase implements IMaterial { + protected final BlockStateList blockStateList; + private IBlockData blockData; // Paper start + public final boolean isDestroyable() { + return com.destroystokyo.paper.PaperConfig.allowBlockPermanentBreakingExploits || @@ -46,7 +46,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public co.aikar.timings.Timing timing; public co.aikar.timings.Timing getTiming() { if (timing == null) { -@@ -0,0 +0,0 @@ public class Block implements IMaterial { +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 { @Deprecated public boolean a(IBlockData iblockdata, BlockActionContext blockactioncontext) { @@ -55,15 +59,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } @Deprecated -@@ -0,0 +0,0 @@ public class Block implements IMaterial { +@@ -0,0 +0,0 @@ public abstract class BlockBase { + public Block getBlock() { + return (Block) this.c; + } +- ++ // Paper start ++ public final boolean isDestroyable() { ++ return getBlock().isDestroyable(); ++ } ++ // Paper end + public Material getMaterial() { + return this.g; + } +@@ -0,0 +0,0 @@ public abstract class BlockBase { + } - @Deprecated - public EnumPistonReaction getPushReaction(IBlockData iblockdata) { -- return this.material.getPushReaction(); -+ return !blockData.isDestroyable() ? EnumPistonReaction.BLOCK : this.material.getPushReaction(); // Paper - } + public EnumPistonReaction getPushReaction() { +- return this.getBlock().getPushReaction(this.p()); ++ return !isDestroyable() ? EnumPistonReaction.BLOCK : this.getBlock().getPushReaction(this.p()); // Paper + } - public void fallOn(World world, BlockPosition blockposition, Entity entity, float f) { + public boolean i(IBlockAccess iblockaccess, BlockPosition blockposition) { diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockPiston.java @@ -82,14 +99,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!world.isClientSide) { boolean flag = this.a(world, blockposition, enumdirection); @@ -0,0 +0,0 @@ public class BlockPiston extends BlockDirectional { - } + IBlockData iblockdata1 = (IBlockData) ((IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPistonMoving.a, enumdirection)).set(BlockPistonMoving.b, this.sticky ? BlockPropertyPistonType.STICKY : BlockPropertyPistonType.DEFAULT); - world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPistonMoving.a, enumdirection)).set(BlockPistonMoving.b, this.sticky ? BlockPropertyPistonType.STICKY : BlockPropertyPistonType.DEFAULT), 3); + world.setTypeAndData(blockposition, iblockdata1, 20); - world.setTileEntity(blockposition, BlockPistonMoving.a((IBlockData) this.getBlockData().set(BlockPiston.FACING, EnumDirection.fromType1(j & 7)), enumdirection, false, true)); -+ world.setTileEntity(blockposition, BlockPistonMoving.a((IBlockData) this.getBlockData().set(BlockPiston.FACING, EnumDirection.fromType1(j & 7)), enumdirection, false, true)); // Paper - diff on change, j is facing direction ++ world.setTileEntity(blockposition, BlockPistonMoving.a((IBlockData) this.getBlockData().set(BlockPiston.FACING, EnumDirection.fromType1(j & 7)), enumdirection, false, true)); // Paper - diff on change, j is facing direction - copy this above + world.update(blockposition, iblockdata1.getBlock()); + iblockdata1.a(world, blockposition, 2); if (this.sticky) { - BlockPosition blockposition1 = blockposition.b(enumdirection.getAdjacentX() * 2, enumdirection.getAdjacentY() * 2, enumdirection.getAdjacentZ() * 2); - IBlockData iblockdata1 = world.getType(blockposition1); @@ -0,0 +0,0 @@ public class BlockPiston extends BlockDirectional { } } @@ -116,8 +133,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 IBlockData iblockdata = this.world.getType(blockposition); + if (!iblockdata.isDestroyable()) continue; // Paper Fluid fluid = iblockdata.getFluid(); // Paper + Optional optional = this.k.a(this, this.world, blockposition, iblockdata, fluid); - if (!iblockdata.isAir() || !fluid.isEmpty()) { @@ -0,0 +0,0 @@ public class Explosion { IBlockData iblockdata = this.world.getType(blockposition); Block block = iblockdata.getBlock(); @@ -127,28 +144,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 BlockPosition blockposition1 = blockposition.immutableCopy(); this.world.getMethodProfiler().enter("explosion_blocks"); -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 (CraftBlockData) cachedCraftBlockData.clone(); - } - // Paper end -+ // Paper start -+ public final boolean isDestroyable() { -+ return getBlock().isDestroyable(); -+ } -+ // Paper end - - public Material getMaterial() { - return this.getBlock().k(this); 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 boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { + public boolean a(BlockPosition blockposition, IBlockData iblockdata, int i, int j) { // CraftBukkit start - tree generation if (this.captureTreeGeneration) { + // Paper start diff --git a/Spigot-Server-Patches/Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/Spigot-Server-Patches/Reduce-allocation-of-Vec3D-by-entity-tracker.patch index b24552de12..7475f09739 100644 --- a/Spigot-Server-Patches/Reduce-allocation-of-Vec3D-by-entity-tracker.patch +++ b/Spigot-Server-Patches/Reduce-allocation-of-Vec3D-by-entity-tracker.patch @@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - remove allocation of Vec3D here boolean flag4 = k < -32768L || k > 32767L || l < -32768L || l > 32767L || i1 < -32768L || i1 > 32767L; - if (!flag4 && this.o <= 400 && !this.q && this.r == this.tracker.onGround) { + if (!flag4 && this.o <= 400 && !this.q && this.r == this.tracker.isOnGround()) { 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 diff --git a/Spigot-Server-Patches/Remove-some-Streams-usage-in-Entity-Collision.patch b/Spigot-Server-Patches/Remove-some-Streams-usage-in-Entity-Collision.patch deleted file mode 100644 index 0576b73640..0000000000 --- a/Spigot-Server-Patches/Remove-some-Streams-usage-in-Entity-Collision.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sat, 9 May 2020 18:36:27 -0400 -Subject: [PATCH] Remove some Streams usage in Entity Collision - -While there is more down the collision system, remove some of the wrapping -Spliterator stuff as even this wrapper stream has shown up in profiling. - -With other collision optimizations, we might also even avoid inner streams too. - -diff --git a/src/main/java/net/minecraft/server/GeneratorAccess.java b/src/main/java/net/minecraft/server/GeneratorAccess.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/GeneratorAccess.java -+++ b/src/main/java/net/minecraft/server/GeneratorAccess.java -@@ -0,0 +0,0 @@ public interface GeneratorAccess extends IEntityAccess, IWorldReader, VirtualLev - this.a((EntityHuman) null, i, blockposition, j); - } - -+ @Override default java.util.List getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set, boolean returnFast) {return IEntityAccess.super.getEntityCollisions(entity, axisalignedbb, set, returnFast); } // Paper - @Override - default Stream b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { - return IEntityAccess.super.b(entity, axisalignedbb, set); -diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/ICollisionAccess.java -+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java -@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess { - - default boolean a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { - try { if (entity != null) entity.collisionLoadChunks = true; // Paper -- return this.c(entity, axisalignedbb, set).allMatch(VoxelShape::isEmpty); -+ // Paper start - reduce stream usage -+ java.util.List blockCollisions = getBlockCollision(entity, axisalignedbb, true); -+ for (int i = 0; i < blockCollisions.size(); i++) { -+ VoxelShape blockCollision = blockCollisions.get(i); -+ if (!blockCollision.isEmpty()) { -+ return false; -+ } -+ } -+ return getEntityCollisions(entity, axisalignedbb, set, true).isEmpty(); -+ // Paper end - } finally { if (entity != null) entity.collisionLoadChunks = false; } // Paper - } - -+ default java.util.List getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set, boolean returnFast) { return java.util.Collections.emptyList(); } // Paper - default Stream b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { - return Stream.empty(); - } - - default Stream c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { -- return Streams.concat(new Stream[]{this.b(entity, axisalignedbb), this.b(entity, axisalignedbb, set)}); -+ // Paper start - reduce stream usage -+ java.util.List blockCollisions = getBlockCollision(entity, axisalignedbb, false); -+ java.util.List entityCollisions = getEntityCollisions(entity, axisalignedbb, set, false); -+ return Stream.concat(blockCollisions.stream(), entityCollisions.stream()); -+ // Paper end - } - - default Stream b(@Nullable final Entity entity, AxisAlignedBB axisalignedbb) { -+ // Paper start - reduce stream usage -+ java.util.List collision = getBlockCollision(entity, axisalignedbb, false); -+ return !collision.isEmpty() ? collision.stream() : Stream.empty(); -+ } -+ -+ default java.util.List getBlockCollision(@Nullable final Entity entity, AxisAlignedBB axisalignedbb, boolean returnFast) { -+ // Paper end - int i = MathHelper.floor(axisalignedbb.minX - 1.0E-7D) - 1; - int j = MathHelper.floor(axisalignedbb.maxX + 1.0E-7D) + 1; - int k = MathHelper.floor(axisalignedbb.minY - 1.0E-7D) - 1; -@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess { - final BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - final VoxelShape voxelshape = VoxelShapes.a(axisalignedbb); - -- return StreamSupport.stream(new AbstractSpliterator(Long.MAX_VALUE, 1280) { -- boolean a = entity == null; -- -- public boolean tryAdvance(Consumer consumer) { -- if (!this.a) { -- this.a = true; -+ // Paper start - reduce stream usage (this part done by Aikar) -+ java.util.List collisions = new java.util.ArrayList<>(); -+ if (true) {//return StreamSupport.stream(new AbstractSpliterator(Long.MAX_VALUE, 1280) { -+ if (true) { //public boolean tryAdvance(Consumer consumer) {*/ // Paper -+ if (entity != null) { -+ // Paper end - VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a(); - boolean flag = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().shrink(1.0E-7D)), OperatorBoolean.AND); - boolean flag1 = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().g(1.0E-7D)), OperatorBoolean.AND); - - if (!flag && flag1) { -- consumer.accept(voxelshape1); -- return true; -+ collisions.add(voxelshape1);// Paper -+ if (returnFast) return collisions; - } - } - -@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess { - ); - if (iblockdata == null) { - if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) { -- VoxelShape voxelshape3 = VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z))); -- consumer.accept(voxelshape3); -- return true; -+ collisions.add(VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z)))); -+ if (returnFast) return collisions; - } - } else { - //blockposition_mutableblockposition.d(k1, l1, i2); // moved up -@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess { - - if (voxelshape2 == VoxelShapes.fullCube()) { - if (axisalignedbb.intersects(x, y, z, x + 1.0D, y + 1.0D, z + 1.0D)) { -- consumer.accept(voxelshape2.offset(x, y, z)); -- return true; -+ collisions.add(voxelshape2.offset(x, y, z)); -+ if (returnFast) return collisions; - } - } else { - VoxelShape shape = voxelshape2.offset(x, y, z); - if (VoxelShapes.applyOperation(shape, voxelshape, OperatorBoolean.AND)) { -- consumer.accept(shape); -- return true; -+ collisions.add(shape); -+ if (returnFast) return collisions; - } - // Paper end - } -@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess { - } - } - -- return false; -+ //return false; // Paper - } -- }, false); -+ } //}, false); -+ return collisions; // Paper - } - } -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 -+++ b/src/main/java/net/minecraft/server/IEntityAccess.java -@@ -0,0 +0,0 @@ public interface IEntityAccess { - // Paper start - remove streams from entity collision - if (axisalignedbb.getAverageSideLength() < 1.0E-7D) { - return Stream.empty(); -- - } -+ return getEntityCollisions(entity, axisalignedbb, set, false).stream(); -+ } -+ default List getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set, boolean returnFast) { - AxisAlignedBB selection = axisalignedbb.grow(1.0E-7D); - List entities = entity != null && entity.hardCollides() ? getEntities(entity, selection) : getHardCollidingEntities(entity, selection); - List shapes = new java.util.ArrayList<>(); -@@ -0,0 +0,0 @@ public interface IEntityAccess { - - if (otherEntityBox != null && selection.intersects(otherEntityBox)) { - shapes.add(VoxelShapes.of(otherEntityBox)); -+ if (returnFast) return shapes; - } - - if (entity != null) { -@@ -0,0 +0,0 @@ public interface IEntityAccess { - - if (otherEntityHardBox != null && selection.intersects(otherEntityHardBox)) { - shapes.add(VoxelShapes.of(otherEntityHardBox)); -+ if (returnFast) return shapes; - } - } - } - -- return shapes.stream(); -+ return shapes; - // Paper end - } - diff --git a/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch b/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch index 6b9f14f647..e0719937b4 100644 --- a/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch +++ b/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch @@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -0,0 +0,0 @@ public class Main { - deadline.add(Calendar.DAY_OF_YEAR, -3); + deadline.add(Calendar.DAY_OF_YEAR, -1); if (buildDate.before(deadline.getTime())) { System.err.println("*** Error, this build is outdated ***"); - System.err.println("*** Please download a new build as per instructions from https://www.spigotmc.org/go/outdated-spigot ***"); diff --git a/Spigot-Server-Patches/Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch b/Spigot-Server-Patches/Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch index 0abc1fe615..da8315f553 100644 --- a/Spigot-Server-Patches/Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch +++ b/Spigot-Server-Patches/Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch @@ -22,13 +22,12 @@ 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 { + this.worldDataServer.setThundering(flag1); } - // CraftBukkit end - @Override - public BiomeBase a(int i, int j, int k) { -+ + public BiomeBase getBiomeBySeed(int i, int j, int k) { return a(i, j, k); } // Paper - OBFHELPER + @Override public BiomeBase a(int i, int j, int k) { return this.getChunkProvider().getChunkGenerator().getWorldChunkManager().getBiome(i, j, k); diff --git a/Spigot-Server-Patches/Wait-for-Async-Tasks-during-shutdown.patch b/Spigot-Server-Patches/Wait-for-Async-Tasks-during-shutdown.patch index dfda5c8dbb..0a4383c036 100644 --- a/Spigot-Server-Patches/Wait-for-Async-Tasks-during-shutdown.patch +++ b/Spigot-Server-Patches/Wait-for-Async-Tasks-during-shutdown.patch @@ -60,4 +60,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override public void reloadData() { - console.reload(); + CommandReload.reload(console); diff --git a/Spigot-Server-Patches/Workaround-for-Client-Lag-Spikes-MC-162253.patch b/Spigot-Server-Patches/Workaround-for-Client-Lag-Spikes-MC-162253.patch index ed514bdb37..d522ba9bda 100644 --- a/Spigot-Server-Patches/Workaround-for-Client-Lag-Spikes-MC-162253.patch +++ b/Spigot-Server-Patches/Workaround-for-Client-Lag-Spikes-MC-162253.patch @@ -102,8 +102,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + apacket = new Packet[10]; + } + // Paper end - apacket[0] = new PacketPlayOutMapChunk(chunk, 65535); - apacket[1] = new PacketPlayOutLightUpdate(chunk.getPos(), this.lightEngine); + apacket[0] = new PacketPlayOutMapChunk(chunk, 65535, true); + apacket[1] = new PacketPlayOutLightUpdate(chunk.getPos(), this.lightEngine, true); + + // Paper start - Fix MC-162253 + final int lightMask = getLightMask(chunk); @@ -127,7 +127,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + continue; + } + -+ apacket[i] = new PacketPlayOutLightUpdate(new ChunkCoordIntPair(chunk.getPos().x + x, chunk.getPos().z + z), lightEngine, updateLightMask, 0); ++ apacket[i] = new PacketPlayOutLightUpdate(new ChunkCoordIntPair(chunk.getPos().x + x, chunk.getPos().z + z), lightEngine, updateLightMask, 0, true); + } + } + } diff --git a/work/Bukkit b/work/Bukkit index 6f3c5f4a5a..8edeffe67d 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 6f3c5f4a5a0867ef265df9d58b48bdc43079e3dd +Subproject commit 8edeffe67d1821afd48d16cd0ec2572251f24ee8 diff --git a/work/CraftBukkit b/work/CraftBukkit index 3f0c333870..d1fb662ec5 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 3f0c333870ba74705e98d19322174d6f0c10c900 +Subproject commit d1fb662ec53c4fd8bc718039b76a3e9a11346371 diff --git a/work/Spigot b/work/Spigot index 758abbeee4..8fc58f10ab 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit 758abbeee4e12f5ff65470999dd9955d0ebb49cd +Subproject commit 8fc58f10ab171ca1979afa2065909214a0ffab32 From fe2a0ea50019b4f4dd8cbabc62d877560430f5bd Mon Sep 17 00:00:00 2001 From: Aikar Date: Fri, 26 Jun 2020 02:29:44 -0400 Subject: [PATCH 13/91] 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 From 67522d46aec369ef91c775e9706158873f7a2100 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Fri, 26 Jun 2020 14:04:38 +0200 Subject: [PATCH 14/91] [1.16] Make it run (#3626) * She compiles! Also readded the armorstand ticking patch, thanks cat * Update mob goal api * Misc fixes to make it run drop per playing mob spawns for now --- Spigot-API-Patches/Add-Mob-Goal-API.patch | 10 + Spigot-API-Patches/Potential-bed-API.patch | 24 - ...Add-Raw-Byte-ItemStack-Serialization.patch | 2 +- Spigot-Server-Patches/Add-TNTPrimeEvent.patch | 2 +- .../Add-Velocity-IP-Forwarding-Support.patch | 10 +- ...Allow-disabling-armour-stand-ticking.patch | 176 ++++ .../Asynchronous-chunk-IO-and-loading.patch | 6 +- .../Configurable-Player-Collision.patch | 6 +- ...le-speed-for-water-flowing-over-lava.patch | 4 +- ...g-Broken-behavior-of-PlayerJoinEvent.patch | 4 +- .../Generator-Settings.patch | 4 +- ...e-Large-Packets-disconnecting-client.patch | 10 +- .../Implement-Brigadier-Mojang-API.patch | 4 +- ...k-Priority-Urgency-System-for-Chunks.patch | 6 +- .../Implement-Mob-Goal-API.patch | 27 +- ...5656-Fix-Follow-Range-Initial-Target.patch | 2 +- Spigot-Server-Patches/MC-Dev-fixes.patch | 60 ++ ...No-Tick-view-distance-implementation.patch | 6 +- ...-Manager-and-add-advanced-packet-sup.patch | 10 +- .../Optimize-RegistryMaterials.patch | 9 + .../Optimize-TileEntity-Ticking.patch | 39 +- ...-isOutsideRange-to-use-distance-maps.patch | 5 - .../Paper-config-files.patch | 2 +- Spigot-Server-Patches/RangedEntity-API.patch | 2 +- ...ok-reference-on-Craft-Entity-removal.patch | 6 +- .../String-based-Action-Bar-API.patch | 15 +- Spigot-Server-Patches/Timings-v2.patch | 5 +- ...tance-map-to-optimise-entity-tracker.patch | 4 +- .../Villager-Restocks-API.patch | 21 +- ...ound-for-Client-Lag-Spikes-MC-162253.patch | 9 - ...ement-optional-per-player-mob-spawns.patch | 825 ------------------ 31 files changed, 395 insertions(+), 920 deletions(-) create mode 100644 Spigot-Server-Patches/Allow-disabling-armour-stand-ticking.patch delete mode 100644 Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch diff --git a/Spigot-API-Patches/Add-Mob-Goal-API.patch b/Spigot-API-Patches/Add-Mob-Goal-API.patch index e60f6b6f57..966f3a9f8d 100644 --- a/Spigot-API-Patches/Add-Mob-Goal-API.patch +++ b/Spigot-API-Patches/Add-Mob-Goal-API.patch @@ -315,7 +315,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + GoalKey PHANTOM_ATTACK_STRATEGY = GoalKey.of(Phantom.class, NamespacedKey.minecraft("phantom_attack_strategy")); + GoalKey PHANTOM_CIRCLE_AROUND_ANCHOR = GoalKey.of(Phantom.class, NamespacedKey.minecraft("phantom_circle_around_anchor")); + GoalKey PHANTOM_SWEEP_ATTACK = GoalKey.of(Phantom.class, NamespacedKey.minecraft("phantom_sweep_attack")); ++ /** ++ * @deprecated removed in 1.16 ++ */ ++ @Deprecated + GoalKey ANGER = GoalKey.of(PigZombie.class, NamespacedKey.minecraft("anger")); ++ /** ++ * @deprecated removed in 1.16 ++ */ ++ @Deprecated + GoalKey ANGER_OTHER = GoalKey.of(PigZombie.class, NamespacedKey.minecraft("anger_other")); + GoalKey POLARBEAR_ATTACK_PLAYERS = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polarbear_attack_players")); + GoalKey POLARBEAR_HURT_BY = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polarbear_hurt_by")); @@ -424,6 +432,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + GoalKey WATER = GoalKey.of(Creature.class, NamespacedKey.minecraft("water")); + GoalKey WATER_JUMP = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("water_jump")); + GoalKey ZOMBIE_ATTACK = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack")); ++ GoalKey STROLL_VILLAGE_GOLEM = GoalKey.of(Creature.class, NamespacedKey.minecraft("stroll_village_golem")); ++ GoalKey UNIVERSAL_ANGER_RESET = GoalKey.of(Mob.class, NamespacedKey.minecraft("universal_anger_reset")); +} diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-API-Patches/Potential-bed-API.patch b/Spigot-API-Patches/Potential-bed-API.patch index e6e0b4f696..8da39c803d 100644 --- a/Spigot-API-Patches/Potential-bed-API.patch +++ b/Spigot-API-Patches/Potential-bed-API.patch @@ -15,14 +15,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 */ public int getSleepTicks(); -+ /** -+ * Gets the Location where the player will spawn at their bed, null if -+ * they have not slept in one or their current bed spawn is invalid. -+ * -+ * @return Bed Spawn Location if bed exists, otherwise null. -+ */ -+ @Nullable -+ public Location getBedSpawnLocation(); + + // Paper start - Potential bed api + /** @@ -35,22 +27,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Nullable + public Location getPotentialBedLocation(); + // Paper end -+ -+ /** -+ * Sets the Location where the player will spawn at their bed. -+ * -+ * @param location where to set the respawn location -+ */ -+ public void setBedSpawnLocation(@Nullable Location location); -+ -+ /** -+ * Sets the Location where the player will spawn at their bed. -+ * -+ * @param location where to set the respawn location -+ * @param force whether to forcefully set the respawn location even if a -+ * valid bed is not present -+ */ -+ public void setBedSpawnLocation(@Nullable Location location, boolean force); + /** * Attempts to make the entity sleep at the given location. diff --git a/Spigot-Server-Patches/Add-Raw-Byte-ItemStack-Serialization.patch b/Spigot-Server-Patches/Add-Raw-Byte-ItemStack-Serialization.patch index dd478869a3..e32dfeeadd 100644 --- a/Spigot-Server-Patches/Add-Raw-Byte-ItemStack-Serialization.patch +++ b/Spigot-Server-Patches/Add-Raw-Byte-ItemStack-Serialization.patch @@ -33,7 +33,7 @@ diff --git a/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java b/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java +++ b/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java -@@ -0,0 +0,0 @@ import java.util.zip.GZIPOutputStream; +@@ -0,0 +0,0 @@ import io.netty.buffer.ByteBufInputStream; // Paper public class NBTCompressedStreamTools { diff --git a/Spigot-Server-Patches/Add-TNTPrimeEvent.patch b/Spigot-Server-Patches/Add-TNTPrimeEvent.patch index e070a1b9cb..0340916701 100644 --- a/Spigot-Server-Patches/Add-TNTPrimeEvent.patch +++ b/Spigot-Server-Patches/Add-TNTPrimeEvent.patch @@ -131,7 +131,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 craftBlock.getNMS().dropNaturally(world, blockposition, ItemStack.b); } + // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = world.getWorld().getBlockAt(blockposition.x, blockposition.y, blockposition.z); ++ org.bukkit.block.Block tntBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.EXPLOSION, explosionSource.getSource().getBukkitEntity()).callEvent()) + continue; + // Paper end diff --git a/Spigot-Server-Patches/Add-Velocity-IP-Forwarding-Support.patch b/Spigot-Server-Patches/Add-Velocity-IP-Forwarding-Support.patch index 34707dec93..b24092e868 100644 --- a/Spigot-Server-Patches/Add-Velocity-IP-Forwarding-Support.patch +++ b/Spigot-Server-Patches/Add-Velocity-IP-Forwarding-Support.patch @@ -133,6 +133,14 @@ diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/ja index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/LoginListener.java +++ b/src/main/java/net/minecraft/server/LoginListener.java +@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.util.Waitable; + import org.bukkit.event.player.AsyncPlayerPreLoginEvent; + import org.bukkit.event.player.PlayerPreLoginEvent; + // CraftBukkit end ++import io.netty.buffer.Unpooled; // Paper + + public class LoginListener implements PacketLoginInListener { + @@ -0,0 +0,0 @@ public class LoginListener implements PacketLoginInListener { private SecretKey loginKey; private EntityPlayer l; @@ -148,7 +156,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - Velocity support + if (com.destroystokyo.paper.PaperConfig.velocitySupport) { + this.velocityLoginMessageId = java.util.concurrent.ThreadLocalRandom.current().nextInt(); -+ PacketLoginOutCustomPayload packet = new PacketLoginOutCustomPayload(this.velocityLoginMessageId, com.destroystokyo.paper.proxy.VelocityProxy.PLAYER_INFO_CHANNEL, new PacketDataSerializer(io.netty.buffer.Unpooled.EMPTY_BUFFER)); ++ PacketLoginOutCustomPayload packet = new PacketLoginOutCustomPayload(this.velocityLoginMessageId, com.destroystokyo.paper.proxy.VelocityProxy.PLAYER_INFO_CHANNEL, new PacketDataSerializer(Unpooled.EMPTY_BUFFER)); + this.networkManager.sendPacket(packet); + return; + } diff --git a/Spigot-Server-Patches/Allow-disabling-armour-stand-ticking.patch b/Spigot-Server-Patches/Allow-disabling-armour-stand-ticking.patch new file mode 100644 index 0000000000..8579fdecc0 --- /dev/null +++ b/Spigot-Server-Patches/Allow-disabling-armour-stand-ticking.patch @@ -0,0 +1,176 @@ +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/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 { + } + } + ++ public void updateEntityEquipment() { q(); }; // Paper + private void q() { + Map map = this.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/Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch index 59a8abc786..b4bb915da0 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.getWorld().getName() +" - "; + String name = ((WorldDataServer) server.getWorldData()).getName() + " - "; @@ -0,0 +0,0 @@ public class WorldTimingsHandler { @@ -1574,7 +1574,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // apply fixes + + try { -+ chunkData.chunkData = chunkManager.getChunkData(this.world.getWorldProvider().getDimensionManager(), ++ chunkData.chunkData = chunkManager.getChunkData(this.world.getTypeKey(), + chunkManager.getWorldPersistentDataSupplier(), chunkData.chunkData, chunkPos, this.world); // clone data for safety, file IO thread does not clone + } catch (final Throwable ex) { + PaperFileIOThread.LOGGER.error("Could not apply datafixers for chunk task: " + this.toString(), ex); @@ -1973,7 +1973,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + for (int i = 0; i < threads; ++i) { + this.workers[i] = new QueueExecutorThread<>(this.queue, (long)0.10e6); //0.1ms -+ this.workers[i].setName("Async chunk loader thread #" + i + " for world: " + world.getWorldData().getName()); ++ this.workers[i].setName("Async chunk loader thread #" + i + " for world: " + world.getWorld().getName()); + this.workers[i].setPriority(Thread.NORM_PRIORITY - 1); + this.workers[i].setUncaughtExceptionHandler((final Thread thread, final Throwable throwable) -> { + PaperFileIOThread.LOGGER.fatal("Thread '" + thread.getName() + "' threw an uncaught exception!", throwable); diff --git a/Spigot-Server-Patches/Configurable-Player-Collision.patch b/Spigot-Server-Patches/Configurable-Player-Collision.patch index 1c79fceb5e..d385b2cb8f 100644 --- a/Spigot-Server-Patches/Configurable-Player-Collision.patch +++ b/Spigot-Server-Patches/Configurable-Player-Collision.patch @@ -73,7 +73,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 entityplayer.syncInventory(); + // Paper start - Add to collideRule team if needed -+ final Scoreboard scoreboard = this.getServer().getWorldServer(DimensionManager.OVERWORLD).getScoreboard(); ++ final Scoreboard scoreboard = this.getServer().getWorldServer(World.OVERWORLD).getScoreboard(); + final ScoreboardTeam collideRuleTeam = scoreboard.getTeam(collideRuleTeamName); + if (this.collideRuleTeamName != null && collideRuleTeam != null && entityplayer.getScoreboardTeam() == null) { + scoreboard.addPlayerToTeam(entityplayer.getName(), collideRuleTeam); @@ -88,7 +88,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - Remove from collideRule team if needed + if (this.collideRuleTeamName != null) { -+ final Scoreboard scoreBoard = this.server.getWorldServer(DimensionManager.OVERWORLD).getScoreboard(); ++ final Scoreboard scoreBoard = this.server.getWorldServer(World.OVERWORLD).getScoreboard(); + final ScoreboardTeam team = scoreBoard.getTeam(this.collideRuleTeamName); + if (entityplayer.getScoreboardTeam() == team && team != null) { + scoreBoard.removePlayerFromTeam(entityplayer.getName(), team); @@ -105,7 +105,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - Remove collideRule team if it exists + if (this.collideRuleTeamName != null) { -+ final Scoreboard scoreboard = this.getServer().getWorldServer(DimensionManager.OVERWORLD).getScoreboard(); ++ final Scoreboard scoreboard = this.getServer().getWorldServer(World.OVERWORLD).getScoreboard(); + final ScoreboardTeam team = scoreboard.getTeam(this.collideRuleTeamName); + if (team != null) scoreboard.removeTeam(team); + } 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 a77bf072f3..26449fed76 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 { - private void armorStandEntityLookups() { - armorStandEntityLookups = getBoolean("armor-stands-do-collision-entity-lookups", true); + this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick); + log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default"); } + + public int waterOverLavaFlowSpeed; diff --git a/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch b/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch index 74b6d19d14..94f40b824d 100644 --- a/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch +++ b/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch @@ -95,8 +95,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start + } -+ public void onPlayerJoinFinish(EntityPlayer entityplayer, WorldServer worldserver, String s1) { ++ public void onPlayerJoinFinish(EntityPlayer entityplayer, WorldServer worldserver1, String s1) { + // Paper end entityplayer.syncInventory(); // Paper start - Add to collideRule team if needed - final Scoreboard scoreboard = this.getServer().getWorldServer(DimensionManager.OVERWORLD).getScoreboard(); + final Scoreboard scoreboard = this.getServer().getWorldServer(World.OVERWORLD).getScoreboard(); diff --git a/Spigot-Server-Patches/Generator-Settings.patch b/Spigot-Server-Patches/Generator-Settings.patch index f4cda5030d..9a058217ab 100644 --- a/Spigot-Server-Patches/Generator-Settings.patch +++ b/Spigot-Server-Patches/Generator-Settings.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 { - private void perPlayerMobSpawns() { - perPlayerMobSpawns = getBoolean("per-player-mob-spawns", false); + } + } } + + public boolean generateFlatBedrock; diff --git a/Spigot-Server-Patches/Handle-Large-Packets-disconnecting-client.patch b/Spigot-Server-Patches/Handle-Large-Packets-disconnecting-client.patch index 88ea38a3bf..9e1e95d4e9 100644 --- a/Spigot-Server-Patches/Handle-Large-Packets-disconnecting-client.patch +++ b/Spigot-Server-Patches/Handle-Large-Packets-disconnecting-client.patch @@ -10,12 +10,20 @@ diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/j index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/NetworkManager.java +++ b/src/main/java/net/minecraft/server/NetworkManager.java +@@ -0,0 +0,0 @@ import io.netty.channel.epoll.EpollEventLoopGroup; + import io.netty.channel.local.LocalChannel; + import io.netty.channel.local.LocalServerChannel; + import io.netty.channel.nio.NioEventLoopGroup; ++import io.netty.handler.codec.EncoderException; // Paper + import io.netty.handler.timeout.TimeoutException; + import io.netty.util.AttributeKey; + import io.netty.util.concurrent.Future; @@ -0,0 +0,0 @@ public class NetworkManager extends SimpleChannelInboundHandler> { } public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) { + // Paper start -+ if (throwable instanceof io.netty.handler.codec.EncoderException && throwable.getCause() instanceof PacketEncoder.PacketTooLargeException) { ++ if (throwable instanceof EncoderException && throwable.getCause() instanceof PacketEncoder.PacketTooLargeException) { + if (((PacketEncoder.PacketTooLargeException) throwable.getCause()).getPacket().packetTooLarge(this)) { + return; + } else { diff --git a/Spigot-Server-Patches/Implement-Brigadier-Mojang-API.patch b/Spigot-Server-Patches/Implement-Brigadier-Mojang-API.patch index 62fecb8ad1..841305f3a9 100644 --- a/Spigot-Server-Patches/Implement-Brigadier-Mojang-API.patch +++ b/Spigot-Server-Patches/Implement-Brigadier-Mojang-API.patch @@ -82,7 +82,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer); + suggestEvent.setCancelled(suggestions.isEmpty()); + if (!suggestEvent.callEvent()) return; -+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper ++ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (com.mojang.brigadier.suggestion.Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper + // Paper end }); }); @@ -92,7 +92,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1); completions.forEach(builder::suggest); - player.playerConnection.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), builder.buildFuture().join())); -+ Suggestions suggestions = builder.buildFuture().join(); ++ com.mojang.brigadier.suggestion.Suggestions suggestions = builder.buildFuture().join(); + com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer); + suggestEvent.setCancelled(suggestions.isEmpty()); + if (!suggestEvent.callEvent()) return; diff --git a/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch b/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch index ee4cbb798c..ff59d05fa0 100644 --- a/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch +++ b/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch @@ -587,8 +587,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private int lastFoodSent = -99999999; private boolean lastSentSaturationZero = true; @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + this.canPickUpLoot = true; this.maxHealthCache = this.getMaxHealth(); - this.cachedSingleMobDistanceMap = new com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper } + // Paper start + public BlockPosition getPointInFront(double inFront) { @@ -1069,8 +1069,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - public void updatePlayerMobTypeMap(Entity entity) { - if (!this.world.paperConfig.perPlayerMobSpawns) { + private static double getDistanceSquaredFromChunk(ChunkCoordIntPair chunkPos, Entity entity) { return a(chunkPos, entity); } // Paper - OBFHELPER + private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { List>> list = Lists.newArrayList(); int j = chunkcoordintpair.x; diff --git a/Spigot-Server-Patches/Implement-Mob-Goal-API.patch b/Spigot-Server-Patches/Implement-Mob-Goal-API.patch index 95d0b0363c..92904a7f0e 100644 --- a/Spigot-Server-Patches/Implement-Mob-Goal-API.patch +++ b/Spigot-Server-Patches/Implement-Mob-Goal-API.patch @@ -251,6 +251,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + bukkitMap.put(EntityZombie.class, Zombie.class); + bukkitMap.put(EntityZombieHusk.class, Husk.class); + bukkitMap.put(EntityZombieVillager.class, ZombieVillager.class); ++ bukkitMap.put(EntityHoglin.class, Hoglin.class); ++ bukkitMap.put(EntityPiglin.class, Piglin.class); ++ bukkitMap.put(EntityStrider.class, Strider.class); ++ bukkitMap.put(EntityZoglin.class, Zoglin.class); + } + + public static String getUsableName(Class clazz) { @@ -857,10 +861,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ +package com.destroystokyo.paper.entity.ai; + -+import com.destroystokyo.paper.entity.ai.GoalKey; -+import com.destroystokyo.paper.entity.ai.MobGoalHelper; -+import com.destroystokyo.paper.entity.ai.VanillaGoal; -+ +import net.minecraft.server.EntityInsentient; +import net.minecraft.server.PathfinderGoal; + @@ -882,11 +882,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + @Test + public void testKeys() { ++ List> deprecated = new ArrayList<>(); + List> keys = new ArrayList<>(); + for (Field field : VanillaGoal.class.getFields()) { + if (field.getType().equals(GoalKey.class)) { + try { -+ keys.add((GoalKey) field.get(null)); ++ GoalKey goalKey = (GoalKey) field.get(null); ++ if (field.getAnnotation(Deprecated.class) != null) { ++ deprecated.add(goalKey); ++ } else { ++ keys.add(goalKey); ++ } + } catch (IllegalAccessException e) { + System.out.println("Skipping " + field.getName() + ": " + e.getMessage()); + } @@ -925,6 +931,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + shouldFail = true; + } + ++ if (deprecated.size() != 0) { ++ System.out.println("Deprecated (might want to remove them at some point): "); ++ deprecated.forEach(System.out::println); ++ } ++ + if (shouldFail) Assert.fail("See above"); + } + @@ -939,12 +950,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + classes = scanResult.getSubclasses("net.minecraft.server.EntityInsentient").loadClasses(); + } + -+ boolean shouldFail =false; ++ boolean shouldFail = false; + for (Class nmsClass : classes) { + Class bukkitClass = MobGoalHelper.toBukkitClass((Class) nmsClass); -+ if(bukkitClass == null) { ++ if (bukkitClass == null) { + shouldFail = true; -+ System.out.println("Missing bukkitMap.put(" + nmsClass.getSimpleName() + ".class, "+nmsClass.getSimpleName().replace("Entity","")+".class);"); ++ System.out.println("Missing bukkitMap.put(" + nmsClass.getSimpleName() + ".class, " + nmsClass.getSimpleName().replace("Entity", "") + ".class);"); + } + } + diff --git a/Spigot-Server-Patches/MC-145656-Fix-Follow-Range-Initial-Target.patch b/Spigot-Server-Patches/MC-145656-Fix-Follow-Range-Initial-Target.patch index 4d9bdd59c1..a3f188ac35 100644 --- a/Spigot-Server-Patches/MC-145656-Fix-Follow-Range-Initial-Target.patch +++ b/Spigot-Server-Patches/MC-145656-Fix-Follow-Range-Initial-Target.patch @@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + private double getFollowRange(EntityLiving entityliving) { -+ AttributeInstance attributeinstance = entityliving.getAttributeInstance(GenericAttributes.FOLLOW_RANGE); ++ AttributeModifiable attributeinstance = entityliving.getAttributeInstance(GenericAttributes.FOLLOW_RANGE); + return attributeinstance == null ? 16.0D : attributeinstance.getValue(); + } + // Paper end diff --git a/Spigot-Server-Patches/MC-Dev-fixes.patch b/Spigot-Server-Patches/MC-Dev-fixes.patch index 71f013b968..2c2209ca14 100644 --- a/Spigot-Server-Patches/MC-Dev-fixes.patch +++ b/Spigot-Server-Patches/MC-Dev-fixes.patch @@ -193,6 +193,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return this.getTemperature() - (f + (float) blockposition.getY() - 64.0F) * 0.05F / 30.0F; } else { +diff --git a/src/main/java/net/minecraft/server/Biomes.java b/src/main/java/net/minecraft/server/Biomes.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/Biomes.java ++++ b/src/main/java/net/minecraft/server/Biomes.java +@@ -0,0 +0,0 @@ public abstract class Biomes { + private static BiomeBase a(int i, String s, BiomeBase biomebase) { + IRegistry.a(IRegistry.BIOME, i, s, biomebase); + if (biomebase.b()) { +- BiomeBase.d.a(biomebase, IRegistry.BIOME.a(IRegistry.BIOME.get(new MinecraftKey(biomebase.l)))); ++ BiomeBase.reg.a(biomebase, IRegistry.BIOME.a(IRegistry.BIOME.get(new MinecraftKey(biomebase.l)))); + } + + return biomebase; diff --git a/src/main/java/net/minecraft/server/BlockStateEnum.java b/src/main/java/net/minecraft/server/BlockStateEnum.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockStateEnum.java @@ -403,6 +416,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.b(); this.g.set(false); })); +diff --git a/src/main/java/net/minecraft/server/LootEntryAbstract.java b/src/main/java/net/minecraft/server/LootEntryAbstract.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/LootEntryAbstract.java ++++ b/src/main/java/net/minecraft/server/LootEntryAbstract.java +@@ -0,0 +0,0 @@ public abstract class LootEntryAbstract implements LootEntryChildren { + + // CraftBukkit start + @Override +- public final void a(JsonObject jsonobject, T t0, JsonSerializationContext jsonserializationcontext) { ++ public void a(JsonObject jsonobject, T t0, JsonSerializationContext jsonserializationcontext) { // Paper - remove final + if (!org.apache.commons.lang3.ArrayUtils.isEmpty(t0.d)) { + jsonobject.add("conditions", jsonserializationcontext.serialize(t0.d)); + } diff --git a/src/main/java/net/minecraft/server/LootItemFunctionExplorationMap.java b/src/main/java/net/minecraft/server/LootItemFunctionExplorationMap.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/LootItemFunctionExplorationMap.java @@ -473,6 +499,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 default String asString() { return this.toString(); +diff --git a/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java b/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java ++++ b/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java +@@ -0,0 +0,0 @@ import java.io.InputStream; + import java.io.OutputStream; + import java.util.zip.GZIPInputStream; + import java.util.zip.GZIPOutputStream; ++import io.netty.buffer.ByteBufInputStream; // Paper + + public class NBTCompressedStreamTools { + +@@ -0,0 +0,0 @@ public class NBTCompressedStreamTools { + + public static NBTTagCompound a(DataInput datainput, NBTReadLimiter nbtreadlimiter) throws IOException { + // Spigot start +- if ( datainput instanceof io.netty.buffer.ByteBufInputStream ) ++ if ( datainput instanceof ByteBufInputStream) // Paper + { + datainput = new DataInputStream(new org.spigotmc.LimitStream((InputStream) datainput, nbtreadlimiter)); + } diff --git a/src/main/java/net/minecraft/server/NBTTagList.java b/src/main/java/net/minecraft/server/NBTTagList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/NBTTagList.java @@ -549,6 +596,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.e = 0; this.f = 0; +diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/StructureGenerator.java ++++ b/src/main/java/net/minecraft/server/StructureGenerator.java +@@ -0,0 +0,0 @@ public abstract class StructureGenerator + private static > F a(String s, F f0, WorldGenStage.Decoration worldgenstage_decoration) { + StructureGenerator.a.put(s.toLowerCase(Locale.ROOT), f0); + StructureGenerator.u.put(f0, worldgenstage_decoration); +- return (StructureGenerator) IRegistry.a(IRegistry.STRUCTURE_FEATURE, s.toLowerCase(Locale.ROOT), (Object) f0); ++ return (F) IRegistry.>a(IRegistry.STRUCTURE_FEATURE, s.toLowerCase(Locale.ROOT), f0); // Paper - decomp fix + } + + public StructureGenerator(Codec codec) { diff --git a/src/main/java/net/minecraft/server/SystemUtils.java b/src/main/java/net/minecraft/server/SystemUtils.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/SystemUtils.java diff --git a/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch b/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch index f3b2891ba8..b497bd6820 100644 --- a/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch +++ b/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch @@ -353,7 +353,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - no-tick view distance } - public void updatePlayerMobTypeMap(Entity entity) { + private static double getDistanceSquaredFromChunk(ChunkCoordIntPair chunkPos, Entity entity) { return a(chunkPos, entity); } // Paper - OBFHELPER @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { completablefuture1.thenAcceptAsync((either) -> { either.mapLeft((chunk) -> { @@ -373,10 +373,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return completablefuture1; } @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + } } - protected void setViewDistance(int i) { +- protected void setViewDistance(int i) { - int j = MathHelper.clamp(i + 1, 3, 33); ++ public void setViewDistance(int i) { // Paper - public + int j = MathHelper.clamp(i + 1, 3, 33); // Paper - diff on change, these make the lower view distance limit 2 and the upper 32 if (j != this.viewDistance) { 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 28eda373bd..135054489f 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 @@ -361,6 +361,14 @@ diff --git a/src/main/java/net/minecraft/server/ServerConnection.java b/src/main index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ServerConnection.java +++ b/src/main/java/net/minecraft/server/ServerConnection.java +@@ -0,0 +0,0 @@ import io.netty.channel.epoll.EpollServerSocketChannel; + import io.netty.channel.nio.NioEventLoopGroup; + import io.netty.channel.socket.ServerSocketChannel; + import io.netty.channel.socket.nio.NioServerSocketChannel; ++import io.netty.handler.flush.FlushConsolidationHandler; // Paper + import io.netty.handler.timeout.ReadTimeoutHandler; + import java.io.IOException; + import java.net.InetAddress; @@ -0,0 +0,0 @@ public class ServerConnection { private final List connectedChannels = Collections.synchronizedList(Lists.newArrayList()); // Paper start - prevent blocking on adding a new network manager while the server is ticking @@ -378,7 +386,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 ; } -+ if (!disableFlushConsolidation) channel.pipeline().addFirst(new io.netty.handler.flush.FlushConsolidationHandler()); // Paper ++ if (!disableFlushConsolidation) channel.pipeline().addFirst(new FlushConsolidationHandler()); // Paper channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)).addLast("legacy_query", new LegacyPingHandler(ServerConnection.this)).addLast("splitter", new PacketSplitter()).addLast("decoder", new PacketDecoder(EnumProtocolDirection.SERVERBOUND)).addLast("prepender", new PacketPrepender()).addLast("encoder", new PacketEncoder(EnumProtocolDirection.CLIENTBOUND)); NetworkManager networkmanager = new NetworkManager(EnumProtocolDirection.SERVERBOUND); diff --git a/Spigot-Server-Patches/Optimize-RegistryMaterials.patch b/Spigot-Server-Patches/Optimize-RegistryMaterials.patch index 631d0e862f..7ff21e016b 100644 --- a/Spigot-Server-Patches/Optimize-RegistryMaterials.patch +++ b/Spigot-Server-Patches/Optimize-RegistryMaterials.patch @@ -42,3 +42,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 builder.add(Pair.of(registrymaterials.c(t0).get(), t0)); } +@@ -0,0 +0,0 @@ public class RegistryMaterials extends IRegistryWritable { + + registrymaterials.bb.entrySet().stream().filter((entry) -> { + return registrymaterials.c((ResourceKey) entry.getKey()); +- }).forEach(com_google_common_collect_immutablemap_builder::put); ++ }).forEach(entry1 -> com_google_common_collect_immutablemap_builder.put((java.util.Map.Entry,? extends T>) entry1)); // Paper - compiler fix (expand method reference + add cast) + return com_google_common_collect_immutablemap_builder.build(); + }); + } diff --git a/Spigot-Server-Patches/Optimize-TileEntity-Ticking.patch b/Spigot-Server-Patches/Optimize-TileEntity-Ticking.patch index 28dcd268e7..6174e02618 100644 --- a/Spigot-Server-Patches/Optimize-TileEntity-Ticking.patch +++ b/Spigot-Server-Patches/Optimize-TileEntity-Ticking.patch @@ -4,6 +4,43 @@ Date: Sun, 8 Mar 2015 22:55:25 -0600 Subject: [PATCH] Optimize TileEntity Ticking +diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/co/aikar/timings/TimingsExport.java ++++ b/src/main/java/co/aikar/timings/TimingsExport.java +@@ -0,0 +0,0 @@ public class TimingsExport extends Thread { + pair("end", System.currentTimeMillis() / 1000), + pair("online-mode", Bukkit.getServer().getOnlineMode()), + pair("sampletime", (System.currentTimeMillis() - TimingsManager.timingStart) / 1000), +- pair("datapacks", toArrayMapper(MinecraftServer.getServer().getResourcePackRepository().d(), pack -> { ++ pair("datapacks", toArrayMapper(MinecraftServer.getServer().getResourcePackRepository().e(), pack -> { + // Don't feel like obf helper'ing these, non fatal if its temp missed. + return ChatColor.stripColor(CraftChatMessage.fromComponent(pack.a(true))); + })) +@@ -0,0 +0,0 @@ public class TimingsExport extends Thread { + ); + + parent.put("worlds", toObjectMapper(MinecraftServer.getServer().getWorlds(), world -> { +- if (world.getWorldData().getName().equals("worldeditregentempworld")) return null; +- return pair(world.getWorldData().getName(), createObject( ++ if (world.getWorld().getName().equals("worldeditregentempworld")) return null; ++ return pair(world.getWorld().getName(), createObject( + pair("gamerules", toObjectMapper(world.getWorld().getGameRules(), rule -> { + return pair(rule, world.getWorld().getGameRuleValue(rule)); + })), +diff --git a/src/main/java/net/minecraft/server/BlockChest.java b/src/main/java/net/minecraft/server/BlockChest.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/BlockChest.java ++++ b/src/main/java/net/minecraft/server/BlockChest.java +@@ -0,0 +0,0 @@ public class BlockChest extends BlockChestAbstract implements I + + public static final BlockStateDirection FACING = BlockFacingHorizontal.FACING; + public static final BlockStateEnum c = BlockProperties.aF; +- public static final BlockStateBoolean d = BlockProperties.C; ++ public static final BlockStateBoolean d = BlockProperties.C; public static final BlockStateBoolean waterlogged() { return d; } // Paper OBFHELPER + protected static final VoxelShape e = Block.a(1.0D, 0.0D, 0.0D, 15.0D, 14.0D, 15.0D); + protected static final VoxelShape f = Block.a(1.0D, 0.0D, 1.0D, 15.0D, 14.0D, 16.0D); + protected static final VoxelShape g = Block.a(0.0D, 0.0D, 1.0D, 15.0D, 14.0D, 15.0D); diff --git a/src/main/java/net/minecraft/server/TileEntityChest.java b/src/main/java/net/minecraft/server/TileEntityChest.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/TileEntityChest.java @@ -70,7 +107,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } private void a(SoundEffect soundeffect) { -+ if (!this.getBlock().hasProperty(BlockChest.c)) { return; } // Paper - this can be delayed, double check exists - Fixes GH-2074 ++ if (!this.getBlock().get(BlockChest.waterlogged())) { return; } // Paper - this can be delayed, double check exists - Fixes GH-2074 BlockPropertyChestType blockpropertychesttype = (BlockPropertyChestType) this.getBlock().get(BlockChest.c); if (blockpropertychesttype != BlockPropertyChestType.LEFT) { diff --git a/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch b/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch index a536028223..bcb3df5f67 100644 --- a/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch +++ b/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch @@ -290,11 +290,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - optimise PlayerChunkMap#isOutsideRange } - public void updatePlayerMobTypeMap(Entity entity) { -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - return entityPlayer.mobCounts[enumCreatureType.ordinal()]; - } - + private static double getDistanceSquaredFromChunk(ChunkCoordIntPair chunkPos, Entity entity) { return a(chunkPos, entity); } // Paper - OBFHELPER private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) { double d0 = (double) (chunkcoordintpair.x * 16 + 8); diff --git a/Spigot-Server-Patches/Paper-config-files.patch b/Spigot-Server-Patches/Paper-config-files.patch index 6cb7313e90..60b387e6d3 100644 --- a/Spigot-Server-Patches/Paper-config-files.patch +++ b/Spigot-Server-Patches/Paper-config-files.patch @@ -564,7 +564,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Spigot end + // Paper start + try { -+ com.destroystokyo.paper.PaperConfig.init((File) options.valueOf("paper-settings")); ++ com.destroystokyo.paper.PaperConfig.init((java.io.File) options.valueOf("paper-settings")); + } catch (Exception e) { + DedicatedServer.LOGGER.error("Unable to load server configuration", e); + return false; diff --git a/Spigot-Server-Patches/RangedEntity-API.patch b/Spigot-Server-Patches/RangedEntity-API.patch index ac299cd0e5..4b16cf4d97 100644 --- a/Spigot-Server-Patches/RangedEntity-API.patch +++ b/Spigot-Server-Patches/RangedEntity-API.patch @@ -43,7 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + void a(EntityLiving entityliving, float f); default void rangedAttack(EntityLiving entityliving, float f) { a(entityliving, f); } // Paper - OBFHELPER + + // - see EntitySkeletonAbstract melee goal -+ void q(boolean flag); default void setChargingAttack(boolean charging) { q(charging); }; // Paper ++ void setAggressive(boolean flag); default void setChargingAttack(boolean charging) { setAggressive(charging); }; // Paper } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/Remove-FishingHook-reference-on-Craft-Entity-removal.patch b/Spigot-Server-Patches/Remove-FishingHook-reference-on-Craft-Entity-removal.patch index b19c38731a..777f149c91 100644 --- a/Spigot-Server-Patches/Remove-FishingHook-reference-on-Craft-Entity-removal.patch +++ b/Spigot-Server-Patches/Remove-FishingHook-reference-on-Craft-Entity-removal.patch @@ -17,10 +17,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override + public void remove() { + super.remove(); -+ if (getHandle().owner != null) { -+ getHandle().owner.hookedFish = null; ++ if (getHandle().getOwner() != null) { ++ getHandle().getOwner().hookedFish = null; + } + } + // Paper end -+ ++ } diff --git a/Spigot-Server-Patches/String-based-Action-Bar-API.patch b/Spigot-Server-Patches/String-based-Action-Bar-API.patch index 66111022b2..20a8e6b311 100644 --- a/Spigot-Server-Patches/String-based-Action-Bar-API.patch +++ b/Spigot-Server-Patches/String-based-Action-Bar-API.patch @@ -4,6 +4,19 @@ Date: Tue, 27 Dec 2016 15:02:42 -0500 Subject: [PATCH] String based Action Bar API +diff --git a/src/main/java/net/minecraft/server/SystemUtils.java b/src/main/java/net/minecraft/server/SystemUtils.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/SystemUtils.java ++++ b/src/main/java/net/minecraft/server/SystemUtils.java +@@ -0,0 +0,0 @@ public class SystemUtils { + private static final ExecutorService e = a("Main"); + private static final ExecutorService f = n(); + public static LongSupplier a = System::nanoTime; +- public static final UUID b = new UUID(0L, 0L); ++ public static final UUID b = new UUID(0L, 0L); public static final UUID getNullUUID() {return b;} // Paper OBFHELPER + private static final Logger LOGGER = LogManager.getLogger(); + + public static Collector, ?, Map> a() { 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 @@ -15,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override + public void sendActionBar(String message) { + if (getHandle().playerConnection == null || message == null || message.isEmpty()) return; -+ getHandle().playerConnection.sendPacket(new PacketPlayOutChat(new net.minecraft.server.ChatComponentText(message), net.minecraft.server.ChatMessageType.GAME_INFO)); ++ getHandle().playerConnection.sendPacket(new PacketPlayOutChat(new net.minecraft.server.ChatComponentText(message), net.minecraft.server.ChatMessageType.GAME_INFO, SystemUtils.getNullUUID())); + } + + @Override diff --git a/Spigot-Server-Patches/Timings-v2.patch b/Spigot-Server-Patches/Timings-v2.patch index 9eaceba285..4a894b8f4b 100644 --- a/Spigot-Server-Patches/Timings-v2.patch +++ b/Spigot-Server-Patches/Timings-v2.patch @@ -551,6 +551,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +package co.aikar.timings; + +import net.minecraft.server.World; ++import net.minecraft.server.WorldDataServer; +import net.minecraft.server.WorldServer; + +/** @@ -608,7 +609,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public final Timing miscMobSpawning; + + public WorldTimingsHandler(World server) { -+ String name = server.getWorld().getName() +" - "; ++ String name = ((WorldDataServer) server.getWorldData()).getName() + " - "; + + mobSpawn = Timings.ofSafe(name + "mobSpawn"); + doChunkUnload = Timings.ofSafe(name + "doChunkUnload"); @@ -663,7 +664,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + public static Timing getTickList(WorldServer worldserver, String timingsType) { -+ return Timings.ofSafe(worldserver.getWorld().getName() + " - Scheduled " + timingsType); ++ return Timings.ofSafe(((WorldDataServer) worldserver.getWorldData()).getName() + " - Scheduled " + timingsType); + } +} diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java 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 2a7b598adc..66bc7675c8 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 @@ -117,9 +117,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Paper end @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + this.l = supplier; this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper this.setViewDistance(i); - this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper + // Paper start - use distance map to optimise entity tracker + this.playerEntityTrackerTrackMaps = new com.destroystokyo.paper.util.misc.PlayerAreaMap[TRACKING_RANGE_TYPES.length]; + this.entityTrackerTrackRanges = new int[TRACKING_RANGE_TYPES.length]; @@ -161,7 +161,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - use distance map to optimise entity tracker } - public void updatePlayerMobTypeMap(Entity entity) { + private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } diff --git a/Spigot-Server-Patches/Villager-Restocks-API.patch b/Spigot-Server-Patches/Villager-Restocks-API.patch index 3bc317aec4..0cbe114363 100644 --- a/Spigot-Server-Patches/Villager-Restocks-API.patch +++ b/Spigot-Server-Patches/Villager-Restocks-API.patch @@ -9,19 +9,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- 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 - - return optional.isPresent() ? i - (Long) optional.get() < 24000L : false; - } -+ -+ // Paper start -+ public int getRestocksToday(){ -+ return this.bL; -+ } -+ public void setRestocksToday(int restocksToday){ -+ this.bL = restocksToday; -+ } -+ // Paper end - } + private long bH; + private int bI; + private long bJ; +- private int bK; ++ private int bK; public int getRestocksToday(){ return this.bK; } public void setRestocksToday(int restocksToday){ this.bK = restocksToday; } // Paper OBFHELPER + private long bL; + private boolean bM; + private static final ImmutableList> bN = ImmutableList.of(MemoryModuleType.HOME, MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, MemoryModuleType.MEETING_POINT, MemoryModuleType.MOBS, MemoryModuleType.VISIBLE_MOBS, MemoryModuleType.VISIBLE_VILLAGER_BABIES, MemoryModuleType.NEAREST_PLAYERS, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, MemoryModuleType.WALK_TARGET, new MemoryModuleType[]{MemoryModuleType.LOOK_TARGET, MemoryModuleType.INTERACTION_TARGET, MemoryModuleType.BREED_TARGET, MemoryModuleType.PATH, MemoryModuleType.INTERACTABLE_DOORS, MemoryModuleType.OPENED_DOORS, MemoryModuleType.NEAREST_BED, MemoryModuleType.HURT_BY, MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.NEAREST_HOSTILE, MemoryModuleType.SECONDARY_JOB_SITE, MemoryModuleType.HIDING_PLACE, MemoryModuleType.HEARD_BELL_TIME, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.LAST_SLEPT, MemoryModuleType.LAST_WOKEN, MemoryModuleType.LAST_WORKED_AT_POI, MemoryModuleType.GOLEM_LAST_SEEN_TIME}); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java diff --git a/Spigot-Server-Patches/Workaround-for-Client-Lag-Spikes-MC-162253.patch b/Spigot-Server-Patches/Workaround-for-Client-Lag-Spikes-MC-162253.patch index d522ba9bda..5843536c77 100644 --- a/Spigot-Server-Patches/Workaround-for-Client-Lag-Spikes-MC-162253.patch +++ b/Spigot-Server-Patches/Workaround-for-Client-Lag-Spikes-MC-162253.patch @@ -40,15 +40,6 @@ diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/j 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 { - player.needsChunkCenterUpdate = false; - player.playerConnection.sendPacket(new PacketPlayOutViewCentre(currPosX, currPosZ)); - } -- PlayerChunkMap.this.sendChunk(player, new ChunkCoordIntPair(rangeX, rangeZ), new Packet[2], false, true); // unloaded, loaded -+ PlayerChunkMap.this.sendChunk(player, new ChunkCoordIntPair(rangeX, rangeZ), new Packet[10], false, true); // unloaded, loaded - }, - (EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ, - com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet newState) -> { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } diff --git a/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch b/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch deleted file mode 100644 index f3e456e258..0000000000 --- a/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch +++ /dev/null @@ -1,825 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kickash32 -Date: Mon, 19 Aug 2019 01:27:58 +0500 -Subject: [PATCH] implement optional per player mob spawns - - -diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java -+++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -@@ -0,0 +0,0 @@ public class WorldTimingsHandler { - - - public final Timing miscMobSpawning; -+ public final Timing playerMobDistanceMapUpdate; - - public final Timing poiUnload; - public final Timing chunkUnload; -@@ -0,0 +0,0 @@ public class WorldTimingsHandler { - - - miscMobSpawning = Timings.ofSafe(name + "Mob spawning - Misc"); -+ playerMobDistanceMapUpdate = Timings.ofSafe(name + "Per Player Mob Spawning - Distance Map Update"); - - poiUnload = Timings.ofSafe(name + "Chunk unload - POI"); - chunkUnload = Timings.ofSafe(name + "Chunk unload - Chunk"); -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 boolean perPlayerMobSpawns = false; -+ private void perPlayerMobSpawns() { -+ perPlayerMobSpawns = getBoolean("per-player-mob-spawns", false); -+ } - } -diff --git a/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java b/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java -@@ -0,0 +0,0 @@ -+package com.destroystokyo.paper.util; -+ -+import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; -+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -+import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; -+import net.minecraft.server.ChunkCoordIntPair; -+import net.minecraft.server.EntityPlayer; -+import net.minecraft.server.SectionPosition; -+import org.spigotmc.AsyncCatcher; -+import java.util.HashMap; -+import java.util.List; -+import java.util.Map; -+import java.util.Set; -+ -+/** @author Spottedleaf */ -+public final class PlayerMobDistanceMap { -+ -+ private static final PooledHashSets.PooledObjectLinkedOpenHashSet EMPTY_SET = new PooledHashSets.PooledObjectLinkedOpenHashSet<>(); -+ -+ private final Map players = new HashMap<>(); -+ // we use linked for better iteration. -+ private final Long2ObjectOpenHashMap> playerMap = new Long2ObjectOpenHashMap<>(32, 0.5f); -+ private int viewDistance; -+ -+ private final PooledHashSets pooledHashSets = new PooledHashSets<>(); -+ -+ public PooledHashSets.PooledObjectLinkedOpenHashSet getPlayersInRange(final ChunkCoordIntPair chunkPos) { -+ return this.getPlayersInRange(chunkPos.x, chunkPos.z); -+ } -+ -+ public PooledHashSets.PooledObjectLinkedOpenHashSet getPlayersInRange(final int chunkX, final int chunkZ) { -+ return this.playerMap.getOrDefault(ChunkCoordIntPair.pair(chunkX, chunkZ), EMPTY_SET); -+ } -+ -+ public void update(final List currentPlayers, final int newViewDistance) { -+ AsyncCatcher.catchOp("Distance map update"); -+ final ObjectLinkedOpenHashSet gone = new ObjectLinkedOpenHashSet<>(this.players.keySet()); -+ -+ final int oldViewDistance = this.viewDistance; -+ this.viewDistance = newViewDistance; -+ -+ for (final EntityPlayer player : currentPlayers) { -+ if (player.isSpectator() || !player.affectsSpawning) { -+ continue; // will be left in 'gone' (or not added at all) -+ } -+ -+ gone.remove(player); -+ -+ final SectionPosition newPosition = player.getPlayerMapSection(); -+ final SectionPosition oldPosition = this.players.put(player, newPosition); -+ -+ if (oldPosition == null) { -+ this.addNewPlayer(player, newPosition, newViewDistance); -+ } else { -+ this.updatePlayer(player, oldPosition, newPosition, oldViewDistance, newViewDistance); -+ } -+ //this.validatePlayer(player, newViewDistance); // debug only -+ } -+ -+ for (final EntityPlayer player : gone) { -+ final SectionPosition oldPosition = this.players.remove(player); -+ if (oldPosition != null) { -+ this.removePlayer(player, oldPosition, oldViewDistance); -+ } -+ } -+ } -+ -+ // expensive op, only for debug -+ private void validatePlayer(final EntityPlayer player, final int viewDistance) { -+ int entiesGot = 0; -+ int expectedEntries = (2 * viewDistance + 1); -+ expectedEntries *= expectedEntries; -+ -+ final SectionPosition currPosition = player.getPlayerMapSection(); -+ -+ final int centerX = currPosition.getX(); -+ final int centerZ = currPosition.getZ(); -+ -+ for (final Long2ObjectLinkedOpenHashMap.Entry> entry : this.playerMap.long2ObjectEntrySet()) { -+ final long key = entry.getLongKey(); -+ final PooledHashSets.PooledObjectLinkedOpenHashSet map = entry.getValue(); -+ -+ if (map.referenceCount == 0) { -+ throw new IllegalStateException("Invalid map"); -+ } -+ -+ if (map.set.contains(player)) { -+ ++entiesGot; -+ -+ final int chunkX = ChunkCoordIntPair.getX(key); -+ final int chunkZ = ChunkCoordIntPair.getZ(key); -+ -+ final int dist = Math.max(Math.abs(chunkX - centerX), Math.abs(chunkZ - centerZ)); -+ -+ if (dist > viewDistance) { -+ throw new IllegalStateException("Expected view distance " + viewDistance + ", got " + dist); -+ } -+ } -+ } -+ -+ if (entiesGot != expectedEntries) { -+ throw new IllegalStateException("Expected " + expectedEntries + ", got " + entiesGot); -+ } -+ } -+ -+ private void addPlayerTo(final EntityPlayer player, final int chunkX, final int chunkZ) { -+ this.playerMap.compute(ChunkCoordIntPair.pair(chunkX, chunkZ), (final Long key, final PooledHashSets.PooledObjectLinkedOpenHashSet players) -> { -+ if (players == null) { -+ return player.cachedSingleMobDistanceMap; -+ } else { -+ return PlayerMobDistanceMap.this.pooledHashSets.findMapWith(players, player); -+ } -+ }); -+ } -+ -+ private void removePlayerFrom(final EntityPlayer player, final int chunkX, final int chunkZ) { -+ this.playerMap.compute(ChunkCoordIntPair.pair(chunkX, chunkZ), (final Long keyInMap, final PooledHashSets.PooledObjectLinkedOpenHashSet players) -> { -+ return PlayerMobDistanceMap.this.pooledHashSets.findMapWithout(players, player); // rets null instead of an empty map -+ }); -+ } -+ -+ private void updatePlayer(final EntityPlayer player, final SectionPosition oldPosition, final SectionPosition newPosition, final int oldViewDistance, final int newViewDistance) { -+ final int toX = newPosition.getX(); -+ final int toZ = newPosition.getZ(); -+ final int fromX = oldPosition.getX(); -+ final int fromZ = oldPosition.getZ(); -+ -+ final int dx = toX - fromX; -+ final int dz = toZ - fromZ; -+ -+ final int totalX = Math.abs(fromX - toX); -+ final int totalZ = Math.abs(fromZ - toZ); -+ -+ if (Math.max(totalX, totalZ) > (2 * oldViewDistance)) { -+ // teleported? -+ this.removePlayer(player, oldPosition, oldViewDistance); -+ this.addNewPlayer(player, newPosition, newViewDistance); -+ return; -+ } -+ -+ // x axis is width -+ // z axis is height -+ // right refers to the x axis of where we moved -+ // top refers to the z axis of where we moved -+ -+ if (oldViewDistance == newViewDistance) { -+ // same view distance -+ -+ // used for relative positioning -+ final int up = 1 | (dz >> (Integer.SIZE - 1)); // 1 if dz >= 0, -1 otherwise -+ final int right = 1 | (dx >> (Integer.SIZE - 1)); // 1 if dx >= 0, -1 otherwise -+ -+ // The area excluded by overlapping the two view distance squares creates four rectangles: -+ // Two on the left, and two on the right. The ones on the left we consider the "removed" section -+ // and on the right the "added" section. -+ // https://i.imgur.com/MrnOBgI.png is a reference image. Note that the outside border is not actually -+ // exclusive to the regions they surround. -+ -+ // 4 points of the rectangle -+ int maxX; // exclusive -+ int minX; // inclusive -+ int maxZ; // exclusive -+ int minZ; // inclusive -+ -+ if (dx != 0) { -+ // handle right addition -+ -+ maxX = toX + (oldViewDistance * right) + right; // exclusive -+ minX = fromX + (oldViewDistance * right) + right; // inclusive -+ maxZ = fromZ + (oldViewDistance * up) + up; // exclusive -+ minZ = toZ - (oldViewDistance * up); // inclusive -+ -+ for (int currX = minX; currX != maxX; currX += right) { -+ for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.addPlayerTo(player, currX, currZ); -+ } -+ } -+ } -+ -+ if (dz != 0) { -+ // handle up addition -+ -+ maxX = toX + (oldViewDistance * right) + right; // exclusive -+ minX = toX - (oldViewDistance * right); // inclusive -+ maxZ = toZ + (oldViewDistance * up) + up; // exclusive -+ minZ = fromZ + (oldViewDistance * up) + up; // inclusive -+ -+ for (int currX = minX; currX != maxX; currX += right) { -+ for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.addPlayerTo(player, currX, currZ); -+ } -+ } -+ } -+ -+ if (dx != 0) { -+ // handle left removal -+ -+ maxX = toX - (oldViewDistance * right); // exclusive -+ minX = fromX - (oldViewDistance * right); // inclusive -+ maxZ = fromZ + (oldViewDistance * up) + up; // exclusive -+ minZ = toZ - (oldViewDistance * up); // inclusive -+ -+ for (int currX = minX; currX != maxX; currX += right) { -+ for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.removePlayerFrom(player, currX, currZ); -+ } -+ } -+ } -+ -+ if (dz != 0) { -+ // handle down removal -+ -+ maxX = fromX + (oldViewDistance * right) + right; // exclusive -+ minX = fromX - (oldViewDistance * right); // inclusive -+ maxZ = toZ - (oldViewDistance * up); // exclusive -+ minZ = fromZ - (oldViewDistance * up); // inclusive -+ -+ for (int currX = minX; currX != maxX; currX += right) { -+ for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.removePlayerFrom(player, currX, currZ); -+ } -+ } -+ } -+ } else { -+ // different view distance -+ // for now :) -+ this.removePlayer(player, oldPosition, oldViewDistance); -+ this.addNewPlayer(player, newPosition, newViewDistance); -+ } -+ } -+ -+ private void removePlayer(final EntityPlayer player, final SectionPosition position, final int viewDistance) { -+ final int x = position.getX(); -+ final int z = position.getZ(); -+ -+ for (int xoff = -viewDistance; xoff <= viewDistance; ++xoff) { -+ for (int zoff = -viewDistance; zoff <= viewDistance; ++zoff) { -+ this.removePlayerFrom(player, x + xoff, z + zoff); -+ } -+ } -+ } -+ -+ private void addNewPlayer(final EntityPlayer player, final SectionPosition position, final int viewDistance) { -+ final int x = position.getX(); -+ final int z = position.getZ(); -+ -+ for (int xoff = -viewDistance; xoff <= viewDistance; ++xoff) { -+ for (int zoff = -viewDistance; zoff <= viewDistance; ++zoff) { -+ this.addPlayerTo(player, x + xoff, z + zoff); -+ } -+ } -+ } -+} -diff --git a/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java b/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java -@@ -0,0 +0,0 @@ -+package com.destroystokyo.paper.util; -+ -+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -+import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; -+import java.lang.ref.WeakReference; -+import java.util.Iterator; -+ -+/** @author Spottedleaf */ -+public class PooledHashSets { -+ -+ // we really want to avoid that equals() check as much as possible... -+ protected final Object2ObjectOpenHashMap, PooledObjectLinkedOpenHashSet> mapPool = new Object2ObjectOpenHashMap<>(64, 0.25f); -+ -+ protected void decrementReferenceCount(final PooledObjectLinkedOpenHashSet current) { -+ if (current.referenceCount == 0) { -+ throw new IllegalStateException("Cannot decrement reference count for " + current); -+ } -+ if (current.referenceCount == -1 || --current.referenceCount > 0) { -+ return; -+ } -+ -+ this.mapPool.remove(current); -+ return; -+ } -+ -+ public PooledObjectLinkedOpenHashSet findMapWith(final PooledObjectLinkedOpenHashSet current, final E object) { -+ final PooledObjectLinkedOpenHashSet cached = current.getAddCache(object); -+ -+ if (cached != null) { -+ if (cached.referenceCount != -1) { -+ ++cached.referenceCount; -+ } -+ -+ decrementReferenceCount(current); -+ -+ return cached; -+ } -+ -+ if (!current.add(object)) { -+ return current; -+ } -+ -+ // we use get/put since we use a different key on put -+ PooledObjectLinkedOpenHashSet ret = this.mapPool.get(current); -+ -+ if (ret == null) { -+ ret = new PooledObjectLinkedOpenHashSet<>(current); -+ current.remove(object); -+ this.mapPool.put(ret, ret); -+ ret.referenceCount = 1; -+ } else { -+ if (ret.referenceCount != -1) { -+ ++ret.referenceCount; -+ } -+ current.remove(object); -+ } -+ -+ current.updateAddCache(object, ret); -+ -+ decrementReferenceCount(current); -+ return ret; -+ } -+ -+ // rets null if current.size() == 1 -+ public PooledObjectLinkedOpenHashSet findMapWithout(final PooledObjectLinkedOpenHashSet current, final E object) { -+ if (current.set.size() == 1) { -+ decrementReferenceCount(current); -+ return null; -+ } -+ -+ final PooledObjectLinkedOpenHashSet cached = current.getRemoveCache(object); -+ -+ if (cached != null) { -+ if (cached.referenceCount != -1) { -+ ++cached.referenceCount; -+ } -+ -+ decrementReferenceCount(current); -+ -+ return cached; -+ } -+ -+ if (!current.remove(object)) { -+ return current; -+ } -+ -+ // we use get/put since we use a different key on put -+ PooledObjectLinkedOpenHashSet ret = this.mapPool.get(current); -+ -+ if (ret == null) { -+ ret = new PooledObjectLinkedOpenHashSet<>(current); -+ current.add(object); -+ this.mapPool.put(ret, ret); -+ ret.referenceCount = 1; -+ } else { -+ if (ret.referenceCount != -1) { -+ ++ret.referenceCount; -+ } -+ current.add(object); -+ } -+ -+ current.updateRemoveCache(object, ret); -+ -+ decrementReferenceCount(current); -+ return ret; -+ } -+ -+ public static final class PooledObjectLinkedOpenHashSet implements Iterable { -+ -+ private static final WeakReference NULL_REFERENCE = new WeakReference(null); -+ -+ final ObjectLinkedOpenHashSet set; -+ int referenceCount; // -1 if special -+ int hash; // optimize hashcode -+ -+ // add cache -+ WeakReference lastAddObject = NULL_REFERENCE; -+ WeakReference> lastAddMap = NULL_REFERENCE; -+ -+ // remove cache -+ WeakReference lastRemoveObject = NULL_REFERENCE; -+ WeakReference> lastRemoveMap = NULL_REFERENCE; -+ -+ public PooledObjectLinkedOpenHashSet() { -+ this.set = new ObjectLinkedOpenHashSet<>(2, 0.6f); -+ } -+ -+ public PooledObjectLinkedOpenHashSet(final E single) { -+ this(); -+ this.referenceCount = -1; -+ this.add(single); -+ } -+ -+ public PooledObjectLinkedOpenHashSet(final PooledObjectLinkedOpenHashSet other) { -+ this.set = other.set.clone(); -+ this.hash = other.hash; -+ } -+ -+ // from https://github.com/Spottedleaf/ConcurrentUtil/blob/master/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java -+ // generated by https://github.com/skeeto/hash-prospector -+ static int hash0(int x) { -+ x *= 0x36935555; -+ x ^= x >>> 16; -+ return x; -+ } -+ -+ public PooledObjectLinkedOpenHashSet getAddCache(final E element) { -+ final E currentAdd = this.lastAddObject.get(); -+ -+ if (currentAdd == null || !(currentAdd == element || currentAdd.equals(element))) { -+ return null; -+ } -+ -+ final PooledObjectLinkedOpenHashSet map = this.lastAddMap.get(); -+ if (map == null || map.referenceCount == 0) { -+ // we need to ret null if ref count is zero as calling code will assume the map is in use -+ return null; -+ } -+ -+ return map; -+ } -+ -+ public PooledObjectLinkedOpenHashSet getRemoveCache(final E element) { -+ final E currentRemove = this.lastRemoveObject.get(); -+ -+ if (currentRemove == null || !(currentRemove == element || currentRemove.equals(element))) { -+ return null; -+ } -+ -+ final PooledObjectLinkedOpenHashSet map = this.lastRemoveMap.get(); -+ if (map == null || map.referenceCount == 0) { -+ // we need to ret null if ref count is zero as calling code will assume the map is in use -+ return null; -+ } -+ -+ return map; -+ } -+ -+ public void updateAddCache(final E element, final PooledObjectLinkedOpenHashSet map) { -+ this.lastAddObject = new WeakReference<>(element); -+ this.lastAddMap = new WeakReference<>(map); -+ } -+ -+ public void updateRemoveCache(final E element, final PooledObjectLinkedOpenHashSet map) { -+ this.lastRemoveObject = new WeakReference<>(element); -+ this.lastRemoveMap = new WeakReference<>(map); -+ } -+ -+ boolean add(final E element) { -+ boolean added = this.set.add(element); -+ -+ if (added) { -+ this.hash += hash0(element.hashCode()); -+ } -+ -+ return added; -+ } -+ -+ boolean remove(Object element) { -+ boolean removed = this.set.remove(element); -+ -+ if (removed) { -+ this.hash -= hash0(element.hashCode()); -+ } -+ -+ return removed; -+ } -+ -+ @Override -+ public Iterator iterator() { -+ return this.set.iterator(); -+ } -+ -+ @Override -+ public int hashCode() { -+ return this.hash; -+ } -+ -+ @Override -+ public boolean equals(final Object other) { -+ if (!(other instanceof PooledObjectLinkedOpenHashSet)) { -+ return false; -+ } -+ if (this.referenceCount == 0) { -+ return other == this; -+ } else { -+ if (other == this) { -+ // Unfortunately we are never equal to our own instance while in use! -+ return false; -+ } -+ return this.hash == ((PooledObjectLinkedOpenHashSet)other).hash && this.set.equals(((PooledObjectLinkedOpenHashSet)other).set); -+ } -+ } -+ -+ @Override -+ public String toString() { -+ return "PooledHashSet: size: " + this.set.size() + ", reference count: " + this.referenceCount + ", hash: " + -+ this.hashCode() + ", identity: " + System.identityHashCode(this) + " map: " + this.set.toString(); -+ } -+ } -+} -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 { - this.world.getMethodProfiler().enter("naturalSpawnCount"); - this.world.timings.countNaturalMobs.startTiming(); // Paper - timings - int l = this.chunkMapDistance.b(); -- SpawnerCreature.d spawnercreature_d = SpawnerCreature.a(l, this.world.z(), this::a); -+ // Paper start - per player mob spawning -+ SpawnerCreature.d spawnercreature_d; // moved down -+ if (this.playerChunkMap.playerMobDistanceMap != null) { -+ // update distance map -+ this.world.timings.playerMobDistanceMapUpdate.startTiming(); -+ this.playerChunkMap.playerMobDistanceMap.update(this.world.players, this.playerChunkMap.viewDistance); -+ this.world.timings.playerMobDistanceMapUpdate.stopTiming(); -+ // re-set mob counts -+ for (EntityPlayer player : this.world.players) { -+ Arrays.fill(player.mobCounts, 0); -+ } -+ spawnercreature_d = SpawnerCreature.countMobs(l, this.world.z(), this::a, true); -+ } else { -+ spawnercreature_d = SpawnerCreature.countMobs(l, this.world.z(), this::a, false); -+ } -+ // Paper end - this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings - - this.p = spawnercreature_d; -diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- 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 boolean queueHealthUpdatePacket = false; - public net.minecraft.server.PacketPlayOutUpdateHealth queuedHealthUpdatePacket; - // Paper end -+ // Paper start - mob spawning rework -+ public static final int ENUMCREATURETYPE_TOTAL_ENUMS = EnumCreatureType.values().length; -+ public final int[] mobCounts = new int[ENUMCREATURETYPE_TOTAL_ENUMS]; // Paper -+ public final com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet cachedSingleMobDistanceMap; -+ // Paper end - - // CraftBukkit start - public String displayName; -@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - this.displayName = this.getName(); - this.canPickUpLoot = true; - this.maxHealthCache = this.getMaxHealth(); -+ this.cachedSingleMobDistanceMap = new com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper - } - - // Yes, this doesn't match Vanilla, but it's the best we can do for now. -@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - - } - -+ public final SectionPosition getPlayerMapSection() { return this.N(); } // Paper - OBFHELPER - public SectionPosition N() { - return this.cq; - } -diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/EntityTypes.java -+++ b/src/main/java/net/minecraft/server/EntityTypes.java -@@ -0,0 +0,0 @@ public class EntityTypes { - return this.bk; - } - -+ public final EnumCreatureType getEnumCreatureType() { return this.e(); } // Paper - OBFHELPER - public EnumCreatureType e() { - return this.bf; - } -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 { - public final Int2ObjectMap trackedEntities; - private final Long2ByteMap z; - private final Queue A; private final Queue getUnloadQueueTasks() { return this.A; } // Paper - OBFHELPER -- private int viewDistance; -+ int viewDistance; // Paper - private -> package private -+ public final com.destroystokyo.paper.util.PlayerMobDistanceMap playerMobDistanceMap; // Paper - - // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() - public final CallbackExecutor callbackExecutor = new CallbackExecutor(); -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - this.l = supplier; - this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper - this.setViewDistance(i); -+ this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper -+ } -+ -+ public void updatePlayerMobTypeMap(Entity entity) { -+ if (!this.world.paperConfig.perPlayerMobSpawns) { -+ return; -+ } -+ int chunkX = (int)Math.floor(entity.locX()) >> 4; -+ int chunkZ = (int)Math.floor(entity.locZ()) >> 4; -+ int index = entity.getEntityType().getEnumCreatureType().ordinal(); -+ -+ for (EntityPlayer player : this.playerMobDistanceMap.getPlayersInRange(chunkX, chunkZ)) { -+ ++player.mobCounts[index]; -+ } -+ } -+ -+ public int getMobCountNear(EntityPlayer entityPlayer, EnumCreatureType enumCreatureType) { -+ return entityPlayer.mobCounts[enumCreatureType.ordinal()]; - } - - private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) { -diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- 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 { - }); - - public static SpawnerCreature.d a(int i, Iterable iterable, SpawnerCreature.b spawnercreature_b) { -+ // Paper start - add countMobs parameter -+ return countMobs(i, iterable, spawnercreature_b, false); -+ } -+ public static SpawnerCreature.d countMobs(int i, Iterable iterable, SpawnerCreature.b spawnercreature_b, boolean countMobs) { -+ // Paper end - add countMobs parameter - SpawnerCreatureProbabilities spawnercreatureprobabilities = new SpawnerCreatureProbabilities(); - Object2IntOpenHashMap object2intopenhashmap = new Object2IntOpenHashMap(); - Iterator iterator = iterable.iterator(); -@@ -0,0 +0,0 @@ public final class SpawnerCreature { - } - - object2intopenhashmap.addTo(enumcreaturetype, 1); -+ // Paper start -+ if (countMobs) { -+ ((WorldServer)chunk.world).getChunkProvider().playerChunkMap.updatePlayerMobTypeMap(entity); -+ } -+ // Paper end - }); - } - } -@@ -0,0 +0,0 @@ public final class SpawnerCreature { - continue; - } - -+ // Paper start - only allow spawns upto the limit per chunk and update count afterwards -+ int currEntityCount = spawnercreature_d.getEntityCountsByType().getInt(enumcreaturetype); -+ int k1 = limit * spawnercreature_d.getSpawnerChunks() / SpawnerCreature.b; -+ int difference = k1 - currEntityCount; -+ -+ if (worldserver.paperConfig.perPlayerMobSpawns) { -+ int minDiff = Integer.MAX_VALUE; -+ for (EntityPlayer entityplayer : worldserver.getChunkProvider().playerChunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) { -+ minDiff = Math.min(limit - worldserver.getChunkProvider().playerChunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff); -+ } -+ difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff; -+ } -+ // Paper end -+ -+ if (difference > 0) { // Paper - if ((flag || !enumcreaturetype.d()) && (flag1 || enumcreaturetype.d()) && (flag2 || !enumcreaturetype.e()) && spawnercreature_d.a(enumcreaturetype, limit)) { - // CraftBukkit end -- a(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> { -+ int spawnCount = spawnMobs(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> { - return spawnercreature_d.a(entitytypes, blockposition, ichunkaccess); - }, (entityinsentient, ichunkaccess) -> { - spawnercreature_d.a(entityinsentient, ichunkaccess); -+ }, -+ limit, worldserver.paperConfig.perPlayerMobSpawns ? worldserver.getChunkProvider().playerChunkMap::updatePlayerMobTypeMap : null); -+ spawnercreature_d.getEntityCountsByType().mergeInt(enumcreaturetype, 0, (keyInMap, valueInMap) -> { -+ return Integer.valueOf(spawnCount + valueInMap.intValue()); - }); -+ } // Paper - } - } - -@@ -0,0 +0,0 @@ public final class SpawnerCreature { - } - - public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a) { -+ // Paper start - add parameters and int ret type -+ spawnMobs(enumcreaturetype, worldserver, chunk, spawnercreature_c, spawnercreature_a, Integer.MAX_VALUE, null); -+ } -+ public static int spawnMobs(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a, int maxSpawns, Consumer trackEntity) { -+ // Paper end - add parameters and int ret type - BlockPosition blockposition = getRandomPosition(worldserver, chunk); - - if (blockposition.getY() >= 1) { -- a(enumcreaturetype, worldserver, (IChunkAccess) chunk, blockposition, spawnercreature_c, spawnercreature_a); -+ return spawnMobsInternal(enumcreaturetype, worldserver, (IChunkAccess) chunk, blockposition, spawnercreature_c, spawnercreature_a, maxSpawns, trackEntity); - } -+ return 0; // Paper - } - - public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition blockposition, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a) { -+ // Paper start - add maxSpawns parameter and return spawned mobs -+ spawnMobsInternal(enumcreaturetype, worldserver, ichunkaccess, blockposition, spawnercreature_c, spawnercreature_a, Integer.MAX_VALUE, null); -+ } -+ public static int spawnMobsInternal(EnumCreatureType enumcreaturetype, WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition blockposition, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a, int maxSpawns, Consumer trackEntity) { -+ // Paper end - add maxSpawns parameter and return spawned mobs - StructureManager structuremanager = worldserver.getStructureManager(); - ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator(); - int i = blockposition.getY(); - IBlockData iblockdata = worldserver.getTypeIfLoadedAndInBounds(blockposition); // Paper - don't load chunks for mob spawn -+ int j = 0; // Paper - moved up - - 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; -+ // Paper - moved up - int k = 0; - - while (k < 3) { -@@ -0,0 +0,0 @@ public final class SpawnerCreature { - // Paper start - Boolean doSpawning = a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2); - if (doSpawning == null) { -- return; -+ return j; // Paper - } - if (doSpawning.booleanValue() && spawnercreature_c.test(biomebase_biomemeta.c, blockposition_mutableblockposition, ichunkaccess)) { // Paper end - EntityInsentient entityinsentient = a(worldserver, biomebase_biomemeta.c); - - if (entityinsentient == null) { -- return; -+ return j; // Paper - } - - entityinsentient.setPositionRotation(d0, (double) i, d1, worldserver.random.nextFloat() * 360.0F, 0.0F); -@@ -0,0 +0,0 @@ public final class SpawnerCreature { - groupdataentity = entityinsentient.prepare(worldserver, worldserver.getDamageScaler(entityinsentient.getChunkCoordinates()), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null); - // CraftBukkit start - if (worldserver.addEntity(entityinsentient, SpawnReason.NATURAL)) { -- ++j; -+ ++j; // Paper - force diff on name change - we expect this to be the total amount spawned - ++k1; - spawnercreature_a.run(entityinsentient, ichunkaccess); -+ // Paper start -+ if (trackEntity != null) { -+ trackEntity.accept(entityinsentient); -+ } -+ // Paper end - } - // CraftBukkit end -- if (j >= entityinsentient.getMaxSpawnGroup()) { -- return; -+ if (j >= entityinsentient.getMaxSpawnGroup() || j >= maxSpawns) { // Paper -+ return j; // Paper - } - - if (entityinsentient.c(k1)) { -@@ -0,0 +0,0 @@ public final class SpawnerCreature { - } - - } -+ return j; // Paper - } - - private static boolean a(WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) { -@@ -0,0 +0,0 @@ public final class SpawnerCreature { - - public static class d { - -- private final int a; -+ private final int a; final int getSpawnerChunks() { return this.a; } // Paper - OBFHELPER - private final Object2IntOpenHashMap b; - private final SpawnerCreatureProbabilities c; -- private final Object2IntMap d; -+ private final Object2IntMap d; final Object2IntMap getEntityCountsByType() { return this.d; } // Paper - OBFHELPER - @Nullable - private BlockPosition e; - @Nullable -@@ -0,0 +0,0 @@ public final class SpawnerCreature { - - // CraftBukkit start - private boolean a(EnumCreatureType enumcreaturetype, int limit) { -- int i = limit * this.a / SpawnerCreature.b; -+ int i = limit * this.a / SpawnerCreature.b; // Paper - diff on change, needed in the spawn method - // CraftBukkit end - - return this.b.getInt(enumcreaturetype) < i; From 7b7d48281830b6b85608e0eb265f70d80d1aff95 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Fri, 26 Jun 2020 18:20:03 +0200 Subject: [PATCH 15/91] [WIP|1.16] Misc fixes (#3627) --- SHIT_TO_CHECK.md | 5 +- ...-Plugin-Tickets-to-API-Chunk-Methods.patch | 2 +- .../Entity-Activation-Range-2.0.patch | 2 +- Spigot-Server-Patches/FIX-DIS-SHIT.patch | 64 +++++++++++++++++++ .../Further-improve-server-tick-loop.patch | 2 +- .../Improved-Watchdog-Support.patch | 2 +- Spigot-Server-Patches/MC-Dev-fixes.patch | 26 ++++++++ ...rovide-E-TE-Chunk-count-stat-methods.patch | 2 +- .../Vanished-players-don-t-have-rights.patch | 2 +- .../incremental-chunk-saving.patch | 2 +- work/Bukkit | 2 +- work/CraftBukkit | 2 +- work/Spigot | 2 +- 13 files changed, 102 insertions(+), 13 deletions(-) create mode 100644 Spigot-Server-Patches/FIX-DIS-SHIT.patch diff --git a/SHIT_TO_CHECK.md b/SHIT_TO_CHECK.md index 98771cea37..9c54b6de4c 100644 --- a/SHIT_TO_CHECK.md +++ b/SHIT_TO_CHECK.md @@ -1,9 +1,8 @@ # 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 * Make sure the flat bedrock setting doesn't do anything stupid * Check DataBits foreach -* Update MobGoalHelper \ No newline at end of file +* lighting is bork (load chunk, fly away, come back, everything or parts are black) +* block actions (particles/sounds) are bork (no chest opening, no bell, no noteblock) diff --git a/Spigot-Server-Patches/Add-Plugin-Tickets-to-API-Chunk-Methods.patch b/Spigot-Server-Patches/Add-Plugin-Tickets-to-API-Chunk-Methods.patch index c8bc1e5932..f7746ec53d 100644 --- a/Spigot-Server-Patches/Add-Plugin-Tickets-to-API-Chunk-Methods.patch +++ b/Spigot-Server-Patches/Add-Plugin-Tickets-to-API-Chunk-Methods.patch @@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 loadIcon(); } @@ -0,0 +0,0 @@ public final class CraftServer implements Server { - waterAnimalSpawn = configuration.getInt("spawn-limits.water-animals"); + waterAmbientSpawn = configuration.getInt("spawn-limits.water-ambient"); ambientSpawn = configuration.getInt("spawn-limits.ambient"); warningState = WarningState.value(configuration.getString("settings.deprecated-verbose")); - TicketType.PLUGIN.loadPeriod = configuration.getInt("chunk-gc.period-in-ticks"); diff --git a/Spigot-Server-Patches/Entity-Activation-Range-2.0.patch b/Spigot-Server-Patches/Entity-Activation-Range-2.0.patch index b1c477a1a5..6b84bb998d 100644 --- a/Spigot-Server-Patches/Entity-Activation-Range-2.0.patch +++ b/Spigot-Server-Patches/Entity-Activation-Range-2.0.patch @@ -322,8 +322,8 @@ 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 { - public long ticksPerMonsterSpawns; public long ticksPerWaterSpawns; + public long ticksPerWaterAmbientSpawns; public long ticksPerAmbientSpawns; + // Paper start + public int wakeupInactiveRemainingAnimals; diff --git a/Spigot-Server-Patches/FIX-DIS-SHIT.patch b/Spigot-Server-Patches/FIX-DIS-SHIT.patch new file mode 100644 index 0000000000..9216d714b7 --- /dev/null +++ b/Spigot-Server-Patches/FIX-DIS-SHIT.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MiniDigger | Martin +Date: Fri, 26 Jun 2020 16:51:44 +0200 +Subject: [PATCH] FIX DIS SHIT + + +diff --git a/src/main/java/net/minecraft/server/SensorHoglinSpecific.java b/src/main/java/net/minecraft/server/SensorHoglinSpecific.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/SensorHoglinSpecific.java ++++ b/src/main/java/net/minecraft/server/SensorHoglinSpecific.java +@@ -0,0 +0,0 @@ public class SensorHoglinSpecific extends Sensor { + protected void a(WorldServer worldserver, EntityHoglin entityhoglin) { + BehaviorController behaviorcontroller = entityhoglin.getBehaviorController(); + +- behaviorcontroller.setMemory(MemoryModuleType.NEAREST_REPELLENT, this.b(worldserver, entityhoglin)); ++ // behaviorcontroller.setMemory(MemoryModuleType.NEAREST_REPELLENT, this.bb(worldserver, entityhoglin)); // Paper - fix dis shit (for now) + rename + Optional optional = Optional.empty(); + int i = 0; + List list = Lists.newArrayList(); +@@ -0,0 +0,0 @@ public class SensorHoglinSpecific extends Sensor { + } + + behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLIN, optional); +- behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_HOGLINS, (Object) list); +- behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT, (Object) i); +- behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT, (Object) list.size()); ++ behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_HOGLINS, list); // Paper - decomp fix ++ behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT, i); // Paper - decomp fix ++ behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT, list.size()); // Paper - decomp fix + } + +- private Optional b(WorldServer worldserver, EntityHoglin entityhoglin) { ++ private Optional bb(WorldServer worldserver, EntityHoglin entityhoglin) { // Paper - rename + return BlockPosition.a(entityhoglin.getChunkCoordinates(), 8, 4, (blockposition) -> { + return worldserver.getType(blockposition).a((Tag) TagsBlock.HOGLIN_REPELLENTS); + }); +diff --git a/src/main/java/net/minecraft/server/SensorPiglinSpecific.java b/src/main/java/net/minecraft/server/SensorPiglinSpecific.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/SensorPiglinSpecific.java ++++ b/src/main/java/net/minecraft/server/SensorPiglinSpecific.java +@@ -0,0 +0,0 @@ public class SensorPiglinSpecific extends Sensor { + protected void a(WorldServer worldserver, EntityLiving entityliving) { + BehaviorController behaviorcontroller = entityliving.getBehaviorController(); + +- behaviorcontroller.setMemory(MemoryModuleType.NEAREST_REPELLENT, c(worldserver, entityliving)); ++// behaviorcontroller.setMemory(MemoryModuleType.NEAREST_REPELLENT, c(worldserver, entityliving)); // Paper - fix dis shit (for now) + Optional optional = Optional.empty(); + Optional optional1 = Optional.empty(); + Optional optional2 = Optional.empty(); +@@ -0,0 +0,0 @@ public class SensorPiglinSpecific extends Sensor { + behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED, optional4); + behaviorcontroller.setMemory(MemoryModuleType.NEAREST_TARGETABLE_PLAYER_NOT_WEARING_GOLD, optional5); + behaviorcontroller.setMemory(MemoryModuleType.NEAREST_PLAYER_HOLDING_WANTED_ITEM, optional6); +- behaviorcontroller.setMemory(MemoryModuleType.NEAREST_ADULT_PIGLINS, (Object) list1); +- behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLINS, (Object) list); +- behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT, (Object) list.size()); +- behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT, (Object) i); ++ behaviorcontroller.setMemory(MemoryModuleType.NEAREST_ADULT_PIGLINS, list1); // Paper - decomp fix ++ behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLINS, list); // Paper - decomp fix ++ behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT, list.size()); // Paper - decomp fix ++ behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT, i); // Paper - decomp fix + } + + private static Optional c(WorldServer worldserver, EntityLiving entityliving) { diff --git a/Spigot-Server-Patches/Further-improve-server-tick-loop.patch b/Spigot-Server-Patches/Further-improve-server-tick-loop.patch index 3396fefad8..fae090a2e7 100644 --- a/Spigot-Server-Patches/Further-improve-server-tick-loop.patch +++ b/Spigot-Server-Patches/Further-improve-server-tick-loop.patch @@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public static int currentTick = 0; // Paper - Further improve tick loop public java.util.Queue processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; - public File bukkitDataPackFolder; + public CommandDispatcher vanillaCommandDispatcher; @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant 64) { +- float f1 = (float) (BiomeFrozenDeepOcean.e.a((double) ((float) blockposition.getX() / 8.0F), (double) ((float) blockposition.getZ() / 8.0F), false) * 4.0D); ++ float f1 = (float) (BiomeFrozenDeepOcean.NOISE_GENERATOR_3.a((double) ((float) blockposition.getX() / 8.0F), (double) ((float) blockposition.getZ() / 8.0F), false) * 4.0D); // Paper - rename + + return f - (f1 + (float) blockposition.getY() - 64.0F) * 0.05F / 30.0F; + } else { +diff --git a/src/main/java/net/minecraft/server/BiomeFrozenOcean.java b/src/main/java/net/minecraft/server/BiomeFrozenOcean.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/BiomeFrozenOcean.java ++++ b/src/main/java/net/minecraft/server/BiomeFrozenOcean.java +@@ -0,0 +0,0 @@ public final class BiomeFrozenOcean extends BiomeBase { + } + + if (blockposition.getY() > 64) { +- float f1 = (float) (BiomeFrozenOcean.e.a((double) ((float) blockposition.getX() / 8.0F), (double) ((float) blockposition.getZ() / 8.0F), false) * 4.0D); ++ float f1 = (float) (BiomeFrozenOcean.NOISE_GENERATOR_3.a((double) ((float) blockposition.getX() / 8.0F), (double) ((float) blockposition.getZ() / 8.0F), false) * 4.0D); // Paper - rename + + return f - (f1 + (float) blockposition.getY() - 64.0F) * 0.05F / 30.0F; + } else { diff --git a/src/main/java/net/minecraft/server/Biomes.java b/src/main/java/net/minecraft/server/Biomes.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/Biomes.java diff --git a/Spigot-Server-Patches/Provide-E-TE-Chunk-count-stat-methods.patch b/Spigot-Server-Patches/Provide-E-TE-Chunk-count-stat-methods.patch index 7160ad188b..ad0cf1e112 100644 --- a/Spigot-Server-Patches/Provide-E-TE-Chunk-count-stat-methods.patch +++ b/Spigot-Server-Patches/Provide-E-TE-Chunk-count-stat-methods.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- 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 { - private int waterAnimalSpawn = -1; + private int waterAmbientSpawn = -1; private int ambientSpawn = -1; + // Paper start - Provide fast information methods 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 cee8d24803..650c07a580 100644 --- a/Spigot-Server-Patches/Vanished-players-don-t-have-rights.patch +++ b/Spigot-Server-Patches/Vanished-players-don-t-have-rights.patch @@ -51,7 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Entity entity1 = this.getShooter(); - + // Paper start - Cancel hit for vanished players -+ if (entity1 instanceof EntityPlayer) { ++ if (entity1 instanceof EntityPlayer && entity 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; diff --git a/Spigot-Server-Patches/incremental-chunk-saving.patch b/Spigot-Server-Patches/incremental-chunk-saving.patch index 69b2449d46..95feb1c103 100644 --- a/Spigot-Server-Patches/incremental-chunk-saving.patch +++ b/Spigot-Server-Patches/incremental-chunk-saving.patch @@ -70,9 +70,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public java.util.Queue processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; + public boolean serverAutoSave = false; // Paper - public File bukkitDataPackFolder; public CommandDispatcher vanillaCommandDispatcher; private boolean forceTicks; + // CraftBukkit end @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant Date: Fri, 26 Jun 2020 21:34:52 +0200 Subject: [PATCH 16/91] Some fixes (#3630) * Fix block action sending * Fix chest property check --- SHIT_TO_CHECK.md | 2 +- Spigot-Server-Patches/Optimize-TileEntity-Ticking.patch | 2 +- .../Optimize-sending-packets-to-nearby-locations-sounds-.patch | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SHIT_TO_CHECK.md b/SHIT_TO_CHECK.md index 9c54b6de4c..d6eeb9a774 100644 --- a/SHIT_TO_CHECK.md +++ b/SHIT_TO_CHECK.md @@ -5,4 +5,4 @@ * Make sure the flat bedrock setting doesn't do anything stupid * Check DataBits foreach * lighting is bork (load chunk, fly away, come back, everything or parts are black) -* block actions (particles/sounds) are bork (no chest opening, no bell, no noteblock) +* chunk generation seems slow with a lot of it happening \ No newline at end of file diff --git a/Spigot-Server-Patches/Optimize-TileEntity-Ticking.patch b/Spigot-Server-Patches/Optimize-TileEntity-Ticking.patch index 6174e02618..3c82f242b6 100644 --- a/Spigot-Server-Patches/Optimize-TileEntity-Ticking.patch +++ b/Spigot-Server-Patches/Optimize-TileEntity-Ticking.patch @@ -107,7 +107,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } private void a(SoundEffect soundeffect) { -+ if (!this.getBlock().get(BlockChest.waterlogged())) { return; } // Paper - this can be delayed, double check exists - Fixes GH-2074 ++ if (!this.getBlock().b(BlockChest.c)) { return; } // Paper - this can be delayed, double check exists - Fixes GH-2074 BlockPropertyChestType blockpropertychesttype = (BlockPropertyChestType) this.getBlock().get(BlockChest.c); if (blockpropertychesttype != BlockPropertyChestType.LEFT) { diff --git a/Spigot-Server-Patches/Optimize-sending-packets-to-nearby-locations-sounds-.patch b/Spigot-Server-Patches/Optimize-sending-packets-to-nearby-locations-sounds-.patch index 134174dfab..25ee7890ef 100644 --- a/Spigot-Server-Patches/Optimize-sending-packets-to-nearby-locations-sounds-.patch +++ b/Spigot-Server-Patches/Optimize-sending-packets-to-nearby-locations-sounds-.patch @@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit end - if (entityplayer != entityhuman && entityplayer.world.getDimensionKey() == resourcekey) { -+ if (entityplayer != entityhuman && entityplayer.world.getDimensionKey() == resourcekey && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { // Paper ++ if (entityplayer != entityhuman && entityplayer.world.getDimensionKey() == resourcekey && (!(entityhuman instanceof EntityPlayer) || entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity()))) { // Paper double d4 = d0 - entityplayer.locX(); double d5 = d1 - entityplayer.locY(); double d6 = d2 - entityplayer.locZ(); From 002d3ab1b52255ff8f24556258ccd094f3126600 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 26 Jun 2020 14:11:08 -0700 Subject: [PATCH 17/91] Fix packed data reading in anti-xray --- Spigot-Server-Patches/fixup-Anti-Xray.patch | 54 +++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Spigot-Server-Patches/fixup-Anti-Xray.patch diff --git a/Spigot-Server-Patches/fixup-Anti-Xray.patch b/Spigot-Server-Patches/fixup-Anti-Xray.patch new file mode 100644 index 0000000000..7c88ddda14 --- /dev/null +++ b/Spigot-Server-Patches/fixup-Anti-Xray.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Fri, 26 Jun 2020 14:10:10 -0700 +Subject: [PATCH] fixup! Anti-Xray + + +diff --git a/src/main/java/com/destroystokyo/paper/antixray/DataBitsReader.java b/src/main/java/com/destroystokyo/paper/antixray/DataBitsReader.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/com/destroystokyo/paper/antixray/DataBitsReader.java ++++ b/src/main/java/com/destroystokyo/paper/antixray/DataBitsReader.java +@@ -0,0 +0,0 @@ public final class DataBitsReader { + bitInLongIndex += bitsPerObject; + + if (bitInLongIndex > 63) { +- bitInLongIndex -= 64; ++ bitInLongIndex = 0; + longInDataBitsIndex += 8; + init(); +- +- if (bitInLongIndex > 0) { +- value |= current << bitsPerObject - bitInLongIndex & mask; +- } + } + + return value; +diff --git a/src/main/java/com/destroystokyo/paper/antixray/DataBitsWriter.java b/src/main/java/com/destroystokyo/paper/antixray/DataBitsWriter.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/com/destroystokyo/paper/antixray/DataBitsWriter.java ++++ b/src/main/java/com/destroystokyo/paper/antixray/DataBitsWriter.java +@@ -0,0 +0,0 @@ public final class DataBitsWriter { + + if (bitInLongIndex > 63) { + finish(); +- bitInLongIndex -= 64; ++ bitInLongIndex = 0; + longInDataBitsIndex += 8; + init(); +- +- if (bitInLongIndex > 0) { +- current = current & ~(mask >>> bitsPerObject - bitInLongIndex) | (value & mask) >>> bitsPerObject - bitInLongIndex; +- dirty = true; +- } + } + } + +@@ -0,0 +0,0 @@ public final class DataBitsWriter { + + if (bitInLongIndex > 63) { + finish(); +- bitInLongIndex -= 64; ++ bitInLongIndex = 0; + longInDataBitsIndex += 8; + init(); + } From 6e59ab0eb590d1ad42c24533391293ca91901248 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 26 Jun 2020 14:31:38 -0700 Subject: [PATCH 18/91] Fix the entity knockback by entity patch --- ...plement-EntityKnockbackByEntityEvent.patch | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 Spigot-Server-Patches/fixup-Implement-EntityKnockbackByEntityEvent.patch diff --git a/Spigot-Server-Patches/fixup-Implement-EntityKnockbackByEntityEvent.patch b/Spigot-Server-Patches/fixup-Implement-EntityKnockbackByEntityEvent.patch new file mode 100644 index 0000000000..3420c57883 --- /dev/null +++ b/Spigot-Server-Patches/fixup-Implement-EntityKnockbackByEntityEvent.patch @@ -0,0 +1,93 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Fri, 26 Jun 2020 14:28:49 -0700 +Subject: [PATCH] fixup! Implement EntityKnockbackByEntityEvent + + +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 ++ ((EntityLiving) entity).doKnockback((float) i * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F)), this); // 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 ++ entityliving.doKnockback(0.4F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F)), this); + } + // 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 ++ ((EntityLiving) entity).doKnockback(f1 * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F)), this); + 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 ++ this.doKnockback(0.4F, d0, d1, entity1); // 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 ++ entityliving.doKnockback(0.5F, entityliving.locX() - this.locX(), entityliving.locZ() - this.locZ(), this); + } + + private boolean f(DamageSource damagesource) { +@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { + } + + public void a(float f, double d0, double d1) { ++ // Paper start - add knockbacking entity parameter ++ this.doKnockback(f, d0, d1, null); ++ } ++ public void doKnockback(float f, double d0, double d1, Entity knockingBackEntity) { ++ // Paper end - add knockbacking entity parameter + f = (float) ((double) f * (1.0D - this.b(GenericAttributes.KNOCKBACK_RESISTANCE))); + if (f > 0.0F) { + this.impulse = true; +@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { + // Paper end + } + } +- EntityLiving knockingBackEntity; // Paper + + @Nullable + protected SoundEffect getSoundHurt(DamageSource damagesource) { From 9b3bb0cf51a89e4fc9cb90b30e1c6663b71a2db4 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 26 Jun 2020 14:33:49 -0700 Subject: [PATCH 19/91] Pass predicate from default get hard colliding entities method --- Spigot-Server-Patches/Anti-Xray.patch | 15 +-- ...plement-EntityKnockbackByEntityEvent.patch | 40 ++++---- ...imise-entity-hard-collision-checking.patch | 2 +- Spigot-Server-Patches/fixup-Anti-Xray.patch | 54 ----------- ...plement-EntityKnockbackByEntityEvent.patch | 93 ------------------- 5 files changed, 26 insertions(+), 178 deletions(-) delete mode 100644 Spigot-Server-Patches/fixup-Anti-Xray.patch delete mode 100644 Spigot-Server-Patches/fixup-Implement-EntityKnockbackByEntityEvent.patch diff --git a/Spigot-Server-Patches/Anti-Xray.patch b/Spigot-Server-Patches/Anti-Xray.patch index 29e5b2e0e2..2ce6dcd9e1 100644 --- a/Spigot-Server-Patches/Anti-Xray.patch +++ b/Spigot-Server-Patches/Anti-Xray.patch @@ -895,13 +895,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + bitInLongIndex += bitsPerObject; + + if (bitInLongIndex > 63) { -+ bitInLongIndex -= 64; ++ bitInLongIndex = 0; + longInDataBitsIndex += 8; + init(); -+ -+ if (bitInLongIndex > 0) { -+ value |= current << bitsPerObject - bitInLongIndex & mask; -+ } + } + + return value; @@ -975,14 +971,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + if (bitInLongIndex > 63) { + finish(); -+ bitInLongIndex -= 64; ++ bitInLongIndex = 0; + longInDataBitsIndex += 8; + init(); -+ -+ if (bitInLongIndex > 0) { -+ current = current & ~(mask >>> bitsPerObject - bitInLongIndex) | (value & mask) >>> bitsPerObject - bitInLongIndex; -+ dirty = true; -+ } + } + } + @@ -991,7 +982,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + if (bitInLongIndex > 63) { + finish(); -+ bitInLongIndex -= 64; ++ bitInLongIndex = 0; + longInDataBitsIndex += 8; + init(); + } diff --git a/Spigot-Server-Patches/Implement-EntityKnockbackByEntityEvent.patch b/Spigot-Server-Patches/Implement-EntityKnockbackByEntityEvent.patch index 957fe3c9b1..8b7ed21d67 100644 --- a/Spigot-Server-Patches/Implement-EntityKnockbackByEntityEvent.patch +++ b/Spigot-Server-Patches/Implement-EntityKnockbackByEntityEvent.patch @@ -13,9 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 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 +- ((EntityLiving) entity).a((float) i * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F))); ++ ((EntityLiving) entity).doKnockback((float) i * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F)), this); // 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)); } @@ -23,9 +22,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 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 +- entityliving.a(0.4F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F))); ++ entityliving.doKnockback(0.4F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F)), this); } // CraftBukkit end } @@ -37,9 +35,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 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 +- ((EntityLiving) entity).a(f1 * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F))); ++ ((EntityLiving) entity).doKnockback(f1 * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F)), this); this.setMot(this.getMot().d(0.6D, 1.0D, 0.6D)); } @@ -51,9 +48,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } 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 +- this.a(0.4F, d0, d1); ++ this.doKnockback(0.4F, d0, d1, entity1); // Paper } else { this.aw = (float) ((int) (Math.random() * 2.0D) * 180); } @@ -61,12 +57,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } 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 +- entityliving.a(0.5F, entityliving.locX() - this.locX(), entityliving.locZ() - this.locZ()); ++ entityliving.doKnockback(0.5F, entityliving.locX() - this.locX(), entityliving.locZ() - this.locZ(), this); } private boolean f(DamageSource damagesource) { +@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { + } + + public void a(float f, double d0, double d1) { ++ // Paper start - add knockbacking entity parameter ++ this.doKnockback(f, d0, d1, null); ++ } ++ public void doKnockback(float f, double d0, double d1, Entity knockingBackEntity) { ++ // Paper end - add knockbacking entity parameter + f = (float) ((double) f * (1.0D - this.b(GenericAttributes.KNOCKBACK_RESISTANCE))); + if (f > 0.0F) { + this.impulse = true; @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { Vec3D vec3d1 = (new Vec3D(d0, 0.0D, d1)).d().a((double) f); @@ -83,7 +90,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end } } -+ EntityLiving knockingBackEntity; // Paper - @Nullable - protected SoundEffect getSoundHurt(DamageSource damagesource) { diff --git a/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch b/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch index e809bb7285..0bd90bb9f8 100644 --- a/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch +++ b/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch @@ -157,7 +157,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * Not guaranteed to only return hard colliding entites + */ + default List getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate) { -+ return this.getEntities(entity, axisalignedbb); ++ return this.getEntities(entity, axisalignedbb, predicate); + } + // Paper end - optimise hard collision + diff --git a/Spigot-Server-Patches/fixup-Anti-Xray.patch b/Spigot-Server-Patches/fixup-Anti-Xray.patch deleted file mode 100644 index 7c88ddda14..0000000000 --- a/Spigot-Server-Patches/fixup-Anti-Xray.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Fri, 26 Jun 2020 14:10:10 -0700 -Subject: [PATCH] fixup! Anti-Xray - - -diff --git a/src/main/java/com/destroystokyo/paper/antixray/DataBitsReader.java b/src/main/java/com/destroystokyo/paper/antixray/DataBitsReader.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/com/destroystokyo/paper/antixray/DataBitsReader.java -+++ b/src/main/java/com/destroystokyo/paper/antixray/DataBitsReader.java -@@ -0,0 +0,0 @@ public final class DataBitsReader { - bitInLongIndex += bitsPerObject; - - if (bitInLongIndex > 63) { -- bitInLongIndex -= 64; -+ bitInLongIndex = 0; - longInDataBitsIndex += 8; - init(); -- -- if (bitInLongIndex > 0) { -- value |= current << bitsPerObject - bitInLongIndex & mask; -- } - } - - return value; -diff --git a/src/main/java/com/destroystokyo/paper/antixray/DataBitsWriter.java b/src/main/java/com/destroystokyo/paper/antixray/DataBitsWriter.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/com/destroystokyo/paper/antixray/DataBitsWriter.java -+++ b/src/main/java/com/destroystokyo/paper/antixray/DataBitsWriter.java -@@ -0,0 +0,0 @@ public final class DataBitsWriter { - - if (bitInLongIndex > 63) { - finish(); -- bitInLongIndex -= 64; -+ bitInLongIndex = 0; - longInDataBitsIndex += 8; - init(); -- -- if (bitInLongIndex > 0) { -- current = current & ~(mask >>> bitsPerObject - bitInLongIndex) | (value & mask) >>> bitsPerObject - bitInLongIndex; -- dirty = true; -- } - } - } - -@@ -0,0 +0,0 @@ public final class DataBitsWriter { - - if (bitInLongIndex > 63) { - finish(); -- bitInLongIndex -= 64; -+ bitInLongIndex = 0; - longInDataBitsIndex += 8; - init(); - } diff --git a/Spigot-Server-Patches/fixup-Implement-EntityKnockbackByEntityEvent.patch b/Spigot-Server-Patches/fixup-Implement-EntityKnockbackByEntityEvent.patch deleted file mode 100644 index 3420c57883..0000000000 --- a/Spigot-Server-Patches/fixup-Implement-EntityKnockbackByEntityEvent.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Fri, 26 Jun 2020 14:28:49 -0700 -Subject: [PATCH] fixup! Implement EntityKnockbackByEntityEvent - - -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 -+ ((EntityLiving) entity).doKnockback((float) i * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F)), this); // 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 -+ entityliving.doKnockback(0.4F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F)), this); - } - // 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 -+ ((EntityLiving) entity).doKnockback(f1 * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F)), this); - 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 -+ this.doKnockback(0.4F, d0, d1, entity1); // 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 -+ entityliving.doKnockback(0.5F, entityliving.locX() - this.locX(), entityliving.locZ() - this.locZ(), this); - } - - private boolean f(DamageSource damagesource) { -@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { - } - - public void a(float f, double d0, double d1) { -+ // Paper start - add knockbacking entity parameter -+ this.doKnockback(f, d0, d1, null); -+ } -+ public void doKnockback(float f, double d0, double d1, Entity knockingBackEntity) { -+ // Paper end - add knockbacking entity parameter - f = (float) ((double) f * (1.0D - this.b(GenericAttributes.KNOCKBACK_RESISTANCE))); - if (f > 0.0F) { - this.impulse = true; -@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { - // Paper end - } - } -- EntityLiving knockingBackEntity; // Paper - - @Nullable - protected SoundEffect getSoundHurt(DamageSource damagesource) { From cd6b64113f7a0744959cd1d6e2adf02728b78c01 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 26 Jun 2020 14:36:48 -0700 Subject: [PATCH 20/91] Fix the piston duplication option when it is on --- .../Fix-piston-physics-inconsistency-MC-188840.patch | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Spigot-Server-Patches/Fix-piston-physics-inconsistency-MC-188840.patch b/Spigot-Server-Patches/Fix-piston-physics-inconsistency-MC-188840.patch index 665a490241..583a4a392b 100644 --- a/Spigot-Server-Patches/Fix-piston-physics-inconsistency-MC-188840.patch +++ b/Spigot-Server-Patches/Fix-piston-physics-inconsistency-MC-188840.patch @@ -63,12 +63,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 blockposition3 = blockposition3.shift(enumdirection1); map.remove(blockposition3); world.setTypeAndData(blockposition3, (IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPiston.FACING, enumdirection), 68); +- world.setTileEntity(blockposition3, BlockPistonMoving.a((IBlockData) list1.get(k), enumdirection, flag, false)); + // Paper start - fix a variety of piston desync dupes + if (!allowDesync) { + iblockdata1 = world.getType(oldPos); + map.replace(oldPos, iblockdata1); + } - world.setTileEntity(blockposition3, BlockPistonMoving.a((IBlockData) list1.get(k), enumdirection, flag, false)); ++ world.setTileEntity(blockposition3, BlockPistonMoving.a(allowDesync ? list1.get(k) : iblockdata1, enumdirection, flag, false)); + if (!allowDesync) { + world.setTypeAndData(oldPos, Blocks.AIR.getBlockData(), 2 | 4 | 16 | 1024); // set air to prevent later physics updates from seeing this block + } From a4f75b1ae07597b89ff96d94ca3dff849ce60a3f Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 26 Jun 2020 15:54:39 -0700 Subject: [PATCH 21/91] fix recursion for leashing an abstract horse --- Spigot-Server-Patches/Undead-horse-leashing.patch | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Spigot-Server-Patches/Undead-horse-leashing.patch b/Spigot-Server-Patches/Undead-horse-leashing.patch index 301d9e4d57..ab489e5730 100644 --- a/Spigot-Server-Patches/Undead-horse-leashing.patch +++ b/Spigot-Server-Patches/Undead-horse-leashing.patch @@ -29,7 +29,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start + @Override -+ public boolean canLeash(EntityHuman entityhuman) { ++ public boolean a(EntityHuman entityhuman) { + return world.paperConfig.allowLeashingUndeadHorse ? super.a(entityhuman) : super.a(entityhuman) && this.getMonsterType() != EnumMonsterType.UNDEAD; // Paper + } + // Paper end @@ -42,14 +42,11 @@ 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 { + } - public boolean a(EntityHuman entityhuman) { -+ // Paper start - allow overriding -+ return this.canLeash(entityhuman); -+ } -+ public boolean canLeash(EntityHuman entityhuman) { -+ // Paper end - allow overriding +- public boolean a(EntityHuman entityhuman) { ++ public boolean a(EntityHuman entityhuman) { // Paper - overriden in EntityHorseAbstract return !this.isLeashed() && !(this instanceof IMonster); } From 8088a420294bf50dc95cfdd678eee0319b5dc7d7 Mon Sep 17 00:00:00 2001 From: stonar96 Date: Sat, 27 Jun 2020 04:27:03 +0200 Subject: [PATCH 22/91] Fix Anti-Xray --- Spigot-Server-Patches/Anti-Xray.patch | 36 ++++++++++----------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/Spigot-Server-Patches/Anti-Xray.patch b/Spigot-Server-Patches/Anti-Xray.patch index 29e5b2e0e2..facbe05cd0 100644 --- a/Spigot-Server-Patches/Anti-Xray.patch +++ b/Spigot-Server-Patches/Anti-Xray.patch @@ -891,19 +891,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + public int read() { -+ int value = (int) (current >>> bitInLongIndex) & mask; -+ bitInLongIndex += bitsPerObject; -+ -+ if (bitInLongIndex > 63) { -+ bitInLongIndex -= 64; ++ if (bitInLongIndex + bitsPerObject > 64) { ++ bitInLongIndex = 0; + longInDataBitsIndex += 8; + init(); -+ -+ if (bitInLongIndex > 0) { -+ value |= current << bitsPerObject - bitInLongIndex & mask; -+ } + } + ++ int value = (int) (current >>> bitInLongIndex) & mask; ++ bitInLongIndex += bitsPerObject; + return value; + } +} @@ -969,29 +964,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + public void write(int value) { ++ if (bitInLongIndex + bitsPerObject > 64) { ++ finish(); ++ bitInLongIndex = 0; ++ longInDataBitsIndex += 8; ++ init(); ++ } ++ + current = current & ~(mask << bitInLongIndex) | (value & mask) << bitInLongIndex; + dirty = true; + bitInLongIndex += bitsPerObject; -+ -+ if (bitInLongIndex > 63) { -+ finish(); -+ bitInLongIndex -= 64; -+ longInDataBitsIndex += 8; -+ init(); -+ -+ if (bitInLongIndex > 0) { -+ current = current & ~(mask >>> bitsPerObject - bitInLongIndex) | (value & mask) >>> bitsPerObject - bitInLongIndex; -+ dirty = true; -+ } -+ } + } + + public void skip() { + bitInLongIndex += bitsPerObject; + -+ if (bitInLongIndex > 63) { ++ if (bitInLongIndex > 64) { + finish(); -+ bitInLongIndex -= 64; ++ bitInLongIndex = bitsPerObject; + longInDataBitsIndex += 8; + init(); + } From faf7dda51c44add0bd00b49406f456017837ebac Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 26 Jun 2020 20:05:12 -0700 Subject: [PATCH 23/91] fix async chunk loading disregardling light data --- Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch | 1 + 1 file changed, 1 insertion(+) diff --git a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch index b4bb915da0..53ce84e8ff 100644 --- a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch @@ -3241,6 +3241,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (ioThrowable != null) { + com.destroystokyo.paper.util.SneakyThrow.sneaky(ioThrowable); + } ++ chunkHolder.tasks.forEach(Runnable::run); + // Paper end - if (nbttagcompound != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings From a8624a2d1ad5f051f007973a6b0c65f1e5398903 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 26 Jun 2020 21:57:36 -0700 Subject: [PATCH 24/91] Re-Add per player mob spawning --- .../Generator-Settings.patch | 4 +- ...k-Priority-Urgency-System-for-Chunks.patch | 6 +- ...No-Tick-view-distance-implementation.patch | 2 +- ...-isOutsideRange-to-use-distance-maps.patch | 5 + ...tance-map-to-optimise-entity-tracker.patch | 4 +- ...ement-optional-per-player-mob-spawns.patch | 823 ++++++++++++++++++ 6 files changed, 836 insertions(+), 8 deletions(-) create mode 100644 Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch diff --git a/Spigot-Server-Patches/Generator-Settings.patch b/Spigot-Server-Patches/Generator-Settings.patch index 9a058217ab..f4cda5030d 100644 --- a/Spigot-Server-Patches/Generator-Settings.patch +++ b/Spigot-Server-Patches/Generator-Settings.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 { - } - } + private void perPlayerMobSpawns() { + perPlayerMobSpawns = getBoolean("per-player-mob-spawns", false); } + + public boolean generateFlatBedrock; diff --git a/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch b/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch index ff59d05fa0..ee4cbb798c 100644 --- a/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch +++ b/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch @@ -587,8 +587,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private int lastFoodSent = -99999999; private boolean lastSentSaturationZero = true; @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - this.canPickUpLoot = true; this.maxHealthCache = this.getMaxHealth(); + this.cachedSingleMobDistanceMap = new com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper } + // Paper start + public BlockPosition getPointInFront(double inFront) { @@ -1069,8 +1069,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - private static double getDistanceSquaredFromChunk(ChunkCoordIntPair chunkPos, Entity entity) { return a(chunkPos, entity); } // Paper - OBFHELPER - private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) { + public void updatePlayerMobTypeMap(Entity entity) { + if (!this.world.paperConfig.perPlayerMobSpawns) { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { List>> list = Lists.newArrayList(); int j = chunkcoordintpair.x; diff --git a/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch b/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch index b497bd6820..47ac87a183 100644 --- a/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch +++ b/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch @@ -353,7 +353,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - no-tick view distance } - private static double getDistanceSquaredFromChunk(ChunkCoordIntPair chunkPos, Entity entity) { return a(chunkPos, entity); } // Paper - OBFHELPER + public void updatePlayerMobTypeMap(Entity entity) { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { completablefuture1.thenAcceptAsync((either) -> { either.mapLeft((chunk) -> { diff --git a/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch b/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch index bcb3df5f67..a536028223 100644 --- a/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch +++ b/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch @@ -290,6 +290,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - optimise PlayerChunkMap#isOutsideRange } + public void updatePlayerMobTypeMap(Entity entity) { +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + return entityPlayer.mobCounts[enumCreatureType.ordinal()]; + } + + private static double getDistanceSquaredFromChunk(ChunkCoordIntPair chunkPos, Entity entity) { return a(chunkPos, entity); } // Paper - OBFHELPER private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) { double d0 = (double) (chunkcoordintpair.x * 16 + 8); 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 66bc7675c8..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 @@ -117,9 +117,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Paper end @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - this.l = supplier; this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper this.setViewDistance(i); + this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper + // Paper start - use distance map to optimise entity tracker + this.playerEntityTrackerTrackMaps = new com.destroystokyo.paper.util.misc.PlayerAreaMap[TRACKING_RANGE_TYPES.length]; + this.entityTrackerTrackRanges = new int[TRACKING_RANGE_TYPES.length]; @@ -161,7 +161,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - use distance map to optimise entity tracker } - private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) { + public void updatePlayerMobTypeMap(Entity entity) { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } diff --git a/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch b/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch new file mode 100644 index 0000000000..187c91562a --- /dev/null +++ b/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch @@ -0,0 +1,823 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: kickash32 +Date: Mon, 19 Aug 2019 01:27:58 +0500 +Subject: [PATCH] implement optional per player mob spawns + + +diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java ++++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java +@@ -0,0 +0,0 @@ public class WorldTimingsHandler { + + + public final Timing miscMobSpawning; ++ public final Timing playerMobDistanceMapUpdate; + + public final Timing poiUnload; + public final Timing chunkUnload; +@@ -0,0 +0,0 @@ public class WorldTimingsHandler { + + + miscMobSpawning = Timings.ofSafe(name + "Mob spawning - Misc"); ++ playerMobDistanceMapUpdate = Timings.ofSafe(name + "Per Player Mob Spawning - Distance Map Update"); + + poiUnload = Timings.ofSafe(name + "Chunk unload - POI"); + chunkUnload = Timings.ofSafe(name + "Chunk unload - Chunk"); +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 boolean perPlayerMobSpawns = false; ++ private void perPlayerMobSpawns() { ++ perPlayerMobSpawns = getBoolean("per-player-mob-spawns", false); ++ } + } +diff --git a/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java b/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java +@@ -0,0 +0,0 @@ ++package com.destroystokyo.paper.util; ++ ++import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; ++import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; ++import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; ++import net.minecraft.server.ChunkCoordIntPair; ++import net.minecraft.server.EntityPlayer; ++import net.minecraft.server.SectionPosition; ++import org.spigotmc.AsyncCatcher; ++import java.util.HashMap; ++import java.util.List; ++import java.util.Map; ++import java.util.Set; ++ ++/** @author Spottedleaf */ ++public final class PlayerMobDistanceMap { ++ ++ private static final PooledHashSets.PooledObjectLinkedOpenHashSet EMPTY_SET = new PooledHashSets.PooledObjectLinkedOpenHashSet<>(); ++ ++ private final Map players = new HashMap<>(); ++ // we use linked for better iteration. ++ private final Long2ObjectOpenHashMap> playerMap = new Long2ObjectOpenHashMap<>(32, 0.5f); ++ private int viewDistance; ++ ++ private final PooledHashSets pooledHashSets = new PooledHashSets<>(); ++ ++ public PooledHashSets.PooledObjectLinkedOpenHashSet getPlayersInRange(final ChunkCoordIntPair chunkPos) { ++ return this.getPlayersInRange(chunkPos.x, chunkPos.z); ++ } ++ ++ public PooledHashSets.PooledObjectLinkedOpenHashSet getPlayersInRange(final int chunkX, final int chunkZ) { ++ return this.playerMap.getOrDefault(ChunkCoordIntPair.pair(chunkX, chunkZ), EMPTY_SET); ++ } ++ ++ public void update(final List currentPlayers, final int newViewDistance) { ++ AsyncCatcher.catchOp("Distance map update"); ++ final ObjectLinkedOpenHashSet gone = new ObjectLinkedOpenHashSet<>(this.players.keySet()); ++ ++ final int oldViewDistance = this.viewDistance; ++ this.viewDistance = newViewDistance; ++ ++ for (final EntityPlayer player : currentPlayers) { ++ if (player.isSpectator() || !player.affectsSpawning) { ++ continue; // will be left in 'gone' (or not added at all) ++ } ++ ++ gone.remove(player); ++ ++ final SectionPosition newPosition = player.getPlayerMapSection(); ++ final SectionPosition oldPosition = this.players.put(player, newPosition); ++ ++ if (oldPosition == null) { ++ this.addNewPlayer(player, newPosition, newViewDistance); ++ } else { ++ this.updatePlayer(player, oldPosition, newPosition, oldViewDistance, newViewDistance); ++ } ++ //this.validatePlayer(player, newViewDistance); // debug only ++ } ++ ++ for (final EntityPlayer player : gone) { ++ final SectionPosition oldPosition = this.players.remove(player); ++ if (oldPosition != null) { ++ this.removePlayer(player, oldPosition, oldViewDistance); ++ } ++ } ++ } ++ ++ // expensive op, only for debug ++ private void validatePlayer(final EntityPlayer player, final int viewDistance) { ++ int entiesGot = 0; ++ int expectedEntries = (2 * viewDistance + 1); ++ expectedEntries *= expectedEntries; ++ ++ final SectionPosition currPosition = player.getPlayerMapSection(); ++ ++ final int centerX = currPosition.getX(); ++ final int centerZ = currPosition.getZ(); ++ ++ for (final Long2ObjectLinkedOpenHashMap.Entry> entry : this.playerMap.long2ObjectEntrySet()) { ++ final long key = entry.getLongKey(); ++ final PooledHashSets.PooledObjectLinkedOpenHashSet map = entry.getValue(); ++ ++ if (map.referenceCount == 0) { ++ throw new IllegalStateException("Invalid map"); ++ } ++ ++ if (map.set.contains(player)) { ++ ++entiesGot; ++ ++ final int chunkX = ChunkCoordIntPair.getX(key); ++ final int chunkZ = ChunkCoordIntPair.getZ(key); ++ ++ final int dist = Math.max(Math.abs(chunkX - centerX), Math.abs(chunkZ - centerZ)); ++ ++ if (dist > viewDistance) { ++ throw new IllegalStateException("Expected view distance " + viewDistance + ", got " + dist); ++ } ++ } ++ } ++ ++ if (entiesGot != expectedEntries) { ++ throw new IllegalStateException("Expected " + expectedEntries + ", got " + entiesGot); ++ } ++ } ++ ++ private void addPlayerTo(final EntityPlayer player, final int chunkX, final int chunkZ) { ++ this.playerMap.compute(ChunkCoordIntPair.pair(chunkX, chunkZ), (final Long key, final PooledHashSets.PooledObjectLinkedOpenHashSet players) -> { ++ if (players == null) { ++ return player.cachedSingleMobDistanceMap; ++ } else { ++ return PlayerMobDistanceMap.this.pooledHashSets.findMapWith(players, player); ++ } ++ }); ++ } ++ ++ private void removePlayerFrom(final EntityPlayer player, final int chunkX, final int chunkZ) { ++ this.playerMap.compute(ChunkCoordIntPair.pair(chunkX, chunkZ), (final Long keyInMap, final PooledHashSets.PooledObjectLinkedOpenHashSet players) -> { ++ return PlayerMobDistanceMap.this.pooledHashSets.findMapWithout(players, player); // rets null instead of an empty map ++ }); ++ } ++ ++ private void updatePlayer(final EntityPlayer player, final SectionPosition oldPosition, final SectionPosition newPosition, final int oldViewDistance, final int newViewDistance) { ++ final int toX = newPosition.getX(); ++ final int toZ = newPosition.getZ(); ++ final int fromX = oldPosition.getX(); ++ final int fromZ = oldPosition.getZ(); ++ ++ final int dx = toX - fromX; ++ final int dz = toZ - fromZ; ++ ++ final int totalX = Math.abs(fromX - toX); ++ final int totalZ = Math.abs(fromZ - toZ); ++ ++ if (Math.max(totalX, totalZ) > (2 * oldViewDistance)) { ++ // teleported? ++ this.removePlayer(player, oldPosition, oldViewDistance); ++ this.addNewPlayer(player, newPosition, newViewDistance); ++ return; ++ } ++ ++ // x axis is width ++ // z axis is height ++ // right refers to the x axis of where we moved ++ // top refers to the z axis of where we moved ++ ++ if (oldViewDistance == newViewDistance) { ++ // same view distance ++ ++ // used for relative positioning ++ final int up = 1 | (dz >> (Integer.SIZE - 1)); // 1 if dz >= 0, -1 otherwise ++ final int right = 1 | (dx >> (Integer.SIZE - 1)); // 1 if dx >= 0, -1 otherwise ++ ++ // The area excluded by overlapping the two view distance squares creates four rectangles: ++ // Two on the left, and two on the right. The ones on the left we consider the "removed" section ++ // and on the right the "added" section. ++ // https://i.imgur.com/MrnOBgI.png is a reference image. Note that the outside border is not actually ++ // exclusive to the regions they surround. ++ ++ // 4 points of the rectangle ++ int maxX; // exclusive ++ int minX; // inclusive ++ int maxZ; // exclusive ++ int minZ; // inclusive ++ ++ if (dx != 0) { ++ // handle right addition ++ ++ maxX = toX + (oldViewDistance * right) + right; // exclusive ++ minX = fromX + (oldViewDistance * right) + right; // inclusive ++ maxZ = fromZ + (oldViewDistance * up) + up; // exclusive ++ minZ = toZ - (oldViewDistance * up); // inclusive ++ ++ for (int currX = minX; currX != maxX; currX += right) { ++ for (int currZ = minZ; currZ != maxZ; currZ += up) { ++ this.addPlayerTo(player, currX, currZ); ++ } ++ } ++ } ++ ++ if (dz != 0) { ++ // handle up addition ++ ++ maxX = toX + (oldViewDistance * right) + right; // exclusive ++ minX = toX - (oldViewDistance * right); // inclusive ++ maxZ = toZ + (oldViewDistance * up) + up; // exclusive ++ minZ = fromZ + (oldViewDistance * up) + up; // inclusive ++ ++ for (int currX = minX; currX != maxX; currX += right) { ++ for (int currZ = minZ; currZ != maxZ; currZ += up) { ++ this.addPlayerTo(player, currX, currZ); ++ } ++ } ++ } ++ ++ if (dx != 0) { ++ // handle left removal ++ ++ maxX = toX - (oldViewDistance * right); // exclusive ++ minX = fromX - (oldViewDistance * right); // inclusive ++ maxZ = fromZ + (oldViewDistance * up) + up; // exclusive ++ minZ = toZ - (oldViewDistance * up); // inclusive ++ ++ for (int currX = minX; currX != maxX; currX += right) { ++ for (int currZ = minZ; currZ != maxZ; currZ += up) { ++ this.removePlayerFrom(player, currX, currZ); ++ } ++ } ++ } ++ ++ if (dz != 0) { ++ // handle down removal ++ ++ maxX = fromX + (oldViewDistance * right) + right; // exclusive ++ minX = fromX - (oldViewDistance * right); // inclusive ++ maxZ = toZ - (oldViewDistance * up); // exclusive ++ minZ = fromZ - (oldViewDistance * up); // inclusive ++ ++ for (int currX = minX; currX != maxX; currX += right) { ++ for (int currZ = minZ; currZ != maxZ; currZ += up) { ++ this.removePlayerFrom(player, currX, currZ); ++ } ++ } ++ } ++ } else { ++ // different view distance ++ // for now :) ++ this.removePlayer(player, oldPosition, oldViewDistance); ++ this.addNewPlayer(player, newPosition, newViewDistance); ++ } ++ } ++ ++ private void removePlayer(final EntityPlayer player, final SectionPosition position, final int viewDistance) { ++ final int x = position.getX(); ++ final int z = position.getZ(); ++ ++ for (int xoff = -viewDistance; xoff <= viewDistance; ++xoff) { ++ for (int zoff = -viewDistance; zoff <= viewDistance; ++zoff) { ++ this.removePlayerFrom(player, x + xoff, z + zoff); ++ } ++ } ++ } ++ ++ private void addNewPlayer(final EntityPlayer player, final SectionPosition position, final int viewDistance) { ++ final int x = position.getX(); ++ final int z = position.getZ(); ++ ++ for (int xoff = -viewDistance; xoff <= viewDistance; ++xoff) { ++ for (int zoff = -viewDistance; zoff <= viewDistance; ++zoff) { ++ this.addPlayerTo(player, x + xoff, z + zoff); ++ } ++ } ++ } ++} +diff --git a/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java b/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java +@@ -0,0 +0,0 @@ ++package com.destroystokyo.paper.util; ++ ++import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; ++import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; ++import java.lang.ref.WeakReference; ++import java.util.Iterator; ++ ++/** @author Spottedleaf */ ++public class PooledHashSets { ++ ++ // we really want to avoid that equals() check as much as possible... ++ protected final Object2ObjectOpenHashMap, PooledObjectLinkedOpenHashSet> mapPool = new Object2ObjectOpenHashMap<>(64, 0.25f); ++ ++ protected void decrementReferenceCount(final PooledObjectLinkedOpenHashSet current) { ++ if (current.referenceCount == 0) { ++ throw new IllegalStateException("Cannot decrement reference count for " + current); ++ } ++ if (current.referenceCount == -1 || --current.referenceCount > 0) { ++ return; ++ } ++ ++ this.mapPool.remove(current); ++ return; ++ } ++ ++ public PooledObjectLinkedOpenHashSet findMapWith(final PooledObjectLinkedOpenHashSet current, final E object) { ++ final PooledObjectLinkedOpenHashSet cached = current.getAddCache(object); ++ ++ if (cached != null) { ++ if (cached.referenceCount != -1) { ++ ++cached.referenceCount; ++ } ++ ++ decrementReferenceCount(current); ++ ++ return cached; ++ } ++ ++ if (!current.add(object)) { ++ return current; ++ } ++ ++ // we use get/put since we use a different key on put ++ PooledObjectLinkedOpenHashSet ret = this.mapPool.get(current); ++ ++ if (ret == null) { ++ ret = new PooledObjectLinkedOpenHashSet<>(current); ++ current.remove(object); ++ this.mapPool.put(ret, ret); ++ ret.referenceCount = 1; ++ } else { ++ if (ret.referenceCount != -1) { ++ ++ret.referenceCount; ++ } ++ current.remove(object); ++ } ++ ++ current.updateAddCache(object, ret); ++ ++ decrementReferenceCount(current); ++ return ret; ++ } ++ ++ // rets null if current.size() == 1 ++ public PooledObjectLinkedOpenHashSet findMapWithout(final PooledObjectLinkedOpenHashSet current, final E object) { ++ if (current.set.size() == 1) { ++ decrementReferenceCount(current); ++ return null; ++ } ++ ++ final PooledObjectLinkedOpenHashSet cached = current.getRemoveCache(object); ++ ++ if (cached != null) { ++ if (cached.referenceCount != -1) { ++ ++cached.referenceCount; ++ } ++ ++ decrementReferenceCount(current); ++ ++ return cached; ++ } ++ ++ if (!current.remove(object)) { ++ return current; ++ } ++ ++ // we use get/put since we use a different key on put ++ PooledObjectLinkedOpenHashSet ret = this.mapPool.get(current); ++ ++ if (ret == null) { ++ ret = new PooledObjectLinkedOpenHashSet<>(current); ++ current.add(object); ++ this.mapPool.put(ret, ret); ++ ret.referenceCount = 1; ++ } else { ++ if (ret.referenceCount != -1) { ++ ++ret.referenceCount; ++ } ++ current.add(object); ++ } ++ ++ current.updateRemoveCache(object, ret); ++ ++ decrementReferenceCount(current); ++ return ret; ++ } ++ ++ public static final class PooledObjectLinkedOpenHashSet implements Iterable { ++ ++ private static final WeakReference NULL_REFERENCE = new WeakReference(null); ++ ++ final ObjectLinkedOpenHashSet set; ++ int referenceCount; // -1 if special ++ int hash; // optimize hashcode ++ ++ // add cache ++ WeakReference lastAddObject = NULL_REFERENCE; ++ WeakReference> lastAddMap = NULL_REFERENCE; ++ ++ // remove cache ++ WeakReference lastRemoveObject = NULL_REFERENCE; ++ WeakReference> lastRemoveMap = NULL_REFERENCE; ++ ++ public PooledObjectLinkedOpenHashSet() { ++ this.set = new ObjectLinkedOpenHashSet<>(2, 0.6f); ++ } ++ ++ public PooledObjectLinkedOpenHashSet(final E single) { ++ this(); ++ this.referenceCount = -1; ++ this.add(single); ++ } ++ ++ public PooledObjectLinkedOpenHashSet(final PooledObjectLinkedOpenHashSet other) { ++ this.set = other.set.clone(); ++ this.hash = other.hash; ++ } ++ ++ // from https://github.com/Spottedleaf/ConcurrentUtil/blob/master/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java ++ // generated by https://github.com/skeeto/hash-prospector ++ static int hash0(int x) { ++ x *= 0x36935555; ++ x ^= x >>> 16; ++ return x; ++ } ++ ++ public PooledObjectLinkedOpenHashSet getAddCache(final E element) { ++ final E currentAdd = this.lastAddObject.get(); ++ ++ if (currentAdd == null || !(currentAdd == element || currentAdd.equals(element))) { ++ return null; ++ } ++ ++ final PooledObjectLinkedOpenHashSet map = this.lastAddMap.get(); ++ if (map == null || map.referenceCount == 0) { ++ // we need to ret null if ref count is zero as calling code will assume the map is in use ++ return null; ++ } ++ ++ return map; ++ } ++ ++ public PooledObjectLinkedOpenHashSet getRemoveCache(final E element) { ++ final E currentRemove = this.lastRemoveObject.get(); ++ ++ if (currentRemove == null || !(currentRemove == element || currentRemove.equals(element))) { ++ return null; ++ } ++ ++ final PooledObjectLinkedOpenHashSet map = this.lastRemoveMap.get(); ++ if (map == null || map.referenceCount == 0) { ++ // we need to ret null if ref count is zero as calling code will assume the map is in use ++ return null; ++ } ++ ++ return map; ++ } ++ ++ public void updateAddCache(final E element, final PooledObjectLinkedOpenHashSet map) { ++ this.lastAddObject = new WeakReference<>(element); ++ this.lastAddMap = new WeakReference<>(map); ++ } ++ ++ public void updateRemoveCache(final E element, final PooledObjectLinkedOpenHashSet map) { ++ this.lastRemoveObject = new WeakReference<>(element); ++ this.lastRemoveMap = new WeakReference<>(map); ++ } ++ ++ boolean add(final E element) { ++ boolean added = this.set.add(element); ++ ++ if (added) { ++ this.hash += hash0(element.hashCode()); ++ } ++ ++ return added; ++ } ++ ++ boolean remove(Object element) { ++ boolean removed = this.set.remove(element); ++ ++ if (removed) { ++ this.hash -= hash0(element.hashCode()); ++ } ++ ++ return removed; ++ } ++ ++ @Override ++ public Iterator iterator() { ++ return this.set.iterator(); ++ } ++ ++ @Override ++ public int hashCode() { ++ return this.hash; ++ } ++ ++ @Override ++ public boolean equals(final Object other) { ++ if (!(other instanceof PooledObjectLinkedOpenHashSet)) { ++ return false; ++ } ++ if (this.referenceCount == 0) { ++ return other == this; ++ } else { ++ if (other == this) { ++ // Unfortunately we are never equal to our own instance while in use! ++ return false; ++ } ++ return this.hash == ((PooledObjectLinkedOpenHashSet)other).hash && this.set.equals(((PooledObjectLinkedOpenHashSet)other).set); ++ } ++ } ++ ++ @Override ++ public String toString() { ++ return "PooledHashSet: size: " + this.set.size() + ", reference count: " + this.referenceCount + ", hash: " + ++ this.hashCode() + ", identity: " + System.identityHashCode(this) + " map: " + this.set.toString(); ++ } ++ } ++} +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 { + this.world.getMethodProfiler().enter("naturalSpawnCount"); + this.world.timings.countNaturalMobs.startTiming(); // Paper - timings + int l = this.chunkMapDistance.b(); +- SpawnerCreature.d spawnercreature_d = SpawnerCreature.a(l, this.world.z(), this::a); ++ // Paper start - per player mob spawning ++ SpawnerCreature.d spawnercreature_d; // moved down ++ if (this.playerChunkMap.playerMobDistanceMap != null) { ++ // update distance map ++ this.world.timings.playerMobDistanceMapUpdate.startTiming(); ++ this.playerChunkMap.playerMobDistanceMap.update(this.world.players, this.playerChunkMap.viewDistance); ++ this.world.timings.playerMobDistanceMapUpdate.stopTiming(); ++ // re-set mob counts ++ for (EntityPlayer player : this.world.players) { ++ Arrays.fill(player.mobCounts, 0); ++ } ++ spawnercreature_d = SpawnerCreature.countMobs(l, this.world.z(), this::a, true); ++ } else { ++ spawnercreature_d = SpawnerCreature.countMobs(l, this.world.z(), this::a, false); ++ } ++ // Paper end + this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings + + this.p = spawnercreature_d; +diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- 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 boolean queueHealthUpdatePacket = false; + public net.minecraft.server.PacketPlayOutUpdateHealth queuedHealthUpdatePacket; + // Paper end ++ // Paper start - mob spawning rework ++ public static final int ENUMCREATURETYPE_TOTAL_ENUMS = EnumCreatureType.values().length; ++ public final int[] mobCounts = new int[ENUMCREATURETYPE_TOTAL_ENUMS]; // Paper ++ public final com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet cachedSingleMobDistanceMap; ++ // Paper end + + // CraftBukkit start + public String displayName; +@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + this.displayName = this.getName(); + this.canPickUpLoot = true; + this.maxHealthCache = this.getMaxHealth(); ++ this.cachedSingleMobDistanceMap = new com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper + } + + // Yes, this doesn't match Vanilla, but it's the best we can do for now. +@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + + } + ++ public final SectionPosition getPlayerMapSection() { return this.N(); } // Paper - OBFHELPER + public SectionPosition N() { + return this.cq; + } +diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/EntityTypes.java ++++ b/src/main/java/net/minecraft/server/EntityTypes.java +@@ -0,0 +0,0 @@ public class EntityTypes { + return this.bk; + } + ++ public final EnumCreatureType getEnumCreatureType() { return this.e(); } // Paper - OBFHELPER + public EnumCreatureType e() { + return this.bf; + } +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 { + public final Int2ObjectMap trackedEntities; + private final Long2ByteMap z; + private final Queue A; private final Queue getUnloadQueueTasks() { return this.A; } // Paper - OBFHELPER +- private int viewDistance; ++ int viewDistance; // Paper - private -> package private ++ public final com.destroystokyo.paper.util.PlayerMobDistanceMap playerMobDistanceMap; // Paper + + // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() + public final CallbackExecutor callbackExecutor = new CallbackExecutor(); +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + this.l = supplier; + this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper + this.setViewDistance(i); ++ this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper ++ } ++ ++ public void updatePlayerMobTypeMap(Entity entity) { ++ if (!this.world.paperConfig.perPlayerMobSpawns) { ++ return; ++ } ++ int chunkX = (int)Math.floor(entity.locX()) >> 4; ++ int chunkZ = (int)Math.floor(entity.locZ()) >> 4; ++ int index = entity.getEntityType().getEnumCreatureType().ordinal(); ++ ++ for (EntityPlayer player : this.playerMobDistanceMap.getPlayersInRange(chunkX, chunkZ)) { ++ ++player.mobCounts[index]; ++ } ++ } ++ ++ public int getMobCountNear(EntityPlayer entityPlayer, EnumCreatureType enumCreatureType) { ++ return entityPlayer.mobCounts[enumCreatureType.ordinal()]; + } + + private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) { +diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- 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 { + }); + + public static SpawnerCreature.d a(int i, Iterable iterable, SpawnerCreature.b spawnercreature_b) { ++ // Paper start - add countMobs parameter ++ return countMobs(i, iterable, spawnercreature_b, false); ++ } ++ public static SpawnerCreature.d countMobs(int i, Iterable iterable, SpawnerCreature.b spawnercreature_b, boolean countMobs) { ++ // Paper end - add countMobs parameter + SpawnerCreatureProbabilities spawnercreatureprobabilities = new SpawnerCreatureProbabilities(); + Object2IntOpenHashMap object2intopenhashmap = new Object2IntOpenHashMap(); + Iterator iterator = iterable.iterator(); +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + } + + object2intopenhashmap.addTo(enumcreaturetype, 1); ++ // Paper start ++ if (countMobs) { ++ ((WorldServer)chunk.world).getChunkProvider().playerChunkMap.updatePlayerMobTypeMap(entity); ++ } ++ // Paper end + }); + } + } +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + continue; + } + ++ // Paper start - only allow spawns upto the limit per chunk and update count afterwards ++ int currEntityCount = spawnercreature_d.getEntityCountsByType().getInt(enumcreaturetype); ++ int k1 = limit * spawnercreature_d.getSpawnerChunks() / SpawnerCreature.b; ++ int difference = k1 - currEntityCount; ++ ++ if (worldserver.paperConfig.perPlayerMobSpawns) { ++ int minDiff = Integer.MAX_VALUE; ++ for (EntityPlayer entityplayer : worldserver.getChunkProvider().playerChunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) { ++ minDiff = Math.min(limit - worldserver.getChunkProvider().playerChunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff); ++ } ++ difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff; ++ } ++ // Paper end ++ ++ if (difference > 0) { // Paper + if ((flag || !enumcreaturetype.d()) && (flag1 || enumcreaturetype.d()) && (flag2 || !enumcreaturetype.e()) && spawnercreature_d.a(enumcreaturetype, limit)) { + // CraftBukkit end +- a(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> { ++ int spawnCount = spawnMobs(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> { + return spawnercreature_d.a(entitytypes, blockposition, ichunkaccess); + }, (entityinsentient, ichunkaccess) -> { + spawnercreature_d.a(entityinsentient, ichunkaccess); ++ }, ++ limit, worldserver.paperConfig.perPlayerMobSpawns ? worldserver.getChunkProvider().playerChunkMap::updatePlayerMobTypeMap : null); ++ spawnercreature_d.getEntityCountsByType().mergeInt(enumcreaturetype, 0, (keyInMap, valueInMap) -> { ++ return Integer.valueOf(spawnCount + valueInMap.intValue()); + }); ++ } // Paper + } + } + +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + } + + public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a) { ++ // Paper start - add parameters and int ret type ++ spawnMobs(enumcreaturetype, worldserver, chunk, spawnercreature_c, spawnercreature_a, Integer.MAX_VALUE, null); ++ } ++ public static int spawnMobs(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a, int maxSpawns, Consumer trackEntity) { ++ // Paper end - add parameters and int ret type + BlockPosition blockposition = getRandomPosition(worldserver, chunk); + + if (blockposition.getY() >= 1) { +- a(enumcreaturetype, worldserver, (IChunkAccess) chunk, blockposition, spawnercreature_c, spawnercreature_a); ++ return spawnMobsInternal(enumcreaturetype, worldserver, (IChunkAccess) chunk, blockposition, spawnercreature_c, spawnercreature_a, maxSpawns, trackEntity); + } ++ return 0; // Paper + } + + public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition blockposition, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a) { ++ // Paper start - add maxSpawns parameter and return spawned mobs ++ spawnMobsInternal(enumcreaturetype, worldserver, ichunkaccess, blockposition, spawnercreature_c, spawnercreature_a, Integer.MAX_VALUE, null); ++ } ++ public static int spawnMobsInternal(EnumCreatureType enumcreaturetype, WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition blockposition, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a, int maxSpawns, Consumer trackEntity) { ++ // Paper end - add maxSpawns parameter and return spawned mobs + StructureManager structuremanager = worldserver.getStructureManager(); + ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator(); + int i = blockposition.getY(); + IBlockData iblockdata = worldserver.getTypeIfLoadedAndInBounds(blockposition); // Paper - don't load chunks for mob spawn ++ int j = 0; // Paper - moved up + + 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; ++ // Paper - moved up + int k = 0; + + while (k < 3) { +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + // Paper start + Boolean doSpawning = a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2); + if (doSpawning == null) { +- return; ++ return j; // Paper + } + if (doSpawning.booleanValue() && spawnercreature_c.test(biomebase_biomemeta.c, blockposition_mutableblockposition, ichunkaccess)) { // Paper end + EntityInsentient entityinsentient = a(worldserver, biomebase_biomemeta.c); + + if (entityinsentient == null) { +- return; ++ return j; // Paper + } + + entityinsentient.setPositionRotation(d0, (double) i, d1, worldserver.random.nextFloat() * 360.0F, 0.0F); +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + groupdataentity = entityinsentient.prepare(worldserver, worldserver.getDamageScaler(entityinsentient.getChunkCoordinates()), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null); + // CraftBukkit start + if (worldserver.addEntity(entityinsentient, SpawnReason.NATURAL)) { +- ++j; ++ ++j; // Paper - force diff on name change - we expect this to be the total amount spawned + ++k1; + spawnercreature_a.run(entityinsentient, ichunkaccess); ++ // Paper start ++ if (trackEntity != null) { ++ trackEntity.accept(entityinsentient); ++ } ++ // Paper end + } + // CraftBukkit end +- if (j >= entityinsentient.getMaxSpawnGroup()) { +- return; ++ if (j >= entityinsentient.getMaxSpawnGroup() || j >= maxSpawns) { // Paper ++ return j; // Paper + } + + if (entityinsentient.c(k1)) { +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + } + + } ++ return j; // Paper + } + + private static boolean a(WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) { +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + + public static class d { + +- private final int a; +- private final Object2IntOpenHashMap b; ++ private final int a; final int getSpawnerChunks() { return this.a; } // Paper - OBFHELPER ++ private final Object2IntOpenHashMap b; final Object2IntMap getEntityCountsByType() { return this.b; } // Paper - OBFHELPER + private final SpawnerCreatureProbabilities c; + private final Object2IntMap d; + @Nullable +@@ -0,0 +0,0 @@ public final class SpawnerCreature { + + // CraftBukkit start + private boolean a(EnumCreatureType enumcreaturetype, int limit) { +- int i = limit * this.a / SpawnerCreature.b; ++ int i = limit * this.a / SpawnerCreature.b; // Paper - diff on change, needed in the spawn method + // CraftBukkit end + + return this.b.getInt(enumcreaturetype) < i; From ce8c91600bea4095248629ec1efe8deea9a8004b Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 26 Jun 2020 22:12:11 -0700 Subject: [PATCH 25/91] Updated Upstream (Bukkit/CraftBukkit/Spigot) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 3284612a SPIGOT-5853: Add DragonBattle#generateEndPortal() e4db04ae SPIGOT-5841: New map colours broken CraftBukkit Changes: d4243510 SPIGOT-5853: DragonBattle#getEndPortalLocation() throws NPE on new world 1601ec31 SPIGOT-5845: ChatColor.RESET does not work in ItemMeta to reset italics 4d92db6f CraftChatMessageTest does not need AbstractTestingBase 71045d3d SPIGOT-5828: Unlock worlds on unload dbc347b9 SPIGOT-5841: New map colours broken 14053c70 SPIGOT-5847: BlockFadeEvent cannot be triggered asynchronously from another thread Spigot Changes: 6f4ff1b6 SPIGOT-5851: ChatColor (HEX) doesn't appear correctly in the ActionBar d94a518a SPIGOT-5848: PlayerSpawnLocationEvent throws NPE when setting a location of another world --- .../Add-PlayerInitialSpawnEvent.patch | 5 +++-- ...-to-disable-ender-dragon-legacy-check.patch | 18 ------------------ ...-t-fire-BlockFade-on-worldgen-threads.patch | 4 ++-- work/Bukkit | 2 +- work/CraftBukkit | 2 +- work/Spigot | 2 +- 6 files changed, 8 insertions(+), 25 deletions(-) diff --git a/Spigot-Server-Patches/Add-PlayerInitialSpawnEvent.patch b/Spigot-Server-Patches/Add-PlayerInitialSpawnEvent.patch index 0518e81866..df948df91f 100644 --- a/Spigot-Server-Patches/Add-PlayerInitialSpawnEvent.patch +++ b/Spigot-Server-Patches/Add-PlayerInitialSpawnEvent.patch @@ -21,9 +21,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Bukkit.getPluginManager().callEvent(ev); Location loc = ev.getSpawnLocation(); - worldserver = ((CraftWorld) loc.getWorld()).getHandle(); +@@ -0,0 +0,0 @@ public abstract class PlayerList { - entityplayer.spawnIn(worldserver); + entityplayer.spawnIn(worldserver1); + entityplayer.playerInteractManager.a((WorldServer) entityplayer.world); - entityplayer.setPosition(loc.getX(), loc.getY(), loc.getZ()); + entityplayer.setPositionRaw(loc.getX(), loc.getY(), loc.getZ()); // Paper - set raw so we aren't fully joined to the world (not added to chunk or world) entityplayer.setYawPitch(loc.getYaw(), loc.getPitch()); 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 c6a4124285..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 @@ -46,21 +46,3 @@ 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/Don-t-fire-BlockFade-on-worldgen-threads.patch b/Spigot-Server-Patches/Don-t-fire-BlockFade-on-worldgen-threads.patch index da24b21125..ea6b460cec 100644 --- a/Spigot-Server-Patches/Don-t-fire-BlockFade-on-worldgen-threads.patch +++ b/Spigot-Server-Patches/Don-t-fire-BlockFade-on-worldgen-threads.patch @@ -15,8 +15,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit start + if (!(generatoraccess instanceof WorldServer)) return this.canPlace(iblockdata, generatoraccess, blockposition) ? (IBlockData) this.a(generatoraccess, blockposition, (Integer) iblockdata.get(BlockFire.AGE)) : Blocks.AIR.getBlockData(); // Paper - don't fire events in world generation if (!this.canPlace(iblockdata, generatoraccess, blockposition)) { - CraftBlockState blockState = CraftBlockState.getBlockState(generatoraccess, blockposition); - blockState.setData(Blocks.AIR.getBlockData()); + // Suppress during worldgen + if (!(generatoraccess instanceof World)) { @@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { return blockState.getHandle(); } diff --git a/work/Bukkit b/work/Bukkit index edc7a378c9..3284612a10 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit edc7a378c9258ef533f90de135e250ca91b1ae02 +Subproject commit 3284612a10e704b4658aa087213a3fa9670b6926 diff --git a/work/CraftBukkit b/work/CraftBukkit index 4ff609e60c..d424351010 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 4ff609e60c191f107682681b5e3a8262f8a4c844 +Subproject commit d4243510102530684b860dbe927311bf47c488db diff --git a/work/Spigot b/work/Spigot index 16d78990fe..6f4ff1b691 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit 16d78990fe27633e0ec129216f96d3b50f770025 +Subproject commit 6f4ff1b691828e538ae534eac66e80a1bf2c1adf From 9e1ccb01be0361390a4f0b869c28c0313466ba11 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 26 Jun 2020 22:37:38 -0700 Subject: [PATCH 26/91] Hide sync chunk writes behind flag --- .../Hide-sync-chunk-writes-behind-flag.patch | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 Spigot-Server-Patches/Hide-sync-chunk-writes-behind-flag.patch diff --git a/Spigot-Server-Patches/Hide-sync-chunk-writes-behind-flag.patch b/Spigot-Server-Patches/Hide-sync-chunk-writes-behind-flag.patch new file mode 100644 index 0000000000..4a0b0832a6 --- /dev/null +++ b/Spigot-Server-Patches/Hide-sync-chunk-writes-behind-flag.patch @@ -0,0 +1,23 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Fri, 26 Jun 2020 22:35:08 -0700 +Subject: [PATCH] Hide sync chunk writes behind flag + +Syncing writes on each write call has terrible performance +on harddrives. + +-DPaper.enable-sync-chunk-writes=true to enable + +diff --git a/src/main/java/net/minecraft/server/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/DedicatedServerProperties.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/DedicatedServerProperties.java ++++ b/src/main/java/net/minecraft/server/DedicatedServerProperties.java +@@ -0,0 +0,0 @@ public class DedicatedServerProperties extends PropertyManager { + return MathHelper.clamp(integer, 1, 29999984); + }, 29999984); +- this.syncChunkWrites = this.getBoolean("sync-chunk-writes", true); ++ this.syncChunkWrites = this.getBoolean("sync-chunk-writes", true) && Boolean.getBoolean("Paper.enable-sync-chunk-writes"); // Paper - hide behind flag + this.enableJmxMonitoring = this.getBoolean("enable-jmx-monitoring", false); + this.enableStatus = this.getBoolean("enable-status", true); + this.entityBroadcastRangePercentage = this.a("entity-broadcast-range-percentage", (integer) -> { From 86eab590182e399d0653e7ad832dec96c8e9c02a Mon Sep 17 00:00:00 2001 From: kickash32 Date: Sat, 27 Jun 2020 12:44:50 -0400 Subject: [PATCH 27/91] someone left this in? --- scripts/importmcdev.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/importmcdev.sh b/scripts/importmcdev.sh index 06ad7ab9b9..269f68bcd4 100755 --- a/scripts/importmcdev.sh +++ b/scripts/importmcdev.sh @@ -94,7 +94,6 @@ done # import FileName -import VoxelShapeSpliterator ######################################################## ######################################################## From c438e9cf0e91dbd62569b7eeec92bc9f6669aca0 Mon Sep 17 00:00:00 2001 From: kickash32 Date: Sat, 27 Jun 2020 14:35:52 -0400 Subject: [PATCH 28/91] port 4 patches --- .../Add-permission-for-command-blocks.patch | 79 +++++++++++ ...sure-Entity-AABB-s-are-never-invalid.patch | 129 ++++++++++++++++++ ...mit-lightning-strike-effect-distance.patch | 93 +++++++++++++ ...WorldBorder-collision-checks-and-air.patch | 63 +++++++++ 4 files changed, 364 insertions(+) create mode 100644 Spigot-Server-Patches/Add-permission-for-command-blocks.patch create mode 100644 Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch create mode 100644 Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch create mode 100644 Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch diff --git a/Spigot-Server-Patches/Add-permission-for-command-blocks.patch b/Spigot-Server-Patches/Add-permission-for-command-blocks.patch new file mode 100644 index 0000000000..950a10be1b --- /dev/null +++ b/Spigot-Server-Patches/Add-permission-for-command-blocks.patch @@ -0,0 +1,79 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: kickash32 +Date: Sat, 27 Jun 2020 13:15:53 -0400 +Subject: [PATCH] Add permission for command blocks + + +diff --git a/src/main/java/net/minecraft/server/BlockCommand.java b/src/main/java/net/minecraft/server/BlockCommand.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/BlockCommand.java ++++ b/src/main/java/net/minecraft/server/BlockCommand.java +@@ -0,0 +0,0 @@ public class BlockCommand extends BlockTileEntity { + public EnumInteractionResult interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { + TileEntity tileentity = world.getTileEntity(blockposition); + +- if (tileentity instanceof TileEntityCommand && entityhuman.isCreativeAndOp()) { ++ if (tileentity instanceof TileEntityCommand && (entityhuman.isCreativeAndOp() || (entityhuman.isCreative() && entityhuman.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission + entityhuman.a((TileEntityCommand) tileentity); + return EnumInteractionResult.a(world.isClientSide); + } else { +diff --git a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java ++++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java +@@ -0,0 +0,0 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener { + } + + public EnumInteractionResult a(EntityHuman entityhuman) { +- if (!entityhuman.isCreativeAndOp()) { ++ if (!entityhuman.isCreativeAndOp() && !entityhuman.isCreative() && !entityhuman.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission + return EnumInteractionResult.PASS; + } else { + if (entityhuman.getWorld().isClientSide) { +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +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 @@ public class PlayerConnection implements PacketListenerPlayIn { + PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandblock, this, this.player.getWorldServer()); + if (!this.minecraftServer.getEnableCommandBlock()) { + this.player.sendMessage(new ChatMessage("advMode.notEnabled"), SystemUtils.b); +- } else if (!this.player.isCreativeAndOp()) { ++ } else if (!this.player.isCreativeAndOp() && !this.player.isCreative() && !this.player.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission + this.player.sendMessage(new ChatMessage("advMode.notAllowed"), SystemUtils.b); + } else { + CommandBlockListenerAbstract commandblocklistenerabstract = null; +@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { + PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandminecart, this, this.player.getWorldServer()); + if (!this.minecraftServer.getEnableCommandBlock()) { + this.player.sendMessage(new ChatMessage("advMode.notEnabled"), SystemUtils.b); +- } else if (!this.player.isCreativeAndOp()) { ++ } else if (!this.player.isCreativeAndOp() && !this.player.isCreative() && !this.player.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission + this.player.sendMessage(new ChatMessage("advMode.notAllowed"), SystemUtils.b); + } else { + CommandBlockListenerAbstract commandblocklistenerabstract = packetplayinsetcommandminecart.a(this.player.world); +diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/PlayerInteractManager.java ++++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java +@@ -0,0 +0,0 @@ public class PlayerInteractManager { + TileEntity tileentity = this.world.getTileEntity(blockposition); + Block block = iblockdata.getBlock(); + +- if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp()) { ++ if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp() && !(block instanceof BlockCommand && (this.player.isCreative() && this.player.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission + this.world.notify(blockposition, iblockdata, iblockdata, 3); + return false; + } else if (this.player.a((World) this.world, blockposition, this.gamemode)) { +diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java +@@ -0,0 +0,0 @@ public final class CraftDefaultPermissions { + DefaultPermissions.registerPermission(ROOT + ".nbt.copy", "Gives the user the ability to copy NBT in creative", org.bukkit.permissions.PermissionDefault.TRUE, parent); + DefaultPermissions.registerPermission(ROOT + ".debugstick", "Gives the user the ability to use the debug stick in creative", org.bukkit.permissions.PermissionDefault.OP, parent); + DefaultPermissions.registerPermission(ROOT + ".debugstick.always", "Gives the user the ability to use the debug stick in all game modes", org.bukkit.permissions.PermissionDefault.FALSE, parent); ++ DefaultPermissions.registerPermission(ROOT + ".commandblock", "Gives the user the ability to use command blocks.", org.bukkit.permissions.PermissionDefault.OP, parent); // Paper + // Spigot end + parent.recalculatePermissibles(); + } diff --git a/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch b/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch new file mode 100644 index 0000000000..c791b1fbe6 --- /dev/null +++ b/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch @@ -0,0 +1,129 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: kickash32 +Date: Sat, 27 Jun 2020 13:32:39 -0400 +Subject: [PATCH] Ensure Entity AABB's are never invalid + + +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 @@ + package net.minecraft.server; + ++import co.aikar.timings.MinecraftTimings; ++import co.aikar.timings.Timing; + import com.google.common.collect.Iterables; + import com.google.common.collect.Lists; + import com.google.common.collect.Sets; + import it.unimi.dsi.fastutil.objects.Object2DoubleArrayMap; + import it.unimi.dsi.fastutil.objects.Object2DoubleMap; +-import java.util.Arrays; +-import java.util.Collection; +-import java.util.Collections; +-import java.util.Iterator; +-import java.util.List; +-import java.util.Locale; +-import java.util.Optional; +-import java.util.Random; +-import java.util.Set; +-import java.util.UUID; +-import java.util.concurrent.atomic.AtomicInteger; +-import java.util.stream.Stream; +-import javax.annotation.Nullable; + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; +- +-// CraftBukkit start + import org.bukkit.Bukkit; + import org.bukkit.Server; + import org.bukkit.block.BlockFace; + import org.bukkit.command.CommandSender; +-import org.bukkit.entity.Hanging; +-import org.bukkit.entity.LivingEntity; +-import org.bukkit.entity.Vehicle; +-import co.aikar.timings.MinecraftTimings; // Paper +-import co.aikar.timings.Timing; // Paper +-import org.bukkit.event.entity.EntityCombustByEntityEvent; +-import org.bukkit.event.hanging.HangingBreakByEntityEvent; +-import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; +-import org.bukkit.event.vehicle.VehicleEnterEvent; +-import org.bukkit.event.vehicle.VehicleExitEvent; + import org.bukkit.craftbukkit.CraftWorld; + import org.bukkit.craftbukkit.entity.CraftEntity; + import org.bukkit.craftbukkit.entity.CraftPlayer; + import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.entity.Hanging; ++import org.bukkit.entity.LivingEntity; + import org.bukkit.entity.Pose; ++import org.bukkit.entity.Vehicle; + import org.bukkit.event.entity.EntityAirChangeEvent; ++import org.bukkit.event.entity.EntityCombustByEntityEvent; + import org.bukkit.event.entity.EntityCombustEvent; + import org.bukkit.event.entity.EntityDropItemEvent; + import org.bukkit.event.entity.EntityPortalEvent; + import org.bukkit.event.entity.EntityPoseChangeEvent; ++import org.bukkit.event.hanging.HangingBreakByEntityEvent; + import org.bukkit.event.player.PlayerTeleportEvent; ++import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; ++import org.bukkit.event.vehicle.VehicleEnterEvent; ++import org.bukkit.event.vehicle.VehicleExitEvent; + import org.bukkit.plugin.PluginManager; ++ ++import javax.annotation.Nullable; ++import java.util.Arrays; ++import java.util.Collection; ++import java.util.Collections; ++import java.util.Iterator; ++import java.util.List; ++import java.util.Locale; ++import java.util.Optional; ++import java.util.Random; ++import java.util.Set; ++import java.util.UUID; ++import java.util.concurrent.atomic.AtomicInteger; ++import java.util.stream.Stream; ++ ++// CraftBukkit start + // CraftBukkit end + + public abstract class Entity implements INamableTileEntity, ICommandListener, KeyedObject { // Paper +@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke + + public void setPosition(double d0, double d1, double d2) { + this.setPositionRaw(d0, d1, d2); +- float f = this.size.width / 2.0F; +- float f1 = this.size.height; ++ // Paper start - move into setPositionRaw ++ //float f = this.size.width / 2.0F; ++ //float f1 = this.size.height; + +- this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f)); ++ //this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f)); ++ // Paper end + if (valid) ((WorldServer) world).chunkCheck(this); // CraftBukkit + } + +@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke + return new AxisAlignedBB(vec3d, vec3d1); + } + ++ public final void setBoundingBox(AxisAlignedBB axisalignedbb) { a(axisalignedbb); } // Paper - OBFHELPER + public void a(AxisAlignedBB axisalignedbb) { + // CraftBukkit start - block invalid bounding boxes + double minX = axisalignedbb.minX, +@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke + } + + public void setPositionRaw(double d0, double d1, double d2) { ++ // Paper start - never allow AABB to become desynced from position ++ // hanging has its own special logic ++ if (!(this instanceof EntityHanging) && (this.loc.x != d0 || this.loc.y != d1 || this.loc.z != d2)) { ++ float f = this.size.width / 2.0F; ++ float f1 = this.size.height; ++ this.setBoundingBox(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f)); ++ } ++ // Paper end + if (this.loc.x != d0 || this.loc.y != d1 || this.loc.z != d2) { + this.loc = new Vec3D(d0, d1, d2); + int i = MathHelper.floor(d0); diff --git a/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch b/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch new file mode 100644 index 0000000000..f8a714ef2d --- /dev/null +++ b/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch @@ -0,0 +1,93 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: kickash32 +Date: Sat, 27 Jun 2020 12:37:58 -0400 +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 @@ + package com.destroystokyo.paper; + +-import java.util.Arrays; +-import java.util.EnumMap; +-import java.util.HashMap; +-import java.util.List; +-import java.util.Map; +- + import com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray.EngineMode; + import org.bukkit.Bukkit; + import org.bukkit.Material; +@@ -0,0 +0,0 @@ import org.bukkit.configuration.ConfigurationSection; + import org.bukkit.configuration.file.YamlConfiguration; + import org.spigotmc.SpigotWorldConfig; + ++import java.util.Arrays; ++import java.util.EnumMap; ++import java.util.HashMap; ++import java.util.List; ++import java.util.Map; ++ + import static com.destroystokyo.paper.PaperConfig.log; + import static com.destroystokyo.paper.PaperConfig.logError; + +@@ -0,0 +0,0 @@ public class PaperWorldConfig { + delayChunkUnloadsBy *= 20; + } + } ++ ++ 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 ++ } ++ } + } +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 + } + + --this.lifeTicks; diff --git a/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch b/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch new file mode 100644 index 0000000000..9b2c2ce091 --- /dev/null +++ b/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: kickash32 +Date: Sat, 27 Jun 2020 14:23:16 -0400 +Subject: [PATCH] Optimize WorldBorder collision checks and air + + +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 + AxisAlignedBB axisalignedbb = this.getBoundingBox(); + VoxelShapeCollision voxelshapecollision = VoxelShapeCollision.a(this); + VoxelShape voxelshape = this.world.getWorldBorder().c(); +- Stream stream = VoxelShapes.c(voxelshape, VoxelShapes.a(axisalignedbb.shrink(1.0E-7D)), OperatorBoolean.AND) ? Stream.empty() : Stream.of(voxelshape); ++ Stream stream = !this.world.getWorldBorder().isInBounds(axisalignedbb) ? Stream.empty() : Stream.of(voxelshape); // Paper + Stream stream1 = this.world.c(this, axisalignedbb.b(vec3d), (entity) -> { + return true; + }); +diff --git a/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java b/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java ++++ b/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java +@@ -0,0 +0,0 @@ public class VoxelShapeSpliterator extends AbstractSpliterator { + AxisAlignedBB axisalignedbb = this.a.getBoundingBox(); + + if (!a(worldborder, axisalignedbb)) { +- VoxelShape voxelshape = worldborder.c(); +- +- if (!b(voxelshape, axisalignedbb) && a(voxelshape, axisalignedbb)) { +- consumer.accept(voxelshape); ++ // Paper start ++ if (worldborder.isInBounds(axisalignedbb.shrink(1.0E-7D)) && !worldborder.isInBounds(axisalignedbb.grow(1.0E-7D))) { ++ consumer.accept(worldborder.asVoxelShape()); ++ // Paper end + return true; + } + } +diff --git a/src/main/java/net/minecraft/server/VoxelShapes.java b/src/main/java/net/minecraft/server/VoxelShapes.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/VoxelShapes.java ++++ b/src/main/java/net/minecraft/server/VoxelShapes.java +@@ -0,0 +0,0 @@ public final class VoxelShapes { + IBlockData iblockdata = iworldreader.getTypeIfLoaded(blockposition_mutableblockposition); // Paper + if (iblockdata == null) return 0.0D; // Paper + +- if ((k2 != 1 || iblockdata.d()) && (k2 != 2 || iblockdata.a(Blocks.MOVING_PISTON))) { ++ if (!iblockdata.isAir() && (k2 != 1 || iblockdata.d()) && (k2 != 2 || iblockdata.a(Blocks.MOVING_PISTON))) { // Paper + d0 = iblockdata.b((IBlockAccess) iworldreader, blockposition_mutableblockposition, voxelshapecollision).a(enumdirection_enumaxis2, axisalignedbb.d((double) (-blockposition_mutableblockposition.getX()), (double) (-blockposition_mutableblockposition.getY()), (double) (-blockposition_mutableblockposition.getZ())), d0); + if (Math.abs(d0) < 1.0E-7D) { + return 0.0D; +diff --git a/src/main/java/net/minecraft/server/WorldBorder.java b/src/main/java/net/minecraft/server/WorldBorder.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/WorldBorder.java ++++ b/src/main/java/net/minecraft/server/WorldBorder.java +@@ -0,0 +0,0 @@ public class WorldBorder { + return (double) chunkcoordintpair.f() > this.e() && (double) chunkcoordintpair.d() < this.g() && (double) chunkcoordintpair.g() > this.f() && (double) chunkcoordintpair.e() < this.h(); + } + ++ public final boolean isInBounds(AxisAlignedBB aabb) { return this.a(aabb); } // Paper - OBFHELPER + public boolean a(AxisAlignedBB axisalignedbb) { + return axisalignedbb.maxX > this.e() && axisalignedbb.minX < this.g() && axisalignedbb.maxZ > this.f() && axisalignedbb.minZ < this.h(); + } From 76f7b1fde778a06d8572c665e2bd1e1462091b3b Mon Sep 17 00:00:00 2001 From: kickash32 Date: Sat, 27 Jun 2020 14:38:26 -0400 Subject: [PATCH 29/91] fix headers --- .../Add-permission-for-command-blocks.patch | 4 ++-- .../Ensure-Entity-AABB-s-are-never-invalid.patch | 4 ++-- .../Limit-lightning-strike-effect-distance.patch | 6 +++--- .../Optimize-WorldBorder-collision-checks-and-air.patch | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Spigot-Server-Patches/Add-permission-for-command-blocks.patch b/Spigot-Server-Patches/Add-permission-for-command-blocks.patch index 950a10be1b..1aac314e43 100644 --- a/Spigot-Server-Patches/Add-permission-for-command-blocks.patch +++ b/Spigot-Server-Patches/Add-permission-for-command-blocks.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kickash32 -Date: Sat, 27 Jun 2020 13:15:53 -0400 +From: Mariell Hoversholm +Date: Sat, 16 May 2020 10:05:30 +0200 Subject: [PATCH] Add permission for command blocks diff --git a/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch b/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch index c791b1fbe6..77f5bba843 100644 --- a/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch +++ b/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kickash32 -Date: Sat, 27 Jun 2020 13:32:39 -0400 +From: Aikar +Date: Sun, 10 May 2020 22:12:46 -0400 Subject: [PATCH] Ensure Entity AABB's are never invalid diff --git a/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch b/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch index f8a714ef2d..92dea53027 100644 --- a/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch +++ b/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kickash32 -Date: Sat, 27 Jun 2020 12:37:58 -0400 -Subject: [PATCH] Limit lightning strike effect distance +From: Aikar +Date: Mon, 17 Sep 2018 23:05:31 -0400 +Subject: [PATCH] Support Overriding World Seeds diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java diff --git a/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch b/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch index 9b2c2ce091..415bd8ddbc 100644 --- a/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch +++ b/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kickash32 -Date: Sat, 27 Jun 2020 14:23:16 -0400 +From: Spottedleaf +Date: Sun, 10 May 2020 22:49:05 -0400 Subject: [PATCH] Optimize WorldBorder collision checks and air From f496665f6790ccf985a4dec3234a8c9e171f58dd Mon Sep 17 00:00:00 2001 From: kickash32 Date: Sat, 27 Jun 2020 15:02:40 -0400 Subject: [PATCH 30/91] fixup --- ...mit-lightning-strike-effect-distance.patch | 31 ++----------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch b/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch index 92dea53027..92f46a1ca5 100644 --- a/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch +++ b/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch @@ -1,38 +1,13 @@ 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 +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 @@ - package com.destroystokyo.paper; - --import java.util.Arrays; --import java.util.EnumMap; --import java.util.HashMap; --import java.util.List; --import java.util.Map; -- - import com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray.EngineMode; - import org.bukkit.Bukkit; - import org.bukkit.Material; -@@ -0,0 +0,0 @@ import org.bukkit.configuration.ConfigurationSection; - import org.bukkit.configuration.file.YamlConfiguration; - import org.spigotmc.SpigotWorldConfig; - -+import java.util.Arrays; -+import java.util.EnumMap; -+import java.util.HashMap; -+import java.util.List; -+import java.util.Map; -+ - import static com.destroystokyo.paper.PaperConfig.log; - import static com.destroystokyo.paper.PaperConfig.logError; - @@ -0,0 +0,0 @@ public class PaperWorldConfig { delayChunkUnloadsBy *= 20; } From 5ead0fc8e0ff64487edd40eb3c628b978117c4bf Mon Sep 17 00:00:00 2001 From: Omer Uddin Date: Sat, 27 Jun 2020 16:00:08 -0400 Subject: [PATCH 31/91] Fix comment mistake --- .../Limit-lightning-strike-effect-distance.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch b/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch index 92f46a1ca5..1fe55e6757 100644 --- a/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch +++ b/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch @@ -62,7 +62,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // 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 ++// 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; From d661902f52db5bd16a80f37e4bfaa374f072660a Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 27 Jun 2020 17:37:09 -0400 Subject: [PATCH 32/91] Updated Upstream (CraftBukkit) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing CraftBukkit Changes: 983305bb SPIGOT-5856: Soul Campfire BlockState cannot be cast to Campfire --- work/CraftBukkit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/work/CraftBukkit b/work/CraftBukkit index d424351010..983305bb4a 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit d4243510102530684b860dbe927311bf47c488db +Subproject commit 983305bb4a8601367e31f44b691f6e598bde9d0c From 5b8bdf1dbc247cf57253c9d4f6cb8d200d1b5e01 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 27 Jun 2020 20:32:49 -0400 Subject: [PATCH 33/91] Fix Piglin issue --- Spigot-Server-Patches/FIX-DIS-SHIT.patch | 64 ------------------------ Spigot-Server-Patches/MC-Dev-fixes.patch | 43 ++++++++++++++++ 2 files changed, 43 insertions(+), 64 deletions(-) delete mode 100644 Spigot-Server-Patches/FIX-DIS-SHIT.patch diff --git a/Spigot-Server-Patches/FIX-DIS-SHIT.patch b/Spigot-Server-Patches/FIX-DIS-SHIT.patch deleted file mode 100644 index 9216d714b7..0000000000 --- a/Spigot-Server-Patches/FIX-DIS-SHIT.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MiniDigger | Martin -Date: Fri, 26 Jun 2020 16:51:44 +0200 -Subject: [PATCH] FIX DIS SHIT - - -diff --git a/src/main/java/net/minecraft/server/SensorHoglinSpecific.java b/src/main/java/net/minecraft/server/SensorHoglinSpecific.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/SensorHoglinSpecific.java -+++ b/src/main/java/net/minecraft/server/SensorHoglinSpecific.java -@@ -0,0 +0,0 @@ public class SensorHoglinSpecific extends Sensor { - protected void a(WorldServer worldserver, EntityHoglin entityhoglin) { - BehaviorController behaviorcontroller = entityhoglin.getBehaviorController(); - -- behaviorcontroller.setMemory(MemoryModuleType.NEAREST_REPELLENT, this.b(worldserver, entityhoglin)); -+ // behaviorcontroller.setMemory(MemoryModuleType.NEAREST_REPELLENT, this.bb(worldserver, entityhoglin)); // Paper - fix dis shit (for now) + rename - Optional optional = Optional.empty(); - int i = 0; - List list = Lists.newArrayList(); -@@ -0,0 +0,0 @@ public class SensorHoglinSpecific extends Sensor { - } - - behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLIN, optional); -- behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_HOGLINS, (Object) list); -- behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT, (Object) i); -- behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT, (Object) list.size()); -+ behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_HOGLINS, list); // Paper - decomp fix -+ behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT, i); // Paper - decomp fix -+ behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT, list.size()); // Paper - decomp fix - } - -- private Optional b(WorldServer worldserver, EntityHoglin entityhoglin) { -+ private Optional bb(WorldServer worldserver, EntityHoglin entityhoglin) { // Paper - rename - return BlockPosition.a(entityhoglin.getChunkCoordinates(), 8, 4, (blockposition) -> { - return worldserver.getType(blockposition).a((Tag) TagsBlock.HOGLIN_REPELLENTS); - }); -diff --git a/src/main/java/net/minecraft/server/SensorPiglinSpecific.java b/src/main/java/net/minecraft/server/SensorPiglinSpecific.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/SensorPiglinSpecific.java -+++ b/src/main/java/net/minecraft/server/SensorPiglinSpecific.java -@@ -0,0 +0,0 @@ public class SensorPiglinSpecific extends Sensor { - protected void a(WorldServer worldserver, EntityLiving entityliving) { - BehaviorController behaviorcontroller = entityliving.getBehaviorController(); - -- behaviorcontroller.setMemory(MemoryModuleType.NEAREST_REPELLENT, c(worldserver, entityliving)); -+// behaviorcontroller.setMemory(MemoryModuleType.NEAREST_REPELLENT, c(worldserver, entityliving)); // Paper - fix dis shit (for now) - Optional optional = Optional.empty(); - Optional optional1 = Optional.empty(); - Optional optional2 = Optional.empty(); -@@ -0,0 +0,0 @@ public class SensorPiglinSpecific extends Sensor { - behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED, optional4); - behaviorcontroller.setMemory(MemoryModuleType.NEAREST_TARGETABLE_PLAYER_NOT_WEARING_GOLD, optional5); - behaviorcontroller.setMemory(MemoryModuleType.NEAREST_PLAYER_HOLDING_WANTED_ITEM, optional6); -- behaviorcontroller.setMemory(MemoryModuleType.NEAREST_ADULT_PIGLINS, (Object) list1); -- behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLINS, (Object) list); -- behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT, (Object) list.size()); -- behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT, (Object) i); -+ behaviorcontroller.setMemory(MemoryModuleType.NEAREST_ADULT_PIGLINS, list1); // Paper - decomp fix -+ behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLINS, list); // Paper - decomp fix -+ behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT, list.size()); // Paper - decomp fix -+ behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT, i); // Paper - decomp fix - } - - private static Optional c(WorldServer worldserver, EntityLiving entityliving) { diff --git a/Spigot-Server-Patches/MC-Dev-fixes.patch b/Spigot-Server-Patches/MC-Dev-fixes.patch index 9e0d8921a5..1835b78734 100644 --- a/Spigot-Server-Patches/MC-Dev-fixes.patch +++ b/Spigot-Server-Patches/MC-Dev-fixes.patch @@ -232,6 +232,49 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } return biomebase; +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 { + }; + } + +- public static Iterable a(BlockPosition blockposition, int i, int j, int k) { +- int l = i + j + k; ++ public static Iterable a(BlockPosition blockposition, int p_i, int p_j, int p_k) { // Paper - decompile issues - variable name conflicts to inner class field refs ++ int l_decompiled = p_i + p_j + p_k; // Paper - decompile issues + int i1 = blockposition.getX(); + int j1 = blockposition.getY(); + int k1 = blockposition.getZ(); +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { + ++this.l; + if (this.l > this.j) { + ++this.i; +- if (this.i > l) { ++ if (this.i > l_decompiled) { // Paper - use proper l above (first line of this method) + return (BlockPosition) this.endOfData(); + } + +- this.j = Math.min(i, this.i); ++ this.j = Math.min(p_i, this.i); // Paper - decompile issues + this.l = -this.j; + } + +- this.k = Math.min(j, this.i - Math.abs(this.l)); ++ this.k = Math.min(p_j, this.i - Math.abs(this.l)); // Paper - decompile issues + this.m = -this.k; + } + +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { + int i2 = this.m; + int j2 = this.i - Math.abs(l1) - Math.abs(i2); + +- if (j2 <= k) { ++ if (j2 <= p_k) { // Paper - decompile issues + this.n = j2 != 0; + blockposition_mutableblockposition = this.h.d(i1 + l1, j1 + i2, k1 + j2); + } diff --git a/src/main/java/net/minecraft/server/BlockStateEnum.java b/src/main/java/net/minecraft/server/BlockStateEnum.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockStateEnum.java From e1088e833cb2926548cc6a8b1e8ca53c710bce77 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 27 Jun 2020 21:54:05 -0400 Subject: [PATCH 34/91] Updated Upstream (Bukkit/CraftBukkit/Spigot) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: f009c3dd SPIGOT-5810, SPIGOT-5835: 'Better' handling of Player.isOnGround e677c370 Update ECJ version 5058a35d SPIGOT-5860: Item.setItemStack should be NotNull CraftBukkit Changes: d77f4d9b SPIGOT-5810, SPIGOT-5835: 'Better' handling of Player.isOnGround 53c95627 SPIGOT-5865: Piglin does not trigger EntityPickupItemEvent 2ab04d24 Update ECJ version 7884e079 SPIGOT-5868: Blocks do not tick in custom nether / end 2a848286 SPIGOT-5863: Don't check colour in scoreboard length validation f2cbce30 SPIGOT-5866: Beehive unknown TargetReason Spigot Changes: ad703da0 SPIGOT-5870: /plugins "website" field shows "version" 1a27cfd8 #98: Improve output of /plugins command using text components 732d5bab Disable checkstyle in Spigot blocks 0199a9a6 #97: Add Memory Usage to Ticks Per Second Command. 33ea98fc SPIGOT-5858: NPE: Joining the server with an invalid dimension --- ...etters-and-setters-for-EntityItem-owner-a.patch | 5 +++-- .../Make-plugins-list-alphabetical.patch | 9 +++++---- .../Further-improve-server-tick-loop.patch | 14 ++++---------- .../No-Tick-view-distance-implementation.patch | 9 --------- ...twork-Manager-and-add-advanced-packet-sup.patch | 12 ++++++------ ...ition-desync-in-playerconnection-causing-.patch | 2 +- work/Bukkit | 2 +- work/CraftBukkit | 2 +- work/Spigot | 2 +- 9 files changed, 22 insertions(+), 35 deletions(-) diff --git a/Spigot-API-Patches/Implement-getters-and-setters-for-EntityItem-owner-a.patch b/Spigot-API-Patches/Implement-getters-and-setters-for-EntityItem-owner-a.patch index f225ec418f..02d2f77fd6 100644 --- a/Spigot-API-Patches/Implement-getters-and-setters-for-EntityItem-owner-a.patch +++ b/Spigot-API-Patches/Implement-getters-and-setters-for-EntityItem-owner-a.patch @@ -9,11 +9,12 @@ diff --git a/src/main/java/org/bukkit/entity/Item.java b/src/main/java/org/bukki index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/entity/Item.java +++ b/src/main/java/org/bukkit/entity/Item.java -@@ -0,0 +0,0 @@ import org.bukkit.inventory.ItemStack; +@@ -0,0 +0,0 @@ package org.bukkit.entity; + import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; - import org.jetbrains.annotations.Nullable; +// Paper start ++import org.jetbrains.annotations.Nullable; +import java.util.UUID; +// Paper end + diff --git a/Spigot-API-Patches/Make-plugins-list-alphabetical.patch b/Spigot-API-Patches/Make-plugins-list-alphabetical.patch index 806b80c559..453af989b1 100644 --- a/Spigot-API-Patches/Make-plugins-list-alphabetical.patch +++ b/Spigot-API-Patches/Make-plugins-list-alphabetical.patch @@ -26,12 +26,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - Plugin[] plugins = Bukkit.getPluginManager().getPlugins(); + // Paper start + TreeMap plugins = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); -+ + +- for (Plugin plugin : plugins) { + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + plugins.put(plugin.getDescription().getName(), plugin); + } - -- for (Plugin plugin : plugins) { ++ + StringBuilder pluginList = new StringBuilder(); + for (Map.Entry entry : plugins.entrySet()) { if (pluginList.length() > 0) { @@ -56,4 +56,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return "(" + plugins.size() + "): " + pluginList.toString(); + // Paper end } - } + + // Spigot start diff --git a/Spigot-Server-Patches/Further-improve-server-tick-loop.patch b/Spigot-Server-Patches/Further-improve-server-tick-loop.patch index fae090a2e7..609a0eb41c 100644 --- a/Spigot-Server-Patches/Further-improve-server-tick-loop.patch +++ b/Spigot-Server-Patches/Further-improve-server-tick-loop.patch @@ -165,15 +165,6 @@ diff --git a/src/main/java/org/spigotmc/TicksPerSecondCommand.java b/src/main/ja index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/spigotmc/TicksPerSecondCommand.java +++ b/src/main/java/org/spigotmc/TicksPerSecondCommand.java -@@ -0,0 +0,0 @@ - package org.spigotmc; - --import com.google.common.base.Joiner; --import net.minecraft.server.MinecraftServer; --import com.google.common.collect.Iterables; - import org.bukkit.ChatColor; - import org.bukkit.command.Command; - import org.bukkit.command.CommandSender; @@ -0,0 +0,0 @@ public class TicksPerSecondCommand extends Command return true; } @@ -191,7 +182,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + tpsAvg[i] = format( tps[i] ); } - sender.sendMessage( sb.substring( 0, sb.length() - 2 ) ); -+ sender.sendMessage( ChatColor.GOLD + "TPS from last 1m, 5m, 15m: " + org.apache.commons.lang.StringUtils.join(tpsAvg, ", ")); +- sender.sendMessage(ChatColor.GOLD + "Current Memory Usage: " + ChatColor.GREEN + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)) + "/" + (Runtime.getRuntime().totalMemory() / (1024 * 1024)) + " mb (Max: " +- + (Runtime.getRuntime().maxMemory() / (1024 * 1024)) + " mb)"); ++ sender.sendMessage(ChatColor.GOLD + "TPS from last 1m, 5m, 15m: " + org.apache.commons.lang.StringUtils.join(tpsAvg, ", ")); ++ sender.sendMessage(ChatColor.GOLD + "Current Memory Usage: " + ChatColor.GREEN + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)) + "/" + (Runtime.getRuntime().totalMemory() / (1024 * 1024)) + " mb (Max: " + (Runtime.getRuntime().maxMemory() / (1024 * 1024)) + " mb)"); + // Paper end return true; diff --git a/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch b/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch index 47ac87a183..98dc5153bd 100644 --- a/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch +++ b/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch @@ -556,15 +556,6 @@ diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/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 { - - // Spigot - view distance - networkmanager.queueImmunity = true; // Paper -- 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())); -+ 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(), worldserver1.getChunkProvider().playerChunkMap.getLoadViewDistance(), flag1, !flag, worldserver1.isDebugWorld(), worldserver1.isFlatWorld())); // Paper - no-tick view distance - entityplayer.getBukkitEntity().sendSupportedChannels(); // CraftBukkit - playerconnection.sendPacket(new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.a, (new PacketDataSerializer(Unpooled.buffer())).a(this.getServer().getServerModName()))); - playerconnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); @@ -0,0 +0,0 @@ public abstract class PlayerList { // CraftBukkit start WorldData worlddata = worldserver1.getWorldData(); 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 135054489f..0160bc2f3e 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 @@ -342,13 +342,13 @@ 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); - - // Spigot - view distance + entityplayer.playerInteractManager.a((WorldServer) entityplayer.world); + entityplayer.setPositionRaw(loc.getX(), loc.getY(), loc.getZ()); // Paper - set raw so we aren't fully joined to the world (not added to chunk or world) + entityplayer.setYawPitch(loc.getYaw(), loc.getPitch()); + networkmanager.queueImmunity = true; // Paper - 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()))); + // Spigot end + + // CraftBukkit - Moved message to after join @@ -0,0 +0,0 @@ public abstract class PlayerList { playerconnection.sendPacket(new PacketPlayOutRecipeUpdate(this.server.getCraftingManager().b())); playerconnection.sendPacket(new PacketPlayOutTags(this.server.getTagRegistry())); diff --git a/Spigot-Server-Patches/Prevent-position-desync-in-playerconnection-causing-.patch b/Spigot-Server-Patches/Prevent-position-desync-in-playerconnection-causing-.patch index a503eadde2..8058812e0d 100644 --- a/Spigot-Server-Patches/Prevent-position-desync-in-playerconnection-causing-.patch +++ b/Spigot-Server-Patches/Prevent-position-desync-in-playerconnection-causing-.patch @@ -18,9 +18,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { - } this.player.move(EnumMoveType.PLAYER, new Vec3D(d7, d8, d9)); + this.player.c(packetplayinflying.b()); // CraftBukkit - SPIGOT-5810, SPIGOT-5835: reset by this.player.move + // Paper start - prevent position desync + if (this.teleportPos != null) { + return; // ... thanks Mojang for letting move calls teleport across dimensions. diff --git a/work/Bukkit b/work/Bukkit index 3284612a10..f009c3dd94 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 3284612a10e704b4658aa087213a3fa9670b6926 +Subproject commit f009c3dd945c627246b383aa4ffad63a067df9ff diff --git a/work/CraftBukkit b/work/CraftBukkit index 983305bb4a..d77f4d9bf3 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 983305bb4a8601367e31f44b691f6e598bde9d0c +Subproject commit d77f4d9bf348534a2a5b2498d0ea7fbe5297521c diff --git a/work/Spigot b/work/Spigot index 6f4ff1b691..ad703da04d 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit 6f4ff1b691828e538ae534eac66e80a1bf2c1adf +Subproject commit ad703da04d2ffbf84a75e5ee32f2829380864bb7 From c5ee34df0eee0b9b5a40600eaabcf6a8077f176b Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sun, 28 Jun 2020 00:58:25 -0400 Subject: [PATCH 35/91] Fix missing chunks on client (View distance issue) --- .../Improved-Watchdog-Support.patch | 1 + Spigot-Server-Patches/MC-Dev-fixes.patch | 13 ----------- ...No-Tick-view-distance-implementation.patch | 23 +++++++++++++++++++ Spigot-Server-Patches/Optimize-Hoppers.patch | 6 ++++- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/Spigot-Server-Patches/Improved-Watchdog-Support.patch b/Spigot-Server-Patches/Improved-Watchdog-Support.patch index 64ca73bee5..fba8cd5b50 100644 --- a/Spigot-Server-Patches/Improved-Watchdog-Support.patch +++ b/Spigot-Server-Patches/Improved-Watchdog-Support.patch @@ -415,6 +415,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Minecraft, seen during saving + tryPreloadClass("net.minecraft.server.LightEngineLayerEventListener$Void"); + tryPreloadClass("net.minecraft.server.LightEngineLayerEventListener"); ++ tryPreloadClass("net.minecraft.server.ExceptionSuppressor"); + // Paper end + } + } diff --git a/Spigot-Server-Patches/MC-Dev-fixes.patch b/Spigot-Server-Patches/MC-Dev-fixes.patch index 1835b78734..7c1d4d68fc 100644 --- a/Spigot-Server-Patches/MC-Dev-fixes.patch +++ b/Spigot-Server-Patches/MC-Dev-fixes.patch @@ -49,19 +49,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } else { System.arraycopy(this.b, 0, au, 0, this.c); if (au.length > this.c) { -diff --git a/src/main/java/net/minecraft/server/BehaviorFindPosition.java b/src/main/java/net/minecraft/server/BehaviorFindPosition.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BehaviorFindPosition.java -+++ b/src/main/java/net/minecraft/server/BehaviorFindPosition.java -@@ -0,0 +0,0 @@ public class BehaviorFindPosition extends Behavior { - villageplace.a(this.b.c(), (blockposition1) -> { - return blockposition1.equals(blockposition); - }, blockposition, 1); -- entitycreature.getBehaviorController().setMemory(this.c, (Object) GlobalPos.create(worldserver.getDimensionKey(), blockposition)); -+ entitycreature.getBehaviorController().setMemory(this.c, GlobalPos.create(worldserver.getDimensionKey(), blockposition)); // Paper - decompile fix - this.f.clear(); - PacketDebug.c(worldserver, blockposition); - }); diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BiomeBase.java diff --git a/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch b/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch index 98dc5153bd..9bfc48e522 100644 --- a/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch +++ b/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch @@ -127,6 +127,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public EntityPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) { super(worldserver, worldserver.getSpawn(), gameprofile); this.spawnDimension = World.OVERWORLD; +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 ++++ b/src/main/java/net/minecraft/server/MCUtil.java +@@ -0,0 +0,0 @@ public final class MCUtil { + }); + + worldData.addProperty("name", world.getWorld().getName()); +- worldData.addProperty("view-distance", world.spigotConfig.viewDistance); ++ worldData.addProperty("view-distance", world.getChunkProvider().playerChunkMap.getEffectiveViewDistance()); ++ worldData.addProperty("no-view-distance", world.getChunkProvider().playerChunkMap.getRawNoTickViewDistance()); + worldData.addProperty("keep-spawn-loaded", world.keepSpawnInMemory); + worldData.addProperty("keep-spawn-loaded-range", world.paperConfig.keepLoadedRange); + worldData.addProperty("visible-chunk-count", visibleChunks.size()); 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 @@ -556,6 +570,15 @@ diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/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 { + boolean flag1 = gamerules.getBoolean(GameRules.REDUCED_DEBUG_INFO); + + // Spigot - view distance +- 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(), worldserver1.spigotConfig.viewDistance, flag1, !flag, worldserver1.isDebugWorld(), worldserver1.isFlatWorld())); ++ 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.getChunkProvider().playerChunkMap.getLoadViewDistance(), flag1, !flag, worldserver1.isDebugWorld(), worldserver1.isFlatWorld())); // Paper - no-tick view distance + entityplayer.getBukkitEntity().sendSupportedChannels(); // CraftBukkit + playerconnection.sendPacket(new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.a, (new PacketDataSerializer(Unpooled.buffer())).a(this.getServer().getServerModName()))); + playerconnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); @@ -0,0 +0,0 @@ public abstract class PlayerList { // CraftBukkit start WorldData worlddata = worldserver1.getWorldData(); diff --git a/Spigot-Server-Patches/Optimize-Hoppers.patch b/Spigot-Server-Patches/Optimize-Hoppers.patch index 47ee597893..6b274f9d54 100644 --- a/Spigot-Server-Patches/Optimize-Hoppers.patch +++ b/Spigot-Server-Patches/Optimize-Hoppers.patch @@ -370,7 +370,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Iterator iterator = c(ihopper).iterator(); @@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi - private static boolean a(IHopper ihopper, IInventory iinventory, int i, EnumDirection enumdirection) { + } + } + +- private static boolean a(IHopper ihopper, IInventory iinventory, int i, EnumDirection enumdirection) { ++ private static boolean a(IHopper ihopper, IInventory iinventory, int i, EnumDirection enumdirection) {// Paper - method unused as logic is inlined above ItemStack itemstack = iinventory.getItem(i); - if (!itemstack.isEmpty() && b(iinventory, itemstack, i, enumdirection)) { From 20018f2b4f9533f019b17d2d77e27c2ffd2eb6c1 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 01:29:54 -0400 Subject: [PATCH 36/91] Disable the memory information in /tps unless argument is passed Memory usage is a pretty useless value in any modern garbage collector as the way memory is used makes this information not representive of any actionable data. In the recommended GC flags, this memory value will constantly rise until it is near max and then goes down. This is perfectly normal and expected. Having this information shown will lead to confusion. Plus, many servers give this command to end users, which now really might not want to expose this memory data. So this disables it unless /tps mem is used, and also requires a permission node to even run this subcommand. --- .../Further-improve-server-tick-loop.patch | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Spigot-Server-Patches/Further-improve-server-tick-loop.patch b/Spigot-Server-Patches/Further-improve-server-tick-loop.patch index 609a0eb41c..9963ca01c4 100644 --- a/Spigot-Server-Patches/Further-improve-server-tick-loop.patch +++ b/Spigot-Server-Patches/Further-improve-server-tick-loop.patch @@ -180,18 +180,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + for ( int i = 0; i < tps.length; i++) { + tpsAvg[i] = format( tps[i] ); ++ } ++ sender.sendMessage(ChatColor.GOLD + "TPS from last 1m, 5m, 15m: " + org.apache.commons.lang.StringUtils.join(tpsAvg, ", ")); ++ if (args.length > 0 && args[0].equals("mem") && sender.hasPermission("bukkit.command.tpsmemory")) { ++ sender.sendMessage(ChatColor.GOLD + "Current Memory Usage: " + ChatColor.GREEN + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)) + "/" + (Runtime.getRuntime().totalMemory() / (1024 * 1024)) + " mb (Max: " + (Runtime.getRuntime().maxMemory() / (1024 * 1024)) + " mb)"); ++ if (!hasShownMemoryWarning) { ++ sender.sendMessage(ChatColor.RED + "Warning: " + ChatColor.GOLD + " Memory usage on modern garbage collectors is not a stable value and it is perfectly normal to see it reach max. Please do not pay it much attention."); ++ hasShownMemoryWarning = true; ++ } } - sender.sendMessage( sb.substring( 0, sb.length() - 2 ) ); - sender.sendMessage(ChatColor.GOLD + "Current Memory Usage: " + ChatColor.GREEN + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)) + "/" + (Runtime.getRuntime().totalMemory() / (1024 * 1024)) + " mb (Max: " - + (Runtime.getRuntime().maxMemory() / (1024 * 1024)) + " mb)"); -+ sender.sendMessage(ChatColor.GOLD + "TPS from last 1m, 5m, 15m: " + org.apache.commons.lang.StringUtils.join(tpsAvg, ", ")); -+ sender.sendMessage(ChatColor.GOLD + "Current Memory Usage: " + ChatColor.GREEN + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)) + "/" + (Runtime.getRuntime().totalMemory() / (1024 * 1024)) + " mb (Max: " + (Runtime.getRuntime().maxMemory() / (1024 * 1024)) + " mb)"); + // Paper end return true; } - private String format(double tps) ++ private boolean hasShownMemoryWarning; // Paper + private static String format(double tps) // Paper - Made static { return ( ( tps > 18.0 ) ? ChatColor.GREEN : ( tps > 16.0 ) ? ChatColor.YELLOW : ChatColor.RED ).toString() From 53ea88badf1573fc3a5f873878786effad96d8b8 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 04:01:01 -0400 Subject: [PATCH 37/91] Fix Per World Difficulty / Remembering Difficulty Fixes per world difficulty with /difficulty command and also makes it so that the server keeps the last difficulty used instead of restoring the server.properties every single load. --- ...ld-Difficulty-Remembering-Difficulty.patch | 77 +++++++++++++++++++ .../Improved-Watchdog-Support.patch | 1 + 2 files changed, 78 insertions(+) create mode 100644 Spigot-Server-Patches/Fix-Per-World-Difficulty-Remembering-Difficulty.patch diff --git a/Spigot-Server-Patches/Fix-Per-World-Difficulty-Remembering-Difficulty.patch b/Spigot-Server-Patches/Fix-Per-World-Difficulty-Remembering-Difficulty.patch new file mode 100644 index 0000000000..de1a6466b3 --- /dev/null +++ b/Spigot-Server-Patches/Fix-Per-World-Difficulty-Remembering-Difficulty.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 28 Jun 2020 03:59:10 -0400 +Subject: [PATCH] Fix Per World Difficulty / Remembering Difficulty + +Fixes per world difficulty with /difficulty command and also +makes it so that the server keeps the last difficulty used instead +of restoring the server.properties every single load. + +diff --git a/src/main/java/net/minecraft/server/CommandDifficulty.java b/src/main/java/net/minecraft/server/CommandDifficulty.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/CommandDifficulty.java ++++ b/src/main/java/net/minecraft/server/CommandDifficulty.java +@@ -0,0 +0,0 @@ public class CommandDifficulty { + public static int a(CommandListenerWrapper commandlistenerwrapper, EnumDifficulty enumdifficulty) throws CommandSyntaxException { + MinecraftServer minecraftserver = commandlistenerwrapper.getServer(); + +- if (minecraftserver.getSaveData().getDifficulty() == enumdifficulty) { ++ WorldServer world = commandlistenerwrapper.getWorld(); // Paper ++ if (world.worldDataServer.getDifficulty() == enumdifficulty) { // Paper + throw CommandDifficulty.a.create(enumdifficulty.c()); + } else { +- minecraftserver.a(enumdifficulty, true); ++ minecraftserver.a(world, enumdifficulty, true); // Paper + commandlistenerwrapper.sendMessage(new ChatMessage("commands.difficulty.success", new Object[]{enumdifficulty.b()}), true); + return 0; + } +diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/DedicatedServer.java ++++ b/src/main/java/net/minecraft/server/DedicatedServer.java +@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer + + @Override + public void updateWorldSettings() { +- this.a(this.getDedicatedServerProperties().difficulty, true); ++ //this.a(this.getDedicatedServerProperties().difficulty, true); // Paper - Don't overwrite level.dat's difficulty, keep current + } + + @Override +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 Date: Sun, 28 Jun 2020 04:21:40 -0400 Subject: [PATCH 38/91] Fix null pointer in portal search config --- .../Add-configurable-portal-search-radius.patch | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch b/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch index ed9e673a98..0763d4b3ec 100644 --- a/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch +++ b/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch @@ -42,7 +42,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Location enter = this.getBukkitEntity().getLocation(); Location exit = (worldserver == null) ? null : new Location(worldserver.getWorld(), d0, d1, d2, f1, f); - PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, resourcekey == DimensionManager.THE_END ? 0 : 16); -+ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, worldserver.paperConfig.portalSearchRadius, true, resourcekey == DimensionManager.THE_END ? 0 : worldserver.paperConfig.portalCreateRadius); ++ com.destroystokyo.paper.PaperWorldConfig config = worldserver != null ? worldserver.paperConfig : worldserver1.paperConfig; // Paper - portal radius ++ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, config.portalSearchRadius, true, resourcekey == DimensionManager.THE_END ? 0 : config.portalCreateRadius); // Paper - portal radius Bukkit.getServer().getPluginManager().callEvent(event); if (event.isCancelled() || event.getTo() == null) { return null; From d0a723841a1a25095be57af897ab52bf5c5a7240 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 04:35:41 -0400 Subject: [PATCH 39/91] Remove no longer needed undead horse leash patch This is now default vanilla behavior Fixes #3644 --- ...urable-Non-Player-Arrow-Despawn-Rate.patch | 4 +- .../Undead-horse-leashing.patch | 52 ------------------- 2 files changed, 2 insertions(+), 54 deletions(-) delete mode 100644 Spigot-Server-Patches/Undead-horse-leashing.patch diff --git a/Spigot-Server-Patches/Configurable-Non-Player-Arrow-Despawn-Rate.patch b/Spigot-Server-Patches/Configurable-Non-Player-Arrow-Despawn-Rate.patch index 93705f7192..ec1cd10e36 100644 --- a/Spigot-Server-Patches/Configurable-Non-Player-Arrow-Despawn-Rate.patch +++ b/Spigot-Server-Patches/Configurable-Non-Player-Arrow-Despawn-Rate.patch @@ -10,8 +10,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 { - private void allowLeashingUndeadHorse() { - allowLeashingUndeadHorse = getBoolean("allow-leashing-undead-horse", false); + private void nonPlayerEntitiesOnScoreboards() { + nonPlayerEntitiesOnScoreboards = getBoolean("allow-non-player-entities-on-scoreboards", false); } + + public int nonPlayerArrowDespawnRate = -1; diff --git a/Spigot-Server-Patches/Undead-horse-leashing.patch b/Spigot-Server-Patches/Undead-horse-leashing.patch deleted file mode 100644 index ab489e5730..0000000000 --- a/Spigot-Server-Patches/Undead-horse-leashing.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Fri, 18 Mar 2016 14:19:19 -0400 -Subject: [PATCH] Undead horse leashing - -default false to match vanilla, but option to allow undead horse types to be leashed. - -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 nonPlayerEntitiesOnScoreboards() { - nonPlayerEntitiesOnScoreboards = getBoolean("allow-non-player-entities-on-scoreboards", false); - } -+ -+ public boolean allowLeashingUndeadHorse = false; -+ private void allowLeashingUndeadHorse() { -+ allowLeashingUndeadHorse = getBoolean("allow-leashing-undead-horse", false); -+ } - } -diff --git a/src/main/java/net/minecraft/server/EntityHorseAbstract.java b/src/main/java/net/minecraft/server/EntityHorseAbstract.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/EntityHorseAbstract.java -+++ b/src/main/java/net/minecraft/server/EntityHorseAbstract.java -@@ -0,0 +0,0 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven - this.bx = flag; - } - -+ // Paper start -+ @Override -+ public boolean a(EntityHuman entityhuman) { -+ return world.paperConfig.allowLeashingUndeadHorse ? super.a(entityhuman) : super.a(entityhuman) && this.getMonsterType() != EnumMonsterType.UNDEAD; // Paper -+ } -+ // Paper end -+ - @Override - protected void t(float f) { - if (f > 6.0F && this.fa()) { -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 { - - } - -- public boolean a(EntityHuman entityhuman) { -+ public boolean a(EntityHuman entityhuman) { // Paper - overriden in EntityHorseAbstract - return !this.isLeashed() && !(this instanceof IMonster); - } - From fcd156a98ea07e36cc9da8f1da557c9e51bb2149 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Sun, 28 Jun 2020 09:43:47 +0100 Subject: [PATCH 40/91] Fix missing hunk from ProfileWhitelistVerifyEvent (Fixes #3645) --- Spigot-Server-Patches/ProfileWhitelistVerifyEvent.patch | 5 ++++- .../Use-ConcurrentHashMap-in-JsonList.patch | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Spigot-Server-Patches/ProfileWhitelistVerifyEvent.patch b/Spigot-Server-Patches/ProfileWhitelistVerifyEvent.patch index d9429a8cb8..283d860642 100644 --- a/Spigot-Server-Patches/ProfileWhitelistVerifyEvent.patch +++ b/Spigot-Server-Patches/ProfileWhitelistVerifyEvent.patch @@ -9,8 +9,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 { + + // return chatmessage; if (!gameprofilebanentry.hasExpired()) event.disallow(PlayerLoginEvent.Result.KICK_BANNED, CraftChatMessage.fromComponent(chatmessage)); // Spigot - } else if (!this.isWhitelisted(gameprofile)) { +- } else if (!this.isWhitelisted(gameprofile)) { ++ } else if (!this.isWhitelisted(gameprofile, event)) { // Paper chatmessage = new ChatMessage("multiplayer.disconnect.not_whitelisted"); - event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot + //event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot // Paper - moved to isWhitelisted diff --git a/Spigot-Server-Patches/Use-ConcurrentHashMap-in-JsonList.patch b/Spigot-Server-Patches/Use-ConcurrentHashMap-in-JsonList.patch index 7fbff83acb..24eca627b3 100644 --- a/Spigot-Server-Patches/Use-ConcurrentHashMap-in-JsonList.patch +++ b/Spigot-Server-Patches/Use-ConcurrentHashMap-in-JsonList.patch @@ -126,7 +126,7 @@ 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 { - } else if (!this.isWhitelisted(gameprofile)) { + } else if (!this.isWhitelisted(gameprofile, event)) { // Paper 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()) { From c09346c7986004469442f0dcb124ed903243c73e Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 05:13:46 -0400 Subject: [PATCH 41/91] Revert recent changes around player skulls using user cache --- .../Basic-PlayerProfile-API.patch | 42 ------------------- 1 file changed, 42 deletions(-) diff --git a/Spigot-Server-Patches/Basic-PlayerProfile-API.patch b/Spigot-Server-Patches/Basic-PlayerProfile-API.patch index 0fa7b80c05..6c12813824 100644 --- a/Spigot-Server-Patches/Basic-PlayerProfile-API.patch +++ b/Spigot-Server-Patches/Basic-PlayerProfile-API.patch @@ -473,48 +473,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public MinecraftSessionService getMinecraftSessionService() { return this.minecraftSessionService; } -diff --git a/src/main/java/net/minecraft/server/TileEntitySkull.java b/src/main/java/net/minecraft/server/TileEntitySkull.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/TileEntitySkull.java -+++ b/src/main/java/net/minecraft/server/TileEntitySkull.java -@@ -0,0 +0,0 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa - private void f() { - // Spigot start - GameProfile profile = this.gameProfile; -+ if (profile != null && profile.isComplete() && profile.getProperties().containsKey("textures")) return; // Paper - b(profile, new Predicate() { - - @Override -@@ -0,0 +0,0 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa - } else if (MinecraftServer.getServer() == null) { - callback.apply(gameprofile); - } else { -- GameProfile profile = skinCache.getIfPresent(gameprofile.getName().toLowerCase(java.util.Locale.ROOT)); -+ // Paper start -+ com.destroystokyo.paper.profile.CraftPlayerProfile paperProfile = new com.destroystokyo.paper.profile.CraftPlayerProfile(gameprofile); -+ if (sync) { -+ // might complete by cache, but if not, go ahead and do it now, avoid the code below -+ paperProfile.complete(true, true); -+ } else { -+ paperProfile.completeFromCache(false, true); -+ } -+ GameProfile profile = paperProfile.getGameProfile(); -+ // Paper end - if (profile != null && Iterables.getFirst(profile.getProperties().get("textures"), (Object) null) != null) { - callback.apply(profile); - -@@ -0,0 +0,0 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa - Callable callable = new Callable() { - @Override - public GameProfile call() { -- final GameProfile profile = skinCache.getUnchecked(gameprofile.getName().toLowerCase(java.util.Locale.ROOT)); -+ // Paper start -+ paperProfile.complete(true, true); -+ final GameProfile profile = paperProfile.getGameProfile(); -+ // Paper end - MinecraftServer.getServer().processQueue.add(new Runnable() { - @Override - public void run() { diff --git a/src/main/java/net/minecraft/server/UserCache.java b/src/main/java/net/minecraft/server/UserCache.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/UserCache.java From 900f77fa664675ad4bb02b270ca844ab16d7aaf5 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 05:34:23 -0400 Subject: [PATCH 42/91] Log Minecraft Internal Scheduler logs correctly --- .../Add-exception-reporting-event.patch | 24 ++++------------- Spigot-Server-Patches/MC-Utils.patch | 26 +++++++++++++++++++ Spigot-Server-Patches/Timings-v2.patch | 4 +-- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/Spigot-Server-Patches/Add-exception-reporting-event.patch b/Spigot-Server-Patches/Add-exception-reporting-event.patch index c94eaf0751..f0f892dad9 100644 --- a/Spigot-Server-Patches/Add-exception-reporting-event.patch +++ b/Spigot-Server-Patches/Add-exception-reporting-event.patch @@ -267,29 +267,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import org.bukkit.plugin.IllegalPluginAccessException; import org.bukkit.plugin.Plugin; @@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler { - try { - task.run(); - } catch (final Throwable throwable) { -+ // Paper start -+ String msg = String.format( -+ "Task #%s for %s generated an exception", -+ task.getTaskId(), -+ task.getOwner().getDescription().getFullName()); - task.getOwner().getLogger().log( - Level.WARNING, -- String.format( -- "Task #%s for %s generated an exception", -- task.getTaskId(), -- task.getOwner().getDescription().getFullName()), -+ msg, + msg, throwable); + } + task.getOwner().getServer().getPluginManager().callEvent( -+ new ServerExceptionEvent(new ServerSchedulerException(msg, throwable, task)) -+ ); -+ // Paper end ++ new ServerExceptionEvent(new ServerSchedulerException(msg, throwable, task))); + // Paper end } finally { currentTask = null; - } +@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler { parsePending(); } else { debugTail = debugTail.setNext(new CraftAsyncDebugger(currentTick + RECENT_TICKS, task.getOwner(), task.getTaskClass())); diff --git a/Spigot-Server-Patches/MC-Utils.patch b/Spigot-Server-Patches/MC-Utils.patch index f17ed02a0d..d84ff986fc 100644 --- a/Spigot-Server-Patches/MC-Utils.patch +++ b/Spigot-Server-Patches/MC-Utils.patch @@ -4494,6 +4494,32 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public BukkitTask runTaskTimer(Plugin plugin, Object runnable, long delay, long period) { validate(plugin, runnable); if (delay < 0L) { +@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler { + task.run(); + task.timings.stopTiming(); // Spigot + } catch (final Throwable throwable) { +- task.getOwner().getLogger().log( ++ // Paper start ++ String msg = String.format( ++ "Task #%s for %s generated an exception", ++ task.getTaskId(), ++ task.getOwner().getDescription().getFullName()); ++ if (task.getOwner() == MINECRAFT) { ++ net.minecraft.server.MinecraftServer.LOGGER.error(msg, throwable); ++ } else { ++ task.getOwner().getLogger().log( + Level.WARNING, +- String.format( +- "Task #%s for %s generated an exception", +- task.getTaskId(), +- task.getOwner().getDescription().getFullName()), ++ msg, + throwable); ++ } ++ // Paper end + } finally { + currentTask = null; + } diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java diff --git a/Spigot-Server-Patches/Timings-v2.patch b/Spigot-Server-Patches/Timings-v2.patch index 4a894b8f4b..eff3a693e5 100644 --- a/Spigot-Server-Patches/Timings-v2.patch +++ b/Spigot-Server-Patches/Timings-v2.patch @@ -2028,8 +2028,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 task.run(); - task.timings.stopTiming(); // Spigot } catch (final Throwable throwable) { - task.getOwner().getLogger().log( - Level.WARNING, + // Paper start + String msg = String.format( @@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler { runners.remove(task.getTaskId()); } From 2a6753b507b8a33f1dcfe944b3db021d8adf3e6b Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Sun, 28 Jun 2020 12:16:36 +0100 Subject: [PATCH 43/91] Restore Player#refreshPlayer (Fixes #3650) untested, don't @ me --- .../Player.setPlayerProfile-API.patch | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Spigot-Server-Patches/Player.setPlayerProfile-API.patch b/Spigot-Server-Patches/Player.setPlayerProfile-API.patch index 47557f196c..4e91c59d43 100644 --- a/Spigot-Server-Patches/Player.setPlayerProfile-API.patch +++ b/Spigot-Server-Patches/Player.setPlayerProfile-API.patch @@ -68,6 +68,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import net.minecraft.server.MapIcon; import net.minecraft.server.MinecraftKey; import net.minecraft.server.NBTTagCompound; +@@ -0,0 +0,0 @@ import net.minecraft.server.PacketPlayOutMap; + import net.minecraft.server.PacketPlayOutNamedSoundEffect; + import net.minecraft.server.PacketPlayOutPlayerInfo; + import net.minecraft.server.PacketPlayOutPlayerListHeaderFooter; ++import net.minecraft.server.PacketPlayOutRespawn; + import net.minecraft.server.PacketPlayOutSpawnPosition; + import net.minecraft.server.PacketPlayOutStopSound; + import net.minecraft.server.PacketPlayOutTitle; @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { hiddenPlayers.put(player.getUniqueId(), hidingPlugins); @@ -134,7 +142,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + reregisterPlayer(handle); + + //Respawn the player then update their position and selected slot -+ //connection.sendPacket(new net.minecraft.server.PacketPlayOutRespawn(handle.dimension, net.minecraft.server.WorldData.c(handle.world.getWorldData().getSeed()), handle.world.getWorldData().getType(), handle.playerInteractManager.getGameMode())); // TODO: Fix this if you care to make it work ++ WorldServer worldserver = handle.getWorldServer(); ++ connection.sendPacket(new net.minecraft.server.PacketPlayOutRespawn(worldserver.getTypeKey(), worldserver.getDimensionKey(), net.minecraft.server.BiomeManager.a(worldserver.getSeed()), handle.playerInteractManager.getGameMode(), handle.playerInteractManager.c(), worldserver.isDebugWorld(), worldserver.isFlatWorld(), true)); + handle.updateAbilities(); + connection.sendPacket(new net.minecraft.server.PacketPlayOutPosition(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), new HashSet<>(), 0)); + net.minecraft.server.MinecraftServer.getServer().getPlayerList().updateClient(handle); From df7c31a1da02cd70da6197fb4b1b8eac9bc3a658 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Sun, 28 Jun 2020 12:24:09 +0100 Subject: [PATCH 44/91] [CI-SKIP] Drop accidental import from last commit --- Spigot-Server-Patches/Player.setPlayerProfile-API.patch | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Spigot-Server-Patches/Player.setPlayerProfile-API.patch b/Spigot-Server-Patches/Player.setPlayerProfile-API.patch index 4e91c59d43..9586e3c3f2 100644 --- a/Spigot-Server-Patches/Player.setPlayerProfile-API.patch +++ b/Spigot-Server-Patches/Player.setPlayerProfile-API.patch @@ -68,14 +68,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import net.minecraft.server.MapIcon; import net.minecraft.server.MinecraftKey; import net.minecraft.server.NBTTagCompound; -@@ -0,0 +0,0 @@ import net.minecraft.server.PacketPlayOutMap; - import net.minecraft.server.PacketPlayOutNamedSoundEffect; - import net.minecraft.server.PacketPlayOutPlayerInfo; - import net.minecraft.server.PacketPlayOutPlayerListHeaderFooter; -+import net.minecraft.server.PacketPlayOutRespawn; - import net.minecraft.server.PacketPlayOutSpawnPosition; - import net.minecraft.server.PacketPlayOutStopSound; - import net.minecraft.server.PacketPlayOutTitle; @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { hiddenPlayers.put(player.getUniqueId(), hidingPlugins); From 2379693a9f1692ad2403187aa07b6bffae499ef5 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Sun, 28 Jun 2020 18:29:52 +0100 Subject: [PATCH 45/91] Fix NPE from an invalid spawn dimension (Fixes #3660) --- .../No-Tick-view-distance-implementation.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch b/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch index 9bfc48e522..ef4ea1eb1e 100644 --- a/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch +++ b/Spigot-Server-Patches/No-Tick-view-distance-implementation.patch @@ -575,7 +575,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Spigot - view distance - 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(), worldserver1.spigotConfig.viewDistance, flag1, !flag, worldserver1.isDebugWorld(), worldserver1.isFlatWorld())); -+ 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.getChunkProvider().playerChunkMap.getLoadViewDistance(), flag1, !flag, worldserver1.isDebugWorld(), worldserver1.isFlatWorld())); // Paper - no-tick view distance ++ 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(), worldserver1.getChunkProvider().playerChunkMap.getLoadViewDistance(), flag1, !flag, worldserver1.isDebugWorld(), worldserver1.isFlatWorld())); // Paper - no-tick view distance entityplayer.getBukkitEntity().sendSupportedChannels(); // CraftBukkit playerconnection.sendPacket(new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.a, (new PacketDataSerializer(Unpooled.buffer())).a(this.getServer().getServerModName()))); playerconnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); From ce5894ab46b6ae8d9454a2742f3ad94409d1deb7 Mon Sep 17 00:00:00 2001 From: HexedHero <6012891+HexedHero@users.noreply.github.com> Date: Sun, 28 Jun 2020 18:49:42 +0100 Subject: [PATCH 46/91] [CI-SKIP] Change 1.16 branch to show 1.16.1 API in readme (#3664) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index be8cacbb4c..78b995ab1b 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ How To (Plugin Developers) com.destroystokyo.paper paper-api - 1.15.2-R0.1-SNAPSHOT + 1.16.1-R0.1-SNAPSHOT provided ``` From 5000be556c9eed68e269a287e9951a8f022948a1 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Sun, 28 Jun 2020 21:57:31 +0200 Subject: [PATCH 47/91] [1.16] Fix MobGoals#getAllGoals not actually returning all goals (#3670) --- Spigot-API-Patches/Add-Mob-Goal-API.patch | 6 +++- .../Implement-Mob-Goal-API.patch | 34 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Spigot-API-Patches/Add-Mob-Goal-API.patch b/Spigot-API-Patches/Add-Mob-Goal-API.patch index 966f3a9f8d..76fc3d5e28 100644 --- a/Spigot-API-Patches/Add-Mob-Goal-API.patch +++ b/Spigot-API-Patches/Add-Mob-Goal-API.patch @@ -162,7 +162,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + MOVE, + LOOK, + JUMP, -+ TARGET ++ TARGET, ++ /** ++ * Used to map vanilla goals, that are a behavior goal but don't have a type set... ++ */ ++ UNKNOWN_BEHAVIOR, + +} diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoals.java b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoals.java diff --git a/Spigot-Server-Patches/Implement-Mob-Goal-API.patch b/Spigot-Server-Patches/Implement-Mob-Goal-API.patch index 92904a7f0e..fdfd3254c8 100644 --- a/Spigot-Server-Patches/Implement-Mob-Goal-API.patch +++ b/Spigot-Server-Patches/Implement-Mob-Goal-API.patch @@ -312,6 +312,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return GoalType.LOOK; + case JUMP: + return GoalType.JUMP; ++ case UNKNOWN_BEHAVIOR: ++ return GoalType.UNKNOWN_BEHAVIOR; + case TARGET: + return GoalType.TARGET; + default: @@ -335,6 +337,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return PathfinderGoal.Type.LOOK; + case JUMP: + return PathfinderGoal.Type.JUMP; ++ case UNKNOWN_BEHAVIOR: ++ return PathfinderGoal.Type.UNKNOWN_BEHAVIOR; + case TARGET: + return PathfinderGoal.Type.TARGET; + default: @@ -400,6 +404,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.handle = handle; + + this.setTypes(MobGoalHelper.paperToVanilla(handle.getTypes())); ++ if (this.getGoalTypes().size() == 0) { ++ this.getGoalTypes().addUnchecked(Type.UNKNOWN_BEHAVIOR); ++ } + } + + @Override @@ -752,8 +759,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/PathfinderGoal.java +++ b/src/main/java/net/minecraft/server/PathfinderGoal.java @@ -0,0 +0,0 @@ public abstract class PathfinderGoal { + private final EnumSet a = EnumSet.noneOf(PathfinderGoal.Type.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. + private final OptimizedSmallEnumSet goalTypes = new OptimizedSmallEnumSet<>(PathfinderGoal.Type.class); // Paper - remove streams from pathfindergoalselector - public PathfinderGoal() {} +- public PathfinderGoal() {} ++ // Paper start make sure goaltypes is never empty ++ public PathfinderGoal() { ++ if (this.goalTypes.size() == 0) { ++ this.goalTypes.addUnchecked(Type.UNKNOWN_BEHAVIOR); ++ } ++ } ++ // paper end - public abstract boolean a(); + public boolean a() { return this.shouldActivate(); } public boolean shouldActivate() { return false;} public boolean shouldActivate2() { return a(); } // Paper - OBFHELPER, for both directions... @@ -783,6 +799,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Paper start - remove streams from pathfindergoalselector this.goalTypes.clear(); this.goalTypes.addAllUnchecked(enumset); ++ // make sure its never empty ++ if (this.goalTypes.size() == 0) { ++ this.goalTypes.addUnchecked(Type.UNKNOWN_BEHAVIOR); ++ } + // Paper end - remove streams from pathfindergoalselector + } + +@@ -0,0 +0,0 @@ public abstract class PathfinderGoal { + + public static enum Type { + +- MOVE, LOOK, JUMP, TARGET; ++ MOVE, LOOK, JUMP, TARGET, UNKNOWN_BEHAVIOR; // Paper - add unknown + + private Type() {} + } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java From 8736217b0f2f571d1b6c4dc8ce94fcd4d87df576 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 18:04:04 -0400 Subject: [PATCH 48/91] Fix player skulls rendering - Fixes #3672 --- ...x-client-rendering-skulls-from-same-user.patch | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) 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 1041163eb7..03dc9c2cea 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 @@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (nbttagcompound != null && nbttagcompound.hasKeyOfType("SkullOwner", 10)) { + NBTTagCompound owner = nbttagcompound.getCompound("SkullOwner"); + if (owner.hasKey("Id")) { -+ nbttagcompound.setString("SkullOwnerOrig", owner.getString("Id")); ++ nbttagcompound.setUUID("SkullOwnerOrig", owner.getUUID("Id")); + TileEntitySkull.sanitizeUUID(owner); + } + } @@ -56,11 +56,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - Fix skulls of same owner - restore orig ID since we changed it on send to client + if (itemstack.tag.hasKey("SkullOwnerOrig")) { + NBTTagCompound owner = itemstack.tag.getCompound("SkullOwner"); -+ String ownerOrig = itemstack.tag.getString("SkullOwnerOrig"); -+ if (!owner.isEmpty() && !ownerOrig.isEmpty()) { -+ owner.setString("Id", ownerOrig); ++ if (itemstack.tag.hasUUID("SkullOwnerOrig")) { ++ owner.setUUID("Id", itemstack.tag.getUUID("SkullOwnerOrig")); ++ itemstack.tag.remove("SkullOwnerOrig"); + } -+ itemstack.tag.remove("SkullOwnerOrig"); + } + // Paper end + // CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); // Paper - This is no longer needed due to NBT being supported @@ -110,12 +109,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (list != null && !list.isEmpty()) { + String textures = ((NBTTagCompound)list.get(0)).getString("Value"); + if (textures != null && textures.length() > 3) { -+ String uuid = UUID.nameUUIDFromBytes(textures.getBytes()).toString(); -+ owner.setString("Id", uuid); ++ UUID uuid = UUID.nameUUIDFromBytes(textures.getBytes()); ++ owner.setUUID("Id", uuid); + return; + } + } -+ owner.setString("Id", UUID.randomUUID().toString()); ++ owner.setUUID("Id", UUID.randomUUID()); + } + // Paper end + From 58d7a7ae1d99c9ab393f76693d42952c7a3a9949 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 18:44:34 -0400 Subject: [PATCH 49/91] Fix more null pointer issues around deleted worlds - Fixes #3660 --- ...g-Broken-behavior-of-PlayerJoinEvent.patch | 8 +-- ...dDebugInfo-not-initialized-on-client.patch | 2 +- ...k-Priority-Urgency-System-for-Chunks.patch | 18 ++----- ...Load-Chunks-for-Login-Asynchronously.patch | 53 +++---------------- ...-Manager-and-add-advanced-packet-sup.patch | 22 +------- 5 files changed, 18 insertions(+), 85 deletions(-) diff --git a/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch b/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch index 94f40b824d..0563a05afc 100644 --- a/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch +++ b/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch @@ -61,9 +61,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks + entityplayer.supressTrackerForLogin = true; -+ worldserver.addPlayerJoin(entityplayer); ++ worldserver1.addPlayerJoin(entityplayer); + this.server.getBossBattleCustomData().a(entityplayer); // see commented out section below worldserver.addPlayerJoin(entityplayer); -+ mountSavedVehicle(entityplayer, worldserver, nbttagcompound); ++ mountSavedVehicle(entityplayer, worldserver1, nbttagcompound); + // Paper end // CraftBukkit start PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(cserver.getPlayer(entityplayer), joinMessage); @@ -82,9 +82,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + // Paper start - move vehicle into method so it can be called above - short circuit around that code -+ onPlayerJoinFinish(entityplayer, worldserver, s1); ++ onPlayerJoinFinish(entityplayer, worldserver1, s1); + } -+ private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver, NBTTagCompound nbttagcompound) { ++ private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver1, NBTTagCompound nbttagcompound) { + // Paper end if (nbttagcompound != null && nbttagcompound.hasKeyOfType("RootVehicle", 10)) { NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("RootVehicle"); diff --git a/Spigot-Server-Patches/Fix-reducedDebugInfo-not-initialized-on-client.patch b/Spigot-Server-Patches/Fix-reducedDebugInfo-not-initialized-on-client.patch index 87ed664b06..69449fc646 100644 --- a/Spigot-Server-Patches/Fix-reducedDebugInfo-not-initialized-on-client.patch +++ b/Spigot-Server-Patches/Fix-reducedDebugInfo-not-initialized-on-client.patch @@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 playerconnection.sendPacket(new PacketPlayOutHeldItemSlot(entityplayer.inventory.itemInHandIndex)); playerconnection.sendPacket(new PacketPlayOutRecipeUpdate(this.server.getCraftingManager().b())); playerconnection.sendPacket(new PacketPlayOutTags(this.server.getTagRegistry())); -+ playerconnection.sendPacket(new PacketPlayOutEntityStatus(entityplayer, (byte) (worldserver.getGameRules().getBoolean(GameRules.REDUCED_DEBUG_INFO) ? 22 : 23))); // Paper - fix this rule not being initialized on the client ++ playerconnection.sendPacket(new PacketPlayOutEntityStatus(entityplayer, (byte) (worldserver1.getGameRules().getBoolean(GameRules.REDUCED_DEBUG_INFO) ? 22 : 23))); // Paper - fix this rule not being initialized on the client this.d(entityplayer); entityplayer.getStatisticManager().c(); entityplayer.B().a(entityplayer); diff --git a/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch b/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch index ee4cbb798c..7d5081bb93 100644 --- a/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch +++ b/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch @@ -1149,23 +1149,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -0,0 +0,0 @@ public abstract class PlayerList { final ChunkCoordIntPair pos = new ChunkCoordIntPair(chunkX, chunkZ); - PlayerChunkMap playerChunkMap = finalWorldserver.getChunkProvider().playerChunkMap; + PlayerChunkMap playerChunkMap = worldserver1.getChunkProvider().playerChunkMap; playerChunkMap.chunkDistanceManager.addTicketAtLevel(TicketType.LOGIN, pos, 31, pos.pair()); -- worldserver.getChunkProvider().tickDistanceManager(); -- worldserver.getChunkProvider().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> { -+ worldserver.getChunkProvider().markAreaHighPriority(pos, 28, 3); -+ worldserver.getChunkProvider().getChunkAtAsynchronously(chunkX, chunkZ, true, false).thenApply(chunk -> { +- worldserver1.getChunkProvider().tickDistanceManager(); +- worldserver1.getChunkProvider().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> { ++ worldserver1.getChunkProvider().markAreaHighPriority(pos, 28, 3); ++ worldserver1.getChunkProvider().getChunkAtAsynchronously(chunkX, chunkZ, true, false).thenApply(chunk -> { PlayerChunk updatingChunk = playerChunkMap.getUpdatingChunk(pos.pair()); if (updatingChunk != null) { return updatingChunk.getEntityTickingFuture(); -@@ -0,0 +0,0 @@ public abstract class PlayerList { - entityplayer, finalWorldserver, finalWorldserver1, networkmanager, playerconnection, - nbttagcompound, networkmanager.getSocketAddress().toString(), lastKnownName - ); -- //playerChunkMap.chunkDistanceManager.removeTicketAtLevel(TicketType.LOGIN, pos, 31, pos.pair()); - }; - }); - } @@ -0,0 +0,0 @@ public abstract class PlayerList { SocketAddress socketaddress = loginlistener.networkManager.getSocketAddress(); diff --git a/Spigot-Server-Patches/Load-Chunks-for-Login-Asynchronously.patch b/Spigot-Server-Patches/Load-Chunks-for-Login-Asynchronously.patch index fb887b8f77..78e44aeffa 100644 --- a/Spigot-Server-Patches/Load-Chunks-for-Login-Asynchronously.patch +++ b/Spigot-Server-Patches/Load-Chunks-for-Login-Asynchronously.patch @@ -113,14 +113,6 @@ diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/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 @@ import java.util.Map; - import java.util.Optional; - import java.util.Set; - import java.util.UUID; -+import java.util.concurrent.CompletableFuture; - import javax.annotation.Nullable; - import org.apache.logging.log4j.LogManager; - import org.apache.logging.log4j.Logger; @@ -0,0 +0,0 @@ public abstract class PlayerList { private static final SimpleDateFormat g = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); private final MinecraftServer server; @@ -161,28 +153,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.sendScoreboard(worldserver1.getScoreboard(), entityplayer); this.server.invalidatePingSample(); + // Paper start - async load spawn in chunk -+ WorldServer finalWorldserver = worldserver; -+ WorldServer finalWorldserver1 = worldserver1; ++ WorldServer finalWorldserver = worldserver1; + int chunkX = loc.getBlockX() >> 4; + int chunkZ = loc.getBlockZ() >> 4; + final ChunkCoordIntPair pos = new ChunkCoordIntPair(chunkX, chunkZ); -+ PlayerChunkMap playerChunkMap = finalWorldserver.getChunkProvider().playerChunkMap; ++ PlayerChunkMap playerChunkMap = worldserver1.getChunkProvider().playerChunkMap; + playerChunkMap.chunkDistanceManager.addTicketAtLevel(TicketType.LOGIN, pos, 31, pos.pair()); -+ worldserver.getChunkProvider().tickDistanceManager(); -+ worldserver.getChunkProvider().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> { ++ worldserver1.getChunkProvider().tickDistanceManager(); ++ worldserver1.getChunkProvider().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> { + PlayerChunk updatingChunk = playerChunkMap.getUpdatingChunk(pos.pair()); + if (updatingChunk != null) { + return updatingChunk.getEntityTickingFuture(); + } else { -+ return CompletableFuture.completedFuture(chunk); ++ return java.util.concurrent.CompletableFuture.completedFuture(chunk); + } + }).thenAccept(chunk -> { + playerconnection.playerJoinReady = () -> { + postChunkLoadJoin( -+ entityplayer, finalWorldserver, finalWorldserver1, networkmanager, playerconnection, ++ entityplayer, finalWorldserver, networkmanager, playerconnection, + nbttagcompound, networkmanager.getSocketAddress().toString(), lastKnownName + ); -+ //playerChunkMap.chunkDistanceManager.removeTicketAtLevel(TicketType.LOGIN, pos, 31, pos.pair()); + }; + }); + } @@ -200,7 +190,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + }); + } + -+ private void postChunkLoadJoin(EntityPlayer entityplayer, WorldServer worldserver, WorldServer worldserver1, NetworkManager networkmanager, PlayerConnection playerconnection, NBTTagCompound nbttagcompound, String s1, String s) { ++ private void postChunkLoadJoin(EntityPlayer entityplayer, WorldServer worldserver1, NetworkManager networkmanager, PlayerConnection playerconnection, NBTTagCompound nbttagcompound, String s1, String s) { + pendingPlayers.remove(entityplayer.getUniqueID(), entityplayer); + if (!networkmanager.isConnected()) { + return; @@ -211,35 +201,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (entityplayer.getProfile().getName().equalsIgnoreCase(s)) { @@ -0,0 +0,0 @@ public abstract class PlayerList { - entityplayer.supressTrackerForLogin = true; - worldserver.addPlayerJoin(entityplayer); - this.server.getBossBattleCustomData().a(entityplayer); // see commented out section below worldserver.addPlayerJoin(entityplayer); -- mountSavedVehicle(entityplayer, worldserver, nbttagcompound); -+ mountSavedVehicle(entityplayer, worldserver, worldserver1, nbttagcompound); - // Paper end - // CraftBukkit start - PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(cserver.getPlayer(entityplayer), joinMessage); -@@ -0,0 +0,0 @@ public abstract class PlayerList { - } - entityplayer.sentListPacket = true; - entityplayer.supressTrackerForLogin = false; // Paper -- ((WorldServer)entityplayer.world).getChunkProvider().playerChunkMap.addEntity(entityplayer); // Paper - track entity now - // CraftBukkit end - - entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityMetadata(entityplayer.getId(), entityplayer.datawatcher, true)); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn -@@ -0,0 +0,0 @@ public abstract class PlayerList { - } - - // Paper start - move vehicle into method so it can be called above - short circuit around that code -+ ((WorldServer)entityplayer.world).getChunkProvider().playerChunkMap.addEntity(entityplayer); // track entity now - onPlayerJoinFinish(entityplayer, worldserver, s1); - } -- private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver, NBTTagCompound nbttagcompound) { -+ private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver, WorldServer worldserver1, NBTTagCompound nbttagcompound) { - // Paper end - if (nbttagcompound != null && nbttagcompound.hasKeyOfType("RootVehicle", 10)) { - NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("RootVehicle"); -@@ -0,0 +0,0 @@ public abstract class PlayerList { protected void savePlayerFile(EntityPlayer entityplayer) { if (!entityplayer.getBukkitEntity().isPersistent()) return; // CraftBukkit 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 0160bc2f3e..02049c806a 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 @@ -84,7 +84,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper start + private static boolean canSendImmediate(NetworkManager networkManager, Packet packet) { -+ return networkManager.isPending || networkManager.protocol != EnumProtocol.PLAY || networkManager.queueImmunity || ++ return networkManager.isPending || networkManager.protocol != EnumProtocol.PLAY || + packet instanceof PacketPlayOutKeepAlive || + packet instanceof PacketPlayOutChat || + packet instanceof PacketPlayOutTabComplete; @@ -337,26 +337,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 default boolean packetTooLarge(NetworkManager manager) { return false; } -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 { - entityplayer.playerInteractManager.a((WorldServer) entityplayer.world); - entityplayer.setPositionRaw(loc.getX(), loc.getY(), loc.getZ()); // Paper - set raw so we aren't fully joined to the world (not added to chunk or world) - entityplayer.setYawPitch(loc.getYaw(), loc.getPitch()); -+ networkmanager.queueImmunity = true; // Paper - // Spigot end - - // CraftBukkit - Moved message to after join -@@ -0,0 +0,0 @@ public abstract class PlayerList { - playerconnection.sendPacket(new PacketPlayOutRecipeUpdate(this.server.getCraftingManager().b())); - playerconnection.sendPacket(new PacketPlayOutTags(this.server.getTagRegistry())); - playerconnection.sendPacket(new PacketPlayOutEntityStatus(entityplayer, (byte) (worldserver.getGameRules().getBoolean(GameRules.REDUCED_DEBUG_INFO) ? 22 : 23))); // Paper - fix this rule not being initialized on the client -+ networkmanager.queueImmunity = false; // Paper - this.d(entityplayer); - entityplayer.getStatisticManager().c(); - entityplayer.B().a(entityplayer); diff --git a/src/main/java/net/minecraft/server/ServerConnection.java b/src/main/java/net/minecraft/server/ServerConnection.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/ServerConnection.java From 0aed7fbd5452b93961ff364508eacf5c2ad553c0 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 19:12:11 -0400 Subject: [PATCH 50/91] Improve Legacy Component serialization size Don't constantly send format: false for all formatting options when parent already has it false Going to PR this to Spigot, but putting it out here for now Should help with reducing size of items with lots of colors from legacy format. --- ...-Legacy-Component-serialization-size.patch | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch diff --git a/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch b/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch new file mode 100644 index 0000000000..64b78da12d --- /dev/null +++ b/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 28 Jun 2020 19:08:41 -0400 +Subject: [PATCH] Improve Legacy Component serialization size + +Don't constantly send format: false for all formatting options when parent already +has it false + +diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +@@ -0,0 +0,0 @@ public final class CraftChatMessage { + // Separate pattern with no group 3, new lines are part of previous string + private static final Pattern INCREMENTAL_PATTERN_KEEP_NEWLINES = Pattern.compile("(" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + "[0-9a-fk-orx])|((?:(?:https?):\\/\\/)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + " ]|$))))", Pattern.CASE_INSENSITIVE); + // ChatColor.b does not explicitly reset, its more of empty ++ private static final ChatModifier EMPTY = ChatModifier.b; // Paper - OBFHELPER + private static final ChatModifier RESET = ChatModifier.b.setBold(false).setItalic(false).setUnderline(false).setStrikethrough(false).setRandom(false); + + private final List list = new ArrayList(); +@@ -0,0 +0,0 @@ public final class CraftChatMessage { + throw new AssertionError("Unexpected message format"); + } + } else { // Color resets formatting +- modifier = RESET.setColor(format); ++ // Paper start - improve legacy formatting ++ ChatModifier previous = modifier; ++ modifier = EMPTY.setColor(format); ++ if (previous.isBold()) { ++ modifier = modifier.setBold(false); ++ } ++ if (previous.isItalic()) { ++ modifier = modifier.setItalic(false); ++ } ++ if (previous.isRandom()) { ++ modifier = modifier.setRandom(false); ++ } ++ if (previous.isStrikethrough()) { ++ modifier = modifier.setStrikethrough(false); ++ } ++ if (previous.isUnderlined()) { ++ modifier = modifier.setUnderline(false); ++ } ++ // Paper end + } + needsAdd = true; + break; From 255f22155013723c7756793693ecd9fa1065f864 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 19:37:31 -0400 Subject: [PATCH 51/91] Don't allow null UUID's for chat Fixes null issue on sending chat packets if some how it got sent null likely caused by plugins --- .../Don-t-allow-null-UUID-s-for-chat.patch | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Spigot-Server-Patches/Don-t-allow-null-UUID-s-for-chat.patch diff --git a/Spigot-Server-Patches/Don-t-allow-null-UUID-s-for-chat.patch b/Spigot-Server-Patches/Don-t-allow-null-UUID-s-for-chat.patch new file mode 100644 index 0000000000..0f275760e4 --- /dev/null +++ b/Spigot-Server-Patches/Don-t-allow-null-UUID-s-for-chat.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 28 Jun 2020 19:36:55 -0400 +Subject: [PATCH] Don't allow null UUID's for chat + + +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutChat.java b/src/main/java/net/minecraft/server/PacketPlayOutChat.java +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 @@ public class PacketPlayOutChat implements Packet { + public PacketPlayOutChat(IChatBaseComponent ichatbasecomponent, ChatMessageType chatmessagetype, UUID uuid) { + this.a = ichatbasecomponent; + this.b = chatmessagetype; +- this.c = uuid; ++ this.c = uuid != null ? uuid : SystemUtils.getNullUUID(); // Paper + } + + @Override From 73fe12740d561ee7d42694ae9c8d8693cc16ab36 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 19:37:53 -0400 Subject: [PATCH 52/91] Fix texture profile properties getting duplicated - Fixes #3667 --- Spigot-Server-Patches/Basic-PlayerProfile-API.patch | 1 + 1 file changed, 1 insertion(+) diff --git a/Spigot-Server-Patches/Basic-PlayerProfile-API.patch b/Spigot-Server-Patches/Basic-PlayerProfile-API.patch index 6c12813824..72db0d0294 100644 --- a/Spigot-Server-Patches/Basic-PlayerProfile-API.patch +++ b/Spigot-Server-Patches/Basic-PlayerProfile-API.patch @@ -220,6 +220,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + for (Property property : sourceProperties.values()) { ++ targetProperties.removeAll(property.getName()); + targetProperties.put(property.getName(), property); + } + } From bc0095b99a0dfd7b32ae3f74126c64d37092d8ce Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 19:38:30 -0400 Subject: [PATCH 53/91] Add /paper dumpitem command Allows inspecting an items NBT at ease of the item in the players hand. --- .../Paper-dumpitem-command.patch | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Spigot-Server-Patches/Paper-dumpitem-command.patch diff --git a/Spigot-Server-Patches/Paper-dumpitem-command.patch b/Spigot-Server-Patches/Paper-dumpitem-command.patch new file mode 100644 index 0000000000..a3f6f7a6dd --- /dev/null +++ b/Spigot-Server-Patches/Paper-dumpitem-command.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 28 Jun 2020 19:27:20 -0400 +Subject: [PATCH] Paper dumpitem command + +Let's you quickly view the item in your hands NBT data + +diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java ++++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java +@@ -0,0 +0,0 @@ import org.bukkit.command.CommandSender; + import org.bukkit.craftbukkit.CraftServer; + import org.bukkit.craftbukkit.CraftWorld; + import org.bukkit.craftbukkit.entity.CraftPlayer; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; + import org.bukkit.entity.Player; ++import org.bukkit.inventory.ItemStack; + + import java.io.File; + import java.io.FileOutputStream; +@@ -0,0 +0,0 @@ public class PaperCommand extends Command { + public PaperCommand(String name) { + super(name); + this.description = "Paper related commands"; +- this.usageMessage = "/paper [heap | entity | reload | version | debug | dumpwaiting | chunkinfo | syncloadinfo | fixlight]"; ++ this.usageMessage = "/paper [heap | entity | reload | version | debug | dumpwaiting | chunkinfo | syncloadinfo | fixlight | dumpitem]"; + this.setPermission("bukkit.command.paper"); + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException { + if (args.length <= 1) +- return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "dumpwaiting", "chunkinfo", "syncloadinfo", "fixlight"); ++ return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "dumpwaiting", "chunkinfo", "syncloadinfo", "fixlight", "dumpitem"); + + switch (args[0].toLowerCase(Locale.ENGLISH)) + { +@@ -0,0 +0,0 @@ public class PaperCommand extends Command { + case "reload": + doReload(sender); + break; ++ case "dumpitem": ++ doDumpItem(sender); ++ break; + case "debug": + doDebug(sender, args); + break; +@@ -0,0 +0,0 @@ public class PaperCommand extends Command { + return true; + } + ++ private void doDumpItem(CommandSender sender) { ++ ItemStack itemInHand = ((CraftPlayer) sender).getItemInHand(); ++ net.minecraft.server.ItemStack itemStack = CraftItemStack.asNMSCopy(itemInHand); ++ NBTTagCompound tag = itemStack.getTag(); ++ if (tag != null) { ++ String nbt = tag.toString(); ++ Bukkit.getConsoleSender().sendMessage(nbt); ++ sender.sendMessage(nbt); ++ } else { ++ sender.sendMessage("Item does not have NBT"); ++ } ++ } ++ + private void doFixLight(CommandSender sender, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("Only players can use this command"); From b15e37b0e9d5ac8bdc50af5d88ad2cb9c9f047f7 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 20:03:31 -0400 Subject: [PATCH 54/91] revert chat changes for now until can get it properly working --- ...-Legacy-Component-serialization-size.patch | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch diff --git a/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch b/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch deleted file mode 100644 index 64b78da12d..0000000000 --- a/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sun, 28 Jun 2020 19:08:41 -0400 -Subject: [PATCH] Improve Legacy Component serialization size - -Don't constantly send format: false for all formatting options when parent already -has it false - -diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java -@@ -0,0 +0,0 @@ public final class CraftChatMessage { - // Separate pattern with no group 3, new lines are part of previous string - private static final Pattern INCREMENTAL_PATTERN_KEEP_NEWLINES = Pattern.compile("(" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + "[0-9a-fk-orx])|((?:(?:https?):\\/\\/)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + " ]|$))))", Pattern.CASE_INSENSITIVE); - // ChatColor.b does not explicitly reset, its more of empty -+ private static final ChatModifier EMPTY = ChatModifier.b; // Paper - OBFHELPER - private static final ChatModifier RESET = ChatModifier.b.setBold(false).setItalic(false).setUnderline(false).setStrikethrough(false).setRandom(false); - - private final List list = new ArrayList(); -@@ -0,0 +0,0 @@ public final class CraftChatMessage { - throw new AssertionError("Unexpected message format"); - } - } else { // Color resets formatting -- modifier = RESET.setColor(format); -+ // Paper start - improve legacy formatting -+ ChatModifier previous = modifier; -+ modifier = EMPTY.setColor(format); -+ if (previous.isBold()) { -+ modifier = modifier.setBold(false); -+ } -+ if (previous.isItalic()) { -+ modifier = modifier.setItalic(false); -+ } -+ if (previous.isRandom()) { -+ modifier = modifier.setRandom(false); -+ } -+ if (previous.isStrikethrough()) { -+ modifier = modifier.setStrikethrough(false); -+ } -+ if (previous.isUnderlined()) { -+ modifier = modifier.setUnderline(false); -+ } -+ // Paper end - } - needsAdd = true; - break; From 52496b075b8ce94021f93c94da15b8f761c1f465 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 20:06:26 -0400 Subject: [PATCH 55/91] Fix Reloadable save players error on stop Not sure what plugins or panels are doing to have triggered this. Reloading resource packs appear to have been happening during shutdown So this will abort the end of the reload process if we are not on the correct thread and stop saving players as part of this task too. --- Spigot-Server-Patches/Improved-Watchdog-Support.patch | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Spigot-Server-Patches/Improved-Watchdog-Support.patch b/Spigot-Server-Patches/Improved-Watchdog-Support.patch index 9b3c6eb6b4..2e355351b1 100644 --- a/Spigot-Server-Patches/Improved-Watchdog-Support.patch +++ b/Spigot-Server-Patches/Improved-Watchdog-Support.patch @@ -260,6 +260,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 throw new RuntimeException("Error generating crash report", t); } // Spigot End +@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant Date: Sun, 28 Jun 2020 20:14:17 -0400 Subject: [PATCH 56/91] Updated Upstream (Bukkit/CraftBukkit) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 85e57f7a SPIGOT-5803: Implement the missing methods for the Piglin API. ce0159b6 SPIGOT-5881: SnakeYaml 1.26 limits non-scalar (null) nodes while 1.25 does not CraftBukkit Changes: 44109b72 SPIGOT-5803: Implement the missing methods for the Piglin API. cf01fd9d #696: Respect the NotNull annotation of getChargedProjectiles in CraftMetaCrossbow 1a3363db SPIGOT-5849: Constantly Raining in World 1.16 --- work/Bukkit | 2 +- work/CraftBukkit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/work/Bukkit b/work/Bukkit index f009c3dd94..85e57f7ac5 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit f009c3dd945c627246b383aa4ffad63a067df9ff +Subproject commit 85e57f7ac56f5cb4741ff21add44372f58c4877c diff --git a/work/CraftBukkit b/work/CraftBukkit index d77f4d9bf3..44109b726b 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit d77f4d9bf348534a2a5b2498d0ea7fbe5297521c +Subproject commit 44109b726b3d248da87fa89a86ca036502e4f52f From 8e46a01608965d3f034e80bec5e6babc135e0e5f Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 20:33:14 -0400 Subject: [PATCH 57/91] Fix case where some skulls still have string UUID's These heads are technically outdated, but this patch shouldn't care about what format the original value was in, so keep it the same. --- .../Fix-client-rendering-skulls-from-same-user.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 03dc9c2cea..954b9d325e 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 @@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (nbttagcompound != null && nbttagcompound.hasKeyOfType("SkullOwner", 10)) { + NBTTagCompound owner = nbttagcompound.getCompound("SkullOwner"); + if (owner.hasKey("Id")) { -+ nbttagcompound.setUUID("SkullOwnerOrig", owner.getUUID("Id")); ++ nbttagcompound.map.put("SkullOwnerOrig", owner.map.get("Id")); + TileEntitySkull.sanitizeUUID(owner); + } + } @@ -56,8 +56,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - Fix skulls of same owner - restore orig ID since we changed it on send to client + if (itemstack.tag.hasKey("SkullOwnerOrig")) { + NBTTagCompound owner = itemstack.tag.getCompound("SkullOwner"); -+ if (itemstack.tag.hasUUID("SkullOwnerOrig")) { -+ owner.setUUID("Id", itemstack.tag.getUUID("SkullOwnerOrig")); ++ if (itemstack.tag.hasKey("SkullOwnerOrig")) { ++ owner.map.put("Id", itemstack.tag.map.get("SkullOwnerOrig")); + itemstack.tag.remove("SkullOwnerOrig"); + } + } From c4520e6199bf3abad37f9c59ca9f4415dfcf13e0 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 28 Jun 2020 21:27:16 -0400 Subject: [PATCH 58/91] Improve Legacy Component serialization size Don't constantly send format: false for all formatting options when parent already has it false Fixes #3680 --- ...-Legacy-Component-serialization-size.patch | 56 +++++++++++++++++++ scripts/testServer.sh | 4 +- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch diff --git a/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch b/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch new file mode 100644 index 0000000000..6e253033cf --- /dev/null +++ b/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch @@ -0,0 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 28 Jun 2020 19:08:41 -0400 +Subject: [PATCH] Improve Legacy Component serialization size + +Don't constantly send format: false for all formatting options when parent already +has it false + +diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +@@ -0,0 +0,0 @@ public final class CraftChatMessage { + // Separate pattern with no group 3, new lines are part of previous string + private static final Pattern INCREMENTAL_PATTERN_KEEP_NEWLINES = Pattern.compile("(" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + "[0-9a-fk-orx])|((?:(?:https?):\\/\\/)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + " ]|$))))", Pattern.CASE_INSENSITIVE); + // ChatColor.b does not explicitly reset, its more of empty ++ private static final ChatModifier EMPTY = ChatModifier.b; // Paper - OBFHELPER + private static final ChatModifier RESET = ChatModifier.b.setBold(false).setItalic(false).setUnderline(false).setStrikethrough(false).setRandom(false); + + private final List list = new ArrayList(); +@@ -0,0 +0,0 @@ public final class CraftChatMessage { + Matcher matcher = (keepNewlines ? INCREMENTAL_PATTERN_KEEP_NEWLINES : INCREMENTAL_PATTERN).matcher(message); + String match = null; + boolean needsAdd = false; ++ boolean hasReset = false; // Paper + while (matcher.find()) { + int groupId = 0; + while ((match = matcher.group(++groupId)) == null) { +@@ -0,0 +0,0 @@ public final class CraftChatMessage { + throw new AssertionError("Unexpected message format"); + } + } else { // Color resets formatting +- modifier = RESET.setColor(format); ++ // Paper start - improve legacy formatting ++ ChatModifier previous = modifier; ++ modifier = (!hasReset ? RESET : EMPTY).setColor(format); ++ hasReset = true; ++ if (previous.isBold()) { ++ modifier = modifier.setBold(false); ++ } ++ if (previous.isItalic()) { ++ modifier = modifier.setItalic(false); ++ } ++ if (previous.isRandom()) { ++ modifier = modifier.setRandom(false); ++ } ++ if (previous.isStrikethrough()) { ++ modifier = modifier.setStrikethrough(false); ++ } ++ if (previous.isUnderlined()) { ++ modifier = modifier.setUnderline(false); ++ } ++ // Paper end + } + needsAdd = true; + break; diff --git a/scripts/testServer.sh b/scripts/testServer.sh index 1ce78a3328..834e4a9178 100755 --- a/scripts/testServer.sh +++ b/scripts/testServer.sh @@ -87,7 +87,9 @@ fi # JVM FLAGS # -cp "$jar" paper.jar +if [ -f "$jar" ]; then + cp "$jar" paper.jar +fi baseargs="-server -Xms${PAPER_MIN_TEST_MEMORY:-512M} -Xmx${PAPER_TEST_MEMORY:-2G} -Dfile.encoding=UTF-8 -XX:MaxGCPauseMillis=150 -XX:+UseG1GC " baseargs="$baseargs -DIReallyKnowWhatIAmDoingISwear=1 " baseargs="$baseargs -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=60 " From b94e8472586eb08d2302d7e6ece6a0bfd1193d09 Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 29 Jun 2020 03:28:10 -0400 Subject: [PATCH 59/91] Support old UUID format for NBT We have stored UUID in plenty of places that did not get DFU'd So just look for old format and load it if it exists. --- .../Support-old-UUID-format-for-NBT.patch | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch diff --git a/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch b/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch new file mode 100644 index 0000000000..f808153712 --- /dev/null +++ b/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Mon, 29 Jun 2020 03:26:17 -0400 +Subject: [PATCH] Support old UUID format for NBT + +We have stored UUID in plenty of places that did not get DFU'd + +So just look for old format and load it if it exists. + +diff --git a/src/main/java/net/minecraft/server/NBTTagCompound.java b/src/main/java/net/minecraft/server/NBTTagCompound.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/NBTTagCompound.java ++++ b/src/main/java/net/minecraft/server/NBTTagCompound.java +@@ -0,0 +0,0 @@ public class NBTTagCompound implements NBTBase { + @Nullable public UUID getUUID(String prefix) { return a(prefix); } // Paper - OBFHELPER + @Nullable + public UUID a(String s) { ++ // Paper start - support old format ++ if (hasKey(s + "Least") && hasKey(s + "Most")) { ++ return new UUID(this.getLong(s + "Most"), this.getLong(s + "Least")); ++ } ++ // Paper end + return GameProfileSerializer.a(this.get(s)); + } + From 849ede231747c31eddeb703a70c867c12fb952f0 Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 29 Jun 2020 04:04:18 -0400 Subject: [PATCH 60/91] Don't fire unleash/dismount events from worldgen threads Mojang can trigger this during worldgen and tries to fire bukkit events. --- ...sh-dismount-events-from-worldgen-thr.patch | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Spigot-Server-Patches/Don-t-fire-unleash-dismount-events-from-worldgen-thr.patch diff --git a/Spigot-Server-Patches/Don-t-fire-unleash-dismount-events-from-worldgen-thr.patch b/Spigot-Server-Patches/Don-t-fire-unleash-dismount-events-from-worldgen-thr.patch new file mode 100644 index 0000000000..4c4ef29049 --- /dev/null +++ b/Spigot-Server-Patches/Don-t-fire-unleash-dismount-events-from-worldgen-thr.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Mon, 29 Jun 2020 04:00:07 -0400 +Subject: [PATCH] Don't fire unleash/dismount events from worldgen threads + +Mojang can trigger this during worldgen and tries to fire bukkit events. + +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 + // CraftBukkit start + CraftEntity craft = (CraftEntity) entity.getBukkitEntity().getVehicle(); + Entity orig = craft == null ? null : craft.getHandle(); +- if (getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) { ++ if (getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity && MCUtil.isMainThread()) { // Paper + VehicleExitEvent event = new VehicleExitEvent( + (Vehicle) getBukkitEntity(), + (LivingEntity) entity.getBukkitEntity(), !suppressCancellation // Paper +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 { + boolean flag1 = super.a(entity, flag); + + if (flag1 && this.isLeashed()) { +- this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit ++ if (MCUtil.isMainThread()) this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit // Paper + this.unleash(true, true); + } + From d84b4a3b26f2e97122fefb580d620fca8f4168c5 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Mon, 29 Jun 2020 14:48:24 +0100 Subject: [PATCH 61/91] fix EntityDismountEvent being fired on gen threads --- ...-fire-unleash-dismount-events-from-worldgen-thr.patch | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Spigot-Server-Patches/Don-t-fire-unleash-dismount-events-from-worldgen-thr.patch b/Spigot-Server-Patches/Don-t-fire-unleash-dismount-events-from-worldgen-thr.patch index 4c4ef29049..4ebbffab02 100644 --- a/Spigot-Server-Patches/Don-t-fire-unleash-dismount-events-from-worldgen-thr.patch +++ b/Spigot-Server-Patches/Don-t-fire-unleash-dismount-events-from-worldgen-thr.patch @@ -18,6 +18,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 VehicleExitEvent event = new VehicleExitEvent( (Vehicle) getBukkitEntity(), (LivingEntity) entity.getBukkitEntity(), !suppressCancellation // Paper +@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke + // CraftBukkit end + // Spigot start + org.spigotmc.event.entity.EntityDismountEvent event = new org.spigotmc.event.entity.EntityDismountEvent(entity.getBukkitEntity(), this.getBukkitEntity(), !suppressCancellation); // Paper +- Bukkit.getPluginManager().callEvent(event); ++ if (MCUtil.isMainThread()) Bukkit.getPluginManager().callEvent(event); // Paper + if (event.isCancelled()) { + return false; + } 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 From f9ada56eda4623280dbde0aaae84cd173697eaeb Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Mon, 29 Jun 2020 14:53:01 +0100 Subject: [PATCH 62/91] Updated Upstream (CraftBukkit) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing CraftBukkit Changes: e2403a3d SPIGOT-5882: NPE when emptying bucket on already waterlogged blocks --- work/CraftBukkit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/work/CraftBukkit b/work/CraftBukkit index 44109b726b..e2403a3d2c 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 44109b726b3d248da87fa89a86ca036502e4f52f +Subproject commit e2403a3d2c4480f129ff5299bc20b3ba60027c5c From d2d7dfbef2c9da472c31dde0314217951c23b974 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Mon, 29 Jun 2020 15:03:41 +0100 Subject: [PATCH 63/91] Fix compile --- Spigot-Server-Patches/Add-hand-to-bucket-events.patch | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Spigot-Server-Patches/Add-hand-to-bucket-events.patch b/Spigot-Server-Patches/Add-hand-to-bucket-events.patch index fbcc5aba57..728d248a3d 100644 --- a/Spigot-Server-Patches/Add-hand-to-bucket-events.patch +++ b/Spigot-Server-Patches/Add-hand-to-bucket-events.patch @@ -63,6 +63,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (event.isCancelled()) { ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutBlockChange(world, blockposition)); // SPIGOT-4238: needed when looking through entity ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541 +@@ -0,0 +0,0 @@ public class ItemBucket extends Item { + } + // CraftBukkit end + if (!flag1) { +- return movingobjectpositionblock != null && this.a(entityhuman, world, movingobjectpositionblock.getBlockPosition().shift(movingobjectpositionblock.getDirection()), (MovingObjectPositionBlock) null, enumdirection, clicked, itemstack); // CraftBukkit ++ return movingobjectpositionblock != null && this.a(entityhuman, world, movingobjectpositionblock.getBlockPosition().shift(movingobjectpositionblock.getDirection()), (MovingObjectPositionBlock) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit // Paper - add enumhand + } else if (world.getDimensionManager().isNether() && this.fluidType.a((Tag) TagsFluid.WATER)) { + int i = blockposition.getX(); + int j = blockposition.getY(); 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 From 113495ff2551e4261acedbc28f154df8b5aae878 Mon Sep 17 00:00:00 2001 From: Callum Seabrook Date: Mon, 29 Jun 2020 21:14:22 +0100 Subject: [PATCH 64/91] Add Gradle usage information to README (#3700) --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 78b995ab1b..a70156e49d 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,23 @@ How To (Plugin Developers) ``` +**Or alternatively, with Gradle:** + + * Repository: +```groovy +repositories { + maven { + url 'https://papermc.io/repo/repository/maven-public/' + } +} +``` + * Artifact: +```groovy +dependencies { + compileOnly 'com.destroystokyo.paper:paper-api:1.16.1-R0.1-SNAPSHOT' +} +``` + How To (Compiling Jar From Source) ------ To compile Paper, you need JDK 8, maven, and an internet connection. From 1e64f560d6d384431b52c63400e81b97d35706e1 Mon Sep 17 00:00:00 2001 From: Automated Date: Mon, 29 Jun 2020 20:02:17 -0400 Subject: [PATCH 65/91] [Auto] Updated Upstream (Bukkit/CraftBukkit) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 3c844f35 #512: Expand Strider and Steerable entity API CraftBukkit Changes: 32acc2621 #686: Expand Strider and Steerable entity API --- work/Bukkit | 2 +- work/CraftBukkit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/work/Bukkit b/work/Bukkit index 85e57f7ac5..3c844f351a 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 85e57f7ac56f5cb4741ff21add44372f58c4877c +Subproject commit 3c844f351a81d1b9bce7a39e7055a933f10c9a96 diff --git a/work/CraftBukkit b/work/CraftBukkit index e2403a3d2c..32acc26217 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit e2403a3d2c4480f129ff5299bc20b3ba60027c5c +Subproject commit 32acc2621791b5f38e71df1da1b43858bdeaa0e2 From 860f4c4b5879756176eff53fd1364d08339b33de Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 30 Jun 2020 01:20:29 -0400 Subject: [PATCH 66/91] Updated Upstream (Bukkit/CraftBukkit/Spigot) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 42d5a714 SPIGOT-5899: Hoglins API similar to Piglins 2c1ee10e SPIGOT-5887: ClickType doesn't include off hand swaps 5ff7c7ce SPIGOT-5886: Missing BlockData CraftBukkit Changes: 7560f5f5 SPIGOT-5905: Fix hex colours not being allowed in MOTD d47c47ee SPIGOT-5889: Villager using composter should call EntityChangeBlockEvent 2fe6b4a3 SPIGOT-5899: Hoglins API similar to Piglins e09dbeca SPIGOT-5887: ClickType doesn't include off hand swaps 23aac2a5 SPIGOT-5903: EntityDismountEvent cannot be triggered asynchronously 92cbf656 SPIGOT-5884: Tab completions lost on reloadData / minecraft:reload fb4e54ad SPIGOT-5902: PlayerRespawnEvent places player at spawn before event is called aa8f3d5a SPIGOT-5901: Structures are generated in all worlds based on the setting for the main world a0c35937 SPIGOT-5895: PlayerChangedWorldEvent#getFrom is incorrect 89c0a5c3 SPIGOT-5886: Missing BlockData Spigot Changes: 0287a20d SPIGOT-5903: EntityDismountEvent cannot be triggered asynchronously --- ...sh-dismount-events-from-worldgen-thr.patch | 42 ------------------- ...-sneak-when-changing-worlds-MC-10657.patch | 2 +- Spigot-Server-Patches/MC-Dev-fixes.patch | 13 ------ ...entity-dismount-during-teleportation.patch | 10 ++--- work/Bukkit | 2 +- work/CraftBukkit | 2 +- work/Spigot | 2 +- 7 files changed, 9 insertions(+), 64 deletions(-) delete mode 100644 Spigot-Server-Patches/Don-t-fire-unleash-dismount-events-from-worldgen-thr.patch diff --git a/Spigot-Server-Patches/Don-t-fire-unleash-dismount-events-from-worldgen-thr.patch b/Spigot-Server-Patches/Don-t-fire-unleash-dismount-events-from-worldgen-thr.patch deleted file mode 100644 index 4ebbffab02..0000000000 --- a/Spigot-Server-Patches/Don-t-fire-unleash-dismount-events-from-worldgen-thr.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Mon, 29 Jun 2020 04:00:07 -0400 -Subject: [PATCH] Don't fire unleash/dismount events from worldgen threads - -Mojang can trigger this during worldgen and tries to fire bukkit events. - -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 - // CraftBukkit start - CraftEntity craft = (CraftEntity) entity.getBukkitEntity().getVehicle(); - Entity orig = craft == null ? null : craft.getHandle(); -- if (getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) { -+ if (getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity && MCUtil.isMainThread()) { // Paper - VehicleExitEvent event = new VehicleExitEvent( - (Vehicle) getBukkitEntity(), - (LivingEntity) entity.getBukkitEntity(), !suppressCancellation // Paper -@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - // CraftBukkit end - // Spigot start - org.spigotmc.event.entity.EntityDismountEvent event = new org.spigotmc.event.entity.EntityDismountEvent(entity.getBukkitEntity(), this.getBukkitEntity(), !suppressCancellation); // Paper -- Bukkit.getPluginManager().callEvent(event); -+ if (MCUtil.isMainThread()) Bukkit.getPluginManager().callEvent(event); // Paper - if (event.isCancelled()) { - return false; - } -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 { - boolean flag1 = super.a(entity, flag); - - if (flag1 && this.isLeashed()) { -- this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit -+ if (MCUtil.isMainThread()) this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit // Paper - this.unleash(true, true); - } - diff --git a/Spigot-Server-Patches/Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch b/Spigot-Server-Patches/Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch index b6eb19fe04..7f90dd3320 100644 --- a/Spigot-Server-Patches/Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch +++ b/Spigot-Server-Patches/Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch @@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + setSneaking(false); // Paper - fix MC-10657 + // CraftBukkit start - PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver.getWorld()); + PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver1.getWorld()); this.world.getServer().getPluginManager().callEvent(changeEvent); diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/Spigot-Server-Patches/MC-Dev-fixes.patch b/Spigot-Server-Patches/MC-Dev-fixes.patch index 7c1d4d68fc..8771d98222 100644 --- a/Spigot-Server-Patches/MC-Dev-fixes.patch +++ b/Spigot-Server-Patches/MC-Dev-fixes.patch @@ -279,19 +279,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 String s1 = ((INamable) t0).getName(); if (this.b.containsKey(s1)) { -diff --git a/src/main/java/net/minecraft/server/ChunkStatus.java b/src/main/java/net/minecraft/server/ChunkStatus.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/ChunkStatus.java -+++ b/src/main/java/net/minecraft/server/ChunkStatus.java -@@ -0,0 +0,0 @@ public class ChunkStatus { - return (CompletableFuture) function.apply(ichunkaccess); - }); - private static final List q = ImmutableList.of(ChunkStatus.FULL, ChunkStatus.FEATURES, ChunkStatus.LIQUID_CARVERS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS); -- private static final IntList r = (IntList) SystemUtils.a((Object) (new IntArrayList(a().size())), (intarraylist) -> { -+ private static final IntList r = (IntList) SystemUtils.a((new IntArrayList(a().size())), (java.util.function.Consumer)(IntArrayList intarraylist) -> { // Paper - decompile fix - int i = 0; - - for (int j = a().size() - 1; j >= 0; --j) { diff --git a/src/main/java/net/minecraft/server/CraftingManager.java b/src/main/java/net/minecraft/server/CraftingManager.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/CraftingManager.java diff --git a/Spigot-Server-Patches/force-entity-dismount-during-teleportation.patch b/Spigot-Server-Patches/force-entity-dismount-during-teleportation.patch index ef177f3574..ce228b2c42 100644 --- a/Spigot-Server-Patches/force-entity-dismount-during-teleportation.patch +++ b/Spigot-Server-Patches/force-entity-dismount-during-teleportation.patch @@ -60,17 +60,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - (LivingEntity) entity.getBukkitEntity() + (LivingEntity) entity.getBukkitEntity(), !suppressCancellation // Paper ); - Bukkit.getPluginManager().callEvent(event); - CraftEntity craftn = (CraftEntity) entity.getBukkitEntity().getVehicle(); + // Suppress during worldgen + if (this.valid) { @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } // CraftBukkit end // Spigot start - org.spigotmc.event.entity.EntityDismountEvent event = new org.spigotmc.event.entity.EntityDismountEvent(entity.getBukkitEntity(), this.getBukkitEntity()); + org.spigotmc.event.entity.EntityDismountEvent event = new org.spigotmc.event.entity.EntityDismountEvent(entity.getBukkitEntity(), this.getBukkitEntity(), !suppressCancellation); // Paper - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) { - return false; + // Suppress during worldgen + if (this.valid) { + Bukkit.getPluginManager().callEvent(event); 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 diff --git a/work/Bukkit b/work/Bukkit index 3c844f351a..42d5a714f4 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 3c844f351a81d1b9bce7a39e7055a933f10c9a96 +Subproject commit 42d5a714f434eb1324dfef1b38218d7e40c67644 diff --git a/work/CraftBukkit b/work/CraftBukkit index 32acc26217..7560f5f5a6 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 32acc2621791b5f38e71df1da1b43858bdeaa0e2 +Subproject commit 7560f5f5a69fc5fa17ec0c33eaba8abe026a53ef diff --git a/work/Spigot b/work/Spigot index ad703da04d..0287a20df3 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit ad703da04d2ffbf84a75e5ee32f2829380864bb7 +Subproject commit 0287a20df344c0bc462ddc64851e5a160a1775fc From ac311eb19182801c08b2e3040f4c829b77d3f0ec Mon Sep 17 00:00:00 2001 From: Automated Date: Tue, 30 Jun 2020 19:42:14 -0400 Subject: [PATCH 67/91] [Auto] Updated Upstream (CraftBukkit) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing CraftBukkit Changes: fdf6017fa Fix event for unlucky composts b567cb433 SPIGOT-5910: loadAdvancement does not work --- work/CraftBukkit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/work/CraftBukkit b/work/CraftBukkit index 7560f5f5a6..fdf6017fa9 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 7560f5f5a69fc5fa17ec0c33eaba8abe026a53ef +Subproject commit fdf6017fa9ea64ddcfa2f2a7d69cda824b381b38 From ec070e4f08256eb17ecd2ebdc3782e39b98ea262 Mon Sep 17 00:00:00 2001 From: Automated Date: Tue, 30 Jun 2020 20:07:16 -0400 Subject: [PATCH 68/91] [Auto] Updated Upstream (Bukkit/CraftBukkit) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: e16de3bb SPIGOT-5906: Huge Fungi tree generation CraftBukkit Changes: a13b8cfc7 SPIGOT-5907: Item Frame NBT data disappears 5a6c52983 SPIGOT-5906: Huge Fungi tree generation --- work/Bukkit | 2 +- work/CraftBukkit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/work/Bukkit b/work/Bukkit index 42d5a714f4..e16de3bb16 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 42d5a714f434eb1324dfef1b38218d7e40c67644 +Subproject commit e16de3bb167910ba20339d2cb5f5c798827f196a diff --git a/work/CraftBukkit b/work/CraftBukkit index fdf6017fa9..a13b8cfc71 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit fdf6017fa9ea64ddcfa2f2a7d69cda824b381b38 +Subproject commit a13b8cfc71be4eb2c7880024a1ae191bbfd51131 From 174c81a9634ad12f93f3fe4c5d4f4286ed9ccca0 Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 1 Jul 2020 02:11:46 -0400 Subject: [PATCH 69/91] Updated Upstream (Bukkit/CraftBukkit/Spigot) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 6ff65c82 SPIGOT-5908: CompassMeta for new lodestone compass data CraftBukkit Changes: 3b9cf0f8 Improve code formatting 008f039f SPIGOT-5913: MOTD no longer supports new line character b8b65eb7 SPIGOT-5908: CompassMeta for new lodestone compass data Spigot Changes: 4d9262cf Rebuild patches d27f7952 SPIGOT-5912: Outdated client message shows outdated server message --- .../Add-ArmorStand-Item-Meta.patch | 14 ++++++-------- ...n-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch | 10 ++++------ work/Bukkit | 2 +- work/CraftBukkit | 2 +- work/Spigot | 2 +- 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/Spigot-Server-Patches/Add-ArmorStand-Item-Meta.patch b/Spigot-Server-Patches/Add-ArmorStand-Item-Meta.patch index b34f121bd9..c444ddd30a 100644 --- a/Spigot-Server-Patches/Add-ArmorStand-Item-Meta.patch +++ b/Spigot-Server-Patches/Add-ArmorStand-Item-Meta.patch @@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 CraftMetaArmorStand(CraftMetaItem meta) { super(meta); -+ ++ + // Paper start + if (!(meta instanceof CraftMetaArmorStand)) { + return; @@ -271,22 +271,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - CraftMetaTropicalFishBucket.VARIANT.NBT, CraftMetaCrossbow.CHARGED.NBT, CraftMetaCrossbow.CHARGED_PROJECTILES.NBT, -- CraftMetaSuspiciousStew.EFFECTS.NBT -+ CraftMetaSuspiciousStew.EFFECTS.NBT, + CraftMetaSuspiciousStew.EFFECTS.NBT, + // Paper start + CraftMetaArmorStand.ENTITY_TAG.NBT, + CraftMetaArmorStand.INVISIBLE.NBT, + CraftMetaArmorStand.NO_BASE_PLATE.NBT, + CraftMetaArmorStand.SHOW_ARMS.NBT, + CraftMetaArmorStand.SMALL.NBT, -+ CraftMetaArmorStand.MARKER.NBT ++ CraftMetaArmorStand.MARKER.NBT, + // Paper end - )); - } - return HANDLED_TAGS; + CraftMetaCompass.LODESTONE_DIMENSION.NBT, + CraftMetaCompass.LODESTONE_POS.NBT, + CraftMetaCompass.LODESTONE_TRACKED.NBT diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java diff --git a/Spigot-Server-Patches/Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch b/Spigot-Server-Patches/Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch index e61cf95fb6..d465dc18ea 100644 --- a/Spigot-Server-Patches/Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch +++ b/Spigot-Server-Patches/Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch @@ -273,16 +273,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 serializeInternal(internalTags); if (!internalTags.isEmpty()) { @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - CraftMetaArmorStand.NO_BASE_PLATE.NBT, CraftMetaArmorStand.SHOW_ARMS.NBT, CraftMetaArmorStand.SMALL.NBT, -- CraftMetaArmorStand.MARKER.NBT -+ CraftMetaArmorStand.MARKER.NBT, + CraftMetaArmorStand.MARKER.NBT, + CAN_DESTROY.NBT, -+ CAN_PLACE_ON.NBT ++ CAN_PLACE_ON.NBT, // Paper end - )); - } + CraftMetaCompass.LODESTONE_DIMENSION.NBT, + CraftMetaCompass.LODESTONE_POS.NBT, @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } // Paper end diff --git a/work/Bukkit b/work/Bukkit index e16de3bb16..6ff65c824a 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit e16de3bb167910ba20339d2cb5f5c798827f196a +Subproject commit 6ff65c824ad8dc9ba9228999800a0d7010904893 diff --git a/work/CraftBukkit b/work/CraftBukkit index a13b8cfc71..3b9cf0f803 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit a13b8cfc71be4eb2c7880024a1ae191bbfd51131 +Subproject commit 3b9cf0f8031a2614ff2a041a1f3be7cc7fb4bbf4 diff --git a/work/Spigot b/work/Spigot index 0287a20df3..4d9262cf9f 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit 0287a20df344c0bc462ddc64851e5a160a1775fc +Subproject commit 4d9262cf9f7cf1a38525d21734708c3fe4a28bcb From d9bdfa4aa24301e2e9682135c7ec543d08006dcd Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 1 Jul 2020 03:13:57 -0400 Subject: [PATCH 70/91] Fix supporting more places of the old UUID format Fixes #3734 --- .../Fix-client-rendering-skulls-from-same-user.patch | 4 ++-- .../Support-old-UUID-format-for-NBT.patch | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) 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 954b9d325e..0df1a6363c 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 @@ -39,8 +39,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start + if (nbttagcompound != null && nbttagcompound.hasKeyOfType("SkullOwner", 10)) { + NBTTagCompound owner = nbttagcompound.getCompound("SkullOwner"); -+ if (owner.hasKey("Id")) { -+ nbttagcompound.map.put("SkullOwnerOrig", owner.map.get("Id")); ++ if (owner.hasUUID("Id")) { ++ nbttagcompound.setUUID("SkullOwnerOrig", owner.getUUID("Id")); + TileEntitySkull.sanitizeUUID(owner); + } + } diff --git a/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch b/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch index f808153712..2d88b65f2a 100644 --- a/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch +++ b/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch @@ -23,3 +23,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return GameProfileSerializer.a(this.get(s)); } + public final boolean hasUUID(String s) { return this.b(s); } // Paper - OBFHELPER + public boolean b(String s) { ++ // Paper start - support old format ++ if (hasKey(s + "Least") && hasKey(s + "Most")) { ++ return true; ++ } ++ // Paper end + NBTBase nbtbase = this.get(s); + + return nbtbase != null && nbtbase.b() == NBTTagIntArray.a && ((NBTTagIntArray) nbtbase).getInts().length == 4; From 438da20dd593e50ff7d59cbaa4bf2ca07e6f987d Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 1 Jul 2020 03:15:52 -0400 Subject: [PATCH 71/91] Clean up duplicated GameProfile Properties We had a bug where we accidently cloned properties resulting in skulls growing to large sizes and preventing login. This now automatically cleans up the extra properties. Fixes #3719 Fixes #3667 --- ...up-duplicated-GameProfile-Properties.patch | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Spigot-Server-Patches/Clean-up-duplicated-GameProfile-Properties.patch diff --git a/Spigot-Server-Patches/Clean-up-duplicated-GameProfile-Properties.patch b/Spigot-Server-Patches/Clean-up-duplicated-GameProfile-Properties.patch new file mode 100644 index 0000000000..9a346080ce --- /dev/null +++ b/Spigot-Server-Patches/Clean-up-duplicated-GameProfile-Properties.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Wed, 1 Jul 2020 03:12:06 -0400 +Subject: [PATCH] Clean up duplicated GameProfile Properties + +We had a bug where we accidently cloned properties resulting in skulls +growing to large sizes and preventing login. + +This now automatically cleans up the extra properties. + +diff --git a/src/main/java/net/minecraft/server/GameProfileSerializer.java b/src/main/java/net/minecraft/server/GameProfileSerializer.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/GameProfileSerializer.java ++++ b/src/main/java/net/minecraft/server/GameProfileSerializer.java +@@ -0,0 +0,0 @@ public final class GameProfileSerializer { + while (iterator.hasNext()) { + String s1 = (String) iterator.next(); + NBTTagList nbttaglist = nbttagcompound1.getList(s1, 10); +- +- for (int i = 0; i < nbttaglist.size(); ++i) { ++ if (nbttaglist.size() == 0) continue; // Paper - remove duplicate properties ++ for (int i = nbttaglist.size() - 1; i < nbttaglist.size(); ++i) { // Paper - remove duplicate properties + NBTTagCompound nbttagcompound2 = nbttaglist.getCompound(i); + String s2 = nbttagcompound2.getString("Value"); + +@@ -0,0 +0,0 @@ public final class GameProfileSerializer { + Optional optional = iblockstate.b(nbttagcompound.getString(s)); + + if (optional.isPresent()) { +- return (IBlockDataHolder) s0.set(iblockstate, (Comparable) optional.get()); ++ return s0.set(iblockstate, optional.get()); // Paper - decompile error + } else { + GameProfileSerializer.LOGGER.warn("Unable to read property: {} with value: {} for blockstate: {}", s, nbttagcompound.getString(s), nbttagcompound1.toString()); + return s0; +@@ -0,0 +0,0 @@ public final class GameProfileSerializer { + return nbttagcompound; + } + +- private static > String a(IBlockState iblockstate, Comparable comparable) { +- return iblockstate.a(comparable); ++ private static > String a(IBlockState iblockstate, Comparable comparable) {// Paper - decompile error ++ return iblockstate.a((T) comparable);// Paper - decompile error + } + + public static NBTTagCompound a(DataFixer datafixer, DataFixTypes datafixtypes, NBTTagCompound nbttagcompound, int i) { +diff --git a/src/main/java/net/minecraft/server/ItemSkullPlayer.java b/src/main/java/net/minecraft/server/ItemSkullPlayer.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/ItemSkullPlayer.java ++++ b/src/main/java/net/minecraft/server/ItemSkullPlayer.java +@@ -0,0 +0,0 @@ public class ItemSkullPlayer extends ItemBlockWallable { + return true; + } else { + // CraftBukkit start ++ // Paper start - clean up old duplicated properties ++ NBTTagCompound properties = nbttagcompound.getCompound("SkullOwner").getCompound("Properties"); ++ for (String key : properties.getKeys()) { ++ NBTTagList values = properties.getList(key, 10); ++ if (values.size() > 1) { ++ NBTBase texture = values.get(values.size() - 1); ++ values = new NBTTagList(); ++ values.add(texture); ++ properties.set(key, values); ++ } ++ } ++ // Paper end + NBTTagList textures = nbttagcompound.getCompound("SkullOwner").getCompound("Properties").getList("textures", 10); // Safe due to method contracts + for (int i = 0; i < textures.size(); i++) { + if (textures.get(i) instanceof NBTTagCompound && !((NBTTagCompound) textures.get(i)).hasKeyOfType("Signature", 8) && ((NBTTagCompound) textures.get(i)).getString("Value").trim().isEmpty()) { From 7b5d35ff25053f1ca4f0120d73b913cc1d832fe5 Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 1 Jul 2020 03:32:26 -0400 Subject: [PATCH 72/91] Fix server not stopping when eula not agreed yet --- .../Improve-Server-Thread-Pool-and-Thread-Priorities.patch | 1 + 1 file changed, 1 insertion(+) 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 363735867f..233db2a9e6 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 @@ -40,6 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + super(target, "Server-Worker-" + threadId.getAndIncrement()); + setPriority(Thread.NORM_PRIORITY-1); // Deprioritize over main + this.setUncaughtExceptionHandler((thread, throwable) -> { ++ thread.setDaemon(true); + if (throwable instanceof CompletionException) { + throwable = throwable.getCause(); + } From be5f765e93339f6f15112726c149a10afd057abb Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 1 Jul 2020 04:28:56 -0400 Subject: [PATCH 73/91] Convert legacy attributes in Item Meta Fixes #3705 --- ...nvert-legacy-attributes-in-Item-Meta.patch | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Spigot-Server-Patches/Convert-legacy-attributes-in-Item-Meta.patch diff --git a/Spigot-Server-Patches/Convert-legacy-attributes-in-Item-Meta.patch b/Spigot-Server-Patches/Convert-legacy-attributes-in-Item-Meta.patch new file mode 100644 index 0000000000..759f24dd73 --- /dev/null +++ b/Spigot-Server-Patches/Convert-legacy-attributes-in-Item-Meta.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Wed, 1 Jul 2020 04:50:22 -0400 +Subject: [PATCH] Convert legacy attributes in Item Meta + + +diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java ++++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java +@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.util.CraftNamespacedKey; + public class CraftAttributeMap implements Attributable { + + private final AttributeMapBase handle; ++ // Paper start - convert legacy attributes ++ private static final com.google.common.collect.ImmutableMap legacyNMS = com.google.common.collect.ImmutableMap.builder().put("generic.maxHealth", "generic.max_health").put("Max Health", "generic.max_health").put("zombie.spawnReinforcements", "zombie.spawn_reinforcements").put("Spawn Reinforcements Chance", "zombie.spawn_reinforcements").put("horse.jumpStrength", "horse.jump_strength").put("Jump Strength", "horse.jump_strength").put("generic.followRange", "generic.follow_range").put("Follow Range", "generic.follow_range").put("generic.knockbackResistance", "generic.knockback_resistance").put("Knockback Resistance", "generic.knockback_resistance").put("generic.movementSpeed", "generic.movement_speed").put("Movement Speed", "generic.movement_speed").put("generic.flyingSpeed", "generic.flying_speed").put("Flying Speed", "generic.flying_speed").put("generic.attackDamage", "generic.attack_damage").put("generic.attackKnockback", "generic.attack_knockback").put("generic.attackSpeed", "generic.attack_speed").put("generic.armorToughness", "generic.armor_toughness").build(); ++ ++ public static String convertIfNeeded(String nms) { ++ if (nms == null) { ++ return null; ++ } ++ nms = legacyNMS.getOrDefault(nms, nms); ++ if (!nms.toLowerCase().equals(nms) || nms.indexOf(' ') != -1) { ++ return null; ++ } ++ return nms; ++ } ++ // Paper end + + public CraftAttributeMap(AttributeMapBase handle) { + this.handle = handle; +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + + AttributeModifier attribMod = CraftAttributeInstance.convert(nmsModifier); + +- String attributeName = entry.getString(ATTRIBUTES_IDENTIFIER.NBT); ++ String attributeName = CraftAttributeMap.convertIfNeeded(entry.getString(ATTRIBUTES_IDENTIFIER.NBT)); // Paper + if (attributeName == null || attributeName.isEmpty()) { + continue; + } From 62802db4ac866323fca04ac1b2801b644d3a802d Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 1 Jul 2020 05:42:22 -0400 Subject: [PATCH 74/91] Allow teleporting through end gateways as a passenger/vehicle Vanilla allows this now for same world teleports Fixes #3735 --- Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch b/Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch index 1d08fe4d31..477b3b7fed 100644 --- a/Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch +++ b/Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch @@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.a((Entity) list.get(this.world.random.nextInt(list.size()))); + // Paper start + for (Entity entity : list) { -+ if (!entity.isPassenger() && !entity.isVehicle() && entity.canPortal()) { ++ if (entity.canPortal()) { + this.a(entity); + break; + } From e32b8cfddb5821a7eea1fb74d9cd6c0fac9d09c4 Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 1 Jul 2020 05:42:51 -0400 Subject: [PATCH 75/91] Improve old UUID support, clean up old legacy keys. If we set a UUID to new format, need to make sure old format doesn't exist anymore. Additionally, ensure if new format exists, we prefer it over old. --- .../Support-old-UUID-format-for-NBT.patch | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch b/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch index 2d88b65f2a..9b8a3ec027 100644 --- a/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch +++ b/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch @@ -11,12 +11,25 @@ diff --git a/src/main/java/net/minecraft/server/NBTTagCompound.java b/src/main/j index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/NBTTagCompound.java +++ b/src/main/java/net/minecraft/server/NBTTagCompound.java +@@ -0,0 +0,0 @@ public class NBTTagCompound implements NBTBase { + + public void setUUID(String prefix, UUID uuid) { a(prefix, uuid); } // Paper - OBFHELPER + public void a(String s, UUID uuid) { ++ // Paper start - support old format ++ if (this.hasKeyOfType(s + "Most", 99) && this.hasKeyOfType(s + "Least", 99)) { ++ this.map.remove(s + "Most"); ++ this.map.remove(s + "Least"); ++ } ++ // Paper end + this.map.put(s, GameProfileSerializer.a(uuid)); + } + @@ -0,0 +0,0 @@ public class NBTTagCompound implements NBTBase { @Nullable public UUID getUUID(String prefix) { return a(prefix); } // Paper - OBFHELPER @Nullable public UUID a(String s) { + // Paper start - support old format -+ if (hasKey(s + "Least") && hasKey(s + "Most")) { ++ if (!hasKeyOfType(s, 11) && this.hasKeyOfType(s + "Most", 99) && this.hasKeyOfType(s + "Least", 99)) { + return new UUID(this.getLong(s + "Most"), this.getLong(s + "Least")); + } + // Paper end @@ -26,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public final boolean hasUUID(String s) { return this.b(s); } // Paper - OBFHELPER public boolean b(String s) { + // Paper start - support old format -+ if (hasKey(s + "Least") && hasKey(s + "Most")) { ++ if (this.hasKeyOfType(s + "Most", 99) && this.hasKeyOfType(s + "Least", 99)) { + return true; + } + // Paper end From 3bc3b61ce38c7e6f9743b464f4e9995fc59f8437 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Wed, 1 Jul 2020 12:21:57 +0100 Subject: [PATCH 76/91] Fix shutdown on eula not being agreed (Fixes #4647) --- .../Improve-Server-Thread-Pool-and-Thread-Priorities.patch | 1 + 1 file changed, 1 insertion(+) 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 233db2a9e6..7ae15efb74 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 @@ -39,6 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public ServerWorkerThread(Runnable target) { + super(target, "Server-Worker-" + threadId.getAndIncrement()); + setPriority(Thread.NORM_PRIORITY-1); // Deprioritize over main ++ this.setDaemon(true); + this.setUncaughtExceptionHandler((thread, throwable) -> { + thread.setDaemon(true); + if (throwable instanceof CompletionException) { From a03c4deb10978c5098d1241fac2a50a146f7a02d Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Wed, 1 Jul 2020 09:53:16 -0400 Subject: [PATCH 77/91] [1.16] Remove some streams from structures (#3704) This showed up a lot in the spark profiler, should have a low-medium performance improvement. --- .../Remove-some-streams-from-structures.patch | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 Spigot-Server-Patches/Remove-some-streams-from-structures.patch diff --git a/Spigot-Server-Patches/Remove-some-streams-from-structures.patch b/Spigot-Server-Patches/Remove-some-streams-from-structures.patch new file mode 100644 index 0000000000..41b3ba71fe --- /dev/null +++ b/Spigot-Server-Patches/Remove-some-streams-from-structures.patch @@ -0,0 +1,111 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Josh Roy <10731363+JRoy@users.noreply.github.com> +Date: Mon, 29 Jun 2020 17:03:06 -0400 +Subject: [PATCH] Remove some streams from structures + +This showed up a lot in the spark profiler, should have a low-medium performance improvement. + +diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java +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 class BiomeBase { + int j1 = l << 4; + + try { +- structuremanager.a(SectionPosition.a(blockposition), structuregenerator).forEach((structurestart) -> { +- structurestart.a(generatoraccessseed, structuremanager, chunkgenerator, seededrandom, new StructureBoundingBox(i1, j1, i1 + 15, j1 + 15), new ChunkCoordIntPair(k, l)); +- }); ++ // Paper start - remove structure streams ++ for (StructureStart structureStart : structuremanager.getFeatureStarts(SectionPosition.a(blockposition), structuregenerator)) { ++ structureStart.a(generatoraccessseed, structuremanager, chunkgenerator, seededrandom, new StructureBoundingBox(i1, j1, i1 + 15, j1 + 15), new ChunkCoordIntPair(k, l)); ++ } ++ // Paper end + } catch (Exception exception) { + CrashReport crashreport = CrashReport.a(exception, "Feature placement"); + +diff --git a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java ++++ b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java +@@ -0,0 +0,0 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator { + while (iterator.hasNext()) { + StructureGenerator structuregenerator = (StructureGenerator) iterator.next(); + +- structuremanager.a(SectionPosition.a(chunkcoordintpair, 0), structuregenerator).forEach((structurestart) -> { ++ for (StructureStart structurestart : structuremanager.getFeatureStarts(SectionPosition.a(chunkcoordintpair, 0), structuregenerator)) { // Paper - remove structure streams + Iterator iterator1 = structurestart.d().iterator(); + + while (iterator1.hasNext()) { +@@ -0,0 +0,0 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator { + } + } + +- }); ++ } // Paper - remove structure streams + } + + double[][][] adouble = new double[2][this.p + 1][this.o + 1]; +diff --git a/src/main/java/net/minecraft/server/StructureManager.java b/src/main/java/net/minecraft/server/StructureManager.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/StructureManager.java ++++ b/src/main/java/net/minecraft/server/StructureManager.java +@@ -0,0 +0,0 @@ import javax.annotation.Nullable; + + public class StructureManager { + +- private final GeneratorAccess a; ++ private final GeneratorAccess a; public GeneratorAccess getLevel() { return a; } // Paper - OBFHELPER + private final GeneratorSettings b; + + public StructureManager(GeneratorAccess generatoraccess, GeneratorSettings generatorsettings) { +@@ -0,0 +0,0 @@ public class StructureManager { + }); + } + ++ // Paper start - remove structure streams ++ public java.util.List> getFeatureStarts(SectionPosition sectionPosition, StructureGenerator structureGenerator) { ++ java.util.List> list = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); ++ for (Long curLong: getLevel().getChunkAt(sectionPosition.a(), sectionPosition.c(), ChunkStatus.STRUCTURE_REFERENCES).b(structureGenerator)) { ++ SectionPosition sectionPosition1 = SectionPosition.a(new ChunkCoordIntPair(curLong), 0); ++ StructureStart structurestart = a(sectionPosition1, structureGenerator, getLevel().getChunkAt(sectionPosition1.a(), sectionPosition1.c(), ChunkStatus.STRUCTURE_STARTS)); ++ if (structurestart != null && structurestart.e()) { ++ list.add(structurestart); ++ } ++ } ++ return list; ++ } ++ // Paper end ++ + @Nullable + public StructureStart a(SectionPosition sectionposition, StructureGenerator structuregenerator, IStructureAccess istructureaccess) { + return istructureaccess.a(structuregenerator); +@@ -0,0 +0,0 @@ public class StructureManager { + } + + public StructureStart a(BlockPosition blockposition, boolean flag, StructureGenerator structuregenerator) { +- return (StructureStart) DataFixUtils.orElse(this.a(SectionPosition.a(blockposition), structuregenerator).filter((structurestart) -> { +- return structurestart.c().b((BaseBlockPosition) blockposition); +- }).filter((structurestart) -> { +- return !flag || structurestart.d().stream().anyMatch((structurepiece) -> { +- return structurepiece.g().b((BaseBlockPosition) blockposition); +- }); +- }).findFirst(), StructureStart.a); ++ // Paper start - remove structure streams ++ for (StructureStart structurestart : getFeatureStarts(SectionPosition.a(blockposition), structuregenerator)) { ++ if (structurestart.c().b(blockposition)) { ++ if (!flag) { ++ return structurestart; ++ } ++ for (StructurePiece structurepiece : structurestart.d()) { ++ if (structurepiece.g().b(blockposition)) { ++ return structurestart; ++ } ++ } ++ } ++ } ++ return StructureStart.a; ++ // Paper end + } + + // Spigot start From 0f6675fffab09de47492d827a1e4fbd04c48b827 Mon Sep 17 00:00:00 2001 From: Automated Date: Wed, 1 Jul 2020 19:17:11 -0400 Subject: [PATCH 78/91] [Auto] Updated Upstream (CraftBukkit) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing CraftBukkit Changes: d9bd43b06 Change outdated build delay to 3 days --- Spigot-Server-Patches/Fix-this-stupid-bullshit.patch | 2 +- Spigot-Server-Patches/POM-Changes.patch | 2 +- .../Show-Paper-in-client-crashes-server-lists-and-Mojang.patch | 2 +- work/CraftBukkit | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Spigot-Server-Patches/Fix-this-stupid-bullshit.patch b/Spigot-Server-Patches/Fix-this-stupid-bullshit.patch index d3df7489ae..df33fd65b8 100644 --- a/Spigot-Server-Patches/Fix-this-stupid-bullshit.patch +++ b/Spigot-Server-Patches/Fix-this-stupid-bullshit.patch @@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -0,0 +0,0 @@ public class Main { Calendar deadline = Calendar.getInstance(); - deadline.add(Calendar.DAY_OF_YEAR, -1); + deadline.add(Calendar.DAY_OF_YEAR, -3); if (buildDate.before(deadline.getTime())) { - System.err.println("*** Error, this build is outdated ***"); + // Paper start - This is some stupid bullshit diff --git a/Spigot-Server-Patches/POM-Changes.patch b/Spigot-Server-Patches/POM-Changes.patch index 6be7b50705..ee23f17e5b 100644 --- a/Spigot-Server-Patches/POM-Changes.patch +++ b/Spigot-Server-Patches/POM-Changes.patch @@ -201,7 +201,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Date buildDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(Main.class.getPackage().getImplementationVendor()); // Paper Calendar deadline = Calendar.getInstance(); - deadline.add(Calendar.DAY_OF_YEAR, -1); + deadline.add(Calendar.DAY_OF_YEAR, -3); diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java diff --git a/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch b/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch index e0719937b4..6b9f14f647 100644 --- a/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch +++ b/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch @@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -0,0 +0,0 @@ public class Main { - deadline.add(Calendar.DAY_OF_YEAR, -1); + deadline.add(Calendar.DAY_OF_YEAR, -3); if (buildDate.before(deadline.getTime())) { System.err.println("*** Error, this build is outdated ***"); - System.err.println("*** Please download a new build as per instructions from https://www.spigotmc.org/go/outdated-spigot ***"); diff --git a/work/CraftBukkit b/work/CraftBukkit index 3b9cf0f803..d9bd43b060 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 3b9cf0f8031a2614ff2a041a1f3be7cc7fb4bbf4 +Subproject commit d9bd43b060322ad72af3008669878ee5d6cc2cc0 From 20bdc049da2dbcda0a1597acb2aa5e51d5a9a880 Mon Sep 17 00:00:00 2001 From: Automated Date: Wed, 1 Jul 2020 19:41:58 -0400 Subject: [PATCH 79/91] [Auto] Updated Upstream (Bukkit/CraftBukkit) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 1cb03826 SPIGOT-5900: Re-order Material enum entries to match Minecraft's order fdd705db #507: Add hasDiscoveredRecipe() and getDiscoveredRecipes() CraftBukkit Changes: 551e770f5 SPIGOT-5900: Add test for the order of Material enum entries 8297676c2 #682: Add hasDiscoveredRecipe() and getDiscoveredRecipes() --- Spigot-API-Patches/Material-API-additions.patch | 2 +- work/Bukkit | 2 +- work/CraftBukkit | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Spigot-API-Patches/Material-API-additions.patch b/Spigot-API-Patches/Material-API-additions.patch index 9e108ac767..30f9e1562e 100644 --- a/Spigot-API-Patches/Material-API-additions.patch +++ b/Spigot-API-Patches/Material-API-additions.patch @@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +@SuppressWarnings({"DeprecatedIsStillUsed", "deprecation"}) // Paper public enum Material implements Keyed { // - ACACIA_BOAT(27326, 1), + AIR(9648, 0), @@ -0,0 +0,0 @@ public enum Material implements Keyed { } } diff --git a/work/Bukkit b/work/Bukkit index 6ff65c824a..1cb03826eb 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 6ff65c824ad8dc9ba9228999800a0d7010904893 +Subproject commit 1cb03826ebde4ef887519ce37b0a2a341494a183 diff --git a/work/CraftBukkit b/work/CraftBukkit index d9bd43b060..551e770f5f 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit d9bd43b060322ad72af3008669878ee5d6cc2cc0 +Subproject commit 551e770f5f981053885e2e1a043b4ecb54a80aef From e69ff08d7272145271729a41a4413a1c6e242391 Mon Sep 17 00:00:00 2001 From: Automated Date: Wed, 1 Jul 2020 21:27:09 -0400 Subject: [PATCH 80/91] [Auto] Updated Upstream (CraftBukkit) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing CraftBukkit Changes: dc7c3c61f SPIGOT-5921: Improve setNoDamageTicks for Players 53849f57f SPIGOT-5922: Smithing recipes not registering --- work/CraftBukkit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/work/CraftBukkit b/work/CraftBukkit index 551e770f5f..dc7c3c61fa 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 551e770f5f981053885e2e1a043b4ecb54a80aef +Subproject commit dc7c3c61fa061c87eca5d158f1f1c369620622b6 From eaeac03650f8fd2378d058b898edce62f3ec0d54 Mon Sep 17 00:00:00 2001 From: chickeneer Date: Wed, 1 Jul 2020 22:02:07 -0500 Subject: [PATCH 81/91] Add more material tags for 1.16 (#3750) --- Spigot-API-Patches/Add-Material-Tags.patch | 84 +++++++++++++++------- 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/Spigot-API-Patches/Add-Material-Tags.patch b/Spigot-API-Patches/Add-Material-Tags.patch index 327145a9de..acb1198bed 100644 --- a/Spigot-API-Patches/Add-Material-Tags.patch +++ b/Spigot-API-Patches/Add-Material-Tags.patch @@ -253,7 +253,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .ensureSize("ARROWS", 3); + + /** -+ * Cover all 16 colors of beds. ++ * Covers all colors of beds. + */ + public static final MaterialSetTag BEDS = new MaterialSetTag(keyFor("beds")) + .endsWith("_BED") @@ -286,14 +286,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .add(Material.COBBLESTONE, Material.MOSSY_COBBLESTONE); + + /** -+ * Covers all 16 colors of concrete. ++ * Covers all colors of concrete. + */ + public static final MaterialSetTag CONCRETES = new MaterialSetTag(keyFor("concretes")) + .endsWith("_CONCRETE") + .ensureSize("CONCRETES", 16); + + /** -+ * Covers all 16 colors of concrete powder. ++ * Covers all colors of concrete powder. + */ + public static final MaterialSetTag CONCRETE_POWDER = new MaterialSetTag(keyFor("concrete_powder")) + .endsWith("_CONCRETE_POWDER") @@ -306,7 +306,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .add(Material.COOKED_COD, Material.COOKED_SALMON); + + /** -+ * Covers all 16 dyes. ++ * Covers all dyes. + */ + public static final MaterialSetTag DYES = new MaterialSetTag(keyFor("dyes")) + .endsWith("_DYE") @@ -327,7 +327,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .ensureSize("FENCES", 9); + + /** -+ * Covers all 4 variants of fish buckets. ++ * Covers all variants of fish buckets. + */ + public static final MaterialSetTag FISH_BUCKETS = new MaterialSetTag(keyFor("fish_buckets")) + .add(Material.COD_BUCKET, Material.PUFFERFISH_BUCKET, Material.SALMON_BUCKET, Material.TROPICAL_FISH_BUCKET); @@ -341,21 +341,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .ensureSize("GLASS", 17); + + /** -+ * Covers the non-colored glass panes and 16 stained glass panes (panes only). ++ * Covers the non-colored glass panes and stained glass panes (panes only). + */ + public static final MaterialSetTag GLASS_PANES = new MaterialSetTag(keyFor("glass_panes")) + .endsWith("GLASS_PANE") + .ensureSize("GLASS_PANES", 17); + + /** -+ * Covers all 16 glazed terracotta blocks. ++ * Covers all glazed terracotta blocks. + */ + public static final MaterialSetTag GLAZED_TERRACOTTA = new MaterialSetTag(keyFor("glazed_terracotta")) + .endsWith("GLAZED_TERRACOTTA") + .ensureSize("GLAZED_TERRACOTTA", 16); + + /** -+ * Covers the 16 colors of stained terracotta. ++ * Covers the colors of stained terracotta. + */ + public static final MaterialSetTag STAINED_TERRACOTTA = new MaterialSetTag(keyFor("stained_terracotta")) + .endsWith("TERRACOTTA") @@ -364,7 +364,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .ensureSize("STAINED_TERRACOTTA", 16); + + /** -+ * Covers terracotta along with the 16 stained variants. ++ * Covers terracotta along with the stained variants. + */ + public static final MaterialSetTag TERRACOTTA = new MaterialSetTag(keyFor("terracotta")) + .endsWith("TERRACOTTA") @@ -379,21 +379,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .ensureSize("GOLDEN_APPLES", 2); + + /** -+ * Covers the 3 variants of horse armor. ++ * Covers the variants of horse armor. + */ + public static final MaterialSetTag HORSE_ARMORS = new MaterialSetTag(keyFor("horse_armors")) + .endsWith("_HORSE_ARMOR") + .ensureSize("HORSE_ARMORS", 4); + + /** -+ * Covers the 6 variants of infested blocks. ++ * Covers the variants of infested blocks. + */ + public static final MaterialSetTag INFESTED_BLOCKS = new MaterialSetTag(keyFor("infested_blocks")) + .startsWith("INFESTED_") + .ensureSize("INFESTED_BLOCKS", 6); + + /** -+ * Covers the 3 variants of mushroom blocks. ++ * Covers the variants of mushroom blocks. + */ + public static final MaterialSetTag MUSHROOM_BLOCKS = new MaterialSetTag(keyFor("mushroom_blocks")) + .endsWith("MUSHROOM_BLOCK") @@ -401,7 +401,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .ensureSize("MUSHROOM_BLOCKS", 3); + + /** -+ * Covers both mushrooms. ++ * Covers all mushrooms. + */ + public static final MaterialSetTag MUSHROOMS = new MaterialSetTag(keyFor("mushrooms")) + .add(Material.BROWN_MUSHROOM, Material.RED_MUSHROOM); @@ -435,38 +435,38 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .ensureSize("POTATOES", 3); + + /** -+ * Covers all wooden pressure plates and the weighted pressure plates and 1 stone pressure plate. ++ * Covers all wooden pressure plates and the weighted pressure plates and the stone pressure plate. + */ + public static final MaterialSetTag PRESSURE_PLATES = new MaterialSetTag(keyFor("pressure_plates")) + .endsWith("_PRESSURE_PLATE") + .ensureSize("PRESSURE_PLATES", 12); + + /** -+ * Covers the 3 variants of prismarine blocks. ++ * Covers the variants of prismarine blocks. + */ + public static final MaterialSetTag PRISMARINE = new MaterialSetTag(keyFor("prismarine")) + .add(Material.PRISMARINE, Material.PRISMARINE_BRICKS, Material.DARK_PRISMARINE); + + /** -+ * Covers the 3 variants of prismarine slabs. ++ * Covers the variants of prismarine slabs. + */ + public static final MaterialSetTag PRISMARINE_SLABS = new MaterialSetTag(keyFor("prismarine_slabs")) + .add(Material.PRISMARINE_SLAB, Material.PRISMARINE_BRICK_SLAB, Material.DARK_PRISMARINE_SLAB); + + /** -+ * Covers the 3 variants of prismarine stairs. ++ * Covers the variants of prismarine stairs. + */ + public static final MaterialSetTag PRISMARINE_STAIRS = new MaterialSetTag(keyFor("prismarine_stairs")) + .add(Material.PRISMARINE_STAIRS, Material.PRISMARINE_BRICK_STAIRS, Material.DARK_PRISMARINE_STAIRS); + + /** -+ * Covers the 3 variants of pumpkins. ++ * Covers the variants of pumpkins. + */ + public static final MaterialSetTag PUMPKINS = new MaterialSetTag(keyFor("pumpkins")) + .add(Material.CARVED_PUMPKIN, Material.JACK_O_LANTERN, Material.PUMPKIN); + + /** -+ * Covers the 4 variants of quartz blocks. ++ * Covers the variants of quartz blocks. + */ + public static final MaterialSetTag QUARTZ_BLOCKS = new MaterialSetTag(keyFor("quartz_blocks")) + .add(Material.QUARTZ_BLOCK, Material.QUARTZ_PILLAR, Material.CHISELED_QUARTZ_BLOCK, Material.SMOOTH_QUARTZ); @@ -478,14 +478,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .add(Material.COD, Material.PUFFERFISH, Material.SALMON, Material.TROPICAL_FISH); + + /** -+ * Covers the 4 variants of red sandstone blocks. ++ * Covers the variants of red sandstone blocks. + */ + public static final MaterialSetTag RED_SANDSTONES = new MaterialSetTag(keyFor("red_sandstones")) + .endsWith("RED_SANDSTONE") + .ensureSize("RED_SANDSTONES", 4); + + /** -+ * Covers the 4 variants of sandstone blocks. ++ * Covers the variants of sandstone blocks. + */ + public static final MaterialSetTag SANDSTONES = new MaterialSetTag(keyFor("sandstones")) + .add(Material.SANDSTONE, Material.CHISELED_SANDSTONE, Material.CUT_SANDSTONE, Material.SMOOTH_SANDSTONE); @@ -498,7 +498,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .ensureSize("SPONGES", 2); + + /** -+ * Covers the non-colored and 16 colored shulker boxes. ++ * Covers the non-colored and colored shulker boxes. + */ + public static final MaterialSetTag SHULKER_BOXES = new MaterialSetTag(keyFor("shulker_boxes")) + .endsWith("SHULKER_BOX") @@ -521,14 +521,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .ensureSize("SPAWN_EGGS", 63); + + /** -+ * Covers all 16 colors of stained glass. ++ * Covers all colors of stained glass. + */ + public static final MaterialSetTag STAINED_GLASS = new MaterialSetTag(keyFor("stained_glass")) + .endsWith("_STAINED_GLASS") + .ensureSize("STAINED_GLASS", 16); + + /** -+ * Covers all 16 colors of stained glass panes. ++ * Covers all colors of stained glass panes. + */ + public static final MaterialSetTag STAINED_GLASS_PANES = new MaterialSetTag(keyFor("stained_glass_panes")) + .endsWith("STAINED_GLASS_PANE") @@ -557,26 +557,62 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .not(Material.IRON_TRAPDOOR) + .ensureSize("WOODEN_TRAPDOORS", 8); + ++ /** ++ * Covers the wood variants of gates. ++ */ + public static final MaterialSetTag WOODEN_GATES = new MaterialSetTag(keyFor("wooden_gates")) + .endsWith("_GATE") + .ensureSize("WOODEN_GATES", 8); + ++ /** ++ * Covers the variants of purpur. ++ */ + public static final MaterialSetTag PURPUR = new MaterialSetTag(keyFor("purpur")) + .startsWith("PURPUR_") + .ensureSize("PURPUR", 4); + ++ /** ++ * Covers the variants of signs. ++ */ + public static final MaterialSetTag SIGNS = new MaterialSetTag(keyFor("signs")) + .endsWith("_SIGN") + .ensureSize("SIGNS", 16); + ++ /** ++ * Covers the variants of a regular torch. ++ */ + public static final MaterialSetTag TORCH = new MaterialSetTag(keyFor("torch")) + .add(Material.TORCH, Material.WALL_TORCH) + .ensureSize("TORCH", 2); + ++ /** ++ * Covers the variants of a redstone torch. ++ */ + public static final MaterialSetTag REDSTONE_TORCH = new MaterialSetTag(keyFor("restone_torch")) + .add(Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH) + .ensureSize("REDSTONE_TORCH", 2); + ++ /** ++ * Covers the variants of a soul torch. ++ */ ++ public static final MaterialSetTag SOUL_TORCH = new MaterialSetTag(keyFor("soul_torch")) ++ .add(Material.SOUL_TORCH, Material.SOUL_WALL_TORCH) ++ .ensureSize("SOUL_TORCH", 2); ++ ++ /** ++ * Covers the variants of torches. ++ */ ++ public static final MaterialSetTag TORCHES = new MaterialSetTag(keyFor("torches")) ++ .add(TORCH, REDSTONE_TORCH, SOUL_TORCH) ++ .ensureSize("TORCHES", 6); ++ ++ /** ++ * Covers the variants of lanterns. ++ */ ++ public static final MaterialSetTag LANTERNS = new MaterialSetTag(keyFor("lanterns")) ++ .add(Material.LANTERN, Material.SOUL_LANTERN) ++ .ensureSize("LANTERNS", 2); ++ + @SuppressWarnings("unchecked") + public static final MaterialSetTag COLORABLE = new MaterialSetTag(keyFor("colorable")) + .add(Tag.WOOL, Tag.CARPETS).add(SHULKER_BOXES, STAINED_GLASS, STAINED_GLASS_PANES, CONCRETES, BEDS); From 85408c2f7412a8d936829ebf1c30e1fcc5ee5195 Mon Sep 17 00:00:00 2001 From: Callum <38501234+calumari@users.noreply.github.com> Date: Thu, 2 Jul 2020 08:19:43 +0100 Subject: [PATCH 82/91] Fix hex colours not being allowed in MOTD (#3755) --- .../Implement-extended-PaperServerListPingEvent.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Spigot-Server-Patches/Implement-extended-PaperServerListPingEvent.patch b/Spigot-Server-Patches/Implement-extended-PaperServerListPingEvent.patch index 0da983877c..cfb600ded0 100644 --- a/Spigot-Server-Patches/Implement-extended-PaperServerListPingEvent.patch +++ b/Spigot-Server-Patches/Implement-extended-PaperServerListPingEvent.patch @@ -71,11 +71,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import com.google.common.base.MoreObjects; +import com.google.common.base.Strings; +import com.mojang.authlib.GameProfile; -+import net.minecraft.server.ChatComponentText; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.NetworkManager; +import net.minecraft.server.PacketStatusOutServerInfo; +import net.minecraft.server.ServerPing; ++import org.bukkit.craftbukkit.util.CraftChatMessage; + +import java.util.List; +import java.util.UUID; @@ -155,7 +155,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + ServerPing ping = new ServerPing(); + + // Description -+ ping.setMOTD(new ChatComponentText(event.getMotd())); ++ ping.setMOTD(CraftChatMessage.fromString(event.getMotd())[0]); + + // Players + if (!event.shouldHidePlayers()) { From c09194971e779439c7a20695f62ee630d2af3da0 Mon Sep 17 00:00:00 2001 From: Callum <38501234+calumari@users.noreply.github.com> Date: Thu, 2 Jul 2020 13:58:39 +0100 Subject: [PATCH 83/91] Fix MOTD new line support (#3756) --- .../Implement-extended-PaperServerListPingEvent.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spigot-Server-Patches/Implement-extended-PaperServerListPingEvent.patch b/Spigot-Server-Patches/Implement-extended-PaperServerListPingEvent.patch index cfb600ded0..059115c5e6 100644 --- a/Spigot-Server-Patches/Implement-extended-PaperServerListPingEvent.patch +++ b/Spigot-Server-Patches/Implement-extended-PaperServerListPingEvent.patch @@ -155,7 +155,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + ServerPing ping = new ServerPing(); + + // Description -+ ping.setMOTD(CraftChatMessage.fromString(event.getMotd())[0]); ++ ping.setMOTD(CraftChatMessage.fromString(event.getMotd(), true)[0]); + + // Players + if (!event.shouldHidePlayers()) { From cbc2d143d74adb3df787416d245d36c710c98f70 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Thu, 2 Jul 2020 17:53:21 +0200 Subject: [PATCH 84/91] Support components in ItemMeta (#3513) --- .../Support-components-in-ItemMeta.patch | 77 +++++++++++++++ .../Support-components-in-ItemMeta.patch | 95 +++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 Spigot-API-Patches/Support-components-in-ItemMeta.patch create mode 100644 Spigot-Server-Patches/Support-components-in-ItemMeta.patch diff --git a/Spigot-API-Patches/Support-components-in-ItemMeta.patch b/Spigot-API-Patches/Support-components-in-ItemMeta.patch new file mode 100644 index 0000000000..14a28f8eb2 --- /dev/null +++ b/Spigot-API-Patches/Support-components-in-ItemMeta.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MiniDigger | Martin +Date: Sat, 6 Jun 2020 18:13:16 +0200 +Subject: [PATCH] Support components in ItemMeta + + +diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java ++++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +@@ -0,0 +0,0 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste + @NotNull + String getDisplayName(); + ++ // Paper start ++ /** ++ * Gets the display name that is set. ++ *

++ * Plugins should check that hasDisplayName() returns true ++ * before calling this method. ++ * ++ * @return the display name that is set ++ */ ++ @NotNull ++ net.md_5.bungee.api.chat.BaseComponent[] getDisplayNameComponent(); ++ // Paper end + /** + * Sets the display name. + * +@@ -0,0 +0,0 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste + */ + void setDisplayName(@Nullable String name); + ++ // Paper start ++ /** ++ * Sets the display name. ++ * ++ * @param component the name component to set ++ */ ++ void setDisplayNameComponent(@Nullable net.md_5.bungee.api.chat.BaseComponent[] component); ++ // Paper end + /** + * Checks for existence of a localized name. + * +@@ -0,0 +0,0 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste + @Nullable + List getLore(); + ++ /** ++ * Gets the lore that is set. ++ *

++ * Plugins should check if hasLore() returns true before ++ * calling this method. ++ * ++ * @return a list of lore that is set ++ */ ++ @Nullable ++ List getLoreComponents(); ++ + /** + * Sets the lore for this item. + * Removes lore when given null. +@@ -0,0 +0,0 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste + */ + void setLore(@Nullable List lore); + ++ /** ++ * Sets the lore for this item. ++ * Removes lore when given null. ++ * ++ * @param lore the lore that will be set ++ */ ++ void setLoreComponents(@Nullable List lore); ++ + /** + * Checks for existence of custom model data. + *

diff --git a/Spigot-Server-Patches/Support-components-in-ItemMeta.patch b/Spigot-Server-Patches/Support-components-in-ItemMeta.patch new file mode 100644 index 0000000000..a56ef76629 --- /dev/null +++ b/Spigot-Server-Patches/Support-components-in-ItemMeta.patch @@ -0,0 +1,95 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MiniDigger | Martin +Date: Sat, 6 Jun 2020 18:13:42 +0200 +Subject: [PATCH] Support components in ItemMeta + + +diff --git a/src/main/java/net/minecraft/server/IChatBaseComponent.java b/src/main/java/net/minecraft/server/IChatBaseComponent.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/IChatBaseComponent.java ++++ b/src/main/java/net/minecraft/server/IChatBaseComponent.java +@@ -0,0 +0,0 @@ public interface IChatBaseComponent extends Message, IChatFormatted, Iterable(Lists.transform(this.lore, CraftChatMessage::fromComponent)); + } + ++ // Paper start ++ @Override ++ public List getLoreComponents() { ++ return this.lore == null ? null : new ArrayList<>(this.lore.stream().map(entry -> ++ net.md_5.bungee.chat.ComponentSerializer.parse(IChatBaseComponent.ChatSerializer.componentToJson(entry) ++ )).collect(java.util.stream.Collectors.toList())); ++ } ++ // Paper end + @Override + public void setLore(List lore) { // too tired to think if .clone is better + if (lore == null) { +@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + } + } + ++ // Paper start ++ @Override ++ public void setLoreComponents(List lore) { ++ if (lore == null) { ++ this.lore = null; ++ } else { ++ if (this.lore == null) { ++ safelyAdd(lore, this.lore = new ArrayList<>(lore.size()), Integer.MAX_VALUE); ++ } else { ++ this.lore.clear(); ++ safelyAdd(lore, this.lore, Integer.MAX_VALUE); ++ } ++ } ++ } ++ // Paper end + @Override + public boolean hasCustomModelData() { + return customModelData != null; +@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + } + + for (Object object : addFrom) { ++ // Paper start - support components ++ if(object instanceof net.md_5.bungee.api.chat.BaseComponent[]) { ++ addTo.add(IChatBaseComponent.ChatSerializer.jsonToComponent(net.md_5.bungee.chat.ComponentSerializer.toString((net.md_5.bungee.api.chat.BaseComponent[]) object))); ++ } else ++ // Paper end + if (!(object instanceof String)) { + if (object != null) { + throw new IllegalArgumentException(addFrom + " cannot contain non-string " + object.getClass().getName()); From 0740b03bab71f79a22cebc665fbab8714fabd5c3 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Thu, 2 Jul 2020 15:42:23 -0600 Subject: [PATCH 85/91] Bandaid italic legacy serialization #3757 (#3760) --- .../Improve-Legacy-Component-serialization-size.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch b/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch index 6e253033cf..34ac1ddeaf 100644 --- a/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch +++ b/Spigot-Server-Patches/Improve-Legacy-Component-serialization-size.patch @@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Separate pattern with no group 3, new lines are part of previous string private static final Pattern INCREMENTAL_PATTERN_KEEP_NEWLINES = Pattern.compile("(" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + "[0-9a-fk-orx])|((?:(?:https?):\\/\\/)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + " ]|$))))", Pattern.CASE_INSENSITIVE); // ChatColor.b does not explicitly reset, its more of empty -+ private static final ChatModifier EMPTY = ChatModifier.b; // Paper - OBFHELPER ++ private static final ChatModifier EMPTY = ChatModifier.b.setItalic(false); // Paper - OBFHELPER private static final ChatModifier RESET = ChatModifier.b.setBold(false).setItalic(false).setUnderline(false).setStrikethrough(false).setRandom(false); private final List list = new ArrayList(); From 23ae9ca116c180b44703f329e9165bf7ae838adf Mon Sep 17 00:00:00 2001 From: JanTuck <10961808+JanTuck@users.noreply.github.com> Date: Thu, 2 Jul 2020 23:44:14 +0200 Subject: [PATCH 86/91] [CI-SKIP] Readme update (#3702) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a70156e49d..fbc4befe6b 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ How To (Plugin Developers) paper-api 1.16.1-R0.1-SNAPSHOT provided - + ``` **Or alternatively, with Gradle:** From d6e23b14a79b96718c7342eeb55636491f653f1f Mon Sep 17 00:00:00 2001 From: Aikar Date: Fri, 3 Jul 2020 02:08:00 -0400 Subject: [PATCH 87/91] Updated Upstream (Bukkit/CraftBukkit/Spigot) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 0ca45a21 #503: Add PlayerHarvestBlockEvent dfa80a52 SPIGOT-5930: Add PlayerRespawnEvent#isAnchorSpawn CraftBukkit Changes: 145921e2 #676: Add PlayerHarvestBlockEvent 47abffa2 SPIGOT-5929: Angered zombified piglins do not inherit killed_by_player status 7f6b4f58 SPIGOT-5930: Add PlayerRespawnEvent#isAnchorSpawn 94eff632 SPIGOT-5867, MC-193339: NPE during shutdown when rcon enabled with no password 068618eb SPIGOT-5927: Some items NBT data disappears Spigot Changes: beb7d47c Rebuild patches Fixes #3738 --- .../Add-ArmorStand-Item-Meta.patch | 23 ++++++++----------- work/Bukkit | 2 +- work/CraftBukkit | 2 +- work/Spigot | 2 +- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/Spigot-Server-Patches/Add-ArmorStand-Item-Meta.patch b/Spigot-Server-Patches/Add-ArmorStand-Item-Meta.patch index c444ddd30a..9240c0c237 100644 --- a/Spigot-Server-Patches/Add-ArmorStand-Item-Meta.patch +++ b/Spigot-Server-Patches/Add-ArmorStand-Item-Meta.patch @@ -40,23 +40,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 NBTTagCompound entityTag; CraftMetaArmorStand(CraftMetaItem meta) { - super(meta); -+ +@@ -0,0 +0,0 @@ public class CraftMetaArmorStand extends CraftMetaItem { + } + + CraftMetaArmorStand armorStand = (CraftMetaArmorStand) meta; + // Paper start -+ if (!(meta instanceof CraftMetaArmorStand)) { -+ return; -+ } -+ -+ CraftMetaArmorStand standMeta = (CraftMetaArmorStand) meta; -+ this.invisible = standMeta.invisible; -+ this.noBasePlate = standMeta.noBasePlate; -+ this.showArms = standMeta.showArms; -+ this.small = standMeta.small; -+ this.marker = standMeta.marker; ++ this.invisible = armorStand.invisible; ++ this.noBasePlate = armorStand.noBasePlate; ++ this.showArms = armorStand.showArms; ++ this.small = armorStand.small; ++ this.marker = armorStand.marker; + // Paper end + this.entityTag = armorStand.entityTag; } - CraftMetaArmorStand(NBTTagCompound tag) { @@ -0,0 +0,0 @@ public class CraftMetaArmorStand extends CraftMetaItem { if (tag.hasKey(ENTITY_TAG.NBT)) { diff --git a/work/Bukkit b/work/Bukkit index 1cb03826eb..0ca45a21b9 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 1cb03826ebde4ef887519ce37b0a2a341494a183 +Subproject commit 0ca45a21b94ba986a410ad495ad40b0ee2aa6de4 diff --git a/work/CraftBukkit b/work/CraftBukkit index dc7c3c61fa..145921e2a6 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit dc7c3c61fa061c87eca5d158f1f1c369620622b6 +Subproject commit 145921e2a6ca99081f6019321b63e80756f9cac9 diff --git a/work/Spigot b/work/Spigot index 4d9262cf9f..beb7d47c1d 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit 4d9262cf9f7cf1a38525d21734708c3fe4a28bcb +Subproject commit beb7d47c1d386faa934fceb3b8bd914721074b59 From d1261a7551270df402ce15ed4fe7cd42c9023ef8 Mon Sep 17 00:00:00 2001 From: Aikar Date: Fri, 3 Jul 2020 02:16:51 -0400 Subject: [PATCH 88/91] Support String UUID's in old player skulls Should fix remaining skull issues for people with unconverted old skulls. Fixes #3734 --- .../Support-old-UUID-format-for-NBT.patch | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch b/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch index 9b8a3ec027..4cdc4dd1ae 100644 --- a/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch +++ b/Spigot-Server-Patches/Support-old-UUID-format-for-NBT.patch @@ -7,6 +7,22 @@ We have stored UUID in plenty of places that did not get DFU'd So just look for old format and load it if it exists. +diff --git a/src/main/java/net/minecraft/server/GameProfileSerializer.java b/src/main/java/net/minecraft/server/GameProfileSerializer.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/GameProfileSerializer.java ++++ b/src/main/java/net/minecraft/server/GameProfileSerializer.java +@@ -0,0 +0,0 @@ public final class GameProfileSerializer { + s = nbttagcompound.getString("Name"); + } + ++ // Paper start - support string UUID's ++ if (nbttagcompound.hasKeyOfType("Id", 8)) { ++ uuid = UUID.fromString(nbttagcompound.getString("Id")); ++ } ++ // Paper end + if (nbttagcompound.b("Id")) { + uuid = nbttagcompound.a("Id"); + } diff --git a/src/main/java/net/minecraft/server/NBTTagCompound.java b/src/main/java/net/minecraft/server/NBTTagCompound.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/NBTTagCompound.java From d9da30e8a322926861bd19723159ca509352c42a Mon Sep 17 00:00:00 2001 From: Automated Date: Fri, 3 Jul 2020 19:12:08 -0400 Subject: [PATCH 89/91] [Auto] Updated Upstream (CraftBukkit) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing CraftBukkit Changes: b6a876bc3 SPIGOT-5936: BlockPlaceEvent does not fire for lily_pad --- work/CraftBukkit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/work/CraftBukkit b/work/CraftBukkit index 145921e2a6..b6a876bc34 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 145921e2a6ca99081f6019321b63e80756f9cac9 +Subproject commit b6a876bc34a0cccbfccb890029a44a61b9853285 From 35348c006b54db5065ca69757e9e9bd18d8004c8 Mon Sep 17 00:00:00 2001 From: Automated Date: Fri, 3 Jul 2020 20:02:02 -0400 Subject: [PATCH 90/91] [Auto] Updated Upstream (Bukkit/Spigot) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: a3e22325 Improve javadocs by adding links to dependency docs Spigot Changes: ccb012a2 Improve javadocs by adding links to dependency docs --- work/Bukkit | 2 +- work/Spigot | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/work/Bukkit b/work/Bukkit index 0ca45a21b9..a3e2232545 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 0ca45a21b94ba986a410ad495ad40b0ee2aa6de4 +Subproject commit a3e223254511014327bf59c76e71b7dfe3b4b850 diff --git a/work/Spigot b/work/Spigot index beb7d47c1d..ccb012a27a 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit beb7d47c1d386faa934fceb3b8bd914721074b59 +Subproject commit ccb012a27ac070ee5e2f924743bbbd8d29931e93 From 9fd4674a11098ab0a5347ce7006d14e9a076dc09 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Fri, 3 Jul 2020 14:57:28 -0400 Subject: [PATCH 91/91] Spawn player in correct world on login --- ...awn-player-in-correct-world-on-login.patch | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 Spigot-Server-Patches/Spawn-player-in-correct-world-on-login.patch diff --git a/Spigot-Server-Patches/Spawn-player-in-correct-world-on-login.patch b/Spigot-Server-Patches/Spawn-player-in-correct-world-on-login.patch new file mode 100644 index 0000000000..8148222591 --- /dev/null +++ b/Spigot-Server-Patches/Spawn-player-in-correct-world-on-login.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Wyatt Childers +Date: Fri, 3 Jul 2020 14:57:05 -0400 +Subject: [PATCH] Spawn player in correct world on login + + +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 { + }String lastKnownName = s; // Paper + // CraftBukkit end + +- if (nbttagcompound != null) { ++ // Paper start - move logic in Entity to here, to use bukkit supplied world UUID. ++ if (nbttagcompound != null && nbttagcompound.hasKey("WorldUUIDMost") && nbttagcompound.hasKey("WorldUUIDLeast")) { ++ UUID uid = new UUID(nbttagcompound.getLong("WorldUUIDMost"), nbttagcompound.getLong("WorldUUIDLeast")); ++ org.bukkit.World bWorld = Bukkit.getServer().getWorld(uid); ++ if (bWorld != null) { ++ resourcekey = ((CraftWorld) bWorld).getHandle().getDimensionKey(); ++ } else { ++ resourcekey = World.OVERWORLD; ++ } ++ } else if (nbttagcompound != null) { ++ // Vanilla migration support ++ // Paper end + DataResult dataresult = DimensionManager.a(new Dynamic(DynamicOpsNBT.a, nbttagcompound.get("Dimension"))); + Logger logger = PlayerList.LOGGER; +