diff --git a/Spigot-Server-Patches/0352-Prevent-rayTrace-from-loading-chunks.patch b/Spigot-Server-Patches/0352-Prevent-rayTrace-from-loading-chunks.patch new file mode 100644 index 0000000000..0fc0b84540 --- /dev/null +++ b/Spigot-Server-Patches/0352-Prevent-rayTrace-from-loading-chunks.patch @@ -0,0 +1,41 @@ +From 50d294d2c40846fbbfb0dd3eb1e2e2dbdd8c4744 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Mon, 26 Nov 2018 19:21:58 -0500 +Subject: [PATCH] Prevent rayTrace from loading chunks + +ray tracing into an unloaded chunk should be treated as a miss +this saves a ton of lag for when AI tries to raytrace near unloaded chunks. + +diff --git a/src/main/java/net/minecraft/server/IBlockAccess.java b/src/main/java/net/minecraft/server/IBlockAccess.java +index 8753bea614..039f27312a 100644 +--- a/src/main/java/net/minecraft/server/IBlockAccess.java ++++ b/src/main/java/net/minecraft/server/IBlockAccess.java +@@ -27,7 +27,15 @@ public interface IBlockAccess { + + default MovingObjectPositionBlock rayTrace(RayTrace raytrace) { + return (MovingObjectPositionBlock) a(raytrace, (raytrace1, blockposition) -> { +- IBlockData iblockdata = this.getType(blockposition); ++ // Paper start - Prevent raytrace from loading chunks ++ IBlockData iblockdata = ((World)this).getTypeIfLoaded(blockposition); ++ if (iblockdata == null) { ++ // copied the last function parameter (listed below) ++ Vec3D vec3d = raytrace1.b().d(raytrace1.a()); ++ ++ return MovingObjectPositionBlock.a(raytrace1.a(), EnumDirection.a(vec3d.x, vec3d.y, vec3d.z), new BlockPosition(raytrace1.a())); ++ } ++ // Paper end + Fluid fluid = this.getFluid(blockposition); + Vec3D vec3d = raytrace1.b(); + Vec3D vec3d1 = raytrace1.a(); +@@ -96,7 +104,7 @@ public interface IBlockAccess { + double d13 = d10 * (i1 > 0 ? 1.0D - MathHelper.h(d4) : MathHelper.h(d4)); + double d14 = d11 * (j1 > 0 ? 1.0D - MathHelper.h(d5) : MathHelper.h(d5)); + +- Object object; ++ T object; // Paper - decompile fix (TODO move to mcdev) + + do { + if (d12 > 1.0D && d13 > 1.0D && d14 > 1.0D) { +-- +2.21.0 + diff --git a/Spigot-Server-Patches/0402-Handle-Large-Packets-disconnecting-client.patch b/Spigot-Server-Patches/0353-Handle-Large-Packets-disconnecting-client.patch similarity index 90% rename from Spigot-Server-Patches/0402-Handle-Large-Packets-disconnecting-client.patch rename to Spigot-Server-Patches/0353-Handle-Large-Packets-disconnecting-client.patch index 11f1ace845..7f12c84f3b 100644 --- a/Spigot-Server-Patches/0402-Handle-Large-Packets-disconnecting-client.patch +++ b/Spigot-Server-Patches/0353-Handle-Large-Packets-disconnecting-client.patch @@ -1,4 +1,4 @@ -From b07b820037f167f150b3af33ed2fff7e9cd88ea6 Mon Sep 17 00:00:00 2001 +From b04ba74419a14965aeb44f1762ee3a39ac70fdfa Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 27 Nov 2018 21:18:06 -0500 Subject: [PATCH] Handle Large Packets disconnecting client @@ -7,7 +7,7 @@ If a players inventory is too big to send in a single packet, split the inventory set into multiple packets instead. diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java -index c536979140..0b8796d0ae 100644 +index 38386d5886..2c28b97d81 100644 --- a/src/main/java/net/minecraft/server/NetworkManager.java +++ b/src/main/java/net/minecraft/server/NetworkManager.java @@ -99,6 +99,15 @@ public class NetworkManager extends SimpleChannelInboundHandler> { @@ -24,7 +24,7 @@ index c536979140..0b8796d0ae 100644 + } + // Paper end if (throwable instanceof SkipEncodeException) { - NetworkManager.g.debug("Skipping packet due to errors", throwable.getCause()); + NetworkManager.LOGGER.debug("Skipping packet due to errors", throwable.getCause()); } else { diff --git a/src/main/java/net/minecraft/server/Packet.java b/src/main/java/net/minecraft/server/Packet.java index 601d4d0fa2..2d8e6a2f4a 100644 @@ -44,7 +44,7 @@ index 601d4d0fa2..2d8e6a2f4a 100644 return false; } diff --git a/src/main/java/net/minecraft/server/PacketEncoder.java b/src/main/java/net/minecraft/server/PacketEncoder.java -index 2aa805eef1..4f7bc186aa 100644 +index 63c4dbd327..b0cfef52cb 100644 --- a/src/main/java/net/minecraft/server/PacketEncoder.java +++ b/src/main/java/net/minecraft/server/PacketEncoder.java @@ -49,7 +49,31 @@ public class PacketEncoder extends MessageToByteEncoder> { @@ -80,20 +80,20 @@ index 2aa805eef1..4f7bc186aa 100644 + // Paper end } diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java -index 8e35d14f97..4a57e8a3ec 100644 +index d19a30ad87..58eccd9c63 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java -@@ -76,7 +76,7 @@ public class PacketPlayOutMapChunk implements Packet { - this.c = packetdataserializer.g(); - int i = packetdataserializer.g(); +@@ -68,7 +68,7 @@ public class PacketPlayOutMapChunk implements Packet { + this.d = packetdataserializer.l(); + int i = packetdataserializer.i(); - if (i > 2097152) { + if (i > 2097152) { // Paper - if this changes, update PacketEncoder throw new RuntimeException("Chunk Packet trying to allocate too much memory on read."); } else { - this.d = new byte[i]; + this.e = new byte[i]; diff --git a/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java b/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java -index 706d843859..c0d8f8b428 100644 +index f7c3655671..631234324d 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java @@ -9,6 +9,15 @@ public class PacketPlayOutWindowItems implements Packet { diff --git a/Spigot-Server-Patches/0403-Lazy-init-world-storage-in-CraftOfflinePlayer.patch b/Spigot-Server-Patches/0354-Lazy-init-world-storage-in-CraftOfflinePlayer.patch similarity index 89% rename from Spigot-Server-Patches/0403-Lazy-init-world-storage-in-CraftOfflinePlayer.patch rename to Spigot-Server-Patches/0354-Lazy-init-world-storage-in-CraftOfflinePlayer.patch index 92eadc8e93..3429a4f3eb 100644 --- a/Spigot-Server-Patches/0403-Lazy-init-world-storage-in-CraftOfflinePlayer.patch +++ b/Spigot-Server-Patches/0354-Lazy-init-world-storage-in-CraftOfflinePlayer.patch @@ -1,4 +1,4 @@ -From 240f4d59799fbc801df981f49420cf9b5a9b563f Mon Sep 17 00:00:00 2001 +From a12c2a8d4e4888be3310169ad4332ec182f89868 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 11 Dec 2018 22:25:07 -0500 Subject: [PATCH] Lazy init world storage in CraftOfflinePlayer @@ -8,10 +8,10 @@ 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 698cfb918b..fbdb2df27d 100644 +index 24b06a0b7e..294f3de00c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java -@@ -27,12 +27,12 @@ import org.bukkit.plugin.Plugin; +@@ -25,12 +25,12 @@ import org.bukkit.plugin.Plugin; public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializable { private final GameProfile profile; private final CraftServer server; @@ -26,7 +26,7 @@ index 698cfb918b..fbdb2df27d 100644 } -@@ -169,8 +169,23 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa +@@ -167,8 +167,23 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa return hash; } @@ -51,7 +51,7 @@ index 698cfb918b..fbdb2df27d 100644 } private NBTTagCompound getBukkitData() { -@@ -187,7 +202,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa +@@ -185,7 +200,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa } private File getDataFile() { diff --git a/Spigot-Server-Patches/0404-Add-PlayerConnectionCloseEvent.patch b/Spigot-Server-Patches/0355-Add-PlayerConnectionCloseEvent.patch similarity index 82% rename from Spigot-Server-Patches/0404-Add-PlayerConnectionCloseEvent.patch rename to Spigot-Server-Patches/0355-Add-PlayerConnectionCloseEvent.patch index 8327d25067..9f23817c16 100644 --- a/Spigot-Server-Patches/0404-Add-PlayerConnectionCloseEvent.patch +++ b/Spigot-Server-Patches/0355-Add-PlayerConnectionCloseEvent.patch @@ -1,4 +1,4 @@ -From 162fee0c9a057136c8fc744b62f1c0926a1e6220 Mon Sep 17 00:00:00 2001 +From 1303e84091c20368a7a27403d046af1ec26ee6f8 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sun, 7 Oct 2018 12:05:28 -0700 Subject: [PATCH] Add PlayerConnectionCloseEvent @@ -34,34 +34,26 @@ how PlayerPreLoginEvent interacts with PlayerConnectionCloseEvent is undefined. diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/java/net/minecraft/server/LoginListener.java -index ca76f2a380..dfe7a029f8 100644 +index 5d46a975e3..9e4bc24058 100644 --- a/src/main/java/net/minecraft/server/LoginListener.java +++ b/src/main/java/net/minecraft/server/LoginListener.java -@@ -35,9 +35,9 @@ public class LoginListener implements PacketLoginInListener, ITickable { +@@ -35,9 +35,9 @@ public class LoginListener implements PacketLoginInListener { private final byte[] e = new byte[4]; private final MinecraftServer server; public final NetworkManager networkManager; - private LoginListener.EnumProtocolState g; + private LoginListener.EnumProtocolState g; public final LoginListener.EnumProtocolState getLoginState() { return this.g; }; // Paper - OBFHELPER private int h; -- private GameProfile i; private void setGameProfile(GameProfile profile) { i = profile; } private GameProfile getGameProfile() { return i; } // Paper - OBFHELPER -+ private GameProfile i; private void setGameProfile(GameProfile profile) { i = profile; } public final GameProfile getGameProfile() { return i; } // Paper - OBFHELPER +- private GameProfile i; private void setGameProfile(final GameProfile profile) { this.i = profile; } private GameProfile getGameProfile() { return this.i; } // Paper - OBFHELPER ++ private GameProfile i; private void setGameProfile(final GameProfile profile) { this.i = profile; } public GameProfile getGameProfile() { return this.i; } // Paper - OBFHELPER private final String j; private SecretKey loginKey; private EntityPlayer l; diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java -index 0b8796d0ae..553637239c 100644 +index 2c28b97d81..1b0643c27f 100644 --- a/src/main/java/net/minecraft/server/NetworkManager.java +++ b/src/main/java/net/minecraft/server/NetworkManager.java -@@ -16,6 +16,7 @@ import io.netty.handler.timeout.TimeoutException; - import io.netty.util.AttributeKey; - import io.netty.util.concurrent.Future; - import io.netty.util.concurrent.GenericFutureListener; -+ - import java.net.SocketAddress; - import java.util.Queue; - import java.util.concurrent.locks.ReentrantReadWriteLock; -@@ -357,6 +358,26 @@ public class NetworkManager extends SimpleChannelInboundHandler> { +@@ -346,6 +346,26 @@ public class NetworkManager extends SimpleChannelInboundHandler> { this.i().a(new ChatMessage("multiplayer.disconnect.generic", new Object[0])); } this.packetQueue.clear(); // Free up packet queue. diff --git a/Spigot-Server-Patches/0405-Prevent-Enderman-from-loading-chunks.patch b/Spigot-Server-Patches/0356-Prevent-Enderman-from-loading-chunks.patch similarity index 68% rename from Spigot-Server-Patches/0405-Prevent-Enderman-from-loading-chunks.patch rename to Spigot-Server-Patches/0356-Prevent-Enderman-from-loading-chunks.patch index 870a384ec9..695795c493 100644 --- a/Spigot-Server-Patches/0405-Prevent-Enderman-from-loading-chunks.patch +++ b/Spigot-Server-Patches/0356-Prevent-Enderman-from-loading-chunks.patch @@ -1,14 +1,14 @@ -From 747ca560c9bc065b36c1649811507dc0d1a6e456 Mon Sep 17 00:00:00 2001 +From dcb15c23a726d0a0bb92270430795b32282595e9 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Tue, 18 Dec 2018 02:15:08 +0000 Subject: [PATCH] Prevent Enderman from loading chunks diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/java/net/minecraft/server/EntityEnderman.java -index e4aba0e0a8..9450404428 100644 +index de2d995349..f08f139e97 100644 --- a/src/main/java/net/minecraft/server/EntityEnderman.java +++ b/src/main/java/net/minecraft/server/EntityEnderman.java -@@ -297,7 +297,8 @@ public class EntityEnderman extends EntityMonster { +@@ -315,7 +315,8 @@ public class EntityEnderman extends EntityMonster { 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); @@ -16,18 +16,18 @@ index e4aba0e0a8..9450404428 100644 + IBlockData iblockdata = world.getTypeIfLoaded(blockposition); // Paper + if (iblockdata == null) return; // Paper Block block = iblockdata.getBlock(); - MovingObjectPosition movingobjectposition = world.rayTrace(new Vec3D((double) ((float) MathHelper.floor(this.enderman.locX) + 0.5F), (double) ((float) j + 0.5F), (double) ((float) MathHelper.floor(this.enderman.locZ) + 0.5F)), new Vec3D((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F)), FluidCollisionOption.NEVER, true, false); - boolean flag = movingobjectposition != null && movingobjectposition.getBlockPosition().equals(blockposition); -@@ -335,7 +336,8 @@ public class EntityEnderman extends EntityMonster { + 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); +@@ -357,7 +358,8 @@ public class EntityEnderman extends EntityMonster { 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); - IBlockData iblockdata = world.getType(blockposition); + IBlockData iblockdata = world.getTypeIfLoaded(blockposition); // Paper + if (iblockdata == null) return; // Paper - IBlockData iblockdata1 = world.getType(blockposition.down()); + BlockPosition blockposition1 = blockposition.down(); + IBlockData iblockdata1 = world.getType(blockposition1); IBlockData iblockdata2 = Block.getValidBlockForPosition(getEnderman().getCarried(), getEnderman().world, blockposition); // Paper - Fix MC-124320 - -- 2.21.0 diff --git a/Spigot-Server-Patches/0406-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch b/Spigot-Server-Patches/0357-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch similarity index 90% rename from Spigot-Server-Patches/0406-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch rename to Spigot-Server-Patches/0357-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch index e587636248..3595af801b 100644 --- a/Spigot-Server-Patches/0406-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch +++ b/Spigot-Server-Patches/0357-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch @@ -1,4 +1,4 @@ -From de09720b1332eaf211d79f51318a4c3c1a12eb2e Mon Sep 17 00:00:00 2001 +From 3addeaa55215900270a9eff5d4a17224047ffc70 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 2 Jan 2019 00:35:43 -0600 Subject: [PATCH] Add APIs to replace OfflinePlayer#getLastPlayed @@ -16,10 +16,10 @@ intent to remove) and replace it with two new methods, clearly named and documented as to their purpose. diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 57c6455bd8..541461275c 100644 +index 71ad35f710..2341638617 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java -@@ -72,6 +72,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { +@@ -74,6 +74,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { public int ping; public boolean viewingCredits; private int containerUpdateDelay; // Paper @@ -28,10 +28,10 @@ index 57c6455bd8..541461275c 100644 public boolean queueHealthUpdatePacket = false; public net.minecraft.server.PacketPlayOutUpdateHealth queuedHealthUpdatePacket; diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java -index ec760325ba..135d25abd2 100644 +index 8233292688..109c27b647 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java -@@ -95,6 +95,7 @@ public abstract class PlayerList { +@@ -94,6 +94,7 @@ public abstract class PlayerList { } public void a(NetworkManager networkmanager, EntityPlayer entityplayer) { @@ -40,10 +40,10 @@ index ec760325ba..135d25abd2 100644 UserCache usercache = this.server.getUserCache(); GameProfile gameprofile1 = usercache.a(gameprofile.getId()); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java -index fbdb2df27d..e1973c5d67 100644 +index 294f3de00c..a3c6032d48 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java -@@ -245,6 +245,61 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa +@@ -243,6 +243,61 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa return getData() != null; } @@ -106,10 +106,10 @@ index fbdb2df27d..e1973c5d67 100644 NBTTagCompound data = getData(); if (data == null) return null; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 8d32982c53..a03796cd5e 100644 +index 5f752784d5..90e61097aa 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -132,6 +132,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -137,6 +137,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; private String resourcePackHash; private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit @@ -117,7 +117,7 @@ index 8d32982c53..a03796cd5e 100644 // Paper end public CraftPlayer(CraftServer server, EntityPlayer entity) { -@@ -1337,6 +1338,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1362,6 +1363,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.firstPlayed = firstPlayed; } @@ -136,7 +136,7 @@ index 8d32982c53..a03796cd5e 100644 public void readExtraData(NBTTagCompound nbttagcompound) { hasPlayedBefore = true; if (nbttagcompound.hasKey("bukkit")) { -@@ -1359,6 +1372,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1384,6 +1397,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } public void setExtraData(NBTTagCompound nbttagcompound) { @@ -145,7 +145,7 @@ index 8d32982c53..a03796cd5e 100644 if (!nbttagcompound.hasKey("bukkit")) { nbttagcompound.set("bukkit", new NBTTagCompound()); } -@@ -1373,6 +1388,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1398,6 +1413,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { data.setLong("firstPlayed", getFirstPlayed()); data.setLong("lastPlayed", System.currentTimeMillis()); data.setString("lastKnownName", handle.getName()); diff --git a/Spigot-Server-Patches/0358-Fix-PlayerEditBookEvent.patch b/Spigot-Server-Patches/0358-Fix-PlayerEditBookEvent.patch new file mode 100644 index 0000000000..161008a0d7 --- /dev/null +++ b/Spigot-Server-Patches/0358-Fix-PlayerEditBookEvent.patch @@ -0,0 +1,33 @@ +From 93c6fab37a8de11d2718a077f6700fd172aa0271 Mon Sep 17 00:00:00 2001 +From: Michael Himing +Date: Sun, 16 Dec 2018 13:07:33 +1100 +Subject: [PATCH] Fix PlayerEditBookEvent + +- Updating book writing (not signing) mutated the original item, making +it impossible to properly cancel the event or modify the book meta + +- When the event was cancelled, the client's book would keep the +cancelled writing + +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index 15fb7ed608..71d10f9b9c 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -860,9 +860,11 @@ public class PlayerConnection implements PacketListenerPlayIn { + itemstack2.a("pages", (NBTBase) nbttaglist); + this.player.a(packetplayinbedit.d(), CraftEventFactory.handleEditBookEvent(player, enumitemslot, itemstack1, itemstack2)); // CraftBukkit + } else { +- ItemStack old = itemstack1.cloneItemStack(); // CraftBukkit +- itemstack1.a("pages", (NBTBase) itemstack.getTag().getList("pages", 8)); +- CraftEventFactory.handleEditBookEvent(player, enumitemslot, old, itemstack1); // CraftBukkit ++ // Paper start - dont mutate players current item, set it from the event ++ ItemStack newBook = itemstack1.cloneItemStack(); ++ newBook.getOrCreateTagAndSet("pages", (NBTBase)itemstack.getTag().getList("pages", 8)); ++ this.player.setSlot(enumitemslot, CraftEventFactory.handleEditBookEvent(player, enumitemslot, itemstack1, newBook)); ++ // Paper end + } + } + +-- +2.21.0 + diff --git a/Spigot-Server-Patches/0408-Workaround-for-vehicle-tracking-issue-on-disconnect.patch b/Spigot-Server-Patches/0359-Workaround-for-vehicle-tracking-issue-on-disconnect.patch similarity index 74% rename from Spigot-Server-Patches/0408-Workaround-for-vehicle-tracking-issue-on-disconnect.patch rename to Spigot-Server-Patches/0359-Workaround-for-vehicle-tracking-issue-on-disconnect.patch index fd3b6aa990..04c15487b9 100644 --- a/Spigot-Server-Patches/0408-Workaround-for-vehicle-tracking-issue-on-disconnect.patch +++ b/Spigot-Server-Patches/0359-Workaround-for-vehicle-tracking-issue-on-disconnect.patch @@ -1,16 +1,16 @@ -From c693e26da2f98ce91cb05d220f05c5faf5a253c3 Mon Sep 17 00:00:00 2001 +From 830ce03b89e87350520c8d80551d9d2a3b9b3063 Mon Sep 17 00:00:00 2001 From: connorhartley Date: Mon, 7 Jan 2019 14:43:48 -0600 Subject: [PATCH] Workaround for vehicle tracking issue on disconnect diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 541461275c..1d37300832 100644 +index 2341638617..f4ee78efc6 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java -@@ -1119,6 +1119,13 @@ public class EntityPlayer extends EntityHuman implements ICrafting { +@@ -1260,6 +1260,13 @@ public class EntityPlayer extends EntityHuman implements ICrafting { public void n() { - this.cB = true; + this.ct = true; this.ejectPassengers(); + + // Paper start - Workaround an issue where the vehicle doesn't track the passenger disconnection dismount. @@ -19,8 +19,8 @@ index 541461275c..1d37300832 100644 + } + // Paper end + - if (this.sleeping) { - this.a(true, false, false); + if (this.isSleeping()) { + this.wakeup(true, false, false); } -- 2.21.0 diff --git a/Spigot-Server-Patches/0409-Fire-BlockPistonRetractEvent-for-all-empty-pistons.patch b/Spigot-Server-Patches/0360-Fire-BlockPistonRetractEvent-for-all-empty-pistons.patch similarity index 91% rename from Spigot-Server-Patches/0409-Fire-BlockPistonRetractEvent-for-all-empty-pistons.patch rename to Spigot-Server-Patches/0360-Fire-BlockPistonRetractEvent-for-all-empty-pistons.patch index a6d13d2990..80065e28a2 100644 --- a/Spigot-Server-Patches/0409-Fire-BlockPistonRetractEvent-for-all-empty-pistons.patch +++ b/Spigot-Server-Patches/0360-Fire-BlockPistonRetractEvent-for-all-empty-pistons.patch @@ -1,4 +1,4 @@ -From c9cd937ba5a7735bb88c1be1b478d0adcc871a9a Mon Sep 17 00:00:00 2001 +From fd910a7bbba041768fa86c732b25481750bffeda Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Thu, 31 Jan 2019 16:33:36 -0500 Subject: [PATCH] Fire BlockPistonRetractEvent for all empty pistons @@ -24,10 +24,10 @@ Instead we opt to remove the check entirely so that the event fires for all piston types. diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java -index dbe0ff33a0..0109484e0a 100644 +index 170a339eda..a5573f21fc 100644 --- a/src/main/java/net/minecraft/server/BlockPiston.java +++ b/src/main/java/net/minecraft/server/BlockPiston.java -@@ -118,7 +118,7 @@ public class BlockPiston extends BlockDirectional { +@@ -121,7 +121,7 @@ public class BlockPiston extends BlockDirectional { } // CraftBukkit start @@ -36,7 +36,7 @@ index dbe0ff33a0..0109484e0a 100644 org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); BlockPistonRetractEvent event = new BlockPistonRetractEvent(block, ImmutableList.of(), CraftBlock.notchToBlockFace(enumdirection)); world.getServer().getPluginManager().callEvent(event); -@@ -126,7 +126,7 @@ public class BlockPiston extends BlockDirectional { +@@ -129,7 +129,7 @@ public class BlockPiston extends BlockDirectional { if (event.isCancelled()) { return; } diff --git a/Spigot-Server-Patches/0410-Block-Entity-remove-from-being-called-on-Players.patch b/Spigot-Server-Patches/0361-Block-Entity-remove-from-being-called-on-Players.patch similarity index 89% rename from Spigot-Server-Patches/0410-Block-Entity-remove-from-being-called-on-Players.patch rename to Spigot-Server-Patches/0361-Block-Entity-remove-from-being-called-on-Players.patch index 681f6c4b2e..c92922a9cb 100644 --- a/Spigot-Server-Patches/0410-Block-Entity-remove-from-being-called-on-Players.patch +++ b/Spigot-Server-Patches/0361-Block-Entity-remove-from-being-called-on-Players.patch @@ -1,4 +1,4 @@ -From 355b9a0bb1d1af72cb61b3f8850c5b387dcf7b89 Mon Sep 17 00:00:00 2001 +From f7a06ddae22fa03ac092cced2e46b70dad904428 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 4 Feb 2019 23:33:24 -0500 Subject: [PATCH] Block Entity#remove from being called on Players @@ -12,10 +12,10 @@ Player we will look at limiting the scope of this change. It appears to be unintentional in the few cases we've seen so far. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a03796cd5e..eb5971ac19 100644 +index 90e61097aa..1412e68fee 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1942,6 +1942,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1952,6 +1952,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void resetCooldown() { getHandle().resetCooldown(); } diff --git a/Spigot-Server-Patches/0411-Allow-Saving-of-Oversized-Chunks.patch b/Spigot-Server-Patches/0362-Allow-Saving-of-Oversized-Chunks.patch similarity index 61% rename from Spigot-Server-Patches/0411-Allow-Saving-of-Oversized-Chunks.patch rename to Spigot-Server-Patches/0362-Allow-Saving-of-Oversized-Chunks.patch index 99f072cb83..d2444078ee 100644 --- a/Spigot-Server-Patches/0411-Allow-Saving-of-Oversized-Chunks.patch +++ b/Spigot-Server-Patches/0362-Allow-Saving-of-Oversized-Chunks.patch @@ -1,4 +1,4 @@ -From 828d56a3dccc292ea38fa319aaec5477291e3e8c Mon Sep 17 00:00:00 2001 +From 2e245eea41f1bb1a961a3c23ac0b696ec6ac3007 Mon Sep 17 00:00:00 2001 From: Aikar Date: Fri, 15 Feb 2019 01:08:19 -0500 Subject: [PATCH] Allow Saving of Oversized Chunks @@ -31,10 +31,10 @@ this fix, as the data will remain in the oversized file. Once the server returns to a jar with this fix, the data will be restored. diff --git a/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java b/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java -index 12268f87b9..e1f7e06ab2 100644 +index 9fd8a75dae..d49afd622e 100644 --- a/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java +++ b/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java -@@ -39,6 +39,7 @@ public class NBTCompressedStreamTools { +@@ -69,6 +69,7 @@ public class NBTCompressedStreamTools { } @@ -42,7 +42,7 @@ index 12268f87b9..e1f7e06ab2 100644 public static NBTTagCompound a(DataInputStream datainputstream) throws IOException { return a((DataInput) datainputstream, NBTReadLimiter.a); } -@@ -59,6 +60,7 @@ public class NBTCompressedStreamTools { +@@ -89,6 +90,7 @@ public class NBTCompressedStreamTools { } } @@ -50,59 +50,81 @@ index 12268f87b9..e1f7e06ab2 100644 public static void a(NBTTagCompound nbttagcompound, DataOutput dataoutput) throws IOException { a((NBTBase) nbttagcompound, dataoutput); } +diff --git a/src/main/java/net/minecraft/server/NBTTagList.java b/src/main/java/net/minecraft/server/NBTTagList.java +index b7c94fe238..80eea5dfbd 100644 +--- a/src/main/java/net/minecraft/server/NBTTagList.java ++++ b/src/main/java/net/minecraft/server/NBTTagList.java +@@ -11,7 +11,7 @@ import java.util.Objects; + + public class NBTTagList extends NBTList { + +- private List list = Lists.newArrayList(); ++ List list = Lists.newArrayList(); // Paper - private -> package + private byte type = 0; + + public NBTTagList() {} diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java -index c20511588d..82f7af46f8 100644 +index e68f901943..995a893774 100644 --- a/src/main/java/net/minecraft/server/RegionFile.java +++ b/src/main/java/net/minecraft/server/RegionFile.java -@@ -78,6 +78,7 @@ public class RegionFile { - } - header.clear(); - java.nio.IntBuffer headerAsInts = header.asIntBuffer(); -+ initOversizedState(); - // Paper End +@@ -23,7 +23,7 @@ public class RegionFile implements AutoCloseable { + // Minecraft is limited to 256 sections per chunk. So 1MB. This can easily be overriden. + // So we extend this to use the REAL size when the count is maxed by seeking to that section and reading the length. + private static final boolean ENABLE_EXTENDED_SAVE = Boolean.parseBoolean(System.getProperty("net.minecraft.server.RegionFile.enableExtendedSave", "true")); +- private final File file; ++ final File file; // Paper - private -> package + // Spigot end + private static final byte[] a = new byte[4096]; + private final RandomAccessFile b; private RandomAccessFile getDataFile() { return this.b; } // Paper - OBFHELPER +@@ -66,6 +66,7 @@ public class RegionFile implements AutoCloseable { + } + header.clear(); + java.nio.IntBuffer headerAsInts = header.asIntBuffer(); ++ initOversizedState(); + // Paper End - for (j = 0; j < 1024; ++j) { -@@ -93,7 +94,7 @@ public class RegionFile { - this.c.seek(j * 4 + 4); // Go back to where we were - } + int k; +@@ -83,7 +84,7 @@ public class RegionFile implements AutoCloseable { + this.b.seek(j * 4 + 4); // Go back to where we were } -- if (k > 0 && (k >> 8) > 1 && (k >> 8) + (k & 255) <= this.f.size()) { // Paper >= 1 as 0/1 are the headers, and negative isnt valid -+ if (k > 0 && (k >> 8) > 1 && (k >> 8) + (length) <= this.f.size()) { // Paper >= 1 as 0/1 are the headers, and negative isnt valid - for (int l = 0; l < (length); ++l) { - // Spigot end - this.f.set((k >> 8) + l, false); -@@ -119,7 +120,7 @@ public class RegionFile { + } +- if (k > 0 && (k >> 8) > 1 && (k >> 8) + (k & 255) <= this.e.size()) { // Paper >= 1 as 0/1 are the headers, and negative isnt valid ++ if (k > 0 && (k >> 8) > 1 && (k >> 8) + (length) <= this.e.size()) { // Paper >= 1 as 0/1 are the headers, and negative isnt valid + for (int l = 0; l < (length); ++l) { + // Spigot end + this.e.set((k >> 8) + l, false); +@@ -106,7 +107,7 @@ public class RegionFile implements AutoCloseable { } @Nullable -- public synchronized DataInputStream a(int i, int j) { -+ public synchronized DataInputStream getReadStream(int i, int j) { return a(i, j); } @Nullable public synchronized DataInputStream a(int i, int j) { // Paper - OBFHELPER - if (this.e(i, j)) { - return null; - } else { -@@ -203,8 +204,8 @@ public class RegionFile { +- public synchronized DataInputStream a(ChunkCoordIntPair chunkcoordintpair) { ++ public synchronized DataInputStream getReadStream(ChunkCoordIntPair chunkcoordintpair) { return this.a(chunkcoordintpair); } public synchronized DataInputStream a(ChunkCoordIntPair chunkcoordintpair) { // Paper - OBFHELPER + try { + int i = this.getOffset(chunkcoordintpair); + +@@ -182,8 +183,8 @@ public class RegionFile implements AutoCloseable { + } } - @Nullable -- public DataOutputStream c(int i, int j) { -- return this.e(i, j) ? null : new DataOutputStream(new BufferedOutputStream(new DeflaterOutputStream(new RegionFile.ChunkBuffer(i, j)))); -+ public DataOutputStream getWriteStream(int i, int j) { return c(i, j); } @Nullable public DataOutputStream c(int i, int j) { // Paper - OBFHELPER -+ return this.e(i, j) ? null : new DataOutputStream(new RegionFile.ChunkBuffer(i, j)); // Paper - remove middleware, move deflate to .close() for dynamic levels +- public DataOutputStream c(ChunkCoordIntPair chunkcoordintpair) { +- return new DataOutputStream(new BufferedOutputStream(new DeflaterOutputStream(new RegionFile.ChunkBuffer(chunkcoordintpair)))); ++ public DataOutputStream getWriteStream(ChunkCoordIntPair chunkcoordintpair) { return this.c(chunkcoordintpair); } public DataOutputStream c(ChunkCoordIntPair chunkcoordintpair) { // Paper - OBFHELPER ++ return new DataOutputStream(new RegionFile.ChunkBuffer(chunkcoordintpair)); // Paper - remove middleware, move deflate to .close() for dynamic levels } - protected synchronized void a(int i, int j, byte[] abyte, int k) { -@@ -222,8 +223,9 @@ public class RegionFile { + protected synchronized void a(ChunkCoordIntPair chunkcoordintpair, byte[] abyte, int i) { +@@ -201,8 +202,9 @@ public class RegionFile implements AutoCloseable { - if (k1 >= 256) { + if (i1 >= 256) { // Spigot start -- if (!ENABLE_EXTENDED_SAVE) return; -+ if (!USE_SPIGOT_OVERSIZED_METHOD && !RegionFileCache.isOverzealous()) throw new ChunkTooLargeException(i, j, k1); // Paper - throw error instead - org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING,"Large Chunk Detected: ({0}, {1}) Size: {2} {3}", new Object[]{i, j, k1, this.b}); -+ if (!ENABLE_EXTENDED_SAVE) return; +- if (!ENABLE_EXTENDED_SAVE) throw new RuntimeException(String.format("Too big to save, %d > 1048576", i)); ++ if (!USE_SPIGOT_OVERSIZED_METHOD && !RegionFileCache.isOverzealous()) throw new ChunkTooLargeException(chunkcoordintpair.x, chunkcoordintpair.z, l); // Paper - throw error instead + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING,"Large Chunk Detected: ({0}) Size: {1} {2}", new Object[]{chunkcoordintpair, i1, this.file}); ++ if (!ENABLE_EXTENDED_SAVE) throw new RuntimeException(String.format("Too big to save, %d > 1048576", i)); // Paper - move after our check // Spigot end } -@@ -374,6 +376,109 @@ public class RegionFile { +@@ -352,6 +354,109 @@ public class RegionFile implements AutoCloseable { logger.error("Error backing up corrupt file" + file.getAbsolutePath(), e); } } @@ -159,11 +181,11 @@ index c20511588d..82f7af46f8 100644 + } + + private File getOversizedMetaFile() { -+ return new File(getFile().getParentFile(), getFile().getName().replaceAll("\\.mca$", "") + ".oversized.nbt"); ++ return new File(this.file.getParentFile(), this.file.getName().replaceAll("\\.mca$", "") + ".oversized.nbt"); + } + + private File getOversizedFile(int x, int z) { -+ return new File(this.getFile().getParentFile(), this.getFile().getName().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt"); ++ return new File(this.file.getParentFile(), this.file.getName().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt"); + } + + void writeOversizedData(int x, int z, NBTTagCompound oversizedData) throws IOException { @@ -193,7 +215,7 @@ index c20511588d..82f7af46f8 100644 + } + public class ChunkTooLargeException extends RuntimeException { + public ChunkTooLargeException(int x, int z, int sectors) { -+ super("Chunk " + x + "," + z + " of " + getFile().toString() + " is too large (" + sectors + "/256)"); ++ super("Chunk " + x + "," + z + " of " + RegionFile.this.file.toString() + " is too large (" + sectors + "/255)"); + } + } + private static class DirectByteArrayOutputStream extends ByteArrayOutputStream { @@ -212,12 +234,12 @@ index c20511588d..82f7af46f8 100644 // Paper end class ChunkBuffer extends ByteArrayOutputStream { -@@ -387,8 +492,35 @@ public class RegionFile { - this.c = j; +@@ -363,8 +468,35 @@ public class RegionFile implements AutoCloseable { + this.b = chunkcoordintpair; } - public void close() { -- RegionFile.this.a(this.b, this.c, this.buf, this.count); +- RegionFile.this.a(this.b, this.buf, this.count); + public void close() throws IOException { + // Paper start - apply dynamic compression + int origLength = this.count; @@ -226,9 +248,9 @@ index c20511588d..82f7af46f8 100644 + byte[] bytes = out.getBuffer(); + int length = out.size(); + -+ RegionFile.this.a(this.b, this.c, bytes, length); // Paper - change to bytes/length -+ } -+ } ++ RegionFile.this.a(this.b, bytes, length); // Paper - change to bytes/length + } + } + + private static final byte[] compressionBuffer = new byte[1024 * 64]; // 64k fits most standard chunks input size even, ideally 1 pass through zlib + private static final java.util.zip.Deflater deflater = new java.util.zip.Deflater(); @@ -245,27 +267,28 @@ index c20511588d..82f7af46f8 100644 + out.close(); + deflater.reset(); + return out; - } - } ++ } ++ } + // Paper end + } diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java -index 8c8b7cbab5..17e76815ad 100644 +index 1b12a16113..6893f3cd34 100644 --- a/src/main/java/net/minecraft/server/RegionFileCache.java +++ b/src/main/java/net/minecraft/server/RegionFileCache.java -@@ -16,6 +16,7 @@ public class RegionFileCache { - - public static final Map cache = new LinkedHashMap(PaperConfig.regionFileCacheSize, 0.75f, true); // Paper - HashMap -> LinkedHashMap - -+ public static synchronized RegionFile getRegionFile(File file, int i, int j) { return a(file, i, j); } // Paper - OBFHELPER - public static synchronized RegionFile a(File file, int i, int j) { - File file1 = new File(file, "region"); - File file2 = new File(file1, "r." + (i >> 5) + "." + (j >> 5) + ".mca"); -@@ -83,6 +84,135 @@ public class RegionFileCache { - public static synchronized boolean hasRegionFile(File file, int i, int j) { - return RegionFileCache.cache.containsKey(getRegionFileName(file, i, j)); +@@ -47,6 +47,7 @@ public abstract class RegionFileCache implements AutoCloseable { + // Paper start } + ++ public RegionFile getRegionFile(ChunkCoordIntPair chunkcoordintpair, boolean existingOnly) throws IOException { return this.a(chunkcoordintpair, existingOnly); } // Paper - OBFHELPER + private RegionFile a(ChunkCoordIntPair chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit + long i = ChunkCoordIntPair.pair(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()); + RegionFile regionfile = (RegionFile) this.cache.getAndMoveToFirst(i); +@@ -79,12 +80,151 @@ public abstract class RegionFileCache implements AutoCloseable { + public synchronized boolean hasRegionFile(File file, int i, int j) { + return cache.containsKey(getRegionFileName(file, i, j)); + } ++ // Paper start + private static void printOversizedLog(String msg, File file, int x, int z) { + org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO PAPER - You may ask for help on Discord, but do not file an issue. These error messages can not be removed."); + } @@ -285,23 +308,26 @@ index 8c8b7cbab5..17e76815ad 100644 + return SIZE_THRESHOLD == OVERZEALOUS_THRESHOLD; + } + -+ private static void writeRegion(File file, int x, int z, NBTTagCompound nbttagcompound) throws IOException { -+ RegionFile regionfile = getRegionFile(file, x, z); ++ private void writeRegion(ChunkCoordIntPair chunk, NBTTagCompound nbttagcompound) throws IOException { ++ RegionFile regionfile = getRegionFile(chunk, false); + -+ DataOutputStream out = regionfile.getWriteStream(x & 31, z & 31); ++ int chunkX = chunk.x; ++ int chunkZ = chunk.z; ++ ++ DataOutputStream out = regionfile.getWriteStream(chunk); + try { + NBTCompressedStreamTools.writeNBT(nbttagcompound, out); + out.close(); -+ regionfile.setOversized(x, z, false); ++ regionfile.setOversized(chunkX, chunkZ, false); + } catch (RegionFile.ChunkTooLargeException ignored) { -+ printOversizedLog("ChunkTooLarge! Someone is trying to duplicate.", file, x, z); ++ printOversizedLog("ChunkTooLarge! Someone is trying to duplicate.", regionfile.file, chunkX, chunkZ); + // Clone as we are now modifying it, don't want to corrupt the pending save state + nbttagcompound = nbttagcompound.clone(); + // Filter out TileEntities and Entities + NBTTagCompound oversizedData = filterChunkData(nbttagcompound); + //noinspection SynchronizationOnLocalVariableOrMethodParameter + synchronized (regionfile) { -+ out = regionfile.getWriteStream(x & 31, z & 31); ++ out = regionfile.getWriteStream(chunk); + NBTCompressedStreamTools.writeNBT(nbttagcompound, out); + try { + out.close(); @@ -310,13 +336,13 @@ index 8c8b7cbab5..17e76815ad 100644 + resetFilterThresholds(); + } + } catch (RegionFile.ChunkTooLargeException e) { -+ printOversizedLog("ChunkTooLarge even after reduction. Trying in overzealous mode.", file, x, z); ++ printOversizedLog("ChunkTooLarge even after reduction. Trying in overzealous mode.", regionfile.file, chunkX, chunkZ); + // Eek, major fail. We have retry logic, so reduce threshholds and fall back + SIZE_THRESHOLD = OVERZEALOUS_THRESHOLD; + throw e; + } + -+ regionfile.writeOversizedData(x, z, oversizedData); ++ regionfile.writeOversizedData(chunkX, chunkZ, oversizedData); + } + } + } @@ -335,7 +361,7 @@ index 8c8b7cbab5..17e76815ad 100644 + NBTTagList list = level.getList(key, 10); + NBTTagList newList = extra.getList(key, 10); + int totalSize = 0; -+ for (Iterator iterator = list.list.iterator(); iterator.hasNext(); ) { ++ for (java.util.Iterator iterator = list.list.iterator(); iterator.hasNext();) { + NBTBase object = iterator.next(); + int nbtSize = getNBTSize(object); + if (nbtSize > SIZE_THRESHOLD || (SIZE_THRESHOLD == OVERZEALOUS_THRESHOLD && totalSize > OVERZEALOUS_TOTAL_THRESHOLD)) { @@ -350,10 +376,10 @@ index 8c8b7cbab5..17e76815ad 100644 + } + + -+ private static NBTTagCompound readOversizedChunk(RegionFile regionfile, int i, int j) throws IOException { ++ private static NBTTagCompound readOversizedChunk(RegionFile regionfile, ChunkCoordIntPair chunkCoordinate) throws IOException { + synchronized (regionfile) { -+ try (DataInputStream datainputstream = regionfile.getReadStream(i & 31, j & 31)) { -+ NBTTagCompound oversizedData = regionfile.getOversizedData(i, j); ++ try (DataInputStream datainputstream = regionfile.getReadStream(chunkCoordinate)) { ++ NBTTagCompound oversizedData = regionfile.getOversizedData(chunkCoordinate.x, chunkCoordinate.z); + NBTTagCompound chunk = NBTCompressedStreamTools.readNBT(datainputstream); + if (oversizedData == null) { + return chunk; @@ -397,40 +423,75 @@ index 8c8b7cbab5..17e76815ad 100644 + // Paper End - public static synchronized void a() { -@@ -108,6 +238,12 @@ public class RegionFileCache { - // CraftBukkit start - call sites hoisted for synchronization - public static NBTTagCompound read(File file, int i, int j) throws IOException { // Paper - remove synchronization - RegionFile regionfile = a(file, i, j); + @Nullable + public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException { + RegionFile regionfile = this.a(chunkcoordintpair, false); // CraftBukkit + DataInputStream datainputstream = regionfile.a(chunkcoordintpair); + // Paper start -+ if (regionfile.isOversized(i, j)) { -+ printOversizedLog("Loading Oversized Chunk!", file, i, j); -+ return readOversizedChunk(regionfile, i, j); ++ if (regionfile.isOversized(chunkcoordintpair.x, chunkcoordintpair.z)) { ++ printOversizedLog("Loading Oversized Chunk!", regionfile.file, chunkcoordintpair.x, chunkcoordintpair.z); ++ return readOversizedChunk(regionfile, chunkcoordintpair); + } + // Paper end + Throwable throwable = null; - DataInputStream datainputstream = regionfile.a(i & 31, j & 31); + NBTTagCompound nbttagcompound; +@@ -119,29 +259,32 @@ public abstract class RegionFileCache implements AutoCloseable { -@@ -121,11 +257,14 @@ public class RegionFileCache { - @Nullable - public static void write(File file, int i, int j, NBTTagCompound nbttagcompound) throws IOException { + protected void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper -- RegionFile regionfile = a(file, i, j); +- RegionFile regionfile = this.a(chunkcoordintpair, false); // CraftBukkit +- DataOutputStream dataoutputstream = regionfile.c(chunkcoordintpair); +- Throwable throwable = null; - -- DataOutputStream dataoutputstream = regionfile.c(i & 31, j & 31); -- NBTCompressedStreamTools.a(nbttagcompound, (java.io.DataOutput) dataoutputstream); -- dataoutputstream.close(); -+ writeRegion(file, i, j, nbttagcompound); // Paper - moved to own method +- try { +- NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) dataoutputstream); +- } catch (Throwable throwable1) { +- throwable = throwable1; +- throw throwable1; +- } finally { +- if (dataoutputstream != null) { +- if (throwable != null) { +- try { +- dataoutputstream.close(); +- } catch (Throwable throwable2) { +- throwable.addSuppressed(throwable2); +- } +- } else { +- dataoutputstream.close(); +- } +- } +- +- } + // Paper start -+// RegionFile regionfile = a(file, i, j); ++ this.writeRegion(chunkcoordintpair, nbttagcompound); ++// RegionFile regionfile = this.a(chunkcoordintpair, false); // CraftBukkit ++// DataOutputStream dataoutputstream = regionfile.c(chunkcoordintpair); ++// Throwable throwable = null; +// -+// DataOutputStream dataoutputstream = regionfile.c(i & 31, j & 31); -+// NBTCompressedStreamTools.a(nbttagcompound, (java.io.DataOutput) dataoutputstream); -+// dataoutputstream.close(); ++// try { ++// NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) dataoutputstream); ++// } catch (Throwable throwable1) { ++// throwable = throwable1; ++// throw throwable1; ++// } finally { ++// if (dataoutputstream != null) { ++// if (throwable != null) { ++// try { ++// dataoutputstream.close(); ++// } catch (Throwable throwable2) { ++// throwable.addSuppressed(throwable2); ++// } ++// } else { ++// dataoutputstream.close(); ++// } ++// } ++// ++// } + // Paper end - // Paper start - laste = null; break; // Paper - } catch (Exception exception) { + + } catch (Exception ex) { + laste = ex; -- 2.21.0 diff --git a/Spigot-Server-Patches/0412-BlockDestroyEvent.patch b/Spigot-Server-Patches/0363-BlockDestroyEvent.patch similarity index 85% rename from Spigot-Server-Patches/0412-BlockDestroyEvent.patch rename to Spigot-Server-Patches/0363-BlockDestroyEvent.patch index d03864e226..f2e053f106 100644 --- a/Spigot-Server-Patches/0412-BlockDestroyEvent.patch +++ b/Spigot-Server-Patches/0363-BlockDestroyEvent.patch @@ -1,4 +1,4 @@ -From 340d46ba0e1d0bac0baffe2a0bcfa0d87fcff70e Mon Sep 17 00:00:00 2001 +From f20c19300456b716f786f8c00c9693b430faaf42 Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 6 Feb 2019 00:20:33 -0500 Subject: [PATCH] BlockDestroyEvent @@ -11,10 +11,10 @@ floating in the air. This can replace many uses of BlockPhysicsEvent diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 1454af710e..e280b58531 100644 +index 17401ea28a..de0ed95083 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -548,8 +548,20 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc +@@ -475,8 +475,20 @@ public abstract class World implements IIBlockAccess, GeneratorAccess, AutoClose return false; } else { Fluid fluid = this.getFluid(blockposition); @@ -34,8 +34,8 @@ index 1454af710e..e280b58531 100644 - this.triggerEffect(2001, blockposition, Block.getCombinedId(iblockdata)); + if (playEffect) this.triggerEffect(2001, blockposition, Block.getCombinedId(iblockdata)); // Paper if (flag) { - iblockdata.a(this, blockposition, 0); - } + TileEntity tileentity = iblockdata.getBlock().isTileEntity() ? this.getTileEntity(blockposition) : null; + -- 2.21.0 diff --git a/Spigot-Server-Patches/0364-Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch b/Spigot-Server-Patches/0364-Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch new file mode 100644 index 0000000000..826c96f6df --- /dev/null +++ b/Spigot-Server-Patches/0364-Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch @@ -0,0 +1,68 @@ +From 08d251a0d010ca279be90e3ae24dceaf47fcc8ab Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Fri, 18 Jan 2019 00:08:15 -0500 +Subject: [PATCH] Fix Custom Shapeless Custom Crafting Recipes + +Mojang implemented Shapeless different than Shaped + +This made the Bukkit RecipeChoice API not work for Shapeless. + +This reimplements vanilla logic using the same test logic as Shaped + +diff --git a/src/main/java/net/minecraft/server/ShapelessRecipes.java b/src/main/java/net/minecraft/server/ShapelessRecipes.java +index 070fc1e3ec..691e697d68 100644 +--- a/src/main/java/net/minecraft/server/ShapelessRecipes.java ++++ b/src/main/java/net/minecraft/server/ShapelessRecipes.java +@@ -63,16 +63,46 @@ public class ShapelessRecipes implements RecipeCrafting { + AutoRecipeStackManager autorecipestackmanager = new AutoRecipeStackManager(); + int i = 0; + ++ // Paper start ++ java.util.List providedItems = new java.util.ArrayList<>(); ++ co.aikar.util.Counter matchedProvided = new co.aikar.util.Counter<>(); ++ co.aikar.util.Counter matchedIngredients = new co.aikar.util.Counter<>(); ++ // Paper end + for (int j = 0; j < inventorycrafting.getSize(); ++j) { + ItemStack itemstack = inventorycrafting.getItem(j); + + if (!itemstack.isEmpty()) { +- ++i; +- autorecipestackmanager.a(itemstack, 1); ++ // Paper start ++ itemstack = itemstack.cloneItemStack(); ++ providedItems.add(itemstack); ++ for (RecipeItemStack ingredient : ingredients) { ++ if (ingredient.test(itemstack)) { ++ matchedProvided.increment(itemstack); ++ matchedIngredients.increment(ingredient); ++ } ++ } ++ // Paper end + } + } + +- return i == this.ingredients.size() && autorecipestackmanager.a(this, (IntList) null); ++ // Paper start ++ java.util.List ingredients = new java.util.ArrayList<>(this.ingredients); ++ providedItems.sort(java.util.Comparator.comparingInt((ItemStack c) -> (int) matchedProvided.getCount(c)).reversed()); ++ ingredients.sort(java.util.Comparator.comparingInt((RecipeItemStack c) -> (int) matchedIngredients.getCount(c))); ++ ++ PROVIDED: ++ for (ItemStack provided : providedItems) { ++ for (Iterator itIngredient = ingredients.iterator(); itIngredient.hasNext(); ) { ++ RecipeItemStack ingredient = itIngredient.next(); ++ if (ingredient.test(provided)) { ++ itIngredient.remove(); ++ continue PROVIDED; ++ } ++ } ++ return false; ++ } ++ return ingredients.isEmpty(); ++ // Paper end + } + + public ItemStack a(InventoryCrafting inventorycrafting) { +-- +2.21.0 + diff --git a/Spigot-Server-Patches/0414-Fix-sign-edit-memory-leak.patch b/Spigot-Server-Patches/0365-Fix-sign-edit-memory-leak.patch similarity index 72% rename from Spigot-Server-Patches/0414-Fix-sign-edit-memory-leak.patch rename to Spigot-Server-Patches/0365-Fix-sign-edit-memory-leak.patch index d2f316477c..0caddafd57 100644 --- a/Spigot-Server-Patches/0414-Fix-sign-edit-memory-leak.patch +++ b/Spigot-Server-Patches/0365-Fix-sign-edit-memory-leak.patch @@ -1,4 +1,4 @@ -From c1585662600e8e6bfee07aa5a791f388de85717a Mon Sep 17 00:00:00 2001 +From fc42c54ec144a4249cf2b4bfdbb668461311717a Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 28 Feb 2019 00:15:28 -0500 Subject: [PATCH] Fix sign edit memory leak @@ -6,23 +6,23 @@ Subject: [PATCH] Fix sign edit memory leak when a player edits a sign, a reference to their Entity is never cleand up. diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index f63943f29f..b193fbab47 100644 +index 71d10f9b9c..60f77ac3df 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -2512,7 +2512,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { +@@ -2561,7 +2561,7 @@ public class PlayerConnection implements PacketListenerPlayIn { TileEntitySign tileentitysign = (TileEntitySign) tileentity; -- if (!tileentitysign.d() || tileentitysign.e() != this.player) { -+ if (!tileentitysign.d() || tileentitysign.signEditor == null || !tileentitysign.signEditor.equals(this.player.getUniqueID())) { // Paper +- if (!tileentitysign.c() || tileentitysign.d() != this.player) { ++ if (!tileentitysign.c() || tileentitysign.signEditor == null || !tileentitysign.signEditor.equals(this.player.getUniqueID())) { this.minecraftServer.warning("Player " + this.player.getDisplayName().getString() + " just tried to change non-editable sign"); 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 -index c2bcbbbab9..fdb771317a 100644 +index 4165c6d11a..7abf533c58 100644 --- a/src/main/java/net/minecraft/server/TileEntitySign.java +++ b/src/main/java/net/minecraft/server/TileEntitySign.java -@@ -14,6 +14,7 @@ public class TileEntitySign extends TileEntity implements ICommandListener { +@@ -17,6 +17,7 @@ public class TileEntitySign extends TileEntity implements ICommandListener { // // Paper start - Strip invalid unicode from signs on load private static final boolean keepInvalidUnicode = Boolean.getBoolean("Paper.keepInvalidUnicode"); // Allow people to keep their bad unicode if they really want it private boolean privateUnicodeRemoved = false; @@ -30,18 +30,18 @@ index c2bcbbbab9..fdb771317a 100644 // Paper end public TileEntitySign() { -@@ -130,7 +131,10 @@ public class TileEntitySign extends TileEntity implements ICommandListener { +@@ -142,7 +143,10 @@ public class TileEntitySign extends TileEntity implements ICommandListener { // } public void a(EntityHuman entityhuman) { -- this.g = entityhuman; +- this.j = entityhuman; + // Paper start + //this.g = entityhuman; + signEditor = entityhuman != null ? entityhuman.getUniqueID() : null; + // Paper end } - public EntityHuman e() { + public EntityHuman d() { -- 2.21.0 diff --git a/Spigot-Server-Patches/0415-Limit-Client-Sign-length-more.patch b/Spigot-Server-Patches/0366-Limit-Client-Sign-length-more.patch similarity index 89% rename from Spigot-Server-Patches/0415-Limit-Client-Sign-length-more.patch rename to Spigot-Server-Patches/0366-Limit-Client-Sign-length-more.patch index 5ff9668fb1..7fe4ab9440 100644 --- a/Spigot-Server-Patches/0415-Limit-Client-Sign-length-more.patch +++ b/Spigot-Server-Patches/0366-Limit-Client-Sign-length-more.patch @@ -1,4 +1,4 @@ -From 9278475d36f65e5b95b44b28ff15b9524015973e Mon Sep 17 00:00:00 2001 +From fbbf174e314e753fdddd0453c194ab6bea60a62c Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 27 Feb 2019 22:18:40 -0500 Subject: [PATCH] Limit Client Sign length more @@ -22,10 +22,10 @@ it only impacts data sent from the client. Set -DPaper.maxSignLength=XX to change limit or -1 to disable diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index b193fbab47..188e450a13 100644 +index 60f77ac3df..39a040a2a0 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -104,6 +104,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { +@@ -105,6 +105,7 @@ public class PlayerConnection implements PacketListenerPlayIn { private int E; private int receivedMovePackets; private int processedMovePackets; @@ -33,7 +33,7 @@ index b193fbab47..188e450a13 100644 private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit public PlayerConnection(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayer entityplayer) { -@@ -2528,6 +2529,15 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { +@@ -2577,6 +2578,15 @@ public class PlayerConnection implements PacketListenerPlayIn { String[] lines = new String[4]; for (int i = 0; i < astring.length; ++i) { diff --git a/Spigot-Server-Patches/0416-Don-t-check-ConvertSigns-boolean-every-sign-save.patch b/Spigot-Server-Patches/0367-Don-t-check-ConvertSigns-boolean-every-sign-save.patch similarity index 79% rename from Spigot-Server-Patches/0416-Don-t-check-ConvertSigns-boolean-every-sign-save.patch rename to Spigot-Server-Patches/0367-Don-t-check-ConvertSigns-boolean-every-sign-save.patch index f20ecbfc99..e2e01fbf6a 100644 --- a/Spigot-Server-Patches/0416-Don-t-check-ConvertSigns-boolean-every-sign-save.patch +++ b/Spigot-Server-Patches/0367-Don-t-check-ConvertSigns-boolean-every-sign-save.patch @@ -1,4 +1,4 @@ -From f0aeb314f4816c28b5007dbfbdb005d10143d724 Mon Sep 17 00:00:00 2001 +From fc7f6b655759cf7f6c66b79f2b114a30e14b1d9f Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 2 Mar 2019 11:11:29 -0500 Subject: [PATCH] Don't check ConvertSigns boolean every sign save @@ -7,10 +7,10 @@ property lookups arent super cheap. they synchronize, validate and check security managers. diff --git a/src/main/java/net/minecraft/server/TileEntitySign.java b/src/main/java/net/minecraft/server/TileEntitySign.java -index fdb771317a..d0a91f6755 100644 +index 7abf533c58..713bb4cd52 100644 --- a/src/main/java/net/minecraft/server/TileEntitySign.java +++ b/src/main/java/net/minecraft/server/TileEntitySign.java -@@ -15,6 +15,7 @@ public class TileEntitySign extends TileEntity implements ICommandListener { +@@ -18,6 +18,7 @@ public class TileEntitySign extends TileEntity implements ICommandListener { // private static final boolean keepInvalidUnicode = Boolean.getBoolean("Paper.keepInvalidUnicode"); // Allow people to keep their bad unicode if they really want it private boolean privateUnicodeRemoved = false; public java.util.UUID signEditor; @@ -18,7 +18,7 @@ index fdb771317a..d0a91f6755 100644 // Paper end public TileEntitySign() { -@@ -31,7 +32,7 @@ public class TileEntitySign extends TileEntity implements ICommandListener { +@@ -36,7 +37,7 @@ public class TileEntitySign extends TileEntity implements ICommandListener { // } // CraftBukkit start diff --git a/Spigot-Server-Patches/0417-Handle-Excessive-Signs-in-Chunks-creating-too-large-.patch b/Spigot-Server-Patches/0368-Handle-Excessive-Signs-in-Chunks-creating-too-large-.patch similarity index 69% rename from Spigot-Server-Patches/0417-Handle-Excessive-Signs-in-Chunks-creating-too-large-.patch rename to Spigot-Server-Patches/0368-Handle-Excessive-Signs-in-Chunks-creating-too-large-.patch index f6473b2618..c614c90a0c 100644 --- a/Spigot-Server-Patches/0417-Handle-Excessive-Signs-in-Chunks-creating-too-large-.patch +++ b/Spigot-Server-Patches/0368-Handle-Excessive-Signs-in-Chunks-creating-too-large-.patch @@ -1,4 +1,4 @@ -From d2464a0cfa4f2c0bb30336e4e6d7d757649c7a21 Mon Sep 17 00:00:00 2001 +From 0fb0803c2d7490a52dfbf7e8260e9a314fb41bbb Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 2 Mar 2019 14:55:01 -0500 Subject: [PATCH] Handle Excessive Signs in Chunks creating too large of @@ -11,10 +11,10 @@ Use -DPaper.excessiveSignsLimit=500 to configure that limit, or -1 to disable the limit and let your players be abused. diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java -index 553637239c..30f646e421 100644 +index 1b0643c27f..4766f7b773 100644 --- a/src/main/java/net/minecraft/server/NetworkManager.java +++ b/src/main/java/net/minecraft/server/NetworkManager.java -@@ -221,6 +221,15 @@ public class NetworkManager extends SimpleChannelInboundHandler> { +@@ -220,6 +220,15 @@ public class NetworkManager extends SimpleChannelInboundHandler> { }); } @@ -29,7 +29,7 @@ index 553637239c..30f646e421 100644 + } - // Paper start - Async-Anti-Xray - Stop dispatching further packets and return false if the peeked packet is a chunk packet which is not ready + private void sendPacketQueue() { this.o(); } // Paper - OBFHELPER diff --git a/src/main/java/net/minecraft/server/Packet.java b/src/main/java/net/minecraft/server/Packet.java index 2d8e6a2f4a..8d0965a053 100644 --- a/src/main/java/net/minecraft/server/Packet.java @@ -43,45 +43,46 @@ index 2d8e6a2f4a..8d0965a053 100644 return false; } diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java -index 4a57e8a3ec..eb54bdb642 100644 +index 58eccd9c63..ef71a1feb3 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java -@@ -23,6 +23,13 @@ public class PacketPlayOutMapChunk implements Packet { - this.ready = true; // Paper - Async-Anti-Xray - Set the ready flag to true - } +@@ -20,6 +20,15 @@ public class PacketPlayOutMapChunk implements Packet { + + public PacketPlayOutMapChunk() {} + // Paper start + private final java.util.List extraPackets = new java.util.ArrayList<>(); + private static final int SKIP_EXCESSIVE_SIGNS_LIMIT = Integer.getInteger("Paper.excessiveSignsLimit", 500); ++ ++ @Override + public java.util.List getExtraPackets() { + return extraPackets; + } + // Paper end public PacketPlayOutMapChunk(Chunk chunk, int i) { - ChunkPacketInfo chunkPacketInfo = chunk.world.chunkPacketBlockController.getChunkPacketInfo(this, chunk, i); // Paper - Anti-Xray - Add chunk packet info - this.a = chunk.locX; -@@ -41,6 +48,7 @@ public class PacketPlayOutMapChunk implements Packet { - this.c = this.writeChunk(new PacketDataSerializer(this.h()), chunk, flag, i, chunkPacketInfo); // Paper - Anti-Xray - Add chunk packet info - this.e = Lists.newArrayList(); - Iterator iterator = chunk.getTileEntities().entrySet().iterator(); + ChunkCoordIntPair chunkcoordintpair = chunk.getPos(); + +@@ -42,6 +51,7 @@ public class PacketPlayOutMapChunk implements Packet { + this.c = this.a(new PacketDataSerializer(this.i()), chunk, i); + this.f = Lists.newArrayList(); + iterator = chunk.getTileEntities().entrySet().iterator(); + int totalSigns = 0; // Paper while (iterator.hasNext()) { - Entry entry = (Entry) iterator.next(); -@@ -49,6 +57,15 @@ public class PacketPlayOutMapChunk implements Packet { + entry = (Entry) iterator.next(); +@@ -50,6 +60,14 @@ public class PacketPlayOutMapChunk implements Packet { int j = blockposition.getY() >> 4; if (this.f() || (i & 1 << j) != 0) { + // Paper start - send signs separately + if (tileentity instanceof TileEntitySign) { + if (SKIP_EXCESSIVE_SIGNS_LIMIT < 0 || ++totalSigns < SKIP_EXCESSIVE_SIGNS_LIMIT) { -+ extraPackets.add(tileentity.getUpdatePacket()); ++ this.extraPackets.add(tileentity.getUpdatePacket()); + } + continue; + } + // Paper end -+ - NBTTagCompound nbttagcompound = tileentity.aa_(); + NBTTagCompound nbttagcompound = tileentity.b(); if (tileentity instanceof TileEntitySkull) { TileEntitySkull.sanitizeTileEntityUUID(nbttagcompound); } // Paper -- diff --git a/Spigot-Server-Patches/0418-MC-145260-Fix-Whitelist-On-Off-inconsistency.patch b/Spigot-Server-Patches/0369-MC-145260-Fix-Whitelist-On-Off-inconsistency.patch similarity index 83% rename from Spigot-Server-Patches/0418-MC-145260-Fix-Whitelist-On-Off-inconsistency.patch rename to Spigot-Server-Patches/0369-MC-145260-Fix-Whitelist-On-Off-inconsistency.patch index ef291025d5..0ed0eaec09 100644 --- a/Spigot-Server-Patches/0418-MC-145260-Fix-Whitelist-On-Off-inconsistency.patch +++ b/Spigot-Server-Patches/0369-MC-145260-Fix-Whitelist-On-Off-inconsistency.patch @@ -1,4 +1,4 @@ -From 4ff4f66ea29bd8405f2e5182c9746214f12b53a3 Mon Sep 17 00:00:00 2001 +From ee42d19ac37a5088bd74c925800bc16f2ac69d62 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 2 Mar 2019 16:12:35 -0500 Subject: [PATCH] MC-145260: Fix Whitelist On/Off inconsistency @@ -11,31 +11,31 @@ 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 b7cde4d418..949039f89a 100644 +index c169d01762..55bc4b265d 100644 --- a/src/main/java/net/minecraft/server/JsonList.java +++ b/src/main/java/net/minecraft/server/JsonList.java @@ -64,6 +64,7 @@ public class JsonList> { return this.e; } -+ public void setEnabled(boolean flag) { a(flag); } // Paper - OBFHeLPER ++ 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 135d25abd2..408c382d2a 100644 +index 109c27b647..6939b5ce1e 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java -@@ -63,7 +63,7 @@ public abstract class PlayerList { +@@ -62,7 +62,7 @@ public abstract class PlayerList { // private final Map p; // CraftBukkit end public IPlayerFileData playerFileData; - private boolean hasWhitelist; -+ //private boolean hasWhitelist; // Paper - moved to whitelist object so not duplicated - protected int maxPlayers; ++ //private boolean hasWhitelist; + protected final int maxPlayers; private int s; private EnumGamemode t; -@@ -1178,9 +1178,9 @@ public abstract class PlayerList { +@@ -896,9 +896,9 @@ public abstract class PlayerList { } public boolean isWhitelisted(GameProfile gameprofile, org.bukkit.event.player.PlayerLoginEvent loginEvent) { boolean isOp = this.operators.d(gameprofile); @@ -47,7 +47,7 @@ index 135d25abd2..408c382d2a 100644 event.callEvent(); if (!event.isWhitelisted()) { if (loginEvent != null) { -@@ -1325,11 +1325,11 @@ public abstract class PlayerList { +@@ -1027,11 +1027,11 @@ public abstract class PlayerList { } public boolean getHasWhitelist() { diff --git a/Spigot-Server-Patches/0419-Set-Zombie-last-tick-at-start-of-drowning-process.patch b/Spigot-Server-Patches/0370-Set-Zombie-last-tick-at-start-of-drowning-process.patch similarity index 70% rename from Spigot-Server-Patches/0419-Set-Zombie-last-tick-at-start-of-drowning-process.patch rename to Spigot-Server-Patches/0370-Set-Zombie-last-tick-at-start-of-drowning-process.patch index 7e9f056a76..1a040bc18d 100644 --- a/Spigot-Server-Patches/0419-Set-Zombie-last-tick-at-start-of-drowning-process.patch +++ b/Spigot-Server-Patches/0370-Set-Zombie-last-tick-at-start-of-drowning-process.patch @@ -1,4 +1,4 @@ -From ff4860cb5f82d587c904247af5dafe3e4f2916a9 Mon Sep 17 00:00:00 2001 +From f08cd8ab6e14fc8f98b58d311a7755e116dea6ed Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 4 Mar 2019 02:23:28 -0500 Subject: [PATCH] Set Zombie last tick at start of drowning process @@ -6,17 +6,17 @@ Subject: [PATCH] Set Zombie last tick at start of drowning process Fixes GH-1887 diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java -index 24bc3e0f08..bf2bed0029 100644 +index f8baaea03e..bf93bb44ea 100644 --- a/src/main/java/net/minecraft/server/EntityZombie.java +++ b/src/main/java/net/minecraft/server/EntityZombie.java -@@ -175,6 +175,7 @@ public class EntityZombie extends EntityMonster { - ++this.bI; - if (this.bI >= 600) { +@@ -167,6 +167,7 @@ public class EntityZombie extends EntityMonster { + ++this.bF; + if (this.bF >= 600) { this.startDrownedConversion(300); + this.lastTick = MinecraftServer.currentTick; // Paper - Make sure this is set at start of process - GH-1887 } } else { - this.bI = -1; + this.bF = -1; -- 2.21.0 diff --git a/Spigot-Server-Patches/0420-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch b/Spigot-Server-Patches/0371-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch similarity index 79% rename from Spigot-Server-Patches/0420-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch rename to Spigot-Server-Patches/0371-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch index 1405803fdc..7f27d34964 100644 --- a/Spigot-Server-Patches/0420-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch +++ b/Spigot-Server-Patches/0371-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch @@ -1,14 +1,14 @@ -From 6bf7f6d474e8bb96afb2cbdd3c273f9a25c269da Mon Sep 17 00:00:00 2001 +From 30a14f63c74cb2d16496273c5412369331a608c0 Mon Sep 17 00:00:00 2001 From: Mark Vainomaa Date: Wed, 13 Mar 2019 20:08:09 +0200 Subject: [PATCH] Call WhitelistToggleEvent when whitelist is toggled diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java -index 408c382d2a..b1630137ec 100644 +index 6939b5ce1e..7d93715424 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java -@@ -1329,6 +1329,7 @@ public abstract class PlayerList { +@@ -1031,6 +1031,7 @@ public abstract class PlayerList { } public void setHasWhitelist(boolean flag) { diff --git a/Spigot-Server-Patches/0421-Use-proper-max-length-when-serialising-BungeeCord-te.patch b/Spigot-Server-Patches/0372-Use-proper-max-length-when-serialising-BungeeCord-te.patch similarity index 91% rename from Spigot-Server-Patches/0421-Use-proper-max-length-when-serialising-BungeeCord-te.patch rename to Spigot-Server-Patches/0372-Use-proper-max-length-when-serialising-BungeeCord-te.patch index 3862458b05..14fa53f36c 100644 --- a/Spigot-Server-Patches/0421-Use-proper-max-length-when-serialising-BungeeCord-te.patch +++ b/Spigot-Server-Patches/0372-Use-proper-max-length-when-serialising-BungeeCord-te.patch @@ -1,4 +1,4 @@ -From f914570652750a8a7d94fe7ccb6b8a860f3c5d25 Mon Sep 17 00:00:00 2001 +From cd0d812a87747584b7ecc356776b21a63dbb10e3 Mon Sep 17 00:00:00 2001 From: kashike Date: Wed, 20 Mar 2019 21:19:29 -0700 Subject: [PATCH] Use proper max length when serialising BungeeCord text @@ -6,7 +6,7 @@ Subject: [PATCH] Use proper max length when serialising BungeeCord text diff --git a/src/main/java/net/minecraft/server/PacketPlayOutChat.java b/src/main/java/net/minecraft/server/PacketPlayOutChat.java -index eba6aadad7..3a332e980d 100644 +index 0ab611564e..f7b2095bb7 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutChat.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutChat.java @@ -3,7 +3,7 @@ package net.minecraft.server; @@ -18,7 +18,7 @@ index eba6aadad7..3a332e980d 100644 private IChatBaseComponent a; public net.md_5.bungee.api.chat.BaseComponent[] components; // Spigot private ChatMessageType b; -@@ -30,9 +30,9 @@ public class PacketPlayOutChat implements Packet { +@@ -32,9 +32,9 @@ public class PacketPlayOutChat implements Packet { //packetdataserializer.a(net.md_5.bungee.chat.ComponentSerializer.toString(components)); // Paper - comment, replaced with below // Paper start - don't nest if we don't need to so that we can preserve formatting if (this.components.length == 1) { diff --git a/Spigot-Server-Patches/0422-Entity-getEntitySpawnReason.patch b/Spigot-Server-Patches/0373-Entity-getEntitySpawnReason.patch similarity index 52% rename from Spigot-Server-Patches/0422-Entity-getEntitySpawnReason.patch rename to Spigot-Server-Patches/0373-Entity-getEntitySpawnReason.patch index 5d114156b9..133c107f4e 100644 --- a/Spigot-Server-Patches/0422-Entity-getEntitySpawnReason.patch +++ b/Spigot-Server-Patches/0373-Entity-getEntitySpawnReason.patch @@ -1,4 +1,4 @@ -From 6878901664ce139320799123c21205c632518b94 Mon Sep 17 00:00:00 2001 +From 726f4cc81771f7b6e8762a1f109a4214b8eee0ea Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 24 Mar 2019 00:24:52 -0400 Subject: [PATCH] Entity#getEntitySpawnReason @@ -9,24 +9,11 @@ Pre existing entities will return NATURAL if it was a non persistenting Living Entity, SPAWNER for spawners, or DEFAULT since data was not stored. -diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -index 7734712af9..dce52ac0fa 100644 ---- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java -+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -@@ -1134,7 +1134,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { - while (iterator.hasNext()) { - Entity entity1 = (Entity) iterator.next(); - -- a(entity1, generatoraccess); -+ a(entity1, generatoraccess, reason); // Paper - } - } - diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index a678dc89c8..581c78e003 100644 +index f945a2df48..cad8613a9b 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -63,6 +63,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke +@@ -65,6 +65,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } }; List entitySlice = null; @@ -34,7 +21,7 @@ index a678dc89c8..581c78e003 100644 // Paper end static boolean isLevelAtLeast(NBTTagCompound tag, int level) { return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level; -@@ -1674,6 +1675,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke +@@ -1579,6 +1580,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke if (origin != null) { nbttagcompound.set("Paper.Origin", this.createList(origin.getX(), origin.getY(), origin.getZ())); } @@ -44,7 +31,7 @@ index a678dc89c8..581c78e003 100644 // Save entity's from mob spawner status if (spawnedViaMobSpawner) { nbttagcompound.setBoolean("Paper.FromMobSpawner", true); -@@ -1827,6 +1831,26 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke +@@ -1712,6 +1716,26 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } spawnedViaMobSpawner = nbttagcompound.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status @@ -59,7 +46,7 @@ index a678dc89c8..581c78e003 100644 + if (spawnReason == null) { + if (spawnedViaMobSpawner) { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; -+ } else if (this instanceof EntityInsentient && this instanceof IAnimal && !((EntityInsentient) this).isTypeNotPersistent()) { ++ } else if (this instanceof EntityInsentient && (this instanceof EntityAnimal || this instanceof EntityFish) && !((EntityInsentient) this).isTypeNotPersistent(0.0)) { + if (!nbttagcompound.getBoolean("PersistenceRequired")) { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL; + } @@ -71,53 +58,41 @@ index a678dc89c8..581c78e003 100644 // Paper end } catch (Throwable throwable) { -diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java -index b2d2de7f81..af38e5396e 100644 ---- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java -+++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java -@@ -117,7 +117,7 @@ public abstract class MobSpawnerAbstract { - } - } - // Paper end -- Entity entity = ChunkRegionLoader.a(nbttagcompound, world, d3, d4, d5, false); -+ Entity entity = ChunkRegionLoader.spawnEntity(nbttagcompound, world, d3, d4, d5, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER); // Paper - - if (entity == null) { - this.i(); diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java -index b1630137ec..df416e3b59 100644 +index 7d93715424..3d1c910ccf 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java -@@ -196,7 +196,7 @@ public abstract class PlayerList { +@@ -248,7 +248,7 @@ public abstract class PlayerList { + // CraftBukkit start + WorldServer finalWorldServer = worldserver; + 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 + // CraftBukkit end + }); - if (nbttagcompound != null && nbttagcompound.hasKeyOfType("RootVehicle", 10)) { - NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("RootVehicle"); -- Entity entity = ChunkRegionLoader.a(nbttagcompound1.getCompound("Entity"), worldserver, true); -+ Entity entity = ChunkRegionLoader.spawnEntity(nbttagcompound1.getCompound("Entity"), worldserver, true, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT); // Paper - - if (entity != null) { - UUID uuid = nbttagcompound1.a("Attach"); -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index e280b58531..0e8025d311 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -1084,6 +1084,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - - public boolean addEntity(Entity entity, SpawnReason spawnReason) { // Changed signature, added SpawnReason - // Paper start -+ if (entity.spawnReason == null) entity.spawnReason = spawnReason; - if (regionLimited != null) { - return regionLimited.addEntity(entity, spawnReason); - } +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index 6d8fb12903..c555478e82 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -939,6 +939,7 @@ public class WorldServer extends World { + // CraftBukkit start + private boolean addEntity0(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) { + org.spigotmc.AsyncCatcher.catchOp( "entity add"); // Spigot ++ if (entity.spawnReason == null) entity.spawnReason = spawnReason; // Paper + if (entity.valid) { MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable()); return true; } // Paper + if (entity.dead) { + // Paper start diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index a0e1a70d43..a12dd4779d 100644 +index 65621f9661..1a5b62cf4b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -861,5 +861,9 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -989,5 +989,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { public boolean fromMobSpawner() { return getHandle().spawnedViaMobSpawner; } + ++ @Override + public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason getEntitySpawnReason() { + return getHandle().spawnReason; + } diff --git a/Spigot-Server-Patches/0424-Update-entity-Metadata-for-all-tracked-players.patch b/Spigot-Server-Patches/0374-Update-entity-Metadata-for-all-tracked-players.patch similarity index 83% rename from Spigot-Server-Patches/0424-Update-entity-Metadata-for-all-tracked-players.patch rename to Spigot-Server-Patches/0374-Update-entity-Metadata-for-all-tracked-players.patch index c524fdbbe1..7e42aa754e 100644 --- a/Spigot-Server-Patches/0424-Update-entity-Metadata-for-all-tracked-players.patch +++ b/Spigot-Server-Patches/0374-Update-entity-Metadata-for-all-tracked-players.patch @@ -1,14 +1,14 @@ -From a10f5f8613944c8b57e54babc61a3f93fc878433 Mon Sep 17 00:00:00 2001 +From 130d65dcf32d7dbe293bad4a3da9acb4c1b3250b Mon Sep 17 00:00:00 2001 From: AgentTroll Date: Fri, 22 Mar 2019 22:24:03 -0700 Subject: [PATCH] Update entity Metadata for all tracked players diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 188e450a13..c1ee63271e 100644 +index 39a040a2a0..c1d1621d9e 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -1975,7 +1975,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { +@@ -2021,7 +2021,7 @@ public class PlayerConnection implements PacketListenerPlayIn { if (event.isCancelled() || this.player.inventory.getItemInHand() == null || this.player.inventory.getItemInHand().getItem() != origItem) { // Refresh the current entity metadata diff --git a/Spigot-Server-Patches/0425-Fire-event-on-GS4-query.patch b/Spigot-Server-Patches/0375-Fire-event-on-GS4-query.patch similarity index 87% rename from Spigot-Server-Patches/0425-Fire-event-on-GS4-query.patch rename to Spigot-Server-Patches/0375-Fire-event-on-GS4-query.patch index 330293f1b8..7c46512a76 100644 --- a/Spigot-Server-Patches/0425-Fire-event-on-GS4-query.patch +++ b/Spigot-Server-Patches/0375-Fire-event-on-GS4-query.patch @@ -1,61 +1,61 @@ -From d93407a6a86afa6ade028a6285c54b2b5374dd9f Mon Sep 17 00:00:00 2001 +From 44b80b979a350005ada09981da707d6ee687982f 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 d875b799ac..bcc36bbbfa 100644 +index 66bfbcf02b..d821ef9a75 100644 --- a/src/main/java/net/minecraft/server/RemoteConnectionThread.java +++ b/src/main/java/net/minecraft/server/RemoteConnectionThread.java @@ -15,7 +15,7 @@ public abstract class RemoteConnectionThread implements Runnable { - private static final Logger h = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private static final AtomicInteger i = new AtomicInteger(0); protected boolean a; -- protected IMinecraftServer b; -+ protected IMinecraftServer b; protected IMinecraftServer getServer() { return b; } // Paper - OBFHELPER +- protected final IMinecraftServer b; ++ protected final IMinecraftServer b; protected IMinecraftServer getServer() { return this.b; } // Paper - OBFHELPER protected final String c; protected Thread d; - protected int e = 5; -@@ -58,6 +58,7 @@ public abstract class RemoteConnectionThread implements Runnable { - this.b.f(s); + protected final int e = 5; +@@ -94,6 +94,7 @@ public abstract class RemoteConnectionThread implements Runnable { + this.b.g(s); } -+ protected int getPlayerCount() { return d(); } // Paper - OBFHELPER ++ 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 7dd81564a2..fd981931b0 100644 +index ddb4ba4899..3770334fc4 100644 --- a/src/main/java/net/minecraft/server/RemoteStatusListener.java +++ b/src/main/java/net/minecraft/server/RemoteStatusListener.java @@ -21,19 +21,19 @@ public class RemoteStatusListener extends RemoteConnectionThread { private long h; - private int i; + 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 j; } // Paper - OBFHELPER -+ private final int k; private int getMaxPlayers() { return k; } // Paper - OBFHELPER -+ private final String l; private String getMotd() { return l; } // Paper - OBFHELPER -+ private final String m; private String getWorldName() { return m; } // Paper - OBFHELPER ++ 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 r; } // Paper - OBFHELPER ++ 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 v; } // Paper - OBFHELPER ++ private final RemoteStatusReply v; private RemoteStatusReply getCachedFullResponse() { return this.v; } // Paper - OBFHELPER private long w; public RemoteStatusListener(IMinecraftServer iminecraftserver) { -@@ -99,6 +99,7 @@ public class RemoteStatusListener extends RemoteConnectionThread { +@@ -91,6 +91,7 @@ public class RemoteStatusListener extends RemoteConnectionThread { remotestatusreply.a((int) 0); remotestatusreply.a(this.a(datagrampacket.getSocketAddress())); @@ -63,7 +63,7 @@ index 7dd81564a2..fd981931b0 100644 remotestatusreply.a(this.l); remotestatusreply.a("SMP"); remotestatusreply.a(this.m); -@@ -106,6 +107,31 @@ public class RemoteStatusListener extends RemoteConnectionThread { +@@ -98,6 +99,31 @@ public class RemoteStatusListener extends RemoteConnectionThread { remotestatusreply.a(Integer.toString(this.k)); remotestatusreply.a((short) this.j); remotestatusreply.a(this.r); @@ -95,7 +95,7 @@ index 7dd81564a2..fd981931b0 100644 this.a(remotestatusreply.a(), datagrampacket); this.a("Status [" + socketaddress + "]"); } -@@ -142,6 +168,7 @@ public class RemoteStatusListener extends RemoteConnectionThread { +@@ -134,6 +160,7 @@ public class RemoteStatusListener extends RemoteConnectionThread { this.v.a("splitnum"); this.v.a((int) 128); this.v.a((int) 0); @@ -103,7 +103,7 @@ index 7dd81564a2..fd981931b0 100644 this.v.a("hostname"); this.v.a(this.l); this.v.a("gametype"); -@@ -177,6 +204,79 @@ public class RemoteStatusListener extends RemoteConnectionThread { +@@ -169,6 +196,79 @@ public class RemoteStatusListener extends RemoteConnectionThread { } this.v.a((int) 0); @@ -184,14 +184,14 @@ index 7dd81564a2..fd981931b0 100644 } } diff --git a/src/main/java/net/minecraft/server/RemoteStatusReply.java b/src/main/java/net/minecraft/server/RemoteStatusReply.java -index 848b5c3f0e..9e8c8b3df2 100644 +index 848b5c3f0e..73efea7e13 100644 --- a/src/main/java/net/minecraft/server/RemoteStatusReply.java +++ b/src/main/java/net/minecraft/server/RemoteStatusReply.java @@ -18,15 +18,27 @@ public class RemoteStatusReply { this.b.write(abyte, 0, abyte.length); } -+ public void writeString(String string) throws IOException { a(string); } // Paper - OBFHELPER ++ 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); @@ -206,12 +206,12 @@ index 848b5c3f0e..9e8c8b3df2 100644 + } + // Paper end -+ public void writeInt(int i) throws IOException { a(i); } // Paper - OBFHELPER ++ 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 { a(i); } // Paper - OBFHELPER ++ 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/0426-Implement-PlayerPostRespawnEvent.patch b/Spigot-Server-Patches/0376-Implement-PlayerPostRespawnEvent.patch similarity index 80% rename from Spigot-Server-Patches/0426-Implement-PlayerPostRespawnEvent.patch rename to Spigot-Server-Patches/0376-Implement-PlayerPostRespawnEvent.patch index a66cd22a10..974161e2bb 100644 --- a/Spigot-Server-Patches/0426-Implement-PlayerPostRespawnEvent.patch +++ b/Spigot-Server-Patches/0376-Implement-PlayerPostRespawnEvent.patch @@ -1,16 +1,16 @@ -From 86fdb38b7adbe22c2122182b9aaa623e0cc59b52 Mon Sep 17 00:00:00 2001 +From 796e45876e53d2dfa0ee09e384d37fd88c22d395 Mon Sep 17 00:00:00 2001 From: MisterVector Date: Fri, 26 Oct 2018 21:31:00 -0700 Subject: [PATCH] Implement PlayerPostRespawnEvent diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java -index df416e3b59..012238ac2b 100644 +index 3d1c910ccf..6c7289f037 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java -@@ -663,9 +663,14 @@ public abstract class PlayerList { +@@ -635,9 +635,14 @@ public abstract class PlayerList { + // this.a(entityplayer1, entityplayer, worldserver); // CraftBukkit - removed - BlockPosition blockposition1; + // Paper start + boolean isBedSpawn = false; @@ -23,8 +23,8 @@ index df416e3b59..012238ac2b 100644 + //boolean isBedSpawn = false; Paper - moved up CraftWorld cworld = (CraftWorld) this.server.server.getWorld(entityplayer.spawnWorld); if (cworld != null && blockposition != null) { - blockposition1 = EntityHuman.getBed(cworld.getHandle(), blockposition, flag1); -@@ -695,6 +700,7 @@ public abstract class PlayerList { + Optional optional = EntityHuman.getBed(cworld.getHandle(), blockposition, flag1); +@@ -670,6 +675,7 @@ public abstract class PlayerList { location = respawnEvent.getRespawnLocation(); entityplayer.reset(); @@ -32,7 +32,7 @@ index df416e3b59..012238ac2b 100644 } else { location.setWorld(server.getWorldServer(dimensionmanager).getWorld()); } -@@ -757,6 +763,13 @@ public abstract class PlayerList { +@@ -730,6 +736,13 @@ public abstract class PlayerList { if (entityplayer.playerConnection.isDisconnected()) { this.savePlayerFile(entityplayer); } diff --git a/Spigot-Server-Patches/0427-don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch b/Spigot-Server-Patches/0377-don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch similarity index 85% rename from Spigot-Server-Patches/0427-don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch rename to Spigot-Server-Patches/0377-don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch index 44f01f4a06..fedf75fd30 100644 --- a/Spigot-Server-Patches/0427-don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch +++ b/Spigot-Server-Patches/0377-don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch @@ -1,4 +1,4 @@ -From 8e7a5ca3bc46e18ff3d7bde7ca3cbe7b713623a8 Mon Sep 17 00:00:00 2001 +From c1087e087ac5d0583ccb2c59fe01a6f7217acac7 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 24 Mar 2019 18:09:20 -0400 Subject: [PATCH] don't go below 0 for pickupDelay, breaks picking up items @@ -6,10 +6,10 @@ Subject: [PATCH] don't go below 0 for pickupDelay, breaks picking up items vanilla checks for == 0 diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java -index e723bd339e..5f6e813724 100644 +index c5fefa060b..43fc790a61 100644 --- a/src/main/java/net/minecraft/server/EntityItem.java +++ b/src/main/java/net/minecraft/server/EntityItem.java -@@ -58,6 +58,7 @@ public class EntityItem extends Entity { +@@ -59,6 +59,7 @@ public class EntityItem extends Entity { // CraftBukkit start - Use wall time for pickup and despawn timers int elapsedTicks = MinecraftServer.currentTick - this.lastTick; if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks; @@ -17,7 +17,7 @@ index e723bd339e..5f6e813724 100644 if (this.age != -32768) this.age += elapsedTicks; this.lastTick = MinecraftServer.currentTick; // CraftBukkit end -@@ -147,6 +148,7 @@ public class EntityItem extends Entity { +@@ -143,6 +144,7 @@ public class EntityItem extends Entity { // CraftBukkit start - Use wall time for pickup and despawn timers int elapsedTicks = MinecraftServer.currentTick - this.lastTick; if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks; diff --git a/Spigot-Server-Patches/0429-Server-Tick-Events.patch b/Spigot-Server-Patches/0378-Server-Tick-Events.patch similarity index 68% rename from Spigot-Server-Patches/0429-Server-Tick-Events.patch rename to Spigot-Server-Patches/0378-Server-Tick-Events.patch index afc6fba092..781b301345 100644 --- a/Spigot-Server-Patches/0429-Server-Tick-Events.patch +++ b/Spigot-Server-Patches/0378-Server-Tick-Events.patch @@ -1,4 +1,4 @@ -From 0051bbc2ee1699aed51c6ca5dddb1a3f033aa444 Mon Sep 17 00:00:00 2001 +From 40e9a766256d4a35e40cd4b074191bb845c1f26b Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 27 Mar 2019 22:48:45 -0400 Subject: [PATCH] Server Tick Events @@ -6,20 +6,20 @@ Subject: [PATCH] Server Tick Events Fires event at start and end of a server tick diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index b93fccf919..d6250c4722 100644 +index e90cf0629a..b790472347 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -927,6 +927,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati +@@ -1032,6 +1032,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant Date: Wed, 27 Mar 2019 23:01:33 -0400 Subject: [PATCH] PlayerDeathEvent#getItemsToKeep @@ -8,10 +8,10 @@ Exposes a mutable array on items a player should keep on death Example Usage: https://gist.github.com/aikar/5bb202de6057a051a950ce1f29feb0b4 diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 1d37300832..b9d0c0f740 100644 +index f4ee78efc6..84159cd7ee 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java -@@ -490,6 +490,46 @@ public class EntityPlayer extends EntityHuman implements ICrafting { +@@ -507,6 +507,46 @@ public class EntityPlayer extends EntityHuman implements ICrafting { }); } @@ -55,10 +55,10 @@ index 1d37300832..b9d0c0f740 100644 + } + // Paper end + + @Override public void die(DamageSource damagesource) { boolean flag = this.world.getGameRules().getBoolean("showDeathMessages"); - // CraftBukkit start - fire PlayerDeathEvent -@@ -567,8 +607,14 @@ public class EntityPlayer extends EntityHuman implements ICrafting { +@@ -585,7 +625,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.releaseShoulderEntities(); // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory. if (!event.getKeepInventory()) { @@ -70,10 +70,8 @@ index 1d37300832..b9d0c0f740 100644 + processKeep(event, null); + // Paper end } -+ - this.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DEATH); // Paper + this.setSpectatorTarget(this); // Remove spectated target - // CraftBukkit end -- 2.21.0 diff --git a/Spigot-Server-Patches/0380-Optimize-Persistent-Data-Loading.patch b/Spigot-Server-Patches/0380-Optimize-Persistent-Data-Loading.patch new file mode 100644 index 0000000000..1bc8a424b2 --- /dev/null +++ b/Spigot-Server-Patches/0380-Optimize-Persistent-Data-Loading.patch @@ -0,0 +1,62 @@ +From eff17eb73df9b06810623213fec383b54253b172 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Fri, 29 Mar 2019 01:25:11 -0400 +Subject: [PATCH] Optimize Persistent Data Loading + +removes Mineshaft loading legacy as we had pre 1.13.2 to avoid managing +that very large data file from legacy systems. + +Previous to 1.13.2 these data files were never loaded to begin with, so they +effectively do not contain valid/relevant data. + +These files take a long time to convert on large worlds and crashes the server. + +Additionally, cache the result of a file being missing so we don't keep spam checking it. + +diff --git a/src/main/java/net/minecraft/server/WorldPersistentData.java b/src/main/java/net/minecraft/server/WorldPersistentData.java +index 47a4ea9985..62081349f1 100644 +--- a/src/main/java/net/minecraft/server/WorldPersistentData.java ++++ b/src/main/java/net/minecraft/server/WorldPersistentData.java +@@ -26,6 +26,7 @@ public class WorldPersistentData { + this.c = datafixer; + this.d = file; + } ++ private static final PersistentBase NO_RESULT = new ForcedChunk(); // Paper + + private File a(String s) { + return new File(this.d, s + ".dat"); +@@ -46,6 +47,7 @@ public class WorldPersistentData { + + @Nullable + public T b(Supplier supplier, String s) { ++ if ("Mineshaft_index".equals(s) || "Mineshaft".equals(s)) return null; // Paper - mineshaft is useless data + PersistentBase persistentbase = (PersistentBase) this.data.get(s); + + if (persistentbase == null) { +@@ -58,13 +60,13 @@ public class WorldPersistentData { + + persistentbase.a(nbttagcompound.getCompound("data")); + this.data.put(s, persistentbase); +- } ++ } else this.data.put(s, NO_RESULT); // Paper + } catch (Exception exception) { + WorldPersistentData.LOGGER.error("Error loading saved data: {}", s, exception); + } + } + +- return (T) persistentbase; // Paper - decompile fix ++ return (T) persistentbase == NO_RESULT ? null : (T) persistentbase; // Paper - decompile fix // Paper + } + + public void a(PersistentBase persistentbase) { +@@ -72,6 +74,7 @@ public class WorldPersistentData { + } + + public NBTTagCompound a(String s, int i) throws IOException { ++ if ("Mineshaft".equals(s) || "Mineshaft_index".equals(s)) return new NBTTagCompound(); // Paper + File file = this.a(s); + PushbackInputStream pushbackinputstream = new PushbackInputStream(new FileInputStream(file), 2); + Throwable throwable = null; +-- +2.21.0 + diff --git a/Spigot-Server-Patches/0432-Allow-login-events-to-fire-only-after-the-server-plu.patch b/Spigot-Server-Patches/0381-Allow-login-events-to-fire-only-after-the-server-plu.patch similarity index 84% rename from Spigot-Server-Patches/0432-Allow-login-events-to-fire-only-after-the-server-plu.patch rename to Spigot-Server-Patches/0381-Allow-login-events-to-fire-only-after-the-server-plu.patch index da68f4a055..c90160e89e 100644 --- a/Spigot-Server-Patches/0432-Allow-login-events-to-fire-only-after-the-server-plu.patch +++ b/Spigot-Server-Patches/0381-Allow-login-events-to-fire-only-after-the-server-plu.patch @@ -1,4 +1,4 @@ -From 75a702d4b18f81dd7b3a17296e9ddef09f7b67d1 Mon Sep 17 00:00:00 2001 +From 958395a3ff4635072301a6fc0fe288e5470421f9 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sun, 31 Mar 2019 22:02:24 -0700 Subject: [PATCH] Allow login events to fire only after the server plugins are @@ -7,10 +7,10 @@ Subject: [PATCH] Allow login events to fire only after the server plugins are Event threads will simply block until they're ready to accept. diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/java/net/minecraft/server/LoginListener.java -index dfe7a029f8..503f665820 100644 +index 9e4bc24058..028c23dbe6 100644 --- a/src/main/java/net/minecraft/server/LoginListener.java +++ b/src/main/java/net/minecraft/server/LoginListener.java -@@ -282,6 +282,36 @@ public class LoginListener implements PacketLoginInListener, ITickable { +@@ -285,6 +285,36 @@ public class LoginListener implements PacketLoginInListener { } } @@ -47,7 +47,7 @@ index dfe7a029f8..503f665820 100644 // Spigot start public class LoginHandler { -@@ -292,6 +322,7 @@ public class LoginListener implements PacketLoginInListener, ITickable { +@@ -295,6 +325,7 @@ public class LoginListener implements PacketLoginInListener { return; } // Paper end @@ -56,17 +56,17 @@ index dfe7a029f8..503f665820 100644 java.net.InetAddress address = ((java.net.InetSocketAddress) networkManager.getSocketAddress()).getAddress(); java.util.UUID uniqueId = i.getId(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index d6250c4722..8db5c6a351 100644 +index b790472347..c28b0738dd 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -606,6 +606,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati - this.x = 0; - // CraftBukkit Start +@@ -461,6 +461,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant +Date: Mon, 1 Apr 2019 18:57:32 -0700 +Subject: [PATCH] Make region files more reliable to write to + +Previously we would write to header before writing our chunk data, +which opens a window for corruption (or we would overwrite entirely). +Now the saving process has been changed to follow this chain of events: + +1. We always allocate a new space to write so we do not potentially +overwrite and corrupt the current data +2. Write the chunk data first (the order of the fields in +the chunk data isn't relevant though) +3. Flush to disk (if the launch flag is used) +4. Write to the region header last +5. Flush to disk (if the launch flag is used) +6. Then we free the previous space allocated + +With this chain of events it is impossible for a chunk write to corrupt +a region file, unless the operating system has lied and we have NOT flushed +to disk. + +However server administrators are still recommended to continue performing +regular backups. + +Note that when Mojang finally decides to change their region format +to deal with oversized chunks this patch must be changed to deal with +whatever system they decide to impose. + +If the paper.flush-on-save startup flag is set to true, then the +steps 3 and 5 will make a call to sync() on the region file's fd, +effectively flushing to disk. + +We also make use of two flushes to disk per chunk save (to ensure +ordering and ensure data has gone to disk), so this will negatively +affect save performance if the startup flag is used (especially on +HDDs). + +diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java +index 995a893774..66d87d64b5 100644 +--- a/src/main/java/net/minecraft/server/RegionFile.java ++++ b/src/main/java/net/minecraft/server/RegionFile.java +@@ -29,7 +29,7 @@ public class RegionFile implements AutoCloseable { + private final RandomAccessFile b; private RandomAccessFile getDataFile() { return this.b; } // Paper - OBFHELPER + private final int[] c = new int[1024]; private int[] offsets = c; // Paper - OBFHELPER + private final int[] d = new int[1024];private int[] timestamps = d; // Paper - OBFHELPER +- private final List e; ++ private final List e; private List getFreeSectors() { return this.e; } // Paper - OBFHELPER + + public RegionFile(File file) throws IOException { + this.b = new RandomAccessFile(file, "rw"); +@@ -190,8 +190,8 @@ public class RegionFile implements AutoCloseable { + protected synchronized void a(ChunkCoordIntPair chunkcoordintpair, byte[] abyte, int i) { + try { + int j = this.getOffset(chunkcoordintpair); +- int k = j >> 8; +- int l = j & 255; ++ int k = j >> 8; final int oldSectorOffset = k; // Paper - store variable for later ++ int l = j & 255; final int oldSectorCount; // Paper - store variable for later + // Spigot start + if (l == 255) { + this.b.seek(k * 4096); +@@ -199,6 +199,7 @@ public class RegionFile implements AutoCloseable { + } + // Spigot end + int i1 = (i + 5) / 4096 + 1; ++ oldSectorCount = l; // Paper - store variable for later (watch out for re-assignments of l) + + if (i1 >= 256) { + // Spigot start +@@ -208,14 +209,12 @@ public class RegionFile implements AutoCloseable { + // Spigot end + } + +- if (k != 0 && l == i1) { ++ if (false && k != 0 && l == i1) { // Paper - We never want to overrite old data + this.a(k, abyte, i); + } else { + int j1; + +- for (j1 = 0; j1 < l; ++j1) { +- this.e.set(k + j1, true); +- } ++ // Paper - We do not free old sectors until we are done writing the new chunk data + + j1 = this.e.indexOf(true); + int k1 = 0; +@@ -242,13 +241,13 @@ public class RegionFile implements AutoCloseable { + + if (k1 >= i1) { + k = j1; +- this.a(chunkcoordintpair, j1 << 8 | (i1 > 255 ? 255 : i1)); // Spigot ++ //this.a(chunkcoordintpair, j1 << 8 | (i1 > 255 ? 255 : i1)); // Spigot // Paper - We only write to header after we've written chunk data + + for (l1 = 0; l1 < i1; ++l1) { + this.e.set(k + l1, false); + } + +- this.a(k, abyte, i); ++ this.writeChunk(chunkcoordintpair, j1 << 8 | (i1 > 255 ? 255 : i1), k, abyte, i); // Paper - Ensure we do not corrupt region files + } else { + this.b.seek(this.b.length()); + k = this.e.size(); +@@ -258,9 +257,14 @@ public class RegionFile implements AutoCloseable { + this.e.add(false); + } + +- this.a(k, abyte, i); +- this.a(chunkcoordintpair, k << 8 | (i1 > 255 ? 255 : i1)); // Spigot ++ this.writeChunk(chunkcoordintpair, k << 8 | (i1 > 255 ? 255 : i1), k, abyte, i); // Paper - Ensure we do not corrupt region files ++ } ++ ++ // Paper start - Now that we've written the new chunk we can free the old data ++ for (int off = 0; off < oldSectorCount; ++off) { ++ this.getFreeSectors().set(oldSectorOffset + off, true); + } ++ // Paper end + } + + this.b(chunkcoordintpair, (int) (SystemUtils.getTimeMillis() / 1000L)); +@@ -270,10 +274,10 @@ public class RegionFile implements AutoCloseable { + + } + ++ private void writeChunkData(final int sectorOffset, final byte[] data, final int dataLength) throws IOException { this.a(sectorOffset, data, dataLength); } // Paper - OBFHELPER + private void a(int i, byte[] abyte, int j) throws IOException { + this.b.seek((long) (i * 4096)); +- this.b.writeInt(j + 1); +- this.b.writeByte(2); ++ this.writeIntAndByte(j + 1, (byte)2); // Paper - Avoid 4 io write calls + this.b.write(abyte, 0, j); + } + +@@ -285,12 +289,13 @@ public class RegionFile implements AutoCloseable { + return this.getOffset(chunkcoordintpair) != 0; + } + ++ private void updateChunkHeader(ChunkCoordIntPair chunkcoordintpair, final int offset) throws IOException { this.a(chunkcoordintpair, offset); } // Paper - OBFHELPER + private void a(ChunkCoordIntPair chunkcoordintpair, int i) throws IOException { + int j = this.f(chunkcoordintpair); + + this.c[j] = i; + this.b.seek((long) (j * 4)); +- this.b.writeInt(i); ++ this.writeInt(i); // Paper - Avoid 3 io write calls + } + + private int f(ChunkCoordIntPair chunkcoordintpair) { +@@ -302,7 +307,7 @@ public class RegionFile implements AutoCloseable { + + this.d[j] = i; + this.b.seek((long) (4096 + j * 4)); +- this.b.writeInt(i); ++ this.writeInt(i); // Paper - Avoid 3 io write calls + } + + public void close() throws IOException { +@@ -310,6 +315,40 @@ public class RegionFile implements AutoCloseable { + } + + // Paper start ++ private static final boolean FLUSH_ON_SAVE = Boolean.getBoolean("paper.flush-on-save"); ++ private void syncRegionFile() throws IOException { ++ if (!FLUSH_ON_SAVE) { ++ return; ++ } ++ this.getDataFile().getFD().sync(); // rethrow exception as we want to avoid corrupting a regionfile ++ } ++ ++ private final java.nio.ByteBuffer scratchBuffer = java.nio.ByteBuffer.allocate(8); ++ ++ private void writeInt(final int value) throws IOException { ++ synchronized (this.scratchBuffer) { ++ this.scratchBuffer.putInt(0, value); ++ this.getDataFile().write(this.scratchBuffer.array(), 0, 4); ++ } ++ } ++ ++ // writes v1 then v2 ++ private void writeIntAndByte(final int v1, final byte v2) throws IOException { ++ synchronized (this.scratchBuffer) { ++ this.scratchBuffer.putInt(0, v1); ++ this.scratchBuffer.put(4, v2); ++ this.getDataFile().write(this.scratchBuffer.array(), 0, 5); ++ } ++ } ++ ++ private void writeChunk(final ChunkCoordIntPair chunk, final int chunkHeaderData, ++ final int chunkOffset, final byte[] chunkData, final int chunkDataLength) throws IOException { ++ this.writeChunkData(chunkOffset, chunkData, chunkDataLength); ++ this.syncRegionFile(); // Sync is required to ensure the previous data is written successfully ++ this.updateChunkHeader(chunk, chunkHeaderData); ++ this.syncRegionFile(); // Ensure header changes go through ++ } ++ + public synchronized void deleteChunk(int j1) { + backup(); + int k = offsets[j1]; +-- +2.21.0 + diff --git a/Spigot-Server-Patches/0434-Optimize-GameRules-to-use-LinkedHashMap.patch b/Spigot-Server-Patches/0383-Optimize-GameRules-to-use-LinkedHashMap.patch similarity index 97% rename from Spigot-Server-Patches/0434-Optimize-GameRules-to-use-LinkedHashMap.patch rename to Spigot-Server-Patches/0383-Optimize-GameRules-to-use-LinkedHashMap.patch index 3068614997..fe4bcbca7d 100644 --- a/Spigot-Server-Patches/0434-Optimize-GameRules-to-use-LinkedHashMap.patch +++ b/Spigot-Server-Patches/0383-Optimize-GameRules-to-use-LinkedHashMap.patch @@ -1,4 +1,4 @@ -From dac566303446ee307bd3875361c7bf94a192e45b Mon Sep 17 00:00:00 2001 +From c995a4c2c06c60db91d8ee6f13a7ffdd3033e832 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 4 Apr 2019 17:55:05 -0700 Subject: [PATCH] Optimize GameRules to use LinkedHashMap @@ -6,7 +6,7 @@ Subject: [PATCH] Optimize GameRules to use LinkedHashMap Previously TreeMap was used which has poor get(K) performance. diff --git a/src/main/java/net/minecraft/server/GameRules.java b/src/main/java/net/minecraft/server/GameRules.java -index fd2a4f1b8c..0bd5e02a28 100644 +index 3de9d264db..c6a8004745 100644 --- a/src/main/java/net/minecraft/server/GameRules.java +++ b/src/main/java/net/minecraft/server/GameRules.java @@ -17,7 +17,17 @@ import javax.annotation.Nullable; diff --git a/Spigot-Server-Patches/0435-Optimize-Captured-TileEntity-Lookup.patch b/Spigot-Server-Patches/0384-Optimize-Captured-TileEntity-Lookup.patch similarity index 80% rename from Spigot-Server-Patches/0435-Optimize-Captured-TileEntity-Lookup.patch rename to Spigot-Server-Patches/0384-Optimize-Captured-TileEntity-Lookup.patch index 180c255bea..9d9cb71c78 100644 --- a/Spigot-Server-Patches/0435-Optimize-Captured-TileEntity-Lookup.patch +++ b/Spigot-Server-Patches/0384-Optimize-Captured-TileEntity-Lookup.patch @@ -1,4 +1,4 @@ -From fd269acdf74f64fba07aebd29ec472cd6f597c70 Mon Sep 17 00:00:00 2001 +From fa5e4953123bf162b1fe07630bd8ef94ff94676b Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 6 Apr 2019 10:16:48 -0400 Subject: [PATCH] Optimize Captured TileEntity Lookup @@ -10,10 +10,10 @@ Optimize to check if the captured list even has values in it, and also to just do a get call since the value can never be null. diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 0e8025d311..b940f95bdb 100644 +index de0ed95083..a038945b36 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -1935,12 +1935,13 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc +@@ -1048,12 +1048,13 @@ public abstract class World implements IIBlockAccess, GeneratorAccess, AutoClose return null; } else { // CraftBukkit start @@ -28,8 +28,8 @@ index 0e8025d311..b940f95bdb 100644 - TileEntity tileentity = null; + //TileEntity tileentity = null; // Paper - move up - if (this.J) { - tileentity = this.E(blockposition); + if (this.tickingTileEntities) { + tileentity = this.B(blockposition); -- 2.21.0 diff --git a/Spigot-Server-Patches/0436-Add-Heightmap-API.patch b/Spigot-Server-Patches/0385-Add-Heightmap-API.patch similarity index 70% rename from Spigot-Server-Patches/0436-Add-Heightmap-API.patch rename to Spigot-Server-Patches/0385-Add-Heightmap-API.patch index a051e25809..76c1f74167 100644 --- a/Spigot-Server-Patches/0436-Add-Heightmap-API.patch +++ b/Spigot-Server-Patches/0385-Add-Heightmap-API.patch @@ -1,27 +1,30 @@ -From 899b3fb3c22a1f365bfef5318b90b99b632c0a49 Mon Sep 17 00:00:00 2001 +From 5a74b48ec46c0aebbd6c846fa9e9931e7cec4f49 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Tue, 1 Jan 2019 02:22:01 -0800 Subject: [PATCH] Add Heightmap API diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index b940f95bdb..d20f6ac7e4 100644 +index a038945b36..54a03fb102 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -720,6 +720,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc +@@ -614,8 +614,8 @@ public abstract class World implements IIBlockAccess, GeneratorAccess, AutoClose } } +- @Override +- public int a(HeightMap.Type heightmap_type, int i, int j) { + public final int getHighestBlockY(final HeightMap.Type heightmap, final int x, final int z) { return this.a(heightmap, x, z); } // Paper - OBFHELPER - public int a(HeightMap.Type heightmap_type, int i, int j) { ++ @Override public int a(HeightMap.Type heightmap_type, int i, int j) { // Paper - OBFHELPER int k; + if (i >= -30000000 && j >= -30000000 && i < 30000000 && j < 30000000) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 40ee34675c..457aa5a3f0 100644 +index 5e672ae2e4..d8ea548383 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -136,6 +136,28 @@ public class CraftWorld implements World { - return world.getHighestBlockYAt(HeightMap.Type.LIGHT_BLOCKING, new BlockPosition(x, 0, z)).getY(); +@@ -308,6 +308,29 @@ public class CraftWorld implements World { + return world.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, new BlockPosition(x, 0, z)).getY(); } + // Paper start - Implement heightmap api @@ -31,7 +34,8 @@ index 40ee34675c..457aa5a3f0 100644 + + switch (heightmap) { + case LIGHT_BLOCKING: -+ return this.world.getHighestBlockY(HeightMap.Type.LIGHT_BLOCKING, x, z); ++ throw new UnsupportedOperationException(); // TODO ++ //return this.world.getHighestBlockY(HeightMap.Type.LIGHT_BLOCKING, x, z); + case ANY: + return this.world.getHighestBlockY(HeightMap.Type.WORLD_SURFACE, x, z); + case SOLID: diff --git a/Spigot-Server-Patches/0437-Handle-bad-chunks-more-gracefully.patch b/Spigot-Server-Patches/0386-Handle-bad-chunks-more-gracefully.patch similarity index 62% rename from Spigot-Server-Patches/0437-Handle-bad-chunks-more-gracefully.patch rename to Spigot-Server-Patches/0386-Handle-bad-chunks-more-gracefully.patch index 5f044d3c10..bb489886cb 100644 --- a/Spigot-Server-Patches/0437-Handle-bad-chunks-more-gracefully.patch +++ b/Spigot-Server-Patches/0386-Handle-bad-chunks-more-gracefully.patch @@ -1,4 +1,4 @@ -From d0f37a6611ca8b011d391ced8e259e23b78aaee9 Mon Sep 17 00:00:00 2001 +From d0e791d2d75975b065d7cb468ccb299b565ee794 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Mon, 15 Apr 2019 02:24:52 +0100 Subject: [PATCH] Handle bad chunks more gracefully @@ -15,47 +15,49 @@ Should Mojang choose to alter this behavior in the future, this change will simply defer to whatever that new behavior is. diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java -index 17e76815ad..369aaa84c4 100644 +index 6893f3cd34..717b0b1f08 100644 --- a/src/main/java/net/minecraft/server/RegionFileCache.java +++ b/src/main/java/net/minecraft/server/RegionFileCache.java -@@ -171,8 +171,20 @@ public class RegionFileCache { - private static NBTTagCompound readOversizedChunk(RegionFile regionfile, int i, int j) throws IOException { +@@ -171,8 +171,21 @@ public abstract class RegionFileCache implements AutoCloseable { + private static NBTTagCompound readOversizedChunk(RegionFile regionfile, ChunkCoordIntPair chunkCoordinate) throws IOException { synchronized (regionfile) { - try (DataInputStream datainputstream = regionfile.getReadStream(i & 31, j & 31)) { -- NBTTagCompound oversizedData = regionfile.getOversizedData(i, j); + try (DataInputStream datainputstream = regionfile.getReadStream(chunkCoordinate)) { +- NBTTagCompound oversizedData = regionfile.getOversizedData(chunkCoordinate.x, chunkCoordinate.z); - NBTTagCompound chunk = NBTCompressedStreamTools.readNBT(datainputstream); + // Paper start - Handle bad chunks more gracefully - also handle similarly with oversized data + NBTTagCompound oversizedData = null; + + try { -+ oversizedData = regionfile.getOversizedData(i, j); ++ oversizedData = regionfile.getOversizedData(chunkCoordinate.x, chunkCoordinate.z); + } catch (Exception ex) {} + + NBTTagCompound chunk; ++ + try { -+ chunk = NBTCompressedStreamTools.readNBT(datainputstream); -+ } catch (Exception ex) { ++ chunk = NBTCompressedStreamTools.readNBT(datainputstream); ++ } catch (final Exception ex) { + return null; + } + // Paper end if (oversizedData == null) { return chunk; } -@@ -251,7 +263,13 @@ public class RegionFileCache { - return null; - } +@@ -231,8 +244,13 @@ public abstract class RegionFileCache implements AutoCloseable { -- return NBTCompressedStreamTools.a(datainputstream); -+ // Paper start - Handle bad chunks more gracefully -+ try { -+ return NBTCompressedStreamTools.a(datainputstream); -+ } catch (Exception ex) { -+ return null; -+ } -+ // Paper end - } + try { + if (datainputstream != null) { +- nbttagcompound = NBTCompressedStreamTools.a(datainputstream); +- return nbttagcompound; ++ // Paper start - Handle bad chunks more gracefully ++ try { ++ return NBTCompressedStreamTools.a(datainputstream); ++ } catch (Exception ex) { ++ return null; ++ } ++ // Paper end + } - @Nullable + nbttagcompound = null; -- 2.21.0 diff --git a/Spigot-Server-Patches/0439-Mob-Spawner-API-Enhancements.patch b/Spigot-Server-Patches/0387-Mob-Spawner-API-Enhancements.patch similarity index 90% rename from Spigot-Server-Patches/0439-Mob-Spawner-API-Enhancements.patch rename to Spigot-Server-Patches/0387-Mob-Spawner-API-Enhancements.patch index d3596719d4..331ae3d8dd 100644 --- a/Spigot-Server-Patches/0439-Mob-Spawner-API-Enhancements.patch +++ b/Spigot-Server-Patches/0387-Mob-Spawner-API-Enhancements.patch @@ -1,11 +1,11 @@ -From 965a2dc88afd9fb86088110cf7104e3aae020428 Mon Sep 17 00:00:00 2001 +From 07455d400728b847b024ababe1faa01081563fa3 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 19 Apr 2019 12:41:13 -0500 Subject: [PATCH] Mob Spawner API Enhancements diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java -index af38e5396e..b0fbd4f6d8 100644 +index 96080b6c73..c0f5a55120 100644 --- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java +++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java @@ -46,6 +46,7 @@ public abstract class MobSpawnerAbstract { @@ -16,7 +16,7 @@ index af38e5396e..b0fbd4f6d8 100644 private boolean h() { BlockPosition blockposition = this.b(); -@@ -176,6 +177,7 @@ public abstract class MobSpawnerAbstract { +@@ -205,6 +206,7 @@ public abstract class MobSpawnerAbstract { } } @@ -24,7 +24,7 @@ index af38e5396e..b0fbd4f6d8 100644 private void i() { if (this.maxSpawnDelay <= this.minSpawnDelay) { this.spawnDelay = this.minSpawnDelay; -@@ -193,7 +195,13 @@ public abstract class MobSpawnerAbstract { +@@ -222,7 +224,13 @@ public abstract class MobSpawnerAbstract { } public void a(NBTTagCompound nbttagcompound) { @@ -38,7 +38,7 @@ index af38e5396e..b0fbd4f6d8 100644 this.mobs.clear(); if (nbttagcompound.hasKeyOfType("SpawnPotentials", 9)) { NBTTagList nbttaglist = nbttagcompound.getList("SpawnPotentials", 10); -@@ -208,10 +216,15 @@ public abstract class MobSpawnerAbstract { +@@ -237,10 +245,15 @@ public abstract class MobSpawnerAbstract { } else if (!this.mobs.isEmpty()) { this.a((MobSpawnerData) WeightedRandom.a(this.a().random, this.mobs)); } @@ -57,7 +57,7 @@ index af38e5396e..b0fbd4f6d8 100644 this.spawnCount = nbttagcompound.getShort("SpawnCount"); } -@@ -236,9 +249,20 @@ public abstract class MobSpawnerAbstract { +@@ -265,9 +278,20 @@ public abstract class MobSpawnerAbstract { if (minecraftkey == null) { return nbttagcompound; } else { @@ -82,10 +82,10 @@ index af38e5396e..b0fbd4f6d8 100644 nbttagcompound.setShort("MaxNearbyEntities", (short) this.maxNearbyEntities); nbttagcompound.setShort("RequiredPlayerRange", (short) this.requiredPlayerRange); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java -index aa63b854d1..a3be2b141e 100644 +index 5c4c3c70c7..e78e3804ba 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java -@@ -122,4 +122,16 @@ public class CraftCreatureSpawner extends CraftBlockEntityState Date: Mon, 22 Apr 2019 19:51:14 +0100 Subject: [PATCH] don't NPE on dimensionmanager toString @@ -14,23 +14,23 @@ this is not super elegant, but is the only route that promises not to break stuff. diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 9c5b79920f..e5242f9f87 100644 +index b05d7b0e87..7cc0c7c162 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -999,7 +999,14 @@ public final class CraftServer implements Server { - } +@@ -993,7 +993,14 @@ public final class CraftServer implements Server { worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end) -- DimensionManager internalDimension = new DimensionManager(dimension, name, name, () -> DimensionManager.a(creator.environment().getId()).e()); + DimensionManager actualDimension = DimensionManager.a(creator.environment().getId()); +- DimensionManager internalDimension = new DimensionManager(dimension, name, name, (w, manager) -> actualDimension.getWorldProvider(w), actualDimension.hasSkyLight()); + // Paper start - override toString -+ DimensionManager internalDimension = new DimensionManager(dimension, name, name, () -> DimensionManager.a(creator.environment().getId()).e()) { ++ DimensionManager internalDimension = new DimensionManager(dimension, name, name, (w, manager) -> actualDimension.getWorldProvider(w), actualDimension.hasSkyLight()) { + @Override + public String toString() { + return name; + } + }; + // Paper end - WorldServer internal = (WorldServer) new WorldServer(console, sdm, persistentcollection, worlddata, internalDimension, console.methodProfiler, creator.environment(), generator).i_(); + WorldServer internal = (WorldServer) new WorldServer(console, console.executorService, sdm, worlddata, internalDimension, console.getMethodProfiler(), getServer().worldLoadListenerFactory.create(11), creator.environment(), generator); if (!(worlds.containsKey(name.toLowerCase(java.util.Locale.ENGLISH)))) { -- diff --git a/Spigot-Server-Patches/0401-Prevent-rayTrace-from-loading-chunks.patch b/Spigot-Server-Patches/0401-Prevent-rayTrace-from-loading-chunks.patch deleted file mode 100644 index 80644b4b1a..0000000000 --- a/Spigot-Server-Patches/0401-Prevent-rayTrace-from-loading-chunks.patch +++ /dev/null @@ -1,35 +0,0 @@ -From b5b512f38eb6de0b6887ea7b61cc07acb4043188 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Mon, 26 Nov 2018 19:21:58 -0500 -Subject: [PATCH] Prevent rayTrace from loading chunks - -ray tracing into an unloaded chunk should be treated as a miss -this saves a ton of lag for when AI tries to raytrace near unloaded chunks. - -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 7721dfee65..1454af710e 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -860,7 +860,8 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - int i1 = MathHelper.floor(d1); - int j1 = MathHelper.floor(d2); - BlockPosition blockposition = new BlockPosition(l, i1, j1); -- IBlockData iblockdata = this.getType(blockposition); -+ IBlockData iblockdata = this.getTypeIfLoaded(blockposition); // Paper -+ if (iblockdata == null) return null; // Paper - Fluid fluid = this.getFluid(blockposition); - boolean flag2; - boolean flag3; -@@ -982,7 +983,8 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - i1 = MathHelper.floor(d1) - (enumdirection == EnumDirection.UP ? 1 : 0); - j1 = MathHelper.floor(d2) - (enumdirection == EnumDirection.SOUTH ? 1 : 0); - blockposition = new BlockPosition(l, i1, j1); -- IBlockData iblockdata1 = this.getType(blockposition); -+ IBlockData iblockdata1 = this.getTypeIfLoaded(blockposition); // Paper -+ if (iblockdata1 == null) return null; // Paper - Fluid fluid1 = this.getFluid(blockposition); - - if (!flag || iblockdata1.getMaterial() == Material.PORTAL || !iblockdata1.getCollisionShape(this, blockposition).isEmpty()) { --- -2.21.0 - diff --git a/Spigot-Server-Patches/0407-Fix-PlayerEditBookEvent.patch b/Spigot-Server-Patches/0407-Fix-PlayerEditBookEvent.patch deleted file mode 100644 index 0d88970c0f..0000000000 --- a/Spigot-Server-Patches/0407-Fix-PlayerEditBookEvent.patch +++ /dev/null @@ -1,35 +0,0 @@ -From a5eec7e0b987b7adeeb8a9ec29aaa09b003b8860 Mon Sep 17 00:00:00 2001 -From: Michael Himing -Date: Sun, 16 Dec 2018 13:07:33 +1100 -Subject: [PATCH] Fix PlayerEditBookEvent - -- Updating book writing (not signing) mutated the original item, making -it impossible to properly cancel the event or modify the book meta - -- When the event was cancelled, the client's book would keep the -cancelled writing - -diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 5c041c48fa..f63943f29f 100644 ---- a/src/main/java/net/minecraft/server/PlayerConnection.java -+++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -823,10 +823,13 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { - - this.player.setSlot(enumitemslot, CraftEventFactory.handleEditBookEvent(player, enumitemslot, itemstack1, itemstack2)); // CraftBukkit - } else { -- ItemStack old = itemstack1.cloneItemStack(); // CraftBukkit -- itemstack1.a("pages", (NBTBase) itemstack.getTag().getList("pages", 8)); -- CraftEventFactory.handleEditBookEvent(player, enumitemslot, old, itemstack1); // CraftBukkit -+ // Paper start - dont mutate players current item, set it from the event -+ ItemStack newBook = itemstack1.cloneItemStack(); -+ newBook.getOrCreateTagAndSet("pages", (NBTBase) itemstack.getTag().getList("pages", 8)); -+ this.player.setSlot(enumitemslot, CraftEventFactory.handleEditBookEvent(player, enumitemslot, itemstack1, newBook)); -+ // Paper end - } -+ player.getBukkitEntity().updateInventory(); // Paper - fix client desync when event is cancelled - } - - } --- -2.21.0 - diff --git a/Spigot-Server-Patches/0413-Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch b/Spigot-Server-Patches/0413-Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch deleted file mode 100644 index 795914e5e8..0000000000 --- a/Spigot-Server-Patches/0413-Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 9ba6775e3eddfd4b8af01471ce6cf7b3a658291a Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Fri, 18 Jan 2019 00:08:15 -0500 -Subject: [PATCH] Fix Custom Shapeless Custom Crafting Recipes - -Mojang implemented Shapeless different than Shaped - -This made the Bukkit RecipeChoice API not work for Shapeless. - -This reimplements vanilla logic using the same test logic as Shaped - -diff --git a/src/main/java/net/minecraft/server/ShapelessRecipes.java b/src/main/java/net/minecraft/server/ShapelessRecipes.java -index 819b4ac2da..ea4083a45a 100644 ---- a/src/main/java/net/minecraft/server/ShapelessRecipes.java -+++ b/src/main/java/net/minecraft/server/ShapelessRecipes.java -@@ -62,18 +62,47 @@ public class ShapelessRecipes implements IRecipe { - AutoRecipeStackManager autorecipestackmanager = new AutoRecipeStackManager(); - int i = 0; - -+ // Paper start -+ java.util.List providedItems = new java.util.ArrayList<>(); -+ co.aikar.util.Counter matchedProvided = new co.aikar.util.Counter<>(); -+ co.aikar.util.Counter matchedIngredients = new co.aikar.util.Counter<>(); -+ // Paper end - for (int j = 0; j < iinventory.n(); ++j) { - for (int k = 0; k < iinventory.U_(); ++k) { - ItemStack itemstack = iinventory.getItem(k + j * iinventory.U_()); - - if (!itemstack.isEmpty()) { -- ++i; -- autorecipestackmanager.b(new ItemStack(itemstack.getItem())); -+ // Paper start -+ itemstack = itemstack.cloneItemStack(); -+ providedItems.add(itemstack); -+ for (RecipeItemStack ingredient : ingredients) { -+ if (ingredient.test(itemstack)) { -+ matchedProvided.increment(itemstack); -+ matchedIngredients.increment(ingredient); -+ } -+ } -+ // Paper end - } - } - } -- -- return i == this.ingredients.size() && autorecipestackmanager.a(this, (IntList) null); -+ // Paper start -+ java.util.List ingredients = new java.util.ArrayList<>(this.ingredients); -+ providedItems.sort(java.util.Comparator.comparingInt((ItemStack c) -> (int) matchedProvided.getCount(c)).reversed()); -+ ingredients.sort(java.util.Comparator.comparingInt((RecipeItemStack c) -> (int) matchedIngredients.getCount(c))); -+ -+ PROVIDED: -+ for (ItemStack provided : providedItems) { -+ for (Iterator itIngredient = ingredients.iterator(); itIngredient.hasNext(); ) { -+ RecipeItemStack ingredient = itIngredient.next(); -+ if (ingredient.test(provided)) { -+ itIngredient.remove(); -+ continue PROVIDED; -+ } -+ } -+ return false; -+ } -+ return ingredients.isEmpty(); -+ // Paper end - } - } - --- -2.21.0 - diff --git a/Spigot-Server-Patches/0428-Don-t-update-entity-trackers-for-worlds-without-play.patch b/Spigot-Server-Patches/0428-Don-t-update-entity-trackers-for-worlds-without-play.patch deleted file mode 100644 index e3348db920..0000000000 --- a/Spigot-Server-Patches/0428-Don-t-update-entity-trackers-for-worlds-without-play.patch +++ /dev/null @@ -1,31 +0,0 @@ -From efd33c3794e72cc40a77a3e58ecf90aec6efd6c2 Mon Sep 17 00:00:00 2001 -From: Shane Freeder -Date: Sun, 24 Mar 2019 18:52:31 +0000 -Subject: [PATCH] Don't update entity trackers for worlds without players - -PlayerList#moveToWorld already untracks the player from the player list, -meaning that we do not need to worry about this untracking players -who've left the world, The server also untracks a player during -disconnect, handing yet another case. - -If we don't need to untrack players who've left the world, it should be -reasonably save to do this, as we're not going to be performing any -server->client updates here, which is what this code is intended to do, -and all players should be untracked. - -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index ce39ea09e8..b93fccf919 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1113,7 +1113,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati - - this.methodProfiler.exit(); - this.methodProfiler.enter("tracker"); -- worldserver.getTracker().updatePlayers(); -+ if (playerList.players.size() > 0) worldserver.getTracker().updatePlayers(); // Paper - No players, why spend time tracking them? (See patch) - this.methodProfiler.exit(); - this.methodProfiler.exit(); - worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions --- -2.21.0 - diff --git a/Spigot-Server-Patches/0431-Optimize-Persistent-Data-Loading.patch b/Spigot-Server-Patches/0431-Optimize-Persistent-Data-Loading.patch deleted file mode 100644 index 33633082d6..0000000000 --- a/Spigot-Server-Patches/0431-Optimize-Persistent-Data-Loading.patch +++ /dev/null @@ -1,69 +0,0 @@ -From f640bef2e74224aa9ef01b0351f951e9e5b517d7 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Fri, 29 Mar 2019 01:25:11 -0400 -Subject: [PATCH] Optimize Persistent Data Loading - -removes Mineshaft loading legacy as we had pre 1.13.2 to avoid managing -that very large data file from legacy systems. - -Previous to 1.13.2 these data files were never loaded to begin with, so they -effectively do not contain valid/relevant data. - -These files take a long time to convert on large worlds and crashes the server. - -Additionally, cache the result of a file being missing so we don't keep spam checking it. - -diff --git a/src/main/java/net/minecraft/server/WorldPersistentData.java b/src/main/java/net/minecraft/server/WorldPersistentData.java -index 8d51af2867..e86d382c8d 100644 ---- a/src/main/java/net/minecraft/server/WorldPersistentData.java -+++ b/src/main/java/net/minecraft/server/WorldPersistentData.java -@@ -39,6 +39,7 @@ public class WorldPersistentData { - - @Nullable - public T a(Function function, String s) { -+ if ("Mineshaft_index".equals(s) || "Mineshaft".equals(s)) return null; // Paper - mineshaft is useless data - T persistentbase = (T) this.data.get(s); // Paper - decompile fix - - if (persistentbase == null && this.e != null) { -@@ -49,14 +50,15 @@ public class WorldPersistentData { - persistentbase = function.apply(s); // Paper - decompile fix - persistentbase.a(a(this.e, this.b, s, 1631).getCompound("data")); - this.data.put(s, persistentbase); -- } -+ } else this.data.put(s, NO_RESULT); // Paper - } catch (Exception exception) { - WorldPersistentData.a.error("Error loading saved data: {}", s, exception); - } - } - -- return persistentbase; -+ return persistentbase == NO_RESULT ? null : persistentbase; // Paper - } -+ private static final PersistentBase NO_RESULT = new ForcedChunk("chunks"); // Paper - - public void a(String s, PersistentBase persistentbase) { - this.data.put(s, persistentbase); -@@ -126,6 +128,7 @@ public class WorldPersistentData { - } - - public static NBTTagCompound a(IDataManager idatamanager, DimensionManager dimensionmanager, String s, int i) throws IOException { -+ if ("Mineshaft".equals(s) || "Mineshaft_index".equals(s)) return new NBTTagCompound(); // Paper - File file = idatamanager.getDataFile(dimensionmanager, s); - FileInputStream fileinputstream = new FileInputStream(file); - Throwable throwable = null; -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 5c2421ac38..ee071ba2f6 100644 ---- a/src/main/java/net/minecraft/server/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -80,7 +80,7 @@ public class WorldServer extends World implements IAsyncTaskHandler { - this.P(); - this.Q(); - this.getWorldBorder().a(minecraftserver.au()); -- MCUtil.scheduleAsyncTask(() -> this.getChunkProvider().chunkLoader.getPersistentStructureLegacy(dimensionmanager, worldMaps)); // Paper -+ MCUtil.scheduleAsyncTask(() -> this.getChunkProvider().chunkLoader.getPersistentStructureLegacy(worldProvider.getDimensionManager(), worldMaps)); // Paper - } - - public WorldServer i_() { --- -2.21.0 - diff --git a/Spigot-Server-Patches/0433-Make-region-files-more-reliable-to-write-to.patch b/Spigot-Server-Patches/0433-Make-region-files-more-reliable-to-write-to.patch deleted file mode 100644 index f7cbe7384b..0000000000 --- a/Spigot-Server-Patches/0433-Make-region-files-more-reliable-to-write-to.patch +++ /dev/null @@ -1,196 +0,0 @@ -From ed7d354ccaa9465fd12030d6a0621780ecbe14fc Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Mon, 1 Apr 2019 18:57:32 -0700 -Subject: [PATCH] Make region files more reliable to write to - -Previously we would write to header before writing our chunk data, -which opens a window for corruption (or we would overwrite entirely). -Now the saving process has been changed to follow this chain of events: - -1. We always allocate a new space to write so we do not potentially -overwrite and corrupt the current data -2. Write the chunk data first (the order of the fields in -the chunk data isn't relevant though) -3. Flush to disk (if the launch flag is used) -4. Write to the region header last -5. Flush to disk (if the launch flag is used) -6. Then we free the previous space allocated - -With this chain of events it is impossible for a chunk write to corrupt -a region file, unless the operating system has lied and we have NOT flushed -to disk. - -However server administrators are still recommended to continue performing -regular backups. - -Note that when Mojang finally decides to change their region format -to deal with oversized chunks this patch must be changed to deal with -whatever system they decide to impose. - -If the paper.flush-on-save startup flag is set to true, then the -steps 3 and 5 will make a call to sync() on the region file's fd, -effectively flushing to disk. - -We also make use of two flushes to disk per chunk save (to ensure -ordering and ensure data has gone to disk), so this will negatively -affect save performance if the startup flag is used (especially on -HDDs). - -diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java -index 82f7af46f8..e5659980b3 100644 ---- a/src/main/java/net/minecraft/server/RegionFile.java -+++ b/src/main/java/net/minecraft/server/RegionFile.java -@@ -29,7 +29,7 @@ public class RegionFile { - private RandomAccessFile c;private RandomAccessFile getDataFile() { return c; } // Paper - OBFHELPER - private final int[] d = new int[1024];private int[] offsets = d; // Paper - OBFHELPER - private final int[] e = new int[1024];private int[] timestamps = e; // Paper - OBFHELPER -- private List f; -+ private List f; private List getFreeSectors() { return this.f; } // Paper - OBFHELPER - private int g; - private long h; - -@@ -211,14 +211,15 @@ public class RegionFile { - protected synchronized void a(int i, int j, byte[] abyte, int k) { - try { - int l = this.getOffset(i, j); -- int i1 = l >> 8; -- int j1 = l & 255; -+ int i1 = l >> 8; final int oldSectorOffset = i1; // Paper - store variable for later -+ int j1 = l & 255; final int oldSectorCount; // Paper - store variable for later - // Spigot start - if (j1 == 255) { - this.c.seek(i1 * 4096); - j1 = (this.c.readInt() + 4) / 4096 + 1; - } - // Spigot end -+ oldSectorCount = j1; // Paper - store variable for later (watch out for re-assignments of j1) - int k1 = (k + 5) / 4096 + 1; - - if (k1 >= 256) { -@@ -229,14 +230,12 @@ public class RegionFile { - // Spigot end - } - -- if (i1 != 0 && j1 == k1) { -+ if (false && i1 != 0 && j1 == k1) { // Paper - We never want to overrite old data - this.a(i1, abyte, k); - } else { - int l1; - -- for (l1 = 0; l1 < j1; ++l1) { -- this.f.set(i1 + l1, true); -- } -+ // Paper - We do not free old sectors until we are done writing the new chunk data - - l1 = this.f.indexOf(true); - int i2 = 0; -@@ -263,13 +262,13 @@ public class RegionFile { - - if (i2 >= k1) { - i1 = l1; -- this.a(i, j, l1 << 8 | (k1 > 255 ? 255 : k1)); // Spigot -+ //this.a(i, j, l1 << 8 | (k1 > 255 ? 255 : k1)); // Spigot // Paper - We only write to header after we've written chunk data - - for (j2 = 0; j2 < k1; ++j2) { - this.f.set(i1 + j2, false); - } - -- this.a(i1, abyte, k); -+ this.writeChunk(i, j,i1 << 8 | (k1 > 255 ? 255 : k1), i1, abyte, k); // Paper - Ensure we do not corrupt region files - } else { - this.c.seek(this.c.length()); - i1 = this.f.size(); -@@ -280,9 +279,14 @@ public class RegionFile { - } - - this.g += 4096 * k1; -- this.a(i1, abyte, k); -- this.a(i, j, i1 << 8 | (k1 > 255 ? 255 : k1)); // Spigot -+ this.writeChunk(i, j, i1 << 8 | (k1 > 255 ? 255 : k1), i1, abyte, k); // Paper - Ensure we do not corrupt region files -+ } -+ -+ // Paper start - Now that we've written the new chunk we can free the old data -+ for (int off = 0; off < oldSectorCount; ++off) { -+ this.getFreeSectors().set(oldSectorOffset + off, true); - } -+ // Paper end - } - - this.b(i, j, (int) (SystemUtils.getTimeMillis() / 1000L)); -@@ -292,10 +296,10 @@ public class RegionFile { - - } - -+ private void writeChunkData(final int sectorOffset, final byte[] data, final int dataLength) throws IOException { this.a(sectorOffset, data, dataLength); } // Paper - OBFHELPER - private void a(int i, byte[] abyte, int j) throws IOException { - this.c.seek((long) (i * 4096)); -- this.c.writeInt(j + 1); -- this.c.writeByte(2); -+ this.writeIntAndByte(j + 1, (byte)2); // Paper - Avoid 4 io write calls - this.c.write(abyte, 0, j); - } - -@@ -311,16 +315,17 @@ public class RegionFile { - return this.getOffset(i, j) != 0; - } - -+ private void updateChunkHeader(final int x, final int z, final int offset) throws IOException { this.a(x, z, offset); } // Paper - OBFHELPER - private void a(int i, int j, int k) throws IOException { - this.d[i + j * 32] = k; - this.c.seek((long) ((i + j * 32) * 4)); -- this.c.writeInt(k); -+ this.writeInt(k); // Paper - Avoid 3 io write calls - } - - private void b(int i, int j, int k) throws IOException { - this.e[i + j * 32] = k; - this.c.seek((long) (4096 + (i + j * 32) * 4)); -- this.c.writeInt(k); -+ this.writeInt(k); // Paper - Avoid 3 io write calls - } - - public void close() throws IOException { -@@ -331,6 +336,40 @@ public class RegionFile { - } - - // Paper start -+ private static final boolean FLUSH_ON_SAVE = Boolean.getBoolean("paper.flush-on-save"); -+ private void syncRegionFile() throws IOException { -+ if (!FLUSH_ON_SAVE) { -+ return; -+ } -+ this.getDataFile().getFD().sync(); // rethrow exception as we want to avoid corrupting a regionfile -+ } -+ -+ private final java.nio.ByteBuffer scratchBuffer = java.nio.ByteBuffer.allocate(8); -+ -+ private void writeInt(final int value) throws IOException { -+ synchronized (scratchBuffer) { -+ this.scratchBuffer.putInt(0, value); -+ this.getDataFile().write(this.scratchBuffer.array(), 0, 4); -+ } -+ } -+ -+ // writes v1 then v2 -+ private void writeIntAndByte(final int v1, final byte v2) throws IOException { -+ synchronized (scratchBuffer) { -+ this.scratchBuffer.putInt(0, v1); -+ this.scratchBuffer.put(4, v2); -+ this.getDataFile().write(this.scratchBuffer.array(), 0, 5); -+ } -+ } -+ -+ private void writeChunk(final int x, final int z, final int chunkHeaderData, -+ final int chunkOffset, final byte[] chunkData, final int chunkDataLength) throws IOException { -+ this.writeChunkData(chunkOffset, chunkData, chunkDataLength); -+ this.syncRegionFile(); // Sync is required to ensure the previous data is written successfully -+ this.updateChunkHeader(x, z, chunkHeaderData); -+ this.syncRegionFile(); // Ensure header changes go through -+ } -+ - public synchronized void deleteChunk(int j1) { - backup(); - int k = offsets[j1]; --- -2.21.0 - diff --git a/Spigot-Server-Patches/0438-Fix-NPE-from-sign-placement.patch b/Spigot-Server-Patches/0438-Fix-NPE-from-sign-placement.patch deleted file mode 100644 index 11bb5611be..0000000000 --- a/Spigot-Server-Patches/0438-Fix-NPE-from-sign-placement.patch +++ /dev/null @@ -1,55 +0,0 @@ -From d5c2e00a30aa96c665393676e4dc49aa0a2feed2 Mon Sep 17 00:00:00 2001 -From: Shane Freeder -Date: Wed, 17 Apr 2019 00:48:59 +0100 -Subject: [PATCH] Fix NPE from sign placement - -This fixes issues with upstreams changes to solve a private issue on -their side, as signs are placed, they may replace existing blocks, e.g. -grass, which breaks upstreams assumption that the sign is always placed -adjacent to a surface - -diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java -index f5d9b4abc2..fdbe9a2adc 100644 ---- a/src/main/java/net/minecraft/server/EntityHuman.java -+++ b/src/main/java/net/minecraft/server/EntityHuman.java -@@ -70,6 +70,7 @@ public abstract class EntityHuman extends EntityLiving { - public EntityFishingHook hookedFish; - // Paper start - public boolean affectsSpawning = true; -+ public BlockPosition openingSign = null; // Paper - fix NPE when opening signs - // Paper end - // Paper start - Player view distance API - private int viewDistance = -1; -diff --git a/src/main/java/net/minecraft/server/ItemSign.java b/src/main/java/net/minecraft/server/ItemSign.java -index 11045ee1e1..7808aed0c0 100644 ---- a/src/main/java/net/minecraft/server/ItemSign.java -+++ b/src/main/java/net/minecraft/server/ItemSign.java -@@ -16,6 +16,7 @@ public class ItemSign extends ItemBlockWallable { - if (!world.isClientSide && !flag && entityhuman != null) { - // CraftBukkit start - SPIGOT-4678 - // entityhuman.openSign((TileEntitySign) world.getTileEntity(blockposition)); -+ entityhuman.openingSign = blockposition; // Paper - fix NPE when opening signs - ItemSign.openSign = true; - // CraftBukkit end - } -diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java -index f8d82a0276..ccc0826bc6 100644 ---- a/src/main/java/net/minecraft/server/ItemStack.java -+++ b/src/main/java/net/minecraft/server/ItemStack.java -@@ -305,7 +305,12 @@ public final class ItemStack { - // SPIGOT-4678 - if (this.item instanceof ItemSign && ItemSign.openSign) { - ItemSign.openSign = false; -- entityhuman.openSign((TileEntitySign) world.getTileEntity(new BlockActionContext(itemactioncontext).getClickPosition())); -+ // Paper start - fix NPE when opening signs -+ if (entityhuman.openingSign != null) { -+ entityhuman.openSign((TileEntitySign) world.getTileEntity(entityhuman.openingSign)); -+ entityhuman.openingSign = null; -+ } -+ // Paper end - } - - // SPIGOT-1288 - play sound stripped from ItemBlock --- -2.21.0 - diff --git a/Spigot-Server-Patches/0400-limit-the-range-at-which-we-ll-consider-an-attackabl.patch b/removed/1.14/0400-limit-the-range-at-which-we-ll-consider-an-attackabl.patch similarity index 100% rename from Spigot-Server-Patches/0400-limit-the-range-at-which-we-ll-consider-an-attackabl.patch rename to removed/1.14/0400-limit-the-range-at-which-we-ll-consider-an-attackabl.patch diff --git a/Spigot-Server-Patches/0423-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch b/removed/1.14/0423-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch similarity index 100% rename from Spigot-Server-Patches/0423-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch rename to removed/1.14/0423-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch