Spigot Timings
Overhauls the Timings System adding performance tracking all around the Minecraft Server By: Aikar <aikar@aikar.co>
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
import net.minecraft.world.level.entity.EntityTypeTest;
|
||||
import net.minecraft.world.level.entity.LevelEntityGetter;
|
||||
import net.minecraft.world.level.gameevent.GameEvent;
|
||||
@@ -81,6 +85,24 @@
|
||||
@@ -81,6 +85,25 @@
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.scores.Scoreboard;
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.craftbukkit.CraftServer;
|
||||
+import org.bukkit.craftbukkit.CraftWorld;
|
||||
+import org.bukkit.craftbukkit.SpigotTimings; // Spigot
|
||||
+import org.bukkit.craftbukkit.block.CapturedBlockState;
|
||||
+import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||
+import org.bukkit.craftbukkit.util.CraftSpawnCategory;
|
||||
@@ -56,7 +57,7 @@
|
||||
public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
|
||||
public static final Codec<ResourceKey<Level>> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION);
|
||||
@@ -121,23 +143,60 @@
|
||||
@@ -121,23 +144,62 @@
|
||||
private final DamageSources damageSources;
|
||||
private long subTickCount;
|
||||
|
||||
@@ -81,6 +82,8 @@
|
||||
+ public boolean populating;
|
||||
+ public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
|
||||
+
|
||||
+ public final SpigotTimings.WorldTimingsHandler timings; // Spigot
|
||||
+
|
||||
+ public CraftWorld getWorld() {
|
||||
+ return this.world;
|
||||
+ }
|
||||
@@ -126,7 +129,7 @@
|
||||
}
|
||||
};
|
||||
} else {
|
||||
@@ -145,11 +204,47 @@
|
||||
@@ -145,11 +207,48 @@
|
||||
}
|
||||
|
||||
this.thread = Thread.currentThread();
|
||||
@@ -176,10 +179,11 @@
|
||||
+ public void onBorderSetDamageSafeZOne(WorldBorder border, double safeZoneRadius) {}
|
||||
+ });
|
||||
+ // CraftBukkit end
|
||||
+ this.timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -207,6 +302,18 @@
|
||||
@@ -207,6 +306,18 @@
|
||||
|
||||
@Override
|
||||
public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) {
|
||||
@@ -198,7 +202,7 @@
|
||||
if (this.isOutsideBuildHeight(pos)) {
|
||||
return false;
|
||||
} else if (!this.isClientSide && this.isDebug()) {
|
||||
@@ -214,45 +321,118 @@
|
||||
@@ -214,44 +325,117 @@
|
||||
} else {
|
||||
LevelChunk chunk = this.getChunkAt(pos);
|
||||
Block block = state.getBlock();
|
||||
@@ -276,10 +280,10 @@
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit start - Split off from above in order to directly send client and physic updates
|
||||
+ public void notifyAndUpdatePhysics(BlockPos blockposition, LevelChunk chunk, BlockState oldBlock, BlockState newBlock, BlockState actualBlock, int i, int j) {
|
||||
+ BlockState iblockdata = newBlock;
|
||||
@@ -299,7 +303,7 @@
|
||||
+ if (!this.isClientSide && iblockdata.hasAnalogOutputSignal()) {
|
||||
+ this.updateNeighbourForOutputSignal(blockposition, newBlock.getBlock());
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ if ((i & 16) == 0 && j > 0) {
|
||||
+ int k = i & -34;
|
||||
@@ -325,14 +329,13 @@
|
||||
+ this.onBlockStateChange(blockposition, iblockdata1, iblockdata2);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
|
||||
public void onBlockStateChange(BlockPos pos, BlockState oldBlock, BlockState newBlock) {}
|
||||
|
||||
@Override
|
||||
@@ -340,6 +520,14 @@
|
||||
@@ -340,6 +524,14 @@
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
@@ -347,15 +350,48 @@
|
||||
if (this.isOutsideBuildHeight(pos)) {
|
||||
return Blocks.VOID_AIR.defaultBlockState();
|
||||
} else {
|
||||
@@ -510,13 +698,29 @@
|
||||
@@ -440,12 +632,15 @@
|
||||
ProfilerFiller gameprofilerfiller = Profiler.get();
|
||||
|
||||
gameprofilerfiller.push("blockEntities");
|
||||
+ this.timings.tileEntityPending.startTiming(); // Spigot
|
||||
this.tickingBlockEntities = true;
|
||||
if (!this.pendingBlockEntityTickers.isEmpty()) {
|
||||
this.blockEntityTickers.addAll(this.pendingBlockEntityTickers);
|
||||
this.pendingBlockEntityTickers.clear();
|
||||
}
|
||||
+ this.timings.tileEntityPending.stopTiming(); // Spigot
|
||||
|
||||
+ this.timings.tileEntityTick.startTiming(); // Spigot
|
||||
Iterator<TickingBlockEntity> iterator = this.blockEntityTickers.iterator();
|
||||
boolean flag = this.tickRateManager().runsNormally();
|
||||
|
||||
@@ -459,13 +654,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ this.timings.tileEntityTick.stopTiming(); // Spigot
|
||||
this.tickingBlockEntities = false;
|
||||
gameprofilerfiller.pop();
|
||||
}
|
||||
|
||||
public <T extends Entity> void guardEntityTick(Consumer<T> tickConsumer, T entity) {
|
||||
try {
|
||||
+ SpigotTimings.tickEntityTimer.startTiming(); // Spigot
|
||||
tickConsumer.accept(entity);
|
||||
+ SpigotTimings.tickEntityTimer.stopTiming(); // Spigot
|
||||
} catch (Throwable throwable) {
|
||||
CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking entity");
|
||||
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being ticked");
|
||||
@@ -510,13 +708,29 @@
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity getBlockEntity(BlockPos pos) {
|
||||
- return this.isOutsideBuildHeight(pos) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(pos).getBlockEntity(pos, LevelChunk.EntityCreationType.IMMEDIATE));
|
||||
+ // CraftBukkit start
|
||||
+ return this.getBlockEntity(pos, true);
|
||||
}
|
||||
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public BlockEntity getBlockEntity(BlockPos blockposition, boolean validate) {
|
||||
+ if (this.capturedTileEntities.containsKey(blockposition)) {
|
||||
@@ -363,8 +399,8 @@
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE));
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
public void setBlockEntity(BlockEntity blockEntity) {
|
||||
BlockPos blockposition = blockEntity.getBlockPos();
|
||||
|
||||
@@ -378,7 +414,7 @@
|
||||
this.getChunkAt(blockposition).addAndRegisterBlockEntity(blockEntity);
|
||||
}
|
||||
}
|
||||
@@ -643,7 +847,7 @@
|
||||
@@ -643,7 +857,7 @@
|
||||
|
||||
for (int k = 0; k < j; ++k) {
|
||||
EnderDragonPart entitycomplexpart = aentitycomplexpart[k];
|
||||
@@ -387,7 +423,7 @@
|
||||
|
||||
if (t0 != null && predicate.test(t0)) {
|
||||
result.add(t0);
|
||||
@@ -912,7 +1116,7 @@
|
||||
@@ -912,7 +1126,7 @@
|
||||
|
||||
public static enum ExplosionInteraction implements StringRepresentable {
|
||||
|
||||
|
||||
@@ -48,7 +48,23 @@
|
||||
list.add(enumcreaturetype);
|
||||
}
|
||||
}
|
||||
@@ -217,10 +238,15 @@
|
||||
@@ -127,6 +148,7 @@
|
||||
ProfilerFiller gameprofilerfiller = Profiler.get();
|
||||
|
||||
gameprofilerfiller.push("spawner");
|
||||
+ world.timings.mobSpawn.startTiming(); // Spigot
|
||||
Iterator iterator = spawnableGroups.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -141,6 +163,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ world.timings.mobSpawn.stopTiming(); // Spigot
|
||||
gameprofilerfiller.pop();
|
||||
}
|
||||
|
||||
@@ -217,10 +240,15 @@
|
||||
entityinsentient.moveTo(d0, (double) i, d1, world.random.nextFloat() * 360.0F, 0.0F);
|
||||
if (NaturalSpawner.isValidPositionForMob(world, entityinsentient, d2)) {
|
||||
groupdataentity = entityinsentient.finalizeSpawn(world, world.getCurrentDifficultyAt(entityinsentient.blockPosition()), EntitySpawnReason.NATURAL, groupdataentity);
|
||||
@@ -68,7 +84,7 @@
|
||||
if (j >= entityinsentient.getMaxSpawnClusterSize()) {
|
||||
return;
|
||||
}
|
||||
@@ -369,7 +395,7 @@
|
||||
@@ -369,7 +397,7 @@
|
||||
|
||||
if (entityinsentient.checkSpawnRules(world, EntitySpawnReason.CHUNK_GENERATION) && entityinsentient.checkSpawnObstruction(world)) {
|
||||
groupdataentity = entityinsentient.finalizeSpawn(world, world.getCurrentDifficultyAt(entityinsentient.blockPosition()), EntitySpawnReason.CHUNK_GENERATION, groupdataentity);
|
||||
@@ -77,7 +93,7 @@
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
@@ -482,10 +508,12 @@
|
||||
@@ -482,10 +510,12 @@
|
||||
return this.unmodifiableMobCategoryCounts;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
@@ -26,8 +26,18 @@
|
||||
@@ -26,8 +26,21 @@
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -9,9 +9,12 @@
|
||||
+import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry;
|
||||
+import org.bukkit.inventory.InventoryHolder;
|
||||
+// CraftBukkit end
|
||||
+
|
||||
+import org.spigotmc.CustomTimingsHandler; // Spigot
|
||||
+
|
||||
public abstract class BlockEntity {
|
||||
|
||||
+ public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot
|
||||
+ // CraftBukkit start - data containers
|
||||
+ private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
|
||||
+ public CraftPersistentDataContainer persistentDataContainer;
|
||||
@@ -19,7 +22,7 @@
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final BlockEntityType<?> type;
|
||||
@Nullable
|
||||
@@ -74,8 +84,17 @@
|
||||
@@ -74,8 +87,17 @@
|
||||
return this.level != null;
|
||||
}
|
||||
|
||||
@@ -38,7 +41,7 @@
|
||||
public final void loadWithComponents(CompoundTag nbt, HolderLookup.Provider registries) {
|
||||
this.loadAdditional(nbt, registries);
|
||||
BlockEntity.ComponentHelper.COMPONENTS_CODEC.parse(registries.createSerializationContext(NbtOps.INSTANCE), nbt).resultOrPartial((s) -> {
|
||||
@@ -114,6 +133,11 @@
|
||||
@@ -114,6 +136,11 @@
|
||||
}).ifPresent((nbtbase) -> {
|
||||
nbttagcompound.merge((CompoundTag) nbtbase);
|
||||
});
|
||||
@@ -50,7 +53,7 @@
|
||||
return nbttagcompound;
|
||||
}
|
||||
|
||||
@@ -263,13 +287,19 @@
|
||||
@@ -263,13 +290,19 @@
|
||||
}
|
||||
|
||||
public final void applyComponents(DataComponentMap defaultComponents, DataComponentPatch components) {
|
||||
@@ -72,7 +75,7 @@
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T get(DataComponentType<T> type) {
|
||||
@@ -284,9 +314,13 @@
|
||||
@@ -284,9 +317,13 @@
|
||||
}
|
||||
});
|
||||
Objects.requireNonNull(set);
|
||||
@@ -87,7 +90,7 @@
|
||||
}
|
||||
|
||||
protected void collectImplicitComponents(DataComponentMap.Builder builder) {}
|
||||
@@ -321,6 +355,15 @@
|
||||
@@ -321,6 +358,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -188,10 +188,14 @@
|
||||
if (tileentity != null) {
|
||||
Level world = this.level;
|
||||
|
||||
@@ -553,6 +582,57 @@
|
||||
|
||||
}
|
||||
|
||||
@@ -549,10 +578,61 @@
|
||||
if (this.postLoad != null) {
|
||||
this.postLoad.run(this);
|
||||
this.postLoad = null;
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ public void loadCallback() {
|
||||
+ org.bukkit.Server server = this.level.getCraftServer();
|
||||
@@ -225,9 +229,9 @@
|
||||
+ }
|
||||
+ server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk));
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
+ }
|
||||
+
|
||||
|
||||
+ public void unloadCallback() {
|
||||
+ org.bukkit.Server server = this.level.getCraftServer();
|
||||
+ org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this);
|
||||
@@ -235,8 +239,8 @@
|
||||
+ server.getPluginManager().callEvent(unloadEvent);
|
||||
+ // note: saving can be prevented, but not forced if no saving is actually required
|
||||
+ this.mustNotSave = !unloadEvent.isSaveChunk();
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public boolean isUnsaved() {
|
||||
+ return super.isUnsaved() && !this.mustNotSave;
|
||||
@@ -264,3 +268,22 @@
|
||||
this.ticker = blockentityticker;
|
||||
}
|
||||
|
||||
@@ -855,6 +935,7 @@
|
||||
ProfilerFiller gameprofilerfiller = Profiler.get();
|
||||
|
||||
gameprofilerfiller.push(this::getType);
|
||||
+ this.blockEntity.tickTimer.startTiming(); // Spigot
|
||||
BlockState iblockdata = LevelChunk.this.getBlockState(blockposition);
|
||||
|
||||
if (this.blockEntity.getType().isValid(iblockdata)) {
|
||||
@@ -872,6 +953,10 @@
|
||||
|
||||
this.blockEntity.fillCrashReportCategory(crashreportsystemdetails);
|
||||
throw new ReportedException(crashreport);
|
||||
+ // Spigot start
|
||||
+ } finally {
|
||||
+ this.blockEntity.tickTimer.stopTiming();
|
||||
+ // Spigot end
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,31 @@
|
||||
return nbttagcompound;
|
||||
}
|
||||
|
||||
@@ -623,6 +649,12 @@
|
||||
@@ -550,12 +576,15 @@
|
||||
@Nullable
|
||||
private static LevelChunk.PostLoadProcessor postLoadChunk(ServerLevel world, List<CompoundTag> entities, List<CompoundTag> blockEntities) {
|
||||
return entities.isEmpty() && blockEntities.isEmpty() ? null : (chunk) -> {
|
||||
+ world.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot
|
||||
if (!entities.isEmpty()) {
|
||||
world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(entities, world, EntitySpawnReason.LOAD));
|
||||
}
|
||||
+ world.timings.syncChunkLoadEntitiesTimer.stopTiming(); // Spigot
|
||||
|
||||
Iterator iterator = blockEntities.iterator();
|
||||
|
||||
+ world.timings.syncChunkLoadTileEntitiesTimer.startTiming(); // Spigot
|
||||
while (iterator.hasNext()) {
|
||||
CompoundTag nbttagcompound = (CompoundTag) iterator.next();
|
||||
boolean flag = nbttagcompound.getBoolean("keepPacked");
|
||||
@@ -571,6 +600,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
+ world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot
|
||||
|
||||
};
|
||||
}
|
||||
@@ -623,6 +653,12 @@
|
||||
StructureStart structurestart = StructureStart.loadStaticStart(context, nbttagcompound1.getCompound(s), worldSeed);
|
||||
|
||||
if (structurestart != null) {
|
||||
|
||||
Reference in New Issue
Block a user