mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-01 04:32:11 -07:00
Re-add entity/tile entity tick limiters
This commit is contained in:
@@ -105,8 +105,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
||||||
public static boolean haveWeSilencedAPhysicsCrash;
|
private org.spigotmc.TickLimiter entityLimiter;
|
||||||
public static String blockLocation;
|
private org.spigotmc.TickLimiter tileLimiter;
|
||||||
private int tileTickPosition;
|
private int tileTickPosition;
|
||||||
+ public ExecutorService lightingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("PaperSpigot - Lighting Thread").build()); // PaperSpigot - Asynchronous lighting updates
|
+ public ExecutorService lightingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("PaperSpigot - Lighting Thread").build()); // PaperSpigot - Asynchronous lighting updates
|
||||||
|
|
||||||
|
@@ -77,6 +77,26 @@ diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/m
|
|||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/src/main/java/net/minecraft/server/World.java
|
--- a/src/main/java/net/minecraft/server/World.java
|
||||||
+++ b/src/main/java/net/minecraft/server/World.java
|
+++ b/src/main/java/net/minecraft/server/World.java
|
||||||
|
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
||||||
|
// Spigot start - guard entity list from removals
|
||||||
|
public final List<Entity> entityList = new java.util.ArrayList<Entity>()
|
||||||
|
{
|
||||||
|
+ // PaperSpigot start - move always activated entities to top of tick list
|
||||||
|
+ @Override
|
||||||
|
+ public boolean add(Entity e)
|
||||||
|
+ {
|
||||||
|
+ if (e.defaultActivationState) {
|
||||||
|
+ super.add(0, e);
|
||||||
|
+ return true;
|
||||||
|
+ } else {
|
||||||
|
+ return super.add(e);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // PaperSpigot end
|
||||||
|
+
|
||||||
|
@Override
|
||||||
|
public Entity remove(int index)
|
||||||
|
{
|
||||||
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
||||||
// Spigot end
|
// Spigot end
|
||||||
protected final List<Entity> g = Lists.newArrayList();
|
protected final List<Entity> g = Lists.newArrayList();
|
||||||
@@ -86,6 +106,72 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
private final List<TileEntity> b = Lists.newArrayList();
|
private final List<TileEntity> b = Lists.newArrayList();
|
||||||
private final List<TileEntity> c = Lists.newArrayList();
|
private final List<TileEntity> c = Lists.newArrayList();
|
||||||
public final List<EntityHuman> players = Lists.newArrayList();
|
public final List<EntityHuman> players = Lists.newArrayList();
|
||||||
|
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
||||||
|
this.getServer().addWorld(this.world);
|
||||||
|
// CraftBukkit end
|
||||||
|
this.keepSpawnInMemory = this.paperSpigotConfig.keepSpawnInMemory; // PaperSpigot
|
||||||
|
- timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings
|
||||||
|
+ timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings
|
||||||
|
this.entityLimiter = new org.spigotmc.TickLimiter(spigotConfig.entityMaxTickTime);
|
||||||
|
this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime);
|
||||||
|
}
|
||||||
|
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
||||||
|
guardEntityList = true; // Spigot
|
||||||
|
// CraftBukkit start - Use field for loop variable
|
||||||
|
int entitiesThisCycle = 0;
|
||||||
|
+
|
||||||
|
+ // PaperSpigot start - Compute minimum tick index
|
||||||
|
+ int minTickIndex = -1;
|
||||||
|
+ ListIterator<Entity> e = entityList.listIterator();
|
||||||
|
+ while (e.hasNext()) {
|
||||||
|
+ if (!e.next().defaultActivationState) {
|
||||||
|
+ minTickIndex = e.previousIndex();
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // PaperSpigot end
|
||||||
|
+
|
||||||
|
if (tickPosition < 0) tickPosition = 0;
|
||||||
|
for (entityLimiter.initTick();
|
||||||
|
- entitiesThisCycle < entityList.size() && (entitiesThisCycle % 10 == 0 || entityLimiter.shouldContinue());
|
||||||
|
+ entitiesThisCycle < entityList.size() && (tickPosition <= minTickIndex || entitiesThisCycle % 10 == 0 || entityLimiter.shouldContinue()); // PaperSpigot
|
||||||
|
tickPosition++, entitiesThisCycle++) {
|
||||||
|
tickPosition = (tickPosition < entityList.size()) ? tickPosition : 0;
|
||||||
|
entity = (Entity) this.entityList.get(this.tickPosition);
|
||||||
|
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
||||||
|
this.c.clear();
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
|
+ Iterator iterator = this.tileEntityList.iterator();
|
||||||
|
|
||||||
|
- // Spigot start
|
||||||
|
- int tilesThisCycle = 0;
|
||||||
|
- for (tileLimiter.initTick();
|
||||||
|
- tilesThisCycle < tileEntityList.size() && (tilesThisCycle % 10 == 0 || tileLimiter.shouldContinue());
|
||||||
|
- tileTickPosition++, tilesThisCycle++) {
|
||||||
|
- tileTickPosition = (tileTickPosition < tileEntityList.size()) ? tileTickPosition : 0;
|
||||||
|
- TileEntity tileentity = (TileEntity) this.tileEntityList.get(tileTickPosition);
|
||||||
|
- // Spigot start
|
||||||
|
+ while (iterator.hasNext()) {
|
||||||
|
+ TileEntity tileentity = (TileEntity) iterator.next();
|
||||||
|
if (tileentity == null) {
|
||||||
|
getServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash");
|
||||||
|
- tilesThisCycle--;
|
||||||
|
- this.tileEntityList.remove(tileTickPosition--);
|
||||||
|
+ iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Spigot end
|
||||||
|
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tileentity.x()) {
|
||||||
|
- tilesThisCycle--;
|
||||||
|
- this.tileEntityList.remove(tileTickPosition--);
|
||||||
|
+ iterator.remove();
|
||||||
|
this.h.remove(tileentity);
|
||||||
|
if (this.isLoaded(tileentity.getPosition())) {
|
||||||
|
this.getChunkAtWorldCoords(tileentity.getPosition()).e(tileentity.getPosition());
|
||||||
diff --git a/src/main/java/org/github/paperspigot/WorldTileEntityList.java b/src/main/java/org/github/paperspigot/WorldTileEntityList.java
|
diff --git a/src/main/java/org/github/paperspigot/WorldTileEntityList.java b/src/main/java/org/github/paperspigot/WorldTileEntityList.java
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||||
@@ -260,5 +346,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
\ No newline at end of file
|
|
||||||
--
|
--
|
@@ -126,7 +126,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
--- a/src/main/java/net/minecraft/server/World.java
|
--- a/src/main/java/net/minecraft/server/World.java
|
||||||
+++ b/src/main/java/net/minecraft/server/World.java
|
+++ b/src/main/java/net/minecraft/server/World.java
|
||||||
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
||||||
public static String blockLocation;
|
private org.spigotmc.TickLimiter tileLimiter;
|
||||||
private int tileTickPosition;
|
private int tileTickPosition;
|
||||||
public ExecutorService lightingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("PaperSpigot - Lighting Thread").build()); // PaperSpigot - Asynchronous lighting updates
|
public ExecutorService lightingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("PaperSpigot - Lighting Thread").build()); // PaperSpigot - Asynchronous lighting updates
|
||||||
+ public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<Explosion.CacheKey, Float>(); // PaperSpigot - Optimize explosions
|
+ public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<Explosion.CacheKey, Float>(); // PaperSpigot - Optimize explosions
|
||||||
|
@@ -1,125 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
|
||||||
Date: Sat, 30 May 2015 01:21:00 -0500
|
|
||||||
Subject: [PATCH] Remove Spigot TileEntity/Enity Tick Time Capping
|
|
||||||
|
|
||||||
Appears to cause visual glitches with TNT Entities and certain types of cannons
|
|
||||||
TileEntity cap removed as we implement our own solution in a later (next) patch.
|
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
||||||
--- a/src/main/java/net/minecraft/server/World.java
|
|
||||||
+++ b/src/main/java/net/minecraft/server/World.java
|
|
||||||
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
|
||||||
private final byte chunkTickRadius;
|
|
||||||
public static boolean haveWeSilencedAPhysicsCrash;
|
|
||||||
public static String blockLocation;
|
|
||||||
- private org.spigotmc.TickLimiter entityLimiter;
|
|
||||||
- private org.spigotmc.TickLimiter tileLimiter;
|
|
||||||
private int tileTickPosition;
|
|
||||||
|
|
||||||
public static long chunkToKey(int x, int z)
|
|
||||||
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
|
||||||
this.getServer().addWorld(this.world);
|
|
||||||
// CraftBukkit end
|
|
||||||
this.keepSpawnInMemory = this.paperSpigotConfig.keepSpawnInMemory; // PaperSpigot
|
|
||||||
- timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings
|
|
||||||
- this.entityLimiter = new org.spigotmc.TickLimiter(spigotConfig.entityMaxTickTime);
|
|
||||||
- this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime);
|
|
||||||
+ timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings
|
|
||||||
}
|
|
||||||
|
|
||||||
public World b() {
|
|
||||||
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
|
||||||
timings.entityTick.startTiming(); // Spigot
|
|
||||||
guardEntityList = true; // Spigot
|
|
||||||
// CraftBukkit start - Use field for loop variable
|
|
||||||
- int entitiesThisCycle = 0;
|
|
||||||
- if (tickPosition < 0) tickPosition = 0;
|
|
||||||
- for (entityLimiter.initTick();
|
|
||||||
- entitiesThisCycle < entityList.size() && (entitiesThisCycle % 10 == 0 || entityLimiter.shouldContinue());
|
|
||||||
- tickPosition++, entitiesThisCycle++) {
|
|
||||||
- tickPosition = (tickPosition < entityList.size()) ? tickPosition : 0;
|
|
||||||
+ for (this.tickPosition = 0; this.tickPosition < this.entityList.size(); ++this.tickPosition) {
|
|
||||||
entity = (Entity) this.entityList.get(this.tickPosition);
|
|
||||||
// CraftBukkit end
|
|
||||||
if (entity.vehicle != null) {
|
|
||||||
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
|
||||||
this.c.clear();
|
|
||||||
}
|
|
||||||
// CraftBukkit end
|
|
||||||
+ Iterator iterator = this.tileEntityList.iterator();
|
|
||||||
|
|
||||||
- // Spigot start
|
|
||||||
- int tilesThisCycle = 0;
|
|
||||||
- for (tileLimiter.initTick();
|
|
||||||
- tilesThisCycle < tileEntityList.size() && (tilesThisCycle % 10 == 0 || tileLimiter.shouldContinue());
|
|
||||||
- tileTickPosition++, tilesThisCycle++) {
|
|
||||||
- tileTickPosition = (tileTickPosition < tileEntityList.size()) ? tileTickPosition : 0;
|
|
||||||
- TileEntity tileentity = (TileEntity) this.tileEntityList.get(tileTickPosition);
|
|
||||||
- // Spigot start
|
|
||||||
+ while (iterator.hasNext()) {
|
|
||||||
+ TileEntity tileentity = (TileEntity) iterator.next();
|
|
||||||
if (tileentity == null) {
|
|
||||||
getServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash");
|
|
||||||
- tilesThisCycle--;
|
|
||||||
- this.tileEntityList.remove(tileTickPosition--);
|
|
||||||
+ iterator.remove();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Spigot end
|
|
||||||
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tileentity.x()) {
|
|
||||||
- tilesThisCycle--;
|
|
||||||
- this.tileEntityList.remove(tileTickPosition--);
|
|
||||||
+ iterator.remove();
|
|
||||||
this.h.remove(tileentity);
|
|
||||||
if (this.isLoaded(tileentity.getPosition())) {
|
|
||||||
this.getChunkAtWorldCoords(tileentity.getPosition()).e(tileentity.getPosition());
|
|
||||||
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
||||||
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
|
||||||
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
|
||||||
@@ -0,0 +0,0 @@ public class SpigotWorldConfig
|
|
||||||
{
|
|
||||||
hangingTickFrequency = getInt( "hanging-tick-frequency", 100 );
|
|
||||||
}
|
|
||||||
-
|
|
||||||
- public int tileMaxTickTime;
|
|
||||||
- public int entityMaxTickTime;
|
|
||||||
- private void maxTickTimes()
|
|
||||||
- {
|
|
||||||
- tileMaxTickTime = getInt("max-tick-time.tile", 50);
|
|
||||||
- entityMaxTickTime = getInt("max-tick-time.entity", 50);
|
|
||||||
- log("Tile Max Tick Time: " + tileMaxTickTime + "ms Entity max Tick Time: " + entityMaxTickTime + "ms");
|
|
||||||
- }
|
|
||||||
}
|
|
||||||
diff --git a/src/main/java/org/spigotmc/TickLimiter.java b/src/main/java/org/spigotmc/TickLimiter.java
|
|
||||||
deleted file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
|
||||||
--- a/src/main/java/org/spigotmc/TickLimiter.java
|
|
||||||
+++ /dev/null
|
|
||||||
@@ -0,0 +0,0 @@
|
|
||||||
-package org.spigotmc;
|
|
||||||
-
|
|
||||||
-public class TickLimiter {
|
|
||||||
-
|
|
||||||
- private final int maxTime;
|
|
||||||
- private long startTime;
|
|
||||||
-
|
|
||||||
- public TickLimiter(int maxtime) {
|
|
||||||
- this.maxTime = maxtime;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- public void initTick() {
|
|
||||||
- startTime = System.currentTimeMillis();
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- public boolean shouldContinue() {
|
|
||||||
- long remaining = System.currentTimeMillis() - startTime;
|
|
||||||
- return remaining < maxTime;
|
|
||||||
- }
|
|
||||||
-}
|
|
||||||
--
|
|
Reference in New Issue
Block a user