mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-23 17:37:45 +01:00
ea855e2b46
Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Developers!: You will need to clean up your work/Minecraft/1.13.2 folder for this Also, restore a patch that was dropped in the last upstream Bukkit Changes: 279eeab3 Fix command description not being set 96e2bb18 Remove debug print from SyntheticEventTest CraftBukkit Changes:d3ed1516
Fix dangerously threaded beacons217a293d
Don't relocate joptsimple to allow --help to work.1be05a21
Prepare for imminent Java 12 releasea49270b2
Mappings Update5259d80c
SPIGOT-4669: Fix PlayerTeleportEvent coordinates for relative teleports Spigot Changes: e6eb36f2 Rebuild patches
218 lines
8.3 KiB
Diff
218 lines
8.3 KiB
Diff
From 4b037a6ff610d3f9552b7f9e348d02ca470b97da Mon Sep 17 00:00:00 2001
|
|
From: Colin Godsey <crgodsey@gmail.com>
|
|
Date: Wed, 8 Aug 2018 10:10:06 -0600
|
|
Subject: [PATCH] Cache World Entity Type counts
|
|
|
|
Optimizes mob spawning by keeping a count of entities by type
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java b/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java
|
|
new file mode 100644
|
|
index 000000000..a10a5bc13
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java
|
|
@@ -0,0 +1,121 @@
|
|
+package com.destroystokyo.paper;
|
|
+
|
|
+import net.minecraft.server.Entity;
|
|
+import net.minecraft.server.EntityInsentient;
|
|
+import net.minecraft.server.EnumCreatureType;
|
|
+import net.minecraft.server.IAnimal;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import net.minecraft.server.World;
|
|
+import net.minecraft.server.WorldServer;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+
|
|
+public class PaperWorldEntityList extends ArrayList<Entity> {
|
|
+
|
|
+ private final WorldServer world;
|
|
+ private final int[] entityCounts = new int[EnumCreatureType.values().length];
|
|
+
|
|
+
|
|
+ public PaperWorldEntityList(World world) {
|
|
+ this.world = (WorldServer) world;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean addAll(Collection<? extends Entity> c) {
|
|
+ for (Entity e : c) {
|
|
+ updateEntityCount(e, 1);
|
|
+ }
|
|
+
|
|
+ return super.addAll(c);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean removeAll(Collection<?> c) {
|
|
+ for (Object e : c) {
|
|
+ if (e instanceof Entity && ((Entity) e).getWorld() == world) {
|
|
+ updateEntityCount((Entity) e, -1);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return super.removeAll(c);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean add(Entity e) {
|
|
+ updateEntityCount(e, 1);
|
|
+
|
|
+ return super.add(e);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Entity remove(int index) {
|
|
+ guard();
|
|
+ Entity entity = super.remove(index);
|
|
+ if (entity != null) updateEntityCount(entity, -1);
|
|
+ return entity;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean remove(Object o) {
|
|
+ guard();
|
|
+ if (super.remove(o)) {
|
|
+ updateEntityCount((Entity) o, -1);
|
|
+ return true;
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ private void guard() {
|
|
+ if (world.guardEntityList) {
|
|
+ throw new java.util.ConcurrentModificationException();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public int getCreatureCount(EnumCreatureType type) {
|
|
+ return entityCounts[type.ordinal()];
|
|
+ }
|
|
+
|
|
+ private void updateEntityCount(EnumCreatureType type, int amt) {
|
|
+ int count = entityCounts[type.ordinal()];
|
|
+
|
|
+ count += amt;
|
|
+
|
|
+ if (count < 0) {
|
|
+ MinecraftServer.LOGGER.error("Paper - Entity count cache has gone negative");
|
|
+ count = 0;
|
|
+ }
|
|
+
|
|
+ entityCounts[type.ordinal()] = count;
|
|
+ }
|
|
+
|
|
+ public void updateEntityCount(Entity entity, int amt) {
|
|
+ if (!(entity instanceof IAnimal)) return;
|
|
+
|
|
+ if (entity instanceof EntityInsentient) {
|
|
+ EntityInsentient entityinsentient = (EntityInsentient) entity;
|
|
+ if (amt > 0 && entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ if (amt < 0) {
|
|
+ if (!entity.hasBeenCounted) {
|
|
+ return;
|
|
+ }
|
|
+ // Only remove once, we remove from if the entity list is guarded, but may be called later
|
|
+ entity.hasBeenCounted = false;
|
|
+ } else {
|
|
+ if (entity.hasBeenCounted) {
|
|
+ return;
|
|
+ }
|
|
+ entity.hasBeenCounted = true;
|
|
+ }
|
|
+
|
|
+ for (EnumCreatureType type : EnumCreatureType.values()) {
|
|
+ if (type.matches(entity)) {
|
|
+ updateEntityCount(type, amt);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
|
index 2d2edbd33..47d3609c3 100644
|
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
|
@@ -122,6 +122,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
private boolean az;
|
|
public boolean dead;
|
|
public boolean shouldBeRemoved; // Paper
|
|
+ public boolean hasBeenCounted = false; // Paper
|
|
public float width;
|
|
public float length;
|
|
public float J;
|
|
diff --git a/src/main/java/net/minecraft/server/EnumCreatureType.java b/src/main/java/net/minecraft/server/EnumCreatureType.java
|
|
index 79e52f7ba..42f6a6a93 100644
|
|
--- a/src/main/java/net/minecraft/server/EnumCreatureType.java
|
|
+++ b/src/main/java/net/minecraft/server/EnumCreatureType.java
|
|
@@ -16,6 +16,8 @@ public enum EnumCreatureType {
|
|
this.h = flag1;
|
|
}
|
|
|
|
+ public boolean matches(Entity entity) { return innerClass().isAssignableFrom(entity.getClass()); } // Paper
|
|
+ public Class<? extends IAnimal> innerClass() { return this.a(); } // Paper - OBFHELPER
|
|
public Class<? extends IAnimal> a() {
|
|
return this.e;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
index e62616552..bfbe4d3e3 100644
|
|
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
@@ -114,7 +114,7 @@ public final class SpawnerCreature {
|
|
|
|
if ((!enumcreaturetype.c() || flag1) && (enumcreaturetype.c() || flag) && (!enumcreaturetype.d() || flag2)) {
|
|
k = limit * i / SpawnerCreature.b; // CraftBukkit - use per-world limits
|
|
- int l1 = worldserver.a(enumcreaturetype.a(), k);
|
|
+ int l1 = worldserver.entityList.getCreatureCount(enumcreaturetype); // Paper - entity count cache
|
|
|
|
if (l1 <= k) {
|
|
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index bd8d9ef48..c25c82bf1 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -45,7 +45,8 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
|
private static final EnumDirection[] a = EnumDirection.values();
|
|
private int b = 63;
|
|
// Spigot start - guard entity list from removals
|
|
- public final List<Entity> entityList = new java.util.ArrayList<Entity>()
|
|
+ public final com.destroystokyo.paper.PaperWorldEntityList entityList = new com.destroystokyo.paper.PaperWorldEntityList(this);
|
|
+ /* // Paper start
|
|
{
|
|
@Override
|
|
public Entity remove(int index)
|
|
@@ -69,6 +70,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
|
}
|
|
}
|
|
};
|
|
+ */ // Paper end
|
|
// Spigot end
|
|
protected final Set<Entity> g = com.google.common.collect.Sets.newHashSet(); public Set<Entity> getEntityUnloadQueue() { return g; };// Paper - OBFHELPER
|
|
//public final List<TileEntity> tileEntityList = Lists.newArrayList(); // Paper - remove unused list
|
|
@@ -139,8 +141,10 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
|
public final com.destroystokyo.paper.PaperWorldConfig paperConfig; // Paper
|
|
|
|
public final co.aikar.timings.WorldTimingsHandler timings; // Paper
|
|
- private boolean guardEntityList; // Spigot
|
|
+ public boolean guardEntityList; // Spigot // Paper - public
|
|
public static BlockPosition lastPhysicsProblem; // Spigot
|
|
+ public static boolean haveWeSilencedAPhysicsCrash;
|
|
+ public static String blockLocation;
|
|
private org.spigotmc.TickLimiter entityLimiter;
|
|
private org.spigotmc.TickLimiter tileLimiter;
|
|
private int tileTickPosition;
|
|
@@ -1122,6 +1126,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
|
this.getChunkAt(i, j).b(entity);
|
|
}
|
|
entity.shouldBeRemoved = true; // Paper
|
|
+ entityList.updateEntityCount(entity, -1); // Paper
|
|
|
|
if (!guardEntityList) { // Spigot - It will get removed after the tick if we are ticking // Paper - always remove from current chunk above
|
|
// CraftBukkit start - Decrement loop variable field if we've already ticked this entity
|
|
--
|
|
2.21.0
|
|
|