1
0
Fork 0
mirror of https://github.com/PaperMC/Paper.git synced 2025-02-17 02:34:30 +01:00

More 1.14 patches

now we can rebase
This commit is contained in:
Spottedleaf 2019-05-05 10:19:34 -07:00
parent 70e4947867
commit 670fbcd29e
41 changed files with 527 additions and 673 deletions
Spigot-Server-Patches
Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patchAdd-Heightmap-API.patchAdd-PlayerConnectionCloseEvent.patchAllow-Saving-of-Oversized-Chunks.patchAllow-login-events-to-fire-only-after-the-server-plu.patchBlock-Entity-remove-from-being-called-on-Players.patchBlockDestroyEvent.patchCall-WhitelistToggleEvent-when-whitelist-is-toggled.patchDon-t-check-ConvertSigns-boolean-every-sign-save.patchDon-t-update-entity-trackers-for-worlds-without-play.patchEntity-getEntitySpawnReason.patchFire-BlockPistonRetractEvent-for-all-empty-pistons.patchFire-event-on-GS4-query.patchFix-Custom-Shapeless-Custom-Crafting-Recipes.patchFix-NPE-from-sign-placement.patchFix-PlayerEditBookEvent.patchFix-sign-edit-memory-leak.patchHandle-Excessive-Signs-in-Chunks-creating-too-large-.patchHandle-Large-Packets-disconnecting-client.patchHandle-bad-chunks-more-gracefully.patchImplement-PlayerPostRespawnEvent.patchLazy-init-world-storage-in-CraftOfflinePlayer.patchLimit-Client-Sign-length-more.patchMC-145260-Fix-Whitelist-On-Off-inconsistency.patchMake-region-files-more-reliable-to-write-to.patchMob-Spawner-API-Enhancements.patchOnly-count-Natural-Spawned-mobs-towards-natural-spaw.patchOptimize-Captured-TileEntity-Lookup.patchOptimize-GameRules-to-use-LinkedHashMap.patchOptimize-Persistent-Data-Loading.patchPlayerDeathEvent-getItemsToKeep.patchPrevent-Enderman-from-loading-chunks.patchPrevent-rayTrace-from-loading-chunks.patchServer-Tick-Events.patchSet-Zombie-last-tick-at-start-of-drowning-process.patchUpdate-entity-Metadata-for-all-tracked-players.patchUse-proper-max-length-when-serialising-BungeeCord-te.patchWorkaround-for-vehicle-tracking-issue-on-disconnect.patchdon-t-NPE-on-dimensionmanager-toString.patchdon-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patchlimit-the-range-at-which-we-ll-consider-an-attackabl.patch

View file

@ -16,7 +16,7 @@ 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
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
@ -28,7 +28,7 @@ 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
@@ -0,0 +0,0 @@ public abstract class PlayerList {
@ -40,7 +40,7 @@ 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
@@ -0,0 +0,0 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
@ -106,7 +106,7 @@ 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
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {

View file

@ -5,23 +5,26 @@ 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
@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
return world.getHighestBlockYAt(HeightMap.Type.LIGHT_BLOCKING, new BlockPosition(x, 0, z)).getY();
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:

View file

@ -34,33 +34,25 @@ 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
@@ -0,0 +0,0 @@ public class LoginListener implements PacketLoginInListener, ITickable {
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ 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;
@@ -0,0 +0,0 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
this.i().a(new ChatMessage("multiplayer.disconnect.generic", new Object[0]));
}

View file

@ -31,7 +31,7 @@ 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
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ import java.util.Objects;
public class NBTTagList extends NBTList<NBTBase> {
- private List<NBTBase> list = Lists.newArrayList();
+ List<NBTBase> 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
@@ -0,0 +0,0 @@ public class RegionFile {
}
header.clear();
java.nio.IntBuffer headerAsInts = header.asIntBuffer();
+ initOversizedState();
// Paper End
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
}
header.clear();
java.nio.IntBuffer headerAsInts = header.asIntBuffer();
+ initOversizedState();
// Paper End
for (j = 0; j < 1024; ++j) {
@@ -0,0 +0,0 @@ public class RegionFile {
this.c.seek(j * 4 + 4); // Go back to where we were
}
int k;
@@ -0,0 +0,0 @@ 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);
@@ -0,0 +0,0 @@ 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);
@@ -0,0 +0,0 @@ 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 {
@@ -0,0 +0,0 @@ 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);
@@ -0,0 +0,0 @@ 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) {
@@ -0,0 +0,0 @@ public class RegionFile {
protected synchronized void a(ChunkCoordIntPair chunkcoordintpair, byte[] abyte, int i) {
@@ -0,0 +0,0 @@ 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
}
@@ -0,0 +0,0 @@ public class RegionFile {
@@ -0,0 +0,0 @@ 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 {
@@ -0,0 +0,0 @@ public class RegionFile {
this.c = j;
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ public class RegionFileCache {
public static final Map<File, RegionFile> 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");
@@ -0,0 +0,0 @@ public class RegionFileCache {
public static synchronized boolean hasRegionFile(File file, int i, int j) {
return RegionFileCache.cache.containsKey(getRegionFileName(file, i, j));
@@ -0,0 +0,0 @@ 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);
@@ -0,0 +0,0 @@ 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<NBTBase> iterator = list.list.iterator(); iterator.hasNext(); ) {
+ for (java.util.Iterator<NBTBase> 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,38 +423,73 @@ index 8c8b7cbab5..17e76815ad 100644
+
// Paper End
public static synchronized void a() {
@@ -0,0 +0,0 @@ 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;
@@ -0,0 +0,0 @@ public abstract class RegionFileCache implements AutoCloseable {
@@ -0,0 +0,0 @@ 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;
--

View file

@ -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
@@ -0,0 +0,0 @@ public class LoginListener implements PacketLoginInListener, ITickable {
@@ -0,0 +0,0 @@ public class LoginListener implements PacketLoginInListener {
}
}
@ -47,7 +47,7 @@ index dfe7a029f8..503f665820 100644
// Spigot start
public class LoginHandler {
@@ -0,0 +0,0 @@ public class LoginListener implements PacketLoginInListener, ITickable {
@@ -0,0 +0,0 @@ public class LoginListener implements PacketLoginInListener {
return;
}
// Paper end
@ -56,15 +56,15 @@ 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
@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
this.x = 0;
// CraftBukkit Start
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
// Paper end
this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD);
+ LoginListener.allowLogins(); // Paper - Allow logins once postworld
this.server.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.STARTUP));
// CraftBukkit end
}
--

View file

@ -12,7 +12,7 @@ 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
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {

View file

@ -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
@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
@@ -0,0 +0,0 @@ public abstract class World implements IIBlockAccess, GeneratorAccess, AutoClose
return false;
} else {
Fluid fluid = this.getFluid(blockposition);
@ -34,6 +34,6 @@ 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;
--

View file

@ -5,7 +5,7 @@ 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
@@ -0,0 +0,0 @@ public abstract class PlayerList {

View file

@ -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
@@ -0,0 +0,0 @@ public class TileEntitySign extends TileEntity implements ICommandListener {
@@ -0,0 +0,0 @@ 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() {
@@ -0,0 +0,0 @@ public class TileEntitySign extends TileEntity implements ICommandListener {
@@ -0,0 +0,0 @@ public class TileEntitySign extends TileEntity implements ICommandListener { //
}
// CraftBukkit start

View file

@ -1,29 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
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
@@ -0,0 +0,0 @@ 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
--

View file

@ -9,21 +9,8 @@ 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
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
@ -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,46 +58,33 @@ 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
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@ -118,6 +92,7 @@ index a0e1a70d43..a12dd4779d 100644
return getHandle().spawnedViaMobSpawner;
}
+
+ @Override
+ public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason getEntitySpawnReason() {
+ return getHandle().spawnReason;
+ }

View file

@ -24,7 +24,7 @@ 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
@@ -0,0 +0,0 @@ public class BlockPiston extends BlockDirectional {

View file

@ -5,53 +5,53 @@ 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
@@ -0,0 +0,0 @@ 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;
protected final int e = 5;
@@ -0,0 +0,0 @@ public abstract class RemoteConnectionThread implements Runnable {
this.b.f(s);
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
@@ -0,0 +0,0 @@ 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<SocketAddress, String> 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<SocketAddress, RemoteStatusListener.RemoteStatusChallenge> 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) {
@ -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
@@ -0,0 +0,0 @@ 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));
}

View file

@ -10,59 +10,57 @@ 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
index 070fc1e3ec..691e697d68 100644
--- a/src/main/java/net/minecraft/server/ShapelessRecipes.java
+++ b/src/main/java/net/minecraft/server/ShapelessRecipes.java
@@ -0,0 +0,0 @@ public class ShapelessRecipes implements IRecipe {
AutoRecipeStackManager autorecipestackmanager = new AutoRecipeStackManager();
int i = 0;
@@ -0,0 +0,0 @@ public class ShapelessRecipes implements RecipeCrafting {
AutoRecipeStackManager autorecipestackmanager = new AutoRecipeStackManager();
int i = 0;
+ // Paper start
+ java.util.List<ItemStack> providedItems = new java.util.ArrayList<>();
+ co.aikar.util.Counter<ItemStack> matchedProvided = new co.aikar.util.Counter<>();
+ co.aikar.util.Counter<RecipeItemStack> 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_());
+ // Paper start
+ java.util.List<ItemStack> providedItems = new java.util.ArrayList<>();
+ co.aikar.util.Counter<ItemStack> matchedProvided = new co.aikar.util.Counter<>();
+ co.aikar.util.Counter<RecipeItemStack> 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.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<RecipeItemStack> 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<RecipeItemStack> itIngredient = ingredients.iterator(); itIngredient.hasNext(); ) {
+ RecipeItemStack ingredient = itIngredient.next();
+ if (ingredient.test(provided)) {
+ itIngredient.remove();
+ continue PROVIDED;
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);
+ }
+ }
+ return false;
+ }
+ return ingredients.isEmpty();
+ // Paper end
+ // Paper end
}
}
- return i == this.ingredients.size() && autorecipestackmanager.a(this, (IntList) null);
+ // Paper start
+ java.util.List<RecipeItemStack> 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<RecipeItemStack> 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) {
--

View file

@ -1,53 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
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
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ 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
--

View file

@ -10,24 +10,22 @@ it impossible to properly cancel the event or modify the book meta
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
index 15fb7ed608..71d10f9b9c 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn, 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
@@ -0,0 +0,0 @@ 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
}
}
--

View file

@ -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
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ public class TileEntitySign extends TileEntity implements ICommandListener {
@@ -0,0 +0,0 @@ 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,16 +30,16 @@ index c2bcbbbab9..fdb771317a 100644
// Paper end
public TileEntitySign() {
@@ -0,0 +0,0 @@ public class TileEntitySign extends TileEntity implements ICommandListener {
@@ -0,0 +0,0 @@ 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() {
--

View file

@ -11,7 +11,7 @@ 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
@@ -0,0 +0,0 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
@ -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,31 +43,33 @@ 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
@@ -0,0 +0,0 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
this.ready = true; // Paper - Async-Anti-Xray - Set the ready flag to true
}
public PacketPlayOutMapChunk() {}
+ // Paper start
+ private final java.util.List<Packet> extraPackets = new java.util.ArrayList<>();
+ private static final int SKIP_EXCESSIVE_SIGNS_LIMIT = Integer.getInteger("Paper.excessiveSignsLimit", 500);
+
+ @Override
+ public java.util.List<Packet> getExtraPackets() {
+ return extraPackets;
+ }
+ // Paper end
public PacketPlayOutMapChunk(Chunk chunk, int i) {
ChunkPacketInfo<IBlockData> chunkPacketInfo = chunk.world.chunkPacketBlockController.getChunkPacketInfo(this, chunk, i); // Paper - Anti-Xray - Add chunk packet info
this.a = chunk.locX;
ChunkCoordIntPair chunkcoordintpair = chunk.getPos();
@@ -0,0 +0,0 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
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();
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<BlockPosition, TileEntity> entry = (Entry) iterator.next();
entry = (Entry) iterator.next();
@@ -0,0 +0,0 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
int j = blockposition.getY() >> 4;
@ -75,13 +77,12 @@ index 4a57e8a3ec..eb54bdb642 100644
+ // 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
--

View file

@ -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
@@ -0,0 +0,0 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
@ -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
@@ -0,0 +0,0 @@ public class PacketEncoder extends MessageToByteEncoder<Packet<?>> {
@ -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
@@ -0,0 +0,0 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
this.c = packetdataserializer.g();
int i = packetdataserializer.g();
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
@@ -0,0 +0,0 @@ public class PacketPlayOutWindowItems implements Packet<PacketListenerPlayOut> {

View file

@ -15,45 +15,47 @@ 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
@@ -0,0 +0,0 @@ public class RegionFileCache {
private static NBTTagCompound readOversizedChunk(RegionFile regionfile, int i, int j) throws IOException {
@@ -0,0 +0,0 @@ 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;
}
@@ -0,0 +0,0 @@ public class RegionFileCache {
return null;
}
@@ -0,0 +0,0 @@ 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;
--

View file

@ -5,12 +5,12 @@ 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
@@ -0,0 +0,0 @@ public abstract class PlayerList {
// this.a(entityplayer1, entityplayer, worldserver); // CraftBukkit - removed
BlockPosition blockposition1;
+ // Paper start
+ boolean isBedSpawn = false;
@ -23,7 +23,7 @@ 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);
Optional<Vec3D> optional = EntityHuman.getBed(cworld.getHandle(), blockposition, flag1);
@@ -0,0 +0,0 @@ public abstract class PlayerList {
location = respawnEvent.getRespawnLocation();

View file

@ -8,7 +8,7 @@ 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
@@ -0,0 +0,0 @@ import org.bukkit.plugin.Plugin;

View file

@ -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
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
@@ -0,0 +0,0 @@ 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) {
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn {
String[] lines = new String[4];
for (int i = 0; i < astring.length; ++i) {

View file

@ -11,19 +11,19 @@ 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
@@ -0,0 +0,0 @@ public class JsonList<K, V extends JsonListEntry<K>> {
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
@@ -0,0 +0,0 @@ public abstract class PlayerList {
@ -31,8 +31,8 @@ index 135d25abd2..408c382d2a 100644
// 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;
@@ -0,0 +0,0 @@ public abstract class PlayerList {

View file

@ -37,76 +37,77 @@ 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
index 995a893774..66d87d64b5 100644
--- a/src/main/java/net/minecraft/server/RegionFile.java
+++ b/src/main/java/net/minecraft/server/RegionFile.java
@@ -0,0 +0,0 @@ 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<Boolean> f;
+ private List<Boolean> f; private List<Boolean> getFreeSectors() { return this.f; } // Paper - OBFHELPER
private int g;
private long h;
@@ -0,0 +0,0 @@ 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<Boolean> e;
+ private final List<Boolean> e; private List<Boolean> getFreeSectors() { return this.e; } // Paper - OBFHELPER
@@ -0,0 +0,0 @@ public class RegionFile {
protected synchronized void a(int i, int j, byte[] abyte, int k) {
public RegionFile(File file) throws IOException {
this.b = new RandomAccessFile(file, "rw");
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
protected synchronized void a(ChunkCoordIntPair chunkcoordintpair, byte[] abyte, int i) {
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
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 (j1 == 255) {
this.c.seek(i1 * 4096);
j1 = (this.c.readInt() + 4) / 4096 + 1;
if (l == 255) {
this.b.seek(k * 4096);
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
}
// Spigot end
+ oldSectorCount = j1; // Paper - store variable for later (watch out for re-assignments of j1)
int k1 = (k + 5) / 4096 + 1;
int i1 = (i + 5) / 4096 + 1;
+ oldSectorCount = l; // Paper - store variable for later (watch out for re-assignments of l)
if (k1 >= 256) {
@@ -0,0 +0,0 @@ public class RegionFile {
if (i1 >= 256) {
// Spigot start
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
// 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);
- 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 l1;
int j1;
- for (l1 = 0; l1 < j1; ++l1) {
- this.f.set(i1 + l1, true);
- 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
l1 = this.f.indexOf(true);
int i2 = 0;
@@ -0,0 +0,0 @@ public class RegionFile {
j1 = this.e.indexOf(true);
int k1 = 0;
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
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
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 (j2 = 0; j2 < k1; ++j2) {
this.f.set(i1 + j2, false);
for (l1 = 0; l1 < i1; ++l1) {
this.e.set(k + l1, 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
- 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.c.seek(this.c.length());
i1 = this.f.size();
@@ -0,0 +0,0 @@ public class RegionFile {
this.b.seek(this.b.length());
k = this.e.size();
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
this.e.add(false);
}
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
- 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
@ -116,41 +117,45 @@ index 82f7af46f8..e5659980b3 100644
+ // Paper end
}
this.b(i, j, (int) (SystemUtils.getTimeMillis() / 1000L));
@@ -0,0 +0,0 @@ public class RegionFile {
this.b(chunkcoordintpair, (int) (SystemUtils.getTimeMillis() / 1000L));
@@ -0,0 +0,0 @@ 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.c.seek((long) (i * 4096));
- this.c.writeInt(j + 1);
- this.c.writeByte(2);
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.c.write(abyte, 0, j);
this.b.write(abyte, 0, j);
}
@@ -0,0 +0,0 @@ public class RegionFile {
return this.getOffset(i, j) != 0;
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
return this.getOffset(chunkcoordintpair) != 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 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 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
private int f(ChunkCoordIntPair chunkcoordintpair) {
@@ -0,0 +0,0 @@ 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 {
@@ -0,0 +0,0 @@ public class RegionFile {
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
}
// Paper start
@ -165,7 +170,7 @@ index 82f7af46f8..e5659980b3 100644
+ private final java.nio.ByteBuffer scratchBuffer = java.nio.ByteBuffer.allocate(8);
+
+ private void writeInt(final int value) throws IOException {
+ synchronized (scratchBuffer) {
+ synchronized (this.scratchBuffer) {
+ this.scratchBuffer.putInt(0, value);
+ this.getDataFile().write(this.scratchBuffer.array(), 0, 4);
+ }
@ -173,18 +178,18 @@ index 82f7af46f8..e5659980b3 100644
+
+ // writes v1 then v2
+ private void writeIntAndByte(final int v1, final byte v2) throws IOException {
+ synchronized (scratchBuffer) {
+ 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 int x, final int z, final int chunkHeaderData,
+ 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(x, z, chunkHeaderData);
+ this.updateChunkHeader(chunk, chunkHeaderData);
+ this.syncRegionFile(); // Ensure header changes go through
+ }
+

View file

@ -5,7 +5,7 @@ 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
@@ -0,0 +0,0 @@ public abstract class MobSpawnerAbstract {
@ -82,7 +82,7 @@ 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
@@ -0,0 +0,0 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<TileEntityMobSpa

View file

@ -1,64 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 24 Mar 2019 01:01:32 -0400
Subject: [PATCH] Only count Natural Spawned mobs towards natural spawn mob
limit
This resolves the super common complaint about mobs not spawning.
This was ultimately a flaw in the vanilla count algorithim that allows
spawners and other misc mobs to count against the mob limit, which are
not bounded, and can prevent the entire world from spawning new.
I believe Bukkits changes around persistence may of actually made it
worse than vanilla.
This should fully solve all of the issues around it so that only natural
influences natural spawns.
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index a70a64070e..bfd690eccd 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
log("Using vanilla redstone algorithm.");
}
}
+
+ public boolean countAllMobsForSpawning = false;
+ private void countAllMobsForSpawning() {
+ countAllMobsForSpawning = getBoolean("count-all-mobs-for-spawning", false);
+ if (countAllMobsForSpawning) {
+ log("Counting all mobs for spawning. Mob farms may reduce natural spawns elsewhere in world.");
+ } else {
+ log("Using improved mob spawn limits (Only Natural Spawns impact spawn limits for more natural spawns)");
+ }
+ }
}
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java b/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java
index a10a5bc138..a5a63f8004 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java
@@ -0,0 +0,0 @@ import net.minecraft.server.IAnimal;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.World;
import net.minecraft.server.WorldServer;
+import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import java.util.ArrayList;
import java.util.Collection;
@@ -0,0 +0,0 @@ public class PaperWorldEntityList extends ArrayList<Entity> {
}
public void updateEntityCount(Entity entity, int amt) {
- if (!(entity instanceof IAnimal)) return;
+ // Only count natural spawns so that mob
+ if (!(entity instanceof IAnimal) || (
+ !world.paperConfig.countAllMobsForSpawning &&
+ entity.spawnReason != SpawnReason.NATURAL &&
+ entity.spawnReason != SpawnReason.CHUNK_GEN
+ )) return;
if (entity instanceof EntityInsentient) {
EntityInsentient entityinsentient = (EntityInsentient) entity;
--

View file

@ -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
@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
@@ -0,0 +0,0 @@ public abstract class World implements IIBlockAccess, GeneratorAccess, AutoClose
return null;
} else {
// CraftBukkit start
@ -28,6 +28,6 @@ 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);
--

View file

@ -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
@@ -0,0 +0,0 @@ import javax.annotation.Nullable;

View file

@ -14,54 +14,47 @@ 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
index 47a4ea9985..62081349f1 100644
--- a/src/main/java/net/minecraft/server/WorldPersistentData.java
+++ b/src/main/java/net/minecraft/server/WorldPersistentData.java
@@ -0,0 +0,0 @@ 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");
@@ -0,0 +0,0 @@ public class WorldPersistentData {
@Nullable
public <T extends PersistentBase> T a(Function<String, T> function, String s) {
public <T extends PersistentBase> T b(Supplier<T> supplier, 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
PersistentBase persistentbase = (PersistentBase) this.data.get(s);
if (persistentbase == null && this.e != null) {
if (persistentbase == null) {
@@ -0,0 +0,0 @@ public class WorldPersistentData {
persistentbase = function.apply(s); // Paper - decompile fix
persistentbase.a(a(this.e, this.b, s, 1631).getCompound("data"));
persistentbase.a(nbttagcompound.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);
WorldPersistentData.LOGGER.error("Error loading saved data: {}", s, exception);
}
}
- return persistentbase;
+ return persistentbase == NO_RESULT ? null : persistentbase; // Paper
- return (T) persistentbase; // Paper - decompile fix
+ return (T) persistentbase == NO_RESULT ? null : (T) persistentbase; // Paper - decompile fix // Paper
}
+ private static final PersistentBase NO_RESULT = new ForcedChunk("chunks"); // Paper
public void a(String s, PersistentBase persistentbase) {
this.data.put(s, persistentbase);
public void a(PersistentBase persistentbase) {
@@ -0,0 +0,0 @@ public class WorldPersistentData {
}
public static NBTTagCompound a(IDataManager idatamanager, DimensionManager dimensionmanager, String s, int i) throws IOException {
public NBTTagCompound a(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);
File file = this.a(s);
PushbackInputStream pushbackinputstream = new PushbackInputStream(new FileInputStream(file), 2);
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
@@ -0,0 +0,0 @@ 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_() {
--

View file

@ -8,7 +8,7 @@ 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
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
@ -55,9 +55,9 @@ index 1d37300832..b9d0c0f740 100644
+ }
+ // Paper end
+
@Override
public void die(DamageSource damagesource) {
boolean flag = this.world.getGameRules().getBoolean("showDeathMessages");
// CraftBukkit start - fire PlayerDeathEvent
@@ -0,0 +0,0 @@ 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.
@ -70,8 +70,6 @@ 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
--

View file

@ -5,7 +5,7 @@ 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
@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster {
@ -16,8 +16,8 @@ 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);
Vec3D vec3d = new Vec3D((double) MathHelper.floor(this.enderman.locX) + 0.5D, (double) j + 0.5D, (double) MathHelper.floor(this.enderman.locZ) + 0.5D);
Vec3D vec3d1 = new Vec3D((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D);
@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster {
int j = MathHelper.floor(this.a.locY + random.nextDouble() * 2.0D);
int k = MathHelper.floor(this.a.locZ - 1.0D + random.nextDouble() * 2.0D);
@ -25,7 +25,7 @@ index e4aba0e0a8..9450404428 100644
- 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
--

View file

@ -6,28 +6,34 @@ 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
@@ -0,0 +0,0 @@ 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;
@@ -0,0 +0,0 @@ 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);
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
@@ -0,0 +0,0 @@ public interface IBlockAccess {
if (!flag || iblockdata1.getMaterial() == Material.PORTAL || !iblockdata1.getCollisionShape(this, blockposition).isEmpty()) {
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();
@@ -0,0 +0,0 @@ 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) {
--

View file

@ -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
@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
co.aikar.timings.TimingsManager.FULL_SERVER_TICK.startTiming(); // Paper
this.slackActivityAccountant.tickStarted(); // Spigot
long i = SystemUtils.getMonotonicNanos(); long startTime = i; // Paper
long i = SystemUtils.getMonotonicNanos();
+ new com.destroystokyo.paper.event.server.ServerTickStartEvent(this.ticks+1).callEvent(); // Paper
++this.ticks;
if (this.S) {
@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
PaperLightingQueue.processQueue(startTime); // Paper
expiringMaps.removeIf(ExpiringMap::clean); // Paper
this.b(booleansupplier);
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.methodProfiler.exit();
org.spigotmc.WatchdogThread.tick(); // Spigot
this.slackActivityAccountant.tickEnded(l); // Spigot
+ // Paper start
+ long endTime = System.nanoTime();

View file

@ -6,15 +6,15 @@ 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
@@ -0,0 +0,0 @@ public class EntityZombie extends EntityMonster {
++this.bI;
if (this.bI >= 600) {
++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;
--

View file

@ -5,10 +5,10 @@ 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
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn {
if (event.isCancelled() || this.player.inventory.getItemInHand() == null || this.player.inventory.getItemInHand().getItem() != origItem) {
// Refresh the current entity metadata

View file

@ -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
@@ -0,0 +0,0 @@ package net.minecraft.server;

View file

@ -5,12 +5,12 @@ 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
@@ -0,0 +0,0 @@ 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,7 +19,7 @@ index 541461275c..1d37300832 100644
+ }
+ // Paper end
+
if (this.sleeping) {
this.a(true, false, false);
if (this.isSleeping()) {
this.wakeup(true, false, false);
}
--

View file

@ -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
@@ -0,0 +0,0 @@ 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)))) {
--

View file

@ -6,7 +6,7 @@ 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
@@ -0,0 +0,0 @@ public class EntityItem extends Entity {

View file

@ -1,33 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Tue, 13 Nov 2018 14:01:00 +0000
Subject: [PATCH] limit the range at which we'll consider an attackable target
This patch aims to ensure that MCP World#getNearestAttackablePlayer
will not trigger chunk loads due to PathfinderGoalNearestAttackableTarget
performing a ray trace operation by pre-checking the maximum limit;
Given that the implementation shows that the limit should only ever
decrease when set, allowing us to skip further checks earlier on
when looking for an attackable entity
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 645af17a58..7721dfee65 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
for (int i = 0; i < this.players.size(); ++i) {
EntityHuman entityhuman1 = (EntityHuman) this.players.get(i);
+ // Paper start
+ // move distance check up, if set, check distance^2 is less than XZlimit^2, continue
+ // 4th method param is XZlimit (at least at the time of commit)
+ double d6 = entityhuman1.d(d0, entityhuman1.locY, d2);
+ if (d3 < 0.0D || d6 < d3 * d3)
if (!entityhuman1.abilities.isInvulnerable && entityhuman1.isAlive() && !entityhuman1.isSpectator() && (predicate == null || predicate.test(entityhuman1))) {
- double d6 = entityhuman1.d(d0, entityhuman1.locY, d2);
+ // Paper end
double d7 = d3;
if (entityhuman1.isSneaking()) {
--