mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-25 00:30:25 +01:00
f956f185c8
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 Bukkit Changes: 47b9cf30 SPIGOT-4372: LightningStrikeEvent cause API a9ceda75 Include the plugin channel name in the exception message CraftBukkit Changes:a4bdecff
SPIGOT-4372: LightningStrikeEvent cause API34caaf6d
SPIGOT-4371: Trident damaged when event cancelled97315374
SPIGOT-4369: Handle cancelled trident eventbf1c8273
SPIGOT-4370: Remove vehicle if its passenger spawn event was cancelled Spigot Changes: 6b015b4b SPIGOT-4370: Remove vehicle if its passenger spawn event was cancelled
226 lines
8.8 KiB
Diff
226 lines
8.8 KiB
Diff
From 0f31bf2ce8e0e92ccf40826a80d2ecd698f7af0f 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 0000000000..35104542c5
|
|
--- /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.isDespawnableByDefault() && 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 02b567d559..f609e2ceda 100644
|
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
|
@@ -124,6 +124,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/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
index 141db48f16..56542d531a 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
@@ -615,6 +615,7 @@ public abstract class EntityInsentient extends EntityLiving {
|
|
return true;
|
|
}
|
|
|
|
+ public boolean isDespawnableByDefault() { return isTypeNotPersistent(); } // Paper - sortof an obf helper, too annoying to change visibility here
|
|
protected boolean isTypeNotPersistent() {
|
|
return true;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/EnumCreatureType.java b/src/main/java/net/minecraft/server/EnumCreatureType.java
|
|
index 8874a05be5..0af387c059 100644
|
|
--- a/src/main/java/net/minecraft/server/EnumCreatureType.java
|
|
+++ b/src/main/java/net/minecraft/server/EnumCreatureType.java
|
|
@@ -18,6 +18,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 95d98b65cf..387570ed67 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 2b7ab82b11..4089204308 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -50,7 +50,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)
|
|
@@ -74,6 +75,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
|
|
@@ -143,7 +145,7 @@ 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 boolean haveWeSilencedAPhysicsCrash;
|
|
public static String blockLocation;
|
|
private org.spigotmc.TickLimiter entityLimiter;
|
|
@@ -1181,6 +1183,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.19.0
|
|
|