diff --git a/patches/api-unmapped/Add-Heightmap-API.patch b/patches/api/Add-Heightmap-API.patch similarity index 100% rename from patches/api-unmapped/Add-Heightmap-API.patch rename to patches/api/Add-Heightmap-API.patch diff --git a/patches/api-unmapped/Flip-some-Spigot-API-null-annotations.patch b/patches/api/Flip-some-Spigot-API-null-annotations.patch similarity index 100% rename from patches/api-unmapped/Flip-some-Spigot-API-null-annotations.patch rename to patches/api/Flip-some-Spigot-API-null-annotations.patch diff --git a/patches/api-unmapped/Ignore-package-private-methods-for-nullability-annot.patch b/patches/api/Ignore-package-private-methods-for-nullability-annot.patch similarity index 100% rename from patches/api-unmapped/Ignore-package-private-methods-for-nullability-annot.patch rename to patches/api/Ignore-package-private-methods-for-nullability-annot.patch diff --git a/patches/api-unmapped/Mob-Spawner-API-Enhancements.patch b/patches/api/Mob-Spawner-API-Enhancements.patch similarity index 100% rename from patches/api-unmapped/Mob-Spawner-API-Enhancements.patch rename to patches/api/Mob-Spawner-API-Enhancements.patch diff --git a/patches/api-unmapped/PlayerDeathEvent-getItemsToKeep.patch b/patches/api/PlayerDeathEvent-getItemsToKeep.patch similarity index 100% rename from patches/api-unmapped/PlayerDeathEvent-getItemsToKeep.patch rename to patches/api/PlayerDeathEvent-getItemsToKeep.patch diff --git a/patches/api-unmapped/Server-Tick-Events.patch b/patches/api/Server-Tick-Events.patch similarity index 100% rename from patches/api-unmapped/Server-Tick-Events.patch rename to patches/api/Server-Tick-Events.patch diff --git a/patches/server-remapped/Add-Heightmap-API.patch b/patches/server-remapped/Add-Heightmap-API.patch deleted file mode 100644 index 335f0334aa..0000000000 --- a/patches/server-remapped/Add-Heightmap-API.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Tue, 1 Jan 2019 02:22:01 -0800 -Subject: [PATCH] Add Heightmap API - - -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - } - } - -- @Override -- public int getHeight(Heightmap.Types heightmap, int x, int z) { -+ public final int getHighestBlockY(final Heightmap.Types heightmap, final int x, final int z) { return this.getHeight(heightmap, x, z); } // Paper - OBFHELPER -+ @Override public int getHeight(Heightmap.Types heightmap, int x, int z) { // Paper - OBFHELPER - int k; - - if (x >= -30000000 && z >= -30000000 && x < 30000000 && z < 30000000) { -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -0,0 +0,0 @@ public class CraftWorld implements World { - return getHighestBlockYAt(x, z, org.bukkit.HeightMap.MOTION_BLOCKING); - } - -+ // Paper start - Implement heightmap api -+ @Override -+ public int getHighestBlockYAt(final int x, final int z, final com.destroystokyo.paper.HeightmapType heightmap) throws UnsupportedOperationException { -+ this.getChunkAt(x >> 4, z >> 4); // heightmap will ret 0 on unloaded areas -+ -+ switch (heightmap) { -+ case LIGHT_BLOCKING: -+ throw new UnsupportedOperationException(); // TODO -+ //return this.world.getHighestBlockY(HeightMap.Type.LIGHT_BLOCKING, x, z); -+ case ANY: -+ return this.world.getHighestBlockY(net.minecraft.world.level.levelgen.Heightmap.Types.WORLD_SURFACE, x, z); -+ case SOLID: -+ return this.world.getHighestBlockY(net.minecraft.world.level.levelgen.Heightmap.Types.OCEAN_FLOOR, x, z); -+ case SOLID_OR_LIQUID: -+ return this.world.getHighestBlockY(net.minecraft.world.level.levelgen.Heightmap.Types.MOTION_BLOCKING, x, z); -+ case SOLID_OR_LIQUID_NO_LEAVES: -+ return this.world.getHighestBlockY(net.minecraft.world.level.levelgen.Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, x, z); -+ default: -+ throw new UnsupportedOperationException(); -+ } -+ } -+ // Paper end -+ - @Override - public Location getSpawnLocation() { - BlockPos spawn = world.getSpawn(); diff --git a/patches/server-remapped/Duplicate-UUID-Resolve-Option.patch b/patches/server-remapped/Duplicate-UUID-Resolve-Option.patch deleted file mode 100644 index 25cae65d72..0000000000 --- a/patches/server-remapped/Duplicate-UUID-Resolve-Option.patch +++ /dev/null @@ -1,249 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sat, 21 Jul 2018 14:27:34 -0400 -Subject: [PATCH] Duplicate UUID Resolve Option - -Due to a bug in https://github.com/PaperMC/Paper/commit/2e29af3df05ec0a383f48be549d1c03200756d24 -which was added all the way back in March of 2016, it was unknown (potentially not at the time) -that an entity might actually change the seed of the random object. - -At some point, EntitySquid did start setting the seed. Due to this shared random, this caused -every entity to use a Random object with a predictable seed. - -This has caused entities to potentially generate with the same UUID.... - -Over the years, servers have had entities disappear, but no sign of trouble -because CraftBukkit removed the log lines indicating that something was wrong. - -We have fixed the root issue causing duplicate UUID's, however we now have chunk -files full of entities that have the same UUID as another entity! - -When these chunks load, the 2nd entity will not be added to the world correctly. - -If that chunk loads in a different order in the future, then it will reverse and the -missing one is now the one added to the world and not the other. This results in very -inconsistent entity behavior. - -This change allows you to recover any duplicate entity by generating a new UUID for it. -This also lets you delete them instead if you don't want to risk having new entities added to -the world that you previously did not see. - -But for those who are ok with leaving this inconsistent behavior, you may use WARN or NOTHING options. - -It is recommended you regenerate the entities, as these were legit entities, and deserve your love. - -diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -0,0 +0,0 @@ public class PaperWorldConfig { - private void preventMovingIntoUnloadedChunks() { - preventMovingIntoUnloadedChunks = getBoolean("prevent-moving-into-unloaded-chunks", false); - } -+ -+ public enum DuplicateUUIDMode { -+ SAFE_REGEN, DELETE, NOTHING, WARN -+ } -+ public DuplicateUUIDMode duplicateUUIDMode = DuplicateUUIDMode.SAFE_REGEN; -+ public int duplicateUUIDDeleteRange = 32; -+ private void repairDuplicateUUID() { -+ String desiredMode = getString("duplicate-uuid-resolver", "saferegen").toLowerCase().trim(); -+ duplicateUUIDDeleteRange = getInt("duplicate-uuid-saferegen-delete-range", duplicateUUIDDeleteRange); -+ switch (desiredMode.toLowerCase()) { -+ case "regen": -+ case "regenerate": -+ case "saferegen": -+ case "saferegenerate": -+ duplicateUUIDMode = DuplicateUUIDMode.SAFE_REGEN; -+ log("Duplicate UUID Resolve: Regenerate New UUID if distant (Delete likely duplicates within " + duplicateUUIDDeleteRange + " blocks)"); -+ break; -+ case "remove": -+ case "delete": -+ duplicateUUIDMode = DuplicateUUIDMode.DELETE; -+ log("Duplicate UUID Resolve: Delete Entity"); -+ break; -+ case "silent": -+ case "nothing": -+ duplicateUUIDMode = DuplicateUUIDMode.NOTHING; -+ logError("Duplicate UUID Resolve: Do Nothing (no logs) - Warning, may lose indication of bad things happening"); -+ break; -+ case "log": -+ case "warn": -+ duplicateUUIDMode = DuplicateUUIDMode.WARN; -+ log("Duplicate UUID Resolve: Warn (do nothing but log it happened, may be spammy)"); -+ break; -+ default: -+ duplicateUUIDMode = DuplicateUUIDMode.WARN; -+ logError("Warning: Invalid duplicate-uuid-resolver config " + desiredMode + " - must be one of: regen, delete, nothing, warn"); -+ log("Duplicate UUID Resolve: Warn (do nothing but log it happened, may be spammy)"); -+ break; -+ } -+ } - } -diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkMap.java -+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -0,0 +0,0 @@ - package net.minecraft.server.level; - - import co.aikar.timings.Timing; // Paper -+import com.destroystokyo.paper.PaperWorldConfig; // Paper - import com.google.common.collect.ImmutableList; - import com.google.common.collect.Iterables; - import com.google.common.collect.ComparisonChain; // Paper -@@ -0,0 +0,0 @@ import it.unimi.dsi.fastutil.objects.ObjectIterator; - import java.io.File; - import java.io.IOException; - import java.io.Writer; -+import java.util.HashMap; // Paper - import java.util.Collection; - import java.util.Iterator; - import java.util.List; -+import java.util.Map; // Paper - import java.util.Objects; - import java.util.Optional; - import java.util.Queue; - import java.util.Set; - import java.util.concurrent.CancellationException; -+import java.util.UUID; // Paper - import java.util.concurrent.CompletableFuture; - import java.util.concurrent.CompletionException; - import java.util.concurrent.Executor; -@@ -0,0 +0,0 @@ import net.minecraft.world.entity.ai.village.poi.PoiManager; - import net.minecraft.world.entity.boss.EnderDragonPart; - import net.minecraft.world.level.ChunkPos; - import net.minecraft.world.level.GameRules; -+import net.minecraft.world.level.Level; - import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.ChunkGenerator; - import net.minecraft.world.level.chunk.ChunkStatus; -@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - if (chunk.needsDecoration) { - net.minecraft.server.dedicated.DedicatedServer server = this.level.getCraftServer().getServer(); - if (!server.areNpcsEnabled() && entity instanceof net.minecraft.world.entity.npc.Npc) { -- entity.remove(); -+ entity.removed = true; // Paper - needsRemoval = true; - } - - if (!server.isSpawningAnimals() && (entity instanceof net.minecraft.world.entity.animal.Animal || entity instanceof net.minecraft.world.entity.animal.WaterAnimal)) { -- entity.remove(); -+ entity.removed = true; // Paper - needsRemoval = true; - } - } -- -- if (!(entity instanceof net.minecraft.world.entity.player.Player) && (needsRemoval || !this.level.loadFromChunk(entity))) { -- // CraftBukkit end -+ // CraftBukkit end -+ checkDupeUUID(entity); // Paper -+ if (!(entity instanceof net.minecraft.world.entity.player.Player) && (entity.removed || !this.level.loadFromChunk(entity))) { // Paper - if (list == null) { - list = Lists.newArrayList(new Entity[]{entity}); - } else { -@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - }); - } - -+ // Paper start -+ private void checkDupeUUID(Entity entity) { -+ PaperWorldConfig.DuplicateUUIDMode mode = level.paperConfig.duplicateUUIDMode; -+ if (mode != PaperWorldConfig.DuplicateUUIDMode.WARN -+ && mode != PaperWorldConfig.DuplicateUUIDMode.DELETE -+ && mode != PaperWorldConfig.DuplicateUUIDMode.SAFE_REGEN) { -+ return; -+ } -+ Entity other = level.getEntity(entity.getUUID()); -+ -+ if (mode == PaperWorldConfig.DuplicateUUIDMode.SAFE_REGEN && other != null && !other.removed -+ && Objects.equals(other.getEncodeId(), entity.getEncodeId()) -+ && entity.getBukkitEntity().getLocation().distance(other.getBukkitEntity().getLocation()) < level.paperConfig.duplicateUUIDDeleteRange -+ ) { -+ if (Level.DEBUG_ENTITIES) LOGGER.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", deleted entity " + entity + " because it was near the duplicate and likely an actual duplicate. See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about."); -+ entity.removed = true; -+ return; -+ } -+ if (other != null && !other.removed) { -+ switch (mode) { -+ case SAFE_REGEN: { -+ entity.setUUID(UUID.randomUUID()); -+ if (Level.DEBUG_ENTITIES) LOGGER.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", regenerated UUID for " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about."); -+ break; -+ } -+ case DELETE: { -+ if (Level.DEBUG_ENTITIES) LOGGER.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", deleted entity " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about."); -+ entity.removed = true; -+ break; -+ } -+ default: -+ if (Level.DEBUG_ENTITIES) LOGGER.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", doing nothing to " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about."); -+ break; -+ } -+ } -+ } -+ // Paper end -+ - public CompletableFuture> postProcess(ChunkHolder holder) { - ChunkPos chunkcoordintpair = holder.getPos(); - CompletableFuture, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getChunkRangeFuture(chunkcoordintpair, 1, (i) -> { -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -0,0 +0,0 @@ import com.google.common.annotations.VisibleForTesting; - import com.google.common.collect.Iterables; - import co.aikar.timings.TimingHistory; // Paper - import co.aikar.timings.Timings; // Paper -+ -+import com.destroystokyo.paper.PaperWorldConfig; // Paper - import com.google.common.collect.Lists; - import com.google.common.collect.Maps; - import com.google.common.collect.Queues; -@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - if (entity1 == null) { - return false; - } else { -+ // Paper start -+ if (entity1.removed) { -+ onEntityRemoved(entity1); // remove the existing entity -+ return false; -+ } -+ // Paper end - ServerLevel.LOGGER.warn("Trying to add entity with duplicated UUID {}. Existing {}#{}, new: {}#{}", uuid, EntityType.getKey(entity1.getType()), entity1.getId(), EntityType.getKey(entity.getType()), entity.getId()); // CraftBukkit // Paper -+ // Paper start -+ if (DEBUG_ENTITIES && entity.level.paperConfig.duplicateUUIDMode != PaperWorldConfig.DuplicateUUIDMode.NOTHING) { -+ if (entity1.addedToWorldStack != null) { -+ entity1.addedToWorldStack.printStackTrace(); -+ } -+ -+ getAddToWorldStackTrace(entity).printStackTrace(); -+ } -+ // Paper end - return true; - } - } -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s - }); - } - -+ public final void setUUID(UUID uuid) { setUUID(uuid); } // Paper - OBFHELPER - public void setUUID(UUID uuid) { - this.uuid = uuid; - this.stringUUID = this.uuid.toString(); -diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess { - if (i != this.chunkPos.x || j != this.chunkPos.z) { - LevelChunk.LOGGER.warn("Wrong location! ({}, {}) should be ({}, {}), {}", i, j, this.chunkPos.x, this.chunkPos.z, entity); - entity.removed = true; -+ return; // Paper - } - - int k = Mth.floor(entity.getY() / 16.0D); diff --git a/patches/server-remapped/Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch b/patches/server-remapped/Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch deleted file mode 100644 index 9af0633a2f..0000000000 --- a/patches/server-remapped/Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Fri, 28 Sep 2018 21:49:53 -0400 -Subject: [PATCH] Fix issues with entity loss due to unloaded chunks - -Vanilla has risk of losing entities by causing them to be -removed from all chunks if they try to move into an unloaded chunk. - -This pretty much means high chance this entity will be lost in this -scenario. - -There is another case that adding an entity to the world can fail if -the chunk isn't loaded. - -Lots of the server is designed around addEntity never expecting to fail -for these reasons, nor is it really logical. - -This change ensures the chunks are always loaded when entities are -added to the world, or a valid entity moves between chunks. - -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - int k = Mth.floor(entity.getZ() / 16.0D); - - if (!entity.inChunk || entity.xChunk != i || entity.yChunk != j || entity.zChunk != k) { -+ // Paper start - remove entity if its in a chunk more correctly. -+ LevelChunk currentChunk = entity.getCurrentChunk(); -+ if (currentChunk != null) { -+ currentChunk.removeEntity(entity); -+ } -+ // Paper end -+ - if (entity.inChunk && this.hasChunk(entity.xChunk, entity.zChunk)) { - this.getChunk(entity.xChunk, entity.zChunk).removeEntity(entity, entity.yChunk); - } - -- if (!entity.checkAndResetForcedChunkAdditionFlag() && !this.hasChunk(i, k)) { -+ if (!entity.valid && !entity.checkAndResetForcedChunkAdditionFlag() && !this.hasChunk(i, k)) { // Paper - always load chunks to register valid entities location - if (entity.inChunk) { - ServerLevel.LOGGER.warn("Entity {} left loaded chunk area", entity); - } -@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - return false; - } - // CraftBukkit end -- ChunkAccess ichunkaccess = this.getChunk(Mth.floor(entity.getX() / 16.0D), Mth.floor(entity.getZ() / 16.0D), ChunkStatus.FULL, entity.forcedLoading); -+ ChunkAccess ichunkaccess = this.getChunk(Mth.floor(entity.getX() / 16.0D), Mth.floor(entity.getZ() / 16.0D), ChunkStatus.FULL, true); // Paper - always load chunks for entity adds - - if (!(ichunkaccess instanceof LevelChunk)) { - return false; diff --git a/patches/server-remapped/MC-114618-Fix-EntityAreaEffectCloud-from-going-negat.patch b/patches/server-remapped/MC-114618-Fix-EntityAreaEffectCloud-from-going-negat.patch deleted file mode 100644 index 33fb5e3613..0000000000 --- a/patches/server-remapped/MC-114618-Fix-EntityAreaEffectCloud-from-going-negat.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Mon, 27 May 2019 17:35:39 -0500 -Subject: [PATCH] MC-114618 - Fix EntityAreaEffectCloud from going negative - size - - -diff --git a/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java b/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java -+++ b/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java -@@ -0,0 +0,0 @@ public class AreaEffectCloud extends Entity { - super.tick(); - boolean flag = this.isWaiting(); - float f = this.getRadius(); -+ // Paper start - fix MC-114618 -+ if (f < 0.0F) { -+ this.remove(); -+ return; -+ } -+ // Paper end - - if (this.level.isClientSide) { - ParticleOptions particleparam = this.getParticle(); diff --git a/patches/server-remapped/Mob-Spawner-API-Enhancements.patch b/patches/server-remapped/Mob-Spawner-API-Enhancements.patch deleted file mode 100644 index ceb44de7f4..0000000000 --- a/patches/server-remapped/Mob-Spawner-API-Enhancements.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 19 Apr 2019 12:41:13 -0500 -Subject: [PATCH] Mob Spawner API Enhancements - - -diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/level/BaseSpawner.java -+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java -@@ -0,0 +0,0 @@ public abstract class BaseSpawner { - this.spawnPotentials.clear(); // CraftBukkit - SPIGOT-3496, MC-92282 - } - -+ public boolean isActivated() { return isNearPlayer(); } // Paper - OBFHELPER - private boolean isNearPlayer() { - BlockPos blockposition = this.getPos(); - -@@ -0,0 +0,0 @@ public abstract class BaseSpawner { - } - } - -+ public void resetTimer() { delay(); } // Paper - OBFHELPER - private void delay() { - if (this.maxSpawnDelay <= this.minSpawnDelay) { - this.spawnDelay = this.minSpawnDelay; -@@ -0,0 +0,0 @@ public abstract class BaseSpawner { - } - - public void load(CompoundTag tag) { -+ // Paper start - use larger int if set -+ if (tag.contains("Paper.Delay")) { -+ this.spawnDelay = tag.getInt("Paper.Delay"); -+ } else { - this.spawnDelay = tag.getShort("Delay"); -+ } -+ // Paper end - this.spawnPotentials.clear(); - if (tag.contains("SpawnPotentials", 9)) { - ListTag nbttaglist = tag.getList("SpawnPotentials", 10); -@@ -0,0 +0,0 @@ public abstract class BaseSpawner { - } else if (!this.spawnPotentials.isEmpty()) { - this.setNextSpawnData((SpawnData) WeighedRandom.getRandomItem(this.getLevel().random, this.spawnPotentials)); - } -- -+ // Paper start - use ints if set -+ if (tag.contains("Paper.MinSpawnDelay", 99)) { -+ this.minSpawnDelay = tag.getInt("Paper.MinSpawnDelay"); -+ this.maxSpawnDelay = tag.getInt("Paper.MaxSpawnDelay"); -+ this.spawnCount = tag.getShort("SpawnCount"); -+ } else // Paper end - if (tag.contains("MinSpawnDelay", 99)) { -- this.minSpawnDelay = tag.getShort("MinSpawnDelay"); -- this.maxSpawnDelay = tag.getShort("MaxSpawnDelay"); -+ this.minSpawnDelay = tag.getInt("MinSpawnDelay"); -+ this.maxSpawnDelay = tag.getInt("MaxSpawnDelay"); - this.spawnCount = tag.getShort("SpawnCount"); - } - -@@ -0,0 +0,0 @@ public abstract class BaseSpawner { - if (minecraftkey == null) { - return tag; - } else { -- tag.putShort("Delay", (short) this.spawnDelay); -- tag.putShort("MinSpawnDelay", (short) this.minSpawnDelay); -- tag.putShort("MaxSpawnDelay", (short) this.maxSpawnDelay); -+ // Paper start -+ if (spawnDelay > Short.MAX_VALUE) { -+ tag.putInt("Paper.Delay", this.spawnDelay); -+ } -+ tag.putShort("Delay", (short) Math.min(Short.MAX_VALUE, this.spawnDelay)); -+ -+ if (minSpawnDelay > Short.MAX_VALUE || maxSpawnDelay > Short.MAX_VALUE) { -+ tag.putInt("Paper.MinSpawnDelay", this.minSpawnDelay); -+ tag.putInt("Paper.MaxSpawnDelay", this.maxSpawnDelay); -+ } -+ -+ tag.putShort("MinSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.minSpawnDelay)); -+ tag.putShort("MaxSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.maxSpawnDelay)); -+ // Paper end - tag.putShort("SpawnCount", (short) this.spawnCount); - tag.putShort("MaxNearbyEntities", (short) this.maxNearbyEntities); - tag.putShort("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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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 @@ - package org.bukkit.craftbukkit.block; - - import com.google.common.base.Preconditions; -+import net.minecraft.core.Registry; -+import net.minecraft.nbt.CompoundTag; - import net.minecraft.resources.ResourceLocation; -+import net.minecraft.world.level.SpawnData; - import net.minecraft.world.level.block.entity.SpawnerBlockEntity; - import org.bukkit.Material; - import org.bukkit.block.Block; - import org.bukkit.block.CreatureSpawner; - import org.bukkit.entity.EntityType; -+// Paper start -+import org.bukkit.craftbukkit.inventory.CraftItemStack; -+import org.bukkit.craftbukkit.util.CraftMagicNumbers; -+import org.bukkit.inventory.ItemStack; -+// Paper end - - public class CraftCreatureSpawner extends CraftBlockEntityState implements CreatureSpawner { - -@@ -0,0 +0,0 @@ public class CraftCreatureSpawner extends CraftBlockEntityState +Date: Tue, 1 Jan 2019 02:22:01 -0800 +Subject: [PATCH] Add Heightmap API + + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -0,0 +0,0 @@ public class CraftWorld implements World { + return this.getHighestBlockYAt(x, z, org.bukkit.HeightMap.MOTION_BLOCKING); + } + ++ // Paper start - Implement heightmap api ++ @Override ++ public int getHighestBlockYAt(final int x, final int z, final com.destroystokyo.paper.HeightmapType heightmap) throws UnsupportedOperationException { ++ this.getChunkAt(x >> 4, z >> 4); // heightmap will ret 0 on unloaded areas ++ ++ switch (heightmap) { ++ case LIGHT_BLOCKING: ++ throw new UnsupportedOperationException(); // TODO ++ //return this.world.getHighestBlockY(HeightMap.Type.LIGHT_BLOCKING, x, z); ++ case ANY: ++ return this.world.getHeight(net.minecraft.world.level.levelgen.Heightmap.Types.WORLD_SURFACE, x, z); ++ case SOLID: ++ return this.world.getHeight(net.minecraft.world.level.levelgen.Heightmap.Types.OCEAN_FLOOR, x, z); ++ case SOLID_OR_LIQUID: ++ return this.world.getHeight(net.minecraft.world.level.levelgen.Heightmap.Types.MOTION_BLOCKING, x, z); ++ case SOLID_OR_LIQUID_NO_LEAVES: ++ return this.world.getHeight(net.minecraft.world.level.levelgen.Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, x, z); ++ default: ++ throw new UnsupportedOperationException(); ++ } ++ } ++ // Paper end ++ + @Override + public Location getSpawnLocation() { + BlockPos spawn = this.world.getSharedSpawnPos(); diff --git a/patches/server-remapped/Configurable-Keep-Spawn-Loaded-range-per-world.patch b/patches/server/Configurable-Keep-Spawn-Loaded-range-per-world.patch similarity index 89% rename from patches/server-remapped/Configurable-Keep-Spawn-Loaded-range-per-world.patch rename to patches/server/Configurable-Keep-Spawn-Loaded-range-per-world.patch index 5af847a28e..356dea6c76 100644 --- a/patches/server-remapped/Configurable-Keep-Spawn-Loaded-range-per-world.patch +++ b/patches/server/Configurable-Keep-Spawn-Loaded-range-per-world.patch @@ -10,16 +10,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -0,0 +0,0 @@ public class PaperWorldConfig { - break; } } -+ + + public short keepLoadedRange; + private void keepLoadedRange() { + keepLoadedRange = (short) (getInt("keep-spawn-loaded-range", Math.min(spigotConfig.viewDistance, 10)) * 16); + log( "Keep Spawn Loaded Range: " + (keepLoadedRange/16)); + } - } ++ + private boolean getBoolean(String path, boolean def) { + config.addDefault("world-settings.default." + path, def); + return config.getBoolean("world-settings." + worldName + "." + path, config.getBoolean("world-settings.default." + path)); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java @@ -33,13 +35,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - } + ServerChunkCache chunkproviderserver = worldserver.getChunkSource(); // Paper - // WorldServer worldserver = this.E(); + // WorldServer worldserver = this.F(); this.forceTicks = true; // CraftBukkit end + if (worldserver.getWorld().getKeepSpawnInMemory()) { // Paper MinecraftServer.LOGGER.info("Preparing start region for dimension {}", worldserver.dimension().location()); - BlockPos blockposition = worldserver.getSpawn(); + BlockPos blockposition = worldserver.getSharedSpawnPos(); worldloadlistener.updateSpawnPos(new ChunkPos(blockposition)); - ServerChunkCache chunkproviderserver = worldserver.getChunkSource(); @@ -51,11 +53,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - - while (chunkproviderserver.getTickingGenerated() != 441) { - // CraftBukkit start -- // this.nextTick = SystemUtils.getMonotonicMillis() + 10L; +- // this.nextTickTime = SystemUtils.getMonotonicMillis() + 10L; - this.executeModerately(); - // CraftBukkit end - } -- + // Paper start - configurable spawn reason + int radiusBlocks = worldserver.paperConfig.keepLoadedRange; + int radiusChunks = radiusBlocks / 16 + ((radiusBlocks & 15) != 0 ? 1 : 0); @@ -64,10 +65,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + worldloadlistener.setChunkRadius(radiusBlocks / 16); + + worldserver.addTicketsForSpawn(radiusBlocks, blockposition); -+ //LOGGER.info("Loaded " + chunkproviderserver.b() + " spawn chunks for world " + worldserver.getWorld().getName()); // Paper + // Paper end + // CraftBukkit start - // this.nextTick = SystemUtils.getMonotonicMillis() + 10L; + // this.nextTickTime = SystemUtils.getMonotonicMillis() + 10L; this.executeModerately(); // Iterator iterator = this.worldServer.values().iterator(); + } @@ -87,16 +88,16 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/mai index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -0,0 +0,0 @@ import net.minecraft.network.protocol.game.ClientboundSoundPacket; +@@ -0,0 +0,0 @@ import net.minecraft.network.protocol.game.ClientboundSoundEntityPacket; + import net.minecraft.network.protocol.game.ClientboundSoundPacket; import net.minecraft.network.protocol.game.DebugPackets; import net.minecraft.resources.ResourceKey; - import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MCUtil; import net.minecraft.server.MinecraftServer; import net.minecraft.server.ServerScoreboard; import net.minecraft.server.level.progress.ChunkProgressListener; @@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - return ((MapIndex) this.getServer().overworld().getDataStorage().computeIfAbsent(MapIndex::new, "idcounts")).getFreeAuxValueForMap(); + return ((MapIndex) this.getServer().overworld().getDataStorage().computeIfAbsent(MapIndex::load, MapIndex::new, "idcounts")).getFreeAuxValueForMap(); } + // Paper start - helper function for configurable spawn radius @@ -192,7 +193,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/level/progress/ChunkProgressListener.java +++ b/src/main/java/net/minecraft/server/level/progress/ChunkProgressListener.java @@ -0,0 +0,0 @@ public interface ChunkProgressListener { - void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status); + void start(); void stop(); + @@ -203,8 +204,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/level/progress/LoggerChunkProgressListener.java +++ b/src/main/java/net/minecraft/server/level/progress/LoggerChunkProgressListener.java @@ -0,0 +0,0 @@ import org.apache.logging.log4j.Logger; - public class LoggerChunkProgressListener implements ChunkProgressListener { + public class LoggerChunkProgressListener implements ChunkProgressListener { private static final Logger LOGGER = LogManager.getLogger(); - private final int maxCount; + private int maxCount; // Paper - remove final @@ -219,15 +220,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + @Override + public void setChunkRadius(int radius) { -+ // Paper - copied from above - int j = radius * 2 + 1; - - this.maxCount = j * j; ++ // Paper end + int i = radius * 2 + 1; + this.maxCount = i * i; } -+ // Paper end - - @Override - public void updateSpawnPos(ChunkPos spawnPos) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -236,23 +232,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void setKeepSpawnInMemory(boolean keepLoaded) { +- world.keepSpawnInMemory = keepLoaded; + // Paper start - Configurable spawn radius + if (keepLoaded == world.keepSpawnInMemory) { + // do nothing, nothing has changed + return; + } - world.keepSpawnInMemory = keepLoaded; ++ this.world.keepSpawnInMemory = keepLoaded; // Grab the worlds spawn chunk -- BlockPos chunkcoordinates = this.world.getSpawn(); -+ BlockPos prevSpawn = this.world.getSpawn(); + BlockPos chunkcoordinates = this.world.getSharedSpawnPos(); if (keepLoaded) { -- world.getChunkSource().addRegionTicket(TicketType.START, new ChunkPos(chunkcoordinates), 11, Unit.INSTANCE); -+ world.addTicketsForSpawn(world.paperConfig.keepLoadedRange, prevSpawn); +- this.world.getChunkSource().addRegionTicket(TicketType.START, new ChunkPos(chunkcoordinates), 11, Unit.INSTANCE); ++ this.world.addTicketsForSpawn(this.world.paperConfig.keepLoadedRange, chunkcoordinates); } else { - // TODO: doesn't work well if spawn changed.... -- world.getChunkSource().removeRegionTicket(TicketType.START, new ChunkPos(chunkcoordinates), 11, Unit.INSTANCE); +- this.world.getChunkSource().removeRegionTicket(TicketType.START, new ChunkPos(chunkcoordinates), 11, Unit.INSTANCE); + // TODO: doesn't work well if spawn changed.... // paper - resolved -+ world.removeTicketsForSpawn(world.paperConfig.keepLoadedRange, prevSpawn); ++ this.world.removeTicketsForSpawn(this.world.paperConfig.keepLoadedRange, chunkcoordinates); } + // Paper end } diff --git a/patches/server-remapped/Fix-CB-call-to-changed-postToMainThread-method.patch b/patches/server/Fix-CB-call-to-changed-postToMainThread-method.patch similarity index 80% rename from patches/server-remapped/Fix-CB-call-to-changed-postToMainThread-method.patch rename to patches/server/Fix-CB-call-to-changed-postToMainThread-method.patch index bb247ce749..5bf339f32c 100644 --- a/patches/server-remapped/Fix-CB-call-to-changed-postToMainThread-method.patch +++ b/patches/server/Fix-CB-call-to-changed-postToMainThread-method.patch @@ -8,12 +8,12 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListener index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { +@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser - this.connection.getClass(); + Objects.requireNonNull(this.connection); // CraftBukkit - Don't wait - minecraftserver.wrapRunnable(networkmanager::handleDisconnection); + minecraftserver.scheduleOnMain(networkmanager::handleDisconnection); // Paper } - private void filterTextPacket(T text, Consumer consumer, BiFunction>> backingFilterer) { + private void filterTextPacket(T text, Consumer consumer, BiFunction> backingFilterer) { diff --git a/patches/server-remapped/Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch b/patches/server/Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch similarity index 94% rename from patches/server-remapped/Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch rename to patches/server/Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch index 76cdfa8529..5f90d1d0b7 100644 --- a/patches/server-remapped/Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch +++ b/patches/server/Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch @@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public boolean isPrimaryThread() { -- return Thread.currentThread().equals(console.serverThread) || console.hasStopped() || !org.spigotmc.AsyncCatcher.enabled; // All bets are off if we have shut down (e.g. due to watchdog) +- return Thread.currentThread().equals(console.serverThread) || this.console.hasStopped() || !org.spigotmc.AsyncCatcher.enabled; // All bets are off if we have shut down (e.g. due to watchdog) + return Thread.currentThread().equals(console.serverThread); // Paper - Fix issues with detecting main thread properly } diff --git a/patches/server-remapped/Fix-sounds-when-item-frames-are-modified-MC-123450.patch b/patches/server/Fix-sounds-when-item-frames-are-modified-MC-123450.patch similarity index 93% rename from patches/server-remapped/Fix-sounds-when-item-frames-are-modified-MC-123450.patch rename to patches/server/Fix-sounds-when-item-frames-are-modified-MC-123450.patch index 5ac3a0ddb8..a6ecbf58c5 100644 --- a/patches/server-remapped/Fix-sounds-when-item-frames-are-modified-MC-123450.patch +++ b/patches/server/Fix-sounds-when-item-frames-are-modified-MC-123450.patch @@ -15,6 +15,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.getEntityData().set(ItemFrame.DATA_ITEM, itemstack); - if (!itemstack.isEmpty() && playSound) { // CraftBukkit + if (!itemstack.isEmpty() && flag && playSound) { // CraftBukkit // Paper - only play sound when update flag is set - this.playSound(SoundEvents.ITEM_FRAME_ADD_ITEM, 1.0F, 1.0F); + this.playSound(this.getAddItemSound(), 1.0F, 1.0F); } diff --git a/patches/server/Mob-Spawner-API-Enhancements.patch b/patches/server/Mob-Spawner-API-Enhancements.patch new file mode 100644 index 0000000000..b2f8cbefd2 --- /dev/null +++ b/patches/server/Mob-Spawner-API-Enhancements.patch @@ -0,0 +1,129 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Fri, 19 Apr 2019 12:41:13 -0500 +Subject: [PATCH] Mob Spawner API Enhancements + + +diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java ++++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java +@@ -0,0 +0,0 @@ public abstract class BaseSpawner { + + private static final Logger LOGGER = LogManager.getLogger(); + private static final int EVENT_SPAWN = 1; +- private static WeightedRandomList EMPTY_POTENTIALS = WeightedRandomList.create(); ++ public static WeightedRandomList EMPTY_POTENTIALS = WeightedRandomList.create(); // Paper - private->public + public int spawnDelay = 20; + public WeightedRandomList spawnPotentials; + public SpawnData nextSpawnData; +@@ -0,0 +0,0 @@ public abstract class BaseSpawner { + this.spawnPotentials = BaseSpawner.EMPTY_POTENTIALS; // CraftBukkit - SPIGOT-3496, MC-92282 + } + +- private boolean isNearPlayer(Level world, BlockPos pos) { ++ public boolean isNearPlayer(Level world, BlockPos pos) { // Paper private->public + return world.isAffectsSpawningPlayerNearby((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, (double) this.requiredPlayerRange); // Paper + } + +@@ -0,0 +0,0 @@ public abstract class BaseSpawner { + } + } + +- private void delay(Level world, BlockPos pos) { ++ public void delay(Level world, BlockPos pos) { // Paper private->public + if (this.maxSpawnDelay <= this.minSpawnDelay) { + this.spawnDelay = this.minSpawnDelay; + } else { +@@ -0,0 +0,0 @@ public abstract class BaseSpawner { + } + + public void load(@Nullable Level world, BlockPos pos, CompoundTag nbt) { ++ // Paper start - use larger int if set ++ if (nbt.contains("Paper.Delay")) { ++ this.spawnDelay = nbt.getInt("Paper.Delay"); ++ } else { + this.spawnDelay = nbt.getShort("Delay"); ++ } ++ // Paper end + List list = Lists.newArrayList(); + + if (nbt.contains("SpawnPotentials", 9)) { +@@ -0,0 +0,0 @@ public abstract class BaseSpawner { + this.setSpawnData(world, pos, mobspawnerdata); + }); + } +- ++ // Paper start - use ints if set ++ if (nbt.contains("Paper.MinSpawnDelay", 99)) { ++ this.minSpawnDelay = nbt.getInt("Paper.MinSpawnDelay"); ++ this.maxSpawnDelay = nbt.getInt("Paper.MaxSpawnDelay"); ++ this.spawnCount = nbt.getShort("SpawnCount"); ++ } else // Paper end + if (nbt.contains("MinSpawnDelay", 99)) { +- this.minSpawnDelay = nbt.getShort("MinSpawnDelay"); +- this.maxSpawnDelay = nbt.getShort("MaxSpawnDelay"); ++ this.minSpawnDelay = nbt.getInt("MinSpawnDelay"); // Paper - short->int ++ this.maxSpawnDelay = nbt.getInt("MaxSpawnDelay"); // Paper - short->int + this.spawnCount = nbt.getShort("SpawnCount"); + } + +@@ -0,0 +0,0 @@ public abstract class BaseSpawner { + if (minecraftkey == null) { + return nbt; + } else { +- nbt.putShort("Delay", (short) this.spawnDelay); +- nbt.putShort("MinSpawnDelay", (short) this.minSpawnDelay); +- nbt.putShort("MaxSpawnDelay", (short) this.maxSpawnDelay); ++ // Paper start ++ if (spawnDelay > Short.MAX_VALUE) { ++ nbt.putInt("Paper.Delay", this.spawnDelay); ++ } ++ nbt.putShort("Delay", (short) Math.min(Short.MAX_VALUE, this.spawnDelay)); ++ ++ if (minSpawnDelay > Short.MAX_VALUE || maxSpawnDelay > Short.MAX_VALUE) { ++ nbt.putInt("Paper.MinSpawnDelay", this.minSpawnDelay); ++ nbt.putInt("Paper.MaxSpawnDelay", this.maxSpawnDelay); ++ } ++ ++ nbt.putShort("MinSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.minSpawnDelay)); ++ nbt.putShort("MaxSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.maxSpawnDelay)); ++ // Paper end + nbt.putShort("SpawnCount", (short) this.spawnCount); + nbt.putShort("MaxNearbyEntities", (short) this.maxNearbyEntities); + nbt.putShort("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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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 inv : this.inventory.getComponents()) { ++ for (NonNullList inv : this.getInventory().getComponents()) { + processKeep(event, inv); + } + processKeep(event, null); diff --git a/patches/server-remapped/Server-Tick-Events.patch b/patches/server/Server-Tick-Events.patch similarity index 100% rename from patches/server-remapped/Server-Tick-Events.patch rename to patches/server/Server-Tick-Events.patch diff --git a/patches/server-remapped/don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch b/patches/server/don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch similarity index 100% rename from patches/server-remapped/don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch rename to patches/server/don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch diff --git a/patches/server-remapped/improve-CraftWorld-isChunkLoaded.patch b/patches/server/improve-CraftWorld-isChunkLoaded.patch similarity index 69% rename from patches/server-remapped/improve-CraftWorld-isChunkLoaded.patch rename to patches/server/improve-CraftWorld-isChunkLoaded.patch index 25e8502abc..706c993b65 100644 --- a/patches/server-remapped/improve-CraftWorld-isChunkLoaded.patch +++ b/patches/server/improve-CraftWorld-isChunkLoaded.patch @@ -16,15 +16,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public boolean isChunkLoaded(int x, int z) { -- return world.getChunkSource().isChunkLoaded(x, z); -+ return world.getChunkSource().getChunkAtIfLoadedImmediately(x, z) != null; // Paper +- return this.world.getChunkSource().isChunkLoaded(x, z); ++ return this.world.getChunkSource().getChunkAtIfLoadedImmediately(x, z) != null; // Paper } @Override public boolean isChunkGenerated(int x, int z) { try { -- return isChunkLoaded(x, z) || world.getChunkSource().chunkMap.read(new ChunkPos(x, z)) != null; -+ return world.getChunkSource().getChunkAtIfCachedImmediately(x, z) != null || world.getChunkSource().chunkMap.read(new ChunkPos(x, z)) != null; // Paper (TODO check if the first part can be removed) +- return this.isChunkLoaded(x, z) || this.world.getChunkSource().chunkMap.read(new ChunkPos(x, z)) != null; ++ return this.world.getChunkSource().getChunkAtIfCachedImmediately(x, z) != null || this.world.getChunkSource().chunkMap.read(new ChunkPos(x, z)) != null; // Paper (TODO check if the first part can be removed) } catch (IOException ex) { throw new RuntimeException(ex); }