diff --git a/Spigot-Server-Patches/0333-Add-entity-count-cache.patch b/Spigot-Server-Patches/0333-Add-entity-count-cache.patch index 7fcf3e7a7..ddccbd1bb 100644 --- a/Spigot-Server-Patches/0333-Add-entity-count-cache.patch +++ b/Spigot-Server-Patches/0333-Add-entity-count-cache.patch @@ -1,14 +1,94 @@ -From 3ac10ee43109b578232e3d127511e761ddc87a1a Mon Sep 17 00:00:00 2001 +From 5b101db469123c2f92ff82fc04a8b77274296bcf Mon Sep 17 00:00:00 2001 From: Colin Godsey Date: Wed, 8 Aug 2018 10:10:06 -0600 Subject: [PATCH] Add entity count cache +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index d6b56d685..3d973deb7 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -1034,6 +1034,14 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati + } + // CraftBukkit end */ + ++ /* ++ * Paper - clear count cache every once in a while. ++ * Cache can never be entirely trusted because ++ * an entity may become persistent or not ++ * during its lifetime. ++ */ ++ if (this.ticks % 600 == 0) worldserver.clearEntityCountCache(); ++ + this.methodProfiler.a("tick"); + + CrashReport crashreport; +diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java +index f525fd1b4..494759a1c 100644 +--- a/src/main/java/net/minecraft/server/SpawnerCreature.java ++++ b/src/main/java/net/minecraft/server/SpawnerCreature.java +@@ -113,7 +113,7 @@ public final class SpawnerCreature { + // CraftBukkit end + + if ((!enumcreaturetype.c() || flag1) && (enumcreaturetype.c() || flag) && (!enumcreaturetype.d() || flag2)) { +- k = worldserver.a(enumcreaturetype.a()); ++ k = worldserver.getCreatureCount(enumcreaturetype); // Paper - entity count cache + int l1 = limit * i / b; // CraftBukkit - use per-world limits + + if (k <= l1) { diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 004c3ec47..c392595c0 100644 +index 004c3ec47..baf73a411 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -50,10 +50,41 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose +@@ -1,28 +1,20 @@ + package net.minecraft.server; + +-import co.aikar.timings.Timings; + import com.destroystokyo.paper.event.server.ServerExceptionEvent; + import com.destroystokyo.paper.exception.ServerInternalException; + import com.google.common.base.MoreObjects; + import com.google.common.collect.Lists; +-import java.util.ArrayList; +-import java.util.Collection; +-import java.util.Iterator; +-import java.util.List; +-import java.util.Random; +-import java.util.UUID; ++ ++import java.util.*; + + import java.util.function.Function; + import java.util.function.Predicate; +-import java.util.function.Supplier; + import javax.annotation.Nullable; + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + + // CraftBukkit start + import com.google.common.collect.Maps; +-import java.util.HashMap; // Paper +-import java.util.Map; + import org.bukkit.Bukkit; + import org.bukkit.block.BlockState; + import org.bukkit.craftbukkit.CraftServer; +@@ -30,16 +22,11 @@ import org.bukkit.craftbukkit.CraftWorld; + import org.bukkit.craftbukkit.block.CraftBlockState; + import org.bukkit.craftbukkit.block.data.CraftBlockData; + import org.bukkit.craftbukkit.event.CraftEventFactory; +-import org.bukkit.craftbukkit.util.CraftMagicNumbers; +-import org.bukkit.craftbukkit.util.LongHashSet; // Paper +-import org.bukkit.entity.Player; +-import org.bukkit.event.block.BlockCanBuildEvent; + import org.bukkit.event.block.BlockPhysicsEvent; + import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; + import org.bukkit.generator.ChunkGenerator; + // CraftBukkit end + // Paper start +-import java.util.Set; + import com.google.common.collect.Sets; + // Paper end + public abstract class World implements GeneratorAccess, IIBlockAccess, AutoCloseable { +@@ -50,10 +37,41 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose // Spigot start - guard entity list from removals public final List entityList = new java.util.ArrayList() { @@ -50,7 +130,7 @@ index 004c3ec47..c392595c0 100644 return super.remove( index ); } -@@ -61,6 +92,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose +@@ -61,6 +79,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose public boolean remove(Object o) { guard(); @@ -58,67 +138,45 @@ index 004c3ec47..c392595c0 100644 return super.remove( o ); } -@@ -82,6 +114,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose +@@ -82,6 +101,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose public final Map playersByName = Maps.newHashMap(); // Paper - World EntityHuman Lookup Optimizations public final List k = Lists.newArrayList(); protected final IntHashMap entitiesById = new IntHashMap(); -+ private Map, Integer> countCache = new HashMap(); // Paper ++ private Map countCache = new EnumMap(EnumCreatureType.class); // Paper - entity count cache private final long G = 16777215L; private int H; public int getSkylightSubtracted() { return this.H; } public void setSkylightSubtracted(int value) { this.H = value;} // Paper - OBFHELPER protected int m = (new Random()).nextInt(); -@@ -2440,6 +2473,8 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose +@@ -2439,6 +2459,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose + } ++ public int getEntityCount(Class oclass) { return a(oclass); } // Paper - OBFHELPER public int a(Class oclass) { -+ if (true) return getEntityCount(oclass); //Paper - short circuit to cached method -+ int i = 0; Iterator iterator = this.entityList.iterator(); - -@@ -2464,6 +2499,71 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose +@@ -2464,6 +2485,61 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose return i; } + // Paper start - entity count cache -+ private int countEntityType(Class oclass) { -+ int i = 0; -+ Iterator iterator = this.entityList.iterator(); ++ public int getCreatureCount(EnumCreatureType typ) { ++ Integer count = countCache.get(typ); + -+ while (iterator.hasNext()) { -+ Entity entity = (Entity) iterator.next(); ++ if (count == null) { ++ count = getEntityCount(typ.a()); + -+ if (shouldIgnoreForCount(entity)) continue; -+ if (oclass.isAssignableFrom(entity.getClass())) i++; ++ countCache.put(typ, count); + } + -+ return i; -+ } -+ -+ public int getEntityCount(Class oclass) { -+ Integer count = countCache.get(oclass); -+ -+ if (count != null) return count; -+ -+ count = countEntityType(oclass); -+ -+ countCache.put(oclass, count); -+ + return count; + } + -+ public boolean shouldIgnoreForCount(Entity entity) { -+ if (entity == null) return true; -+ -+ if (entity instanceof EntityInsentient) { -+ EntityInsentient entityinsentient = (EntityInsentient) entity; -+ return entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent(); -+ } -+ -+ return false; ++ void clearEntityCountCache() { ++ countCache.clear(); + } + -+ protected void updateEntityCount(Class clazz, boolean incr) { -+ Integer countObject = countCache.get(clazz); ++ protected void updateEntityCount(EnumCreatureType typ, boolean incr) { ++ Integer countObject = countCache.get(typ); + + if (countObject == null) return; + @@ -127,19 +185,30 @@ index 004c3ec47..c392595c0 100644 + if (incr) count++; + else count--; + -+ if(count < 0) { ++ if (count < 0) { + e.warn("Entity count cache has gone negative"); + count = 0; + } + -+ countCache.put(clazz, count); ++ countCache.put(typ, count); + } + + protected void updateEntityCount(Entity entity, boolean incr) { -+ if (shouldIgnoreForCount(entity)) return; ++ if (entity == null || !(entity instanceof IAnimal)) return; + -+ for (Class clazz = entity.getClass() ; !clazz.equals(Object.class) ; clazz = clazz.getSuperclass()) { -+ updateEntityCount(clazz, incr); ++ if (entity instanceof EntityInsentient) { ++ EntityInsentient entityinsentient = (EntityInsentient) entity; ++ if (entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) { ++ return; ++ } ++ } ++ ++ Class clazz = entity.getClass(); ++ ++ for (EnumCreatureType typ : EnumCreatureType.values()) { ++ if (typ.a().isAssignableFrom(clazz)) { ++ updateEntityCount(typ, incr); ++ } + } + } + // Paper end diff --git a/Spigot-Server-Patches/0334-Configurable-speed-for-water-flowing-over-lava.patch b/Spigot-Server-Patches/0334-Configurable-speed-for-water-flowing-over-lava.patch deleted file mode 100644 index d7f5d993b..000000000 --- a/Spigot-Server-Patches/0334-Configurable-speed-for-water-flowing-over-lava.patch +++ /dev/null @@ -1,65 +0,0 @@ -From b9f0b43802d049d91f4db3cf26bce5f2084de76e Mon Sep 17 00:00:00 2001 -From: Colin Godsey -Date: Wed, 8 Aug 2018 11:33:21 -0600 -Subject: [PATCH] Configurable speed for water flowing over lava - - -diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 61c8b58b1..ab3f59ad7 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -436,6 +436,12 @@ public class PaperWorldConfig { - } - } - -+ public int waterOverLavaFlowSpeed; -+ private void waterOverLavaFlowSpeed() { -+ waterOverLavaFlowSpeed = getInt("water-over-lava-flow-speed", 5); -+ log("Water over lava flow speed: " + waterOverLavaFlowSpeed); -+ } -+ - public enum DuplicateUUIDMode { - SAFE_REGEN, REGEN, DELETE, NOTHING, WARN - } -diff --git a/src/main/java/net/minecraft/server/BlockFluids.java b/src/main/java/net/minecraft/server/BlockFluids.java -index 6ecc1f84e..637f6580b 100644 ---- a/src/main/java/net/minecraft/server/BlockFluids.java -+++ b/src/main/java/net/minecraft/server/BlockFluids.java -@@ -67,10 +67,24 @@ public class BlockFluids extends Block implements IFluidSource { - - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { - if (this.a(world, blockposition, iblockdata)) { -- world.H().a(blockposition, iblockdata.s().c(), this.a((IWorldReader) world)); -+ world.H().a(blockposition, iblockdata.s().c(), this.getFlowSpeed(world, blockposition)); // Paper - } - - } -+ -+ /** -+ * Paper - Get flow speed. Throttle if its water and flowing adjacent to lava -+ */ -+ public int getFlowSpeed(World world, BlockPosition blockposition) { -+ if (this.material == Material.WATER && ( -+ world.getType(blockposition.north(1)).getBlock().material == Material.LAVA || -+ world.getType(blockposition.south(1)).getBlock().material == Material.LAVA || -+ world.getType(blockposition.west(1)).getBlock().material == Material.LAVA || -+ world.getType(blockposition.east(1)).getBlock().material == Material.LAVA)) { -+ return world.paperConfig.waterOverLavaFlowSpeed; -+ } -+ return this.a(world); -+ } - - public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { - if (iblockdata.s().d() || iblockdata1.s().d()) { -@@ -82,7 +96,7 @@ public class BlockFluids extends Block implements IFluidSource { - - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { - if (this.a(world, blockposition, iblockdata)) { -- world.H().a(blockposition, iblockdata.s().c(), this.a((IWorldReader) world)); -+ world.H().a(blockposition, iblockdata.s().c(), this.getFlowSpeed(world, blockposition)); // Paper - } - - } --- -2.15.2 (Apple Git-101.1) -