mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-01 17:01:56 +01:00
603159dedf
Removes PlayerMicroMoveEvent API, the ability to disable the AsyncCatcher, and the TeleportPassengerVehicleWithPlayer patch
264 lines
No EOL
11 KiB
Diff
264 lines
No EOL
11 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Sun, 8 Mar 2015 01:56:22 -0600
|
|
Subject: [PATCH] Optimize TileEntity Ticking
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/TileEntity.java
|
|
+++ b/src/main/java/net/minecraft/server/TileEntity.java
|
|
@@ -0,0 +0,0 @@ public abstract class TileEntity {
|
|
private int h;
|
|
protected Block e;
|
|
|
|
+ // PaperSpigot start - Optimized TileEntity tick changes
|
|
+ private static int tileEntityCounter = 0;
|
|
+ public boolean isAdded = false;
|
|
+ public int tileId = tileEntityCounter++;
|
|
+ // PaperSpigot end
|
|
+
|
|
public TileEntity() {
|
|
this.position = BlockPosition.ZERO;
|
|
this.h = -1;
|
|
diff --git a/src/main/java/net/minecraft/server/TileEntityBeacon.java b/src/main/java/net/minecraft/server/TileEntityBeacon.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/TileEntityBeacon.java
|
|
+++ b/src/main/java/net/minecraft/server/TileEntityBeacon.java
|
|
@@ -0,0 +0,0 @@ public class TileEntityBeacon extends TileEntityContainer implements IUpdatePlay
|
|
public TileEntityBeacon() {}
|
|
|
|
public void c() {
|
|
- if (this.world.getTime() % 80L == 0L) {
|
|
+ if (true || this.world.getTime() % 80L == 0L) { // PaperSpigot - Controlled by improved tick handling
|
|
this.m();
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/TileEntityChest.java b/src/main/java/net/minecraft/server/TileEntityChest.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/TileEntityChest.java
|
|
+++ b/src/main/java/net/minecraft/server/TileEntityChest.java
|
|
@@ -0,0 +0,0 @@ public class TileEntityChest extends TileEntityContainer implements IUpdatePlaye
|
|
++this.n;
|
|
float f;
|
|
|
|
- if (!this.world.isClientSide && this.l != 0 && (this.n + i + j + k) % 200 == 0) {
|
|
+ if (!this.world.isClientSide && this.l != 0 && (this.n + i + j + k) % 10 == 0) { // PaperSpigot - Reduced 200 -> 10 due to reduced interval from improved tick handling
|
|
this.l = 0;
|
|
f = 5.0F;
|
|
List list = this.world.a(EntityHuman.class, new AxisAlignedBB((double) ((float) i - f), (double) ((float) j - f), (double) ((float) k - f), (double) ((float) (i + 1) + f), (double) ((float) (j + 1) + f), (double) ((float) (k + 1) + f)));
|
|
diff --git a/src/main/java/net/minecraft/server/TileEntityEnderChest.java b/src/main/java/net/minecraft/server/TileEntityEnderChest.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/TileEntityEnderChest.java
|
|
+++ b/src/main/java/net/minecraft/server/TileEntityEnderChest.java
|
|
@@ -0,0 +0,0 @@ public class TileEntityEnderChest extends TileEntity implements IUpdatePlayerLis
|
|
public TileEntityEnderChest() {}
|
|
|
|
public void c() {
|
|
- if (++this.h % 20 * 4 == 0) {
|
|
+ if (++this.h % 4 == 0) { // PaperSpigot - Reduced (20 * 4) -> 4 interval due to reduced tick rate from improved tick handling
|
|
this.world.playBlockAction(this.position, Blocks.ENDER_CHEST, 1, this.g);
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/TileEntityLightDetector.java b/src/main/java/net/minecraft/server/TileEntityLightDetector.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/TileEntityLightDetector.java
|
|
+++ b/src/main/java/net/minecraft/server/TileEntityLightDetector.java
|
|
@@ -0,0 +0,0 @@ public class TileEntityLightDetector extends TileEntity implements IUpdatePlayer
|
|
public TileEntityLightDetector() {}
|
|
|
|
public void c() {
|
|
- if (this.world != null && !this.world.isClientSide && this.world.getTime() % 20L == 0L) {
|
|
+ if (this.world != null && !this.world.isClientSide /*&& this.world.getTime() % 20L == 0L*/) { // PaperSpigot - interval controlled by improved tick handling
|
|
this.e = this.w();
|
|
if (this.e instanceof BlockDaylightDetector) {
|
|
((BlockDaylightDetector) this.e).f(this.world, this.position);
|
|
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 {
|
|
// Spigot end
|
|
protected final List<Entity> g = Lists.newArrayList();
|
|
public final List<TileEntity> h = Lists.newArrayList();
|
|
- public final List<TileEntity> tileEntityList = Lists.newArrayList();
|
|
+ public final Set<TileEntity> tileEntityList = new org.github.paperspigot.WorldTileEntityList(this); // PaperSpigot
|
|
private final List<TileEntity> b = Lists.newArrayList();
|
|
private final List<TileEntity> c = Lists.newArrayList();
|
|
public final List<EntityHuman> players = Lists.newArrayList();
|
|
diff --git a/src/main/java/org/github/paperspigot/WorldTileEntityList.java b/src/main/java/org/github/paperspigot/WorldTileEntityList.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
|
--- /dev/null
|
|
+++ b/src/main/java/org/github/paperspigot/WorldTileEntityList.java
|
|
@@ -0,0 +0,0 @@
|
|
+package org.github.paperspigot;
|
|
+
|
|
+import com.google.common.collect.ArrayListMultimap;
|
|
+import com.google.common.collect.Maps;
|
|
+import com.google.common.collect.Multimap;
|
|
+import net.minecraft.server.*;
|
|
+import gnu.trove.map.hash.TObjectIntHashMap;
|
|
+
|
|
+import java.util.Collection;
|
|
+import java.util.HashSet;
|
|
+import java.util.Iterator;
|
|
+import java.util.Map;
|
|
+
|
|
+public class WorldTileEntityList extends HashSet<TileEntity> {
|
|
+ private static final TObjectIntHashMap<Class<? extends TileEntity>> tileEntityTickIntervals =
|
|
+ new TObjectIntHashMap<Class<? extends TileEntity>>() {{
|
|
+ // Use -1 for no ticking
|
|
+ // These TE's have empty tick methods, doing nothing. Never bother ticking them.
|
|
+ for (Class<? extends TileEntity> ignored : new Class[]{
|
|
+ BlockJukeBox.TileEntityRecordPlayer.class,
|
|
+ TileEntityDispenser.class,
|
|
+ TileEntityDropper.class,
|
|
+ TileEntitySign.class,
|
|
+ TileEntityNote.class,
|
|
+ TileEntityEnderPortal.class,
|
|
+ TileEntityCommand.class,
|
|
+ TileEntitySkull.class,
|
|
+ TileEntityComparator.class,
|
|
+ TileEntityFlowerPot.class
|
|
+ }) {
|
|
+ put(ignored, -1);
|
|
+ }
|
|
+
|
|
+ // does findPlayer lookup, so this helps performance to slow down
|
|
+ put(TileEntityEnchantTable.class, 20);
|
|
+
|
|
+ // Vanilla controlled values - These are checks already done in vanilla, so don't tick on ticks we know
|
|
+ // won't do anything anyways
|
|
+ put(TileEntityBeacon.class, 80);
|
|
+ put(TileEntityLightDetector.class, 20);
|
|
+ }};
|
|
+
|
|
+ private static int getInterval(Class<? extends TileEntity> cls) {
|
|
+ int tickInterval = tileEntityTickIntervals.get(cls);
|
|
+ return tickInterval != 0 ? tickInterval : 1;
|
|
+ }
|
|
+
|
|
+ private static int getBucketId(TileEntity entity, Integer interval) {
|
|
+ return entity.tileId % interval;
|
|
+ }
|
|
+
|
|
+ private final Map<Integer, Multimap<Integer, TileEntity>> tickList = Maps.newHashMap();
|
|
+ private final WorldServer world;
|
|
+
|
|
+ public WorldTileEntityList(World world) {
|
|
+ this.world = (WorldServer) world;
|
|
+ }
|
|
+
|
|
+
|
|
+ private Multimap<Integer, TileEntity> getBucket(int interval) {
|
|
+ Multimap<Integer, TileEntity> intervalBucket = tickList.get(interval);
|
|
+ if (intervalBucket == null) {
|
|
+ intervalBucket = ArrayListMultimap.create();
|
|
+ tickList.put(interval, intervalBucket);
|
|
+ }
|
|
+ return intervalBucket;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Adds the TileEntity to the tick list only if it is expected to tick
|
|
+ */
|
|
+ @Override
|
|
+ public boolean add(TileEntity entity) {
|
|
+ if (entity.isAdded) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ int interval = getInterval(entity.getClass());
|
|
+ if (interval > 0) {
|
|
+ entity.isAdded = true;
|
|
+ int bucket = getBucketId(entity, interval);
|
|
+ Multimap<Integer, TileEntity> typeBucket = getBucket(interval);
|
|
+ return typeBucket.put(bucket, entity);
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean remove(Object o) {
|
|
+ if (!(o instanceof TileEntity)) {
|
|
+ return false;
|
|
+ }
|
|
+ TileEntity entity = (TileEntity) o;
|
|
+ if (!entity.isAdded) {
|
|
+ return false;
|
|
+ }
|
|
+ entity.isAdded = false;
|
|
+ int interval = getInterval(entity.getClass());
|
|
+ int bucket = getBucketId(entity, interval);
|
|
+ Multimap<Integer, TileEntity> typeBucket = getBucket(interval);
|
|
+ return typeBucket.remove(bucket, entity);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Iterator iterator() {
|
|
+ return new WorldTileEntityIterator();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean contains(Object o) {
|
|
+ return o instanceof TileEntity && ((TileEntity) o).isAdded;
|
|
+ }
|
|
+
|
|
+ private class WorldTileEntityIterator implements Iterator<TileEntity> {
|
|
+ private final Iterator<Map.Entry<Integer, Multimap<Integer, TileEntity>>> intervalIterator;
|
|
+ private Map.Entry<Integer, Multimap<Integer, TileEntity>> intervalMap = null;
|
|
+ private Iterator<TileEntity> listIterator = null;
|
|
+
|
|
+ protected WorldTileEntityIterator() {
|
|
+ intervalIterator = tickList.entrySet().iterator();
|
|
+ nextInterval();
|
|
+ }
|
|
+
|
|
+ private boolean nextInterval() {
|
|
+ listIterator = null;
|
|
+ if (intervalIterator.hasNext()) {
|
|
+ intervalMap = intervalIterator.next();
|
|
+
|
|
+ final Integer interval = intervalMap.getKey();
|
|
+ final Multimap<Integer, TileEntity> buckets = intervalMap.getValue();
|
|
+
|
|
+ int bucket = (int) (world.getTime() % interval);
|
|
+
|
|
+ if (!buckets.isEmpty() && buckets.containsKey(bucket)) {
|
|
+ final Collection<TileEntity> tileList = buckets.get(bucket);
|
|
+
|
|
+ if (tileList != null && !tileList.isEmpty()) {
|
|
+ listIterator = tileList.iterator();
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean hasNext() {
|
|
+ do {
|
|
+ if (listIterator != null && listIterator.hasNext()) {
|
|
+ return true;
|
|
+ }
|
|
+ } while (nextInterval());
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public TileEntity next() {
|
|
+ return listIterator.next();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void remove() {
|
|
+ listIterator.remove();
|
|
+ }
|
|
+ }
|
|
+}
|
|
\ No newline at end of file
|
|
--
|