diff --git a/patches/api/0015-Implement-ChunkTooLargeEvent.patch b/patches/api/0015-Implement-ChunkTooLargeEvent.patch new file mode 100644 index 000000000..5ebf034e0 --- /dev/null +++ b/patches/api/0015-Implement-ChunkTooLargeEvent.patch @@ -0,0 +1,127 @@ +From ec162d14f8c9a6210b1b0702fb06afbd3e84ed9a Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Fri, 12 Jul 2019 02:09:58 -0500 +Subject: [PATCH] Implement ChunkTooLargeEvent + +--- + .../pl3x/purpur/event/ChunkTooLargeEvent.java | 108 ++++++++++++++++++ + 1 file changed, 108 insertions(+) + create mode 100644 src/main/java/net/pl3x/purpur/event/ChunkTooLargeEvent.java + +diff --git a/src/main/java/net/pl3x/purpur/event/ChunkTooLargeEvent.java b/src/main/java/net/pl3x/purpur/event/ChunkTooLargeEvent.java +new file mode 100644 +index 000000000..8f2077e21 +--- /dev/null ++++ b/src/main/java/net/pl3x/purpur/event/ChunkTooLargeEvent.java +@@ -0,0 +1,108 @@ ++package net.pl3x.purpur.event; ++ ++import org.bukkit.Bukkit; ++import org.bukkit.Location; ++import org.bukkit.World; ++import org.bukkit.event.Event; ++import org.bukkit.event.HandlerList; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++/** ++ * Called when an oversized chunk loads or saves ++ */ ++public class ChunkTooLargeEvent extends Event { ++ private static final HandlerList handlers = new HandlerList(); ++ private final String worldName; ++ private final World world; ++ private final int chunkX; ++ private final int chunkZ; ++ private final boolean saving; ++ private final boolean overzealous; ++ ++ public ChunkTooLargeEvent(String worldName, int chunkX, int chunkZ, boolean saving, boolean overzealous) { ++ this.worldName = worldName; ++ this.world = Bukkit.getWorld(worldName); ++ this.chunkX = chunkX; ++ this.chunkZ = chunkZ; ++ this.saving = saving; ++ this.overzealous = overzealous; ++ } ++ ++ /** ++ * Get the world name according to the save directory ++ * ++ * @return World name ++ */ ++ @NotNull ++ public String getWorldName() { ++ return worldName; ++ } ++ ++ /** ++ * Get the world ++ * ++ * @return World, or null if world not loaded ++ */ ++ @Nullable ++ public World getWorld() { ++ return world; ++ } ++ ++ /** ++ * Get the X chunk coordinate ++ * ++ * @return X chunk coordinate ++ */ ++ public int getChunkX() { ++ return chunkX; ++ } ++ ++ /** ++ * Get the Z chunk coordinate ++ * ++ * @return Z chunk coordinate ++ */ ++ public int getChunkZ() { ++ return chunkZ; ++ } ++ ++ /** ++ * Whether this happened during a save attempt. ++ * ++ * @return True if saving, false if loading ++ */ ++ public boolean isSaving() { ++ return saving; ++ } ++ ++ /** ++ * If saving, was this is overzealous mode ++ * ++ * @return True if saving in overzealous mode ++ */ ++ public boolean isOverzealous() { ++ return overzealous; ++ } ++ ++ /** ++ * Get the location ++ * ++ * @return Location, or null if world not loaded ++ */ ++ @Nullable ++ public Location getLocation() { ++ return world == null ? null : new Location(world, chunkX << 4, 128, chunkZ << 4); ++ } ++ ++ @NotNull ++ @Override ++ public HandlerList getHandlers() { ++ return handlers; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return handlers; ++ } ++} +-- +2.20.1 + diff --git a/patches/server/0049-Implement-ChunkTooLargeEvent.patch b/patches/server/0049-Implement-ChunkTooLargeEvent.patch new file mode 100644 index 000000000..d500056af --- /dev/null +++ b/patches/server/0049-Implement-ChunkTooLargeEvent.patch @@ -0,0 +1,64 @@ +From 1394bec8ee78bd00371ee774e4b9f8f1596b73cd Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Fri, 12 Jul 2019 02:10:06 -0500 +Subject: [PATCH] Implement ChunkTooLargeEvent + +--- + src/main/java/net/minecraft/server/RegionFileCache.java | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java +index d2b3289450..e0fdf5f90f 100644 +--- a/src/main/java/net/minecraft/server/RegionFileCache.java ++++ b/src/main/java/net/minecraft/server/RegionFileCache.java +@@ -21,6 +21,7 @@ public abstract class RegionFileCache implements AutoCloseable { + private final File actualWorld; + private boolean useAltWorld; + // Paper end ++ private final String worldName; // Purpur + + + protected RegionFileCache(File file) { +@@ -35,6 +36,7 @@ public abstract class RegionFileCache implements AutoCloseable { + if (name.equals("DIM-1") || name.equals("DIM1")) { + container = container.getParentFile(); + } ++ worldName = container.getName(); // Purpur + this.templateWorld = new File(container, name); + File region = new File(file, "region"); + if (!region.exists()) { +@@ -43,6 +45,7 @@ public abstract class RegionFileCache implements AutoCloseable { + } else { + this.useAltWorld = false; + this.templateWorld = file; ++ worldName = file.getParentFile().getParentFile().getName(); // Purpur + } + // Paper start + } +@@ -119,6 +122,7 @@ public abstract class RegionFileCache implements AutoCloseable { + regionfile.setStatus(chunk.x, chunk.z, ChunkRegionLoader.getStatus(nbttagcompound)); // Paper - cache status on disk + regionfile.setOversized(chunkX, chunkZ, false); + } catch (RegionFile.ChunkTooLargeException ignored) { ++ new net.pl3x.purpur.event.ChunkTooLargeEvent(worldName, chunkX, chunkZ, true, false).callEvent(); // Purpur + 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(); +@@ -136,6 +140,7 @@ public abstract class RegionFileCache implements AutoCloseable { + } + regionfile.setStatus(chunk.x, chunk.z, ChunkRegionLoader.getStatus(nbttagcompound)); // Paper - cache status on disk + } catch (RegionFile.ChunkTooLargeException e) { ++ new net.pl3x.purpur.event.ChunkTooLargeEvent(worldName, chunkX, chunkZ, true, true).callEvent(); // Purpur + 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; +@@ -242,6 +247,7 @@ public abstract class RegionFileCache implements AutoCloseable { + DataInputStream datainputstream = regionfile.a(chunkcoordintpair); + // Paper start + if (regionfile.isOversized(chunkcoordintpair.x, chunkcoordintpair.z)) { ++ new net.pl3x.purpur.event.ChunkTooLargeEvent(worldName, chunkcoordintpair.x, chunkcoordintpair.z, false, false).callEvent(); // Purpur + printOversizedLog("Loading Oversized Chunk!", regionfile.file, chunkcoordintpair.x, chunkcoordintpair.z); + return readOversizedChunk(regionfile, chunkcoordintpair); + } +-- +2.20.1 +