Paper/Spigot-Server-Patches/0009-Timings-v2.patch
Aikar e7a59cde75
clear current chunk and entity slice on chunk unload
ideally this should of never mattered, as it will only
be hit if you teleport out of an unloaded chunk...

But apparently some people are triggering this.

See #1223
2018-07-30 00:51:58 -04:00

1950 lines
86 KiB
Diff

From 7efabb01daa41444c86d565126597aa9f5ee134b Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 3 Mar 2016 04:00:11 -0600
Subject: [PATCH] Timings v2
diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java
new file mode 100644
index 0000000000..4f624e39c7
--- /dev/null
+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java
@@ -0,0 +1,125 @@
+package co.aikar.timings;
+
+import net.minecraft.server.*;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.scheduler.BukkitTask;
+
+import org.bukkit.craftbukkit.scheduler.CraftTask;
+
+public final class MinecraftTimings {
+
+ public static final Timing playerListTimer = Timings.ofSafe("Player List");
+ public static final Timing commandFunctionsTimer = Timings.ofSafe("Command Functions");
+ public static final Timing connectionTimer = Timings.ofSafe("Connection Handler");
+ public static final Timing tickablesTimer = Timings.ofSafe("Tickables");
+ public static final Timing minecraftSchedulerTimer = Timings.ofSafe("Minecraft Scheduler");
+ public static final Timing bukkitSchedulerTimer = Timings.ofSafe("Bukkit Scheduler");
+ public static final Timing bukkitSchedulerPendingTimer = Timings.ofSafe("Bukkit Scheduler - Pending");
+ public static final Timing bukkitSchedulerFinishTimer = Timings.ofSafe("Bukkit Scheduler - Finishing");
+ public static final Timing chunkIOTickTimer = Timings.ofSafe("ChunkIOTick");
+ public static final Timing timeUpdateTimer = Timings.ofSafe("Time Update");
+ public static final Timing serverCommandTimer = Timings.ofSafe("Server Command");
+ public static final Timing savePlayers = Timings.ofSafe("Save Players");
+
+ public static final Timing tickEntityTimer = Timings.ofSafe("## tickEntity");
+ public static final Timing tickTileEntityTimer = Timings.ofSafe("## tickTileEntity");
+ public static final Timing packetProcessTimer = Timings.ofSafe("## Packet Processing");
+ public static final Timing scheduledBlocksTimer = Timings.ofSafe("## Scheduled Blocks");
+ public static final Timing structureGenerationTimer = Timings.ofSafe("Structure Generation");
+
+ public static final Timing processQueueTimer = Timings.ofSafe("processQueue");
+
+ public static final Timing playerCommandTimer = Timings.ofSafe("playerCommand");
+
+ public static final Timing entityActivationCheckTimer = Timings.ofSafe("entityActivationCheck");
+
+ public static final Timing antiXrayUpdateTimer = Timings.ofSafe("anti-xray - update");
+ public static final Timing antiXrayObfuscateTimer = Timings.ofSafe("anti-xray - obfuscate");
+
+ private MinecraftTimings() {}
+
+ /**
+ * Gets a timer associated with a plugins tasks.
+ * @param bukkitTask
+ * @param period
+ * @return
+ */
+ public static Timing getPluginTaskTimings(BukkitTask bukkitTask, long period) {
+ if (!bukkitTask.isSync()) {
+ return null;
+ }
+ Plugin plugin;
+
+ Runnable task = ((CraftTask) bukkitTask).task;
+
+ final Class<? extends Runnable> taskClass = task.getClass();
+ if (bukkitTask.getOwner() != null) {
+ plugin = bukkitTask.getOwner();
+ } else {
+ plugin = TimingsManager.getPluginByClassloader(taskClass);
+ }
+
+ final String taskname;
+ if (taskClass.isAnonymousClass()) {
+ taskname = taskClass.getName();
+ } else {
+ taskname = taskClass.getCanonicalName();
+ }
+
+ StringBuilder name = new StringBuilder(64);
+ name.append("Task: ").append(taskname);
+ if (period > 0) {
+ name.append(" (interval:").append(period).append(")");
+ } else {
+ name.append(" (Single)");
+ }
+
+ if (plugin == null) {
+ return Timings.ofSafe(null, name.toString());
+ }
+
+ return Timings.ofSafe(plugin, name.toString());
+ }
+
+ /**
+ * Get a named timer for the specified entity type to track type specific timings.
+ * @param entity
+ * @return
+ */
+ public static Timing getEntityTimings(Entity entity) {
+ String entityType = entity.getClass().getName();
+ return Timings.ofSafe("Minecraft", "## tickEntity - " + entityType, tickEntityTimer);
+ }
+
+ /**
+ * Get a named timer for the specified tile entity type to track type specific timings.
+ * @param entity
+ * @return
+ */
+ public static Timing getTileEntityTimings(TileEntity entity) {
+ String entityType = entity.getClass().getName();
+ return Timings.ofSafe("Minecraft", "## tickTileEntity - " + entityType, tickTileEntityTimer);
+ }
+ public static Timing getCancelTasksTimer() {
+ return Timings.ofSafe("Cancel Tasks");
+ }
+ public static Timing getCancelTasksTimer(Plugin plugin) {
+ return Timings.ofSafe(plugin, "Cancel Tasks");
+ }
+
+ public static void stopServer() {
+ TimingsManager.stopServer();
+ }
+
+ public static Timing getBlockTiming(Block block) {
+ return Timings.ofSafe("## Scheduled Block: " + block.toString(), scheduledBlocksTimer);
+ }
+/*
+ public static Timing getStructureTiming(StructureGenerator structureGenerator) {
+ return Timings.ofSafe("Structure Generator - " + structureGenerator.getName(), structureGenerationTimer);
+ }*/
+
+ public static Timing getPacketTiming(Packet packet) {
+ return Timings.ofSafe("## Packet - " + packet.getClass().getSimpleName(), packetProcessTimer);
+ }
+}
diff --git a/src/main/java/co/aikar/timings/TimedChunkGenerator.java b/src/main/java/co/aikar/timings/TimedChunkGenerator.java
new file mode 100644
index 0000000000..0bb63600f3
--- /dev/null
+++ b/src/main/java/co/aikar/timings/TimedChunkGenerator.java
@@ -0,0 +1,180 @@
+/*
+ * This file is licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2014-2016 Daniel Ennis <http://aikar.co>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package co.aikar.timings;
+
+import net.minecraft.server.BiomeBase;
+import net.minecraft.server.BiomeBase.BiomeMeta;
+import net.minecraft.server.BlockPosition;
+import net.minecraft.server.Chunk;
+import net.minecraft.server.EnumCreatureType;
+import net.minecraft.server.GeneratorSettings;
+import net.minecraft.server.IChunkAccess;
+import net.minecraft.server.RegionLimitedWorldAccess;
+import net.minecraft.server.StructureGenerator;
+import net.minecraft.server.StructureStart;
+import net.minecraft.server.World;
+import net.minecraft.server.WorldChunkManager;
+import net.minecraft.server.WorldGenFeatureConfiguration;
+import net.minecraft.server.WorldGenStage;
+import net.minecraft.server.WorldServer;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.generator.InternalChunkGenerator;
+import org.bukkit.generator.BlockPopulator;
+
+import javax.annotation.Nullable;
+import java.util.List;
+import java.util.Random;
+
+import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
+import it.unimi.dsi.fastutil.longs.LongSet;
+
+// TODO: timing handlers
+public class TimedChunkGenerator extends InternalChunkGenerator {
+ private final WorldServer world;
+ private final InternalChunkGenerator timedGenerator;
+
+ public TimedChunkGenerator(WorldServer worldServer, InternalChunkGenerator gen) {
+ world = worldServer;
+ timedGenerator = gen;
+ }
+
+
+ @Override
+ public ChunkData generateChunkData(org.bukkit.World world, Random random, int x, int z, BiomeGrid biome) {
+ return timedGenerator.generateChunkData(world, random, x, z, biome);
+ }
+
+ @Override
+ public boolean canSpawn(org.bukkit.World world, int x, int z) {
+ return timedGenerator.canSpawn(world, x, z);
+ }
+
+ @Override
+ public List<BlockPopulator> getDefaultPopulators(org.bukkit.World world) {
+ return timedGenerator.getDefaultPopulators(world);
+ }
+
+ @Override
+ public Location getFixedSpawnLocation(org.bukkit.World world, Random random) {
+ return timedGenerator.getFixedSpawnLocation(world, random);
+ }
+ /*
+ @Override
+ public Chunk getOrCreateChunk(int i, int j) {
+ try (Timing ignored = world.timings.chunkGeneration.startTiming()) {
+ return timedGenerator.getOrCreateChunk(i, j);
+ }
+ }
+ */
+
+ @Override
+ public void createChunk(IChunkAccess ichunkaccess) {
+ try (Timing ignored = world.timings.chunkGeneration.startTiming()) {
+ timedGenerator.createChunk(ichunkaccess);
+ }
+ }
+
+ @Override
+ public void addFeatures(RegionLimitedWorldAccess regionlimitedworldaccess, WorldGenStage.Features worldgenstage_features) {
+ timedGenerator.addFeatures(regionlimitedworldaccess, worldgenstage_features);
+ }
+
+ @Override
+ public void addDecorations(RegionLimitedWorldAccess regionlimitedworldaccess) {
+ timedGenerator.addDecorations(regionlimitedworldaccess);
+ }
+
+ @Override
+ public void addMobs(RegionLimitedWorldAccess regionlimitedworldaccess) {
+ timedGenerator.addMobs(regionlimitedworldaccess);
+ }
+
+ @Override
+ public List<BiomeBase.BiomeMeta> getMobsFor(EnumCreatureType enumcreaturetype, BlockPosition blockposition) {
+ return timedGenerator.getMobsFor(enumcreaturetype, blockposition);
+ }
+
+ @Nullable
+ @Override
+ public BlockPosition findNearestMapFeature(World world, String s, BlockPosition blockposition, int i) {
+ return timedGenerator.findNearestMapFeature(world, s, blockposition, i);
+ }
+
+ @Override
+ public GeneratorSettings getSettings() {
+ return timedGenerator.getSettings();
+ }
+
+ @Override
+ public int a(World world, boolean flag, boolean flag1) {
+ return timedGenerator.a(world, flag, flag1);
+ }
+
+ @Override
+ public WorldChunkManager getWorldChunkManager() {
+ return timedGenerator.getWorldChunkManager();
+ }
+
+ @Override
+ public long getSeed() {
+ return timedGenerator.getSeed();
+ }
+
+ @Override
+ public int getSpawnHeight() {
+ return timedGenerator.getSpawnHeight();
+ }
+
+ @Override
+ public int e() {
+ return timedGenerator.e();
+ }
+
+ @Override
+ public World getWorld() {
+ return timedGenerator.getWorld();
+ }
+
+ @Override
+ public Long2ObjectMap<LongSet> getStructureCache(StructureGenerator structuregenerator) {
+ return timedGenerator.getStructureCache(structuregenerator);
+ }
+
+ @Override
+ public Long2ObjectMap<StructureStart> getStructureStartCache(StructureGenerator structuregenerator) {
+ return timedGenerator.getStructureStartCache(structuregenerator);
+ }
+
+ @Nullable
+ @Override
+ public WorldGenFeatureConfiguration getFeatureConfiguration(BiomeBase biomebase, StructureGenerator structuregenerator) {
+ return timedGenerator.getFeatureConfiguration(biomebase, structuregenerator);
+ }
+
+ @Override
+ public boolean canSpawnStructure(BiomeBase biomebase, StructureGenerator structuregenerator) {
+ return timedGenerator.canSpawnStructure(biomebase, structuregenerator);
+ }
+}
diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java
new file mode 100644
index 0000000000..145cb274b0
--- /dev/null
+++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java
@@ -0,0 +1,104 @@
+package co.aikar.timings;
+
+import net.minecraft.server.World;
+import net.minecraft.server.WorldServer;
+
+/**
+ * Set of timers per world, to track world specific timings.
+ */
+public class WorldTimingsHandler {
+ public final Timing mobSpawn;
+ public final Timing doChunkUnload;
+ public final Timing doPortalForcer;
+ public final Timing scheduledBlocks;
+ public final Timing scheduledBlocksCleanup;
+ public final Timing scheduledBlocksTicking;
+ public final Timing chunkTicks;
+ public final Timing lightChunk;
+ public final Timing chunkTicksBlocks;
+ public final Timing doVillages;
+ public final Timing doChunkMap;
+ public final Timing doChunkMapUpdate;
+ public final Timing doChunkMapToUpdate;
+ public final Timing doChunkMapSortMissing;
+ public final Timing doChunkMapSortSendToPlayers;
+ public final Timing doChunkMapPlayersNeedingChunks;
+ public final Timing doChunkMapPendingSendToPlayers;
+ public final Timing doChunkMapUnloadChunks;
+ public final Timing doChunkGC;
+ public final Timing doSounds;
+ public final Timing entityRemoval;
+ public final Timing entityTick;
+ public final Timing tileEntityTick;
+ public final Timing tileEntityPending;
+ public final Timing tracker1;
+ public final Timing tracker2;
+ public final Timing doTick;
+ public final Timing tickEntities;
+
+ public final Timing syncChunkLoadTimer;
+ public final Timing syncChunkLoadDataTimer;
+ public final Timing syncChunkLoadStructuresTimer;
+ public final Timing syncChunkLoadPostTimer;
+ public final Timing syncChunkLoadPopulateTimer;
+ public final Timing chunkLoadLevelTimer;
+ public final Timing chunkGeneration;
+ public final Timing chunkIOStage1;
+ public final Timing chunkIOStage2;
+ public final Timing worldSave;
+ public final Timing worldSaveChunks;
+ public final Timing worldSaveLevel;
+ public final Timing chunkSaveData;
+
+ public WorldTimingsHandler(World server) {
+ String name = server.worldData.getName() +" - ";
+
+ mobSpawn = Timings.ofSafe(name + "mobSpawn");
+ doChunkUnload = Timings.ofSafe(name + "doChunkUnload");
+ scheduledBlocks = Timings.ofSafe(name + "Scheduled Blocks");
+ scheduledBlocksCleanup = Timings.ofSafe(name + "Scheduled Blocks - Cleanup");
+ scheduledBlocksTicking = Timings.ofSafe(name + "Scheduled Blocks - Ticking");
+ chunkTicks = Timings.ofSafe(name + "Chunk Ticks");
+ lightChunk = Timings.ofSafe(name + "Light Chunk");
+ chunkTicksBlocks = Timings.ofSafe(name + "Chunk Ticks - Blocks");
+ doVillages = Timings.ofSafe(name + "doVillages");
+ doChunkMap = Timings.ofSafe(name + "doChunkMap");
+ doChunkMapUpdate = Timings.ofSafe(name + "doChunkMap - Update");
+ doChunkMapToUpdate = Timings.ofSafe(name + "doChunkMap - To Update");
+ doChunkMapSortMissing = Timings.ofSafe(name + "doChunkMap - Sort Missing");
+ doChunkMapSortSendToPlayers = Timings.ofSafe(name + "doChunkMap - Sort Send To Players");
+ doChunkMapPlayersNeedingChunks = Timings.ofSafe(name + "doChunkMap - Players Needing Chunks");
+ doChunkMapPendingSendToPlayers = Timings.ofSafe(name + "doChunkMap - Pending Send To Players");
+ doChunkMapUnloadChunks = Timings.ofSafe(name + "doChunkMap - Unload Chunks");
+ doSounds = Timings.ofSafe(name + "doSounds");
+ doChunkGC = Timings.ofSafe(name + "doChunkGC");
+ doPortalForcer = Timings.ofSafe(name + "doPortalForcer");
+ entityTick = Timings.ofSafe(name + "entityTick");
+ entityRemoval = Timings.ofSafe(name + "entityRemoval");
+ tileEntityTick = Timings.ofSafe(name + "tileEntityTick");
+ tileEntityPending = Timings.ofSafe(name + "tileEntityPending");
+
+ syncChunkLoadTimer = Timings.ofSafe(name + "syncChunkLoad");
+ syncChunkLoadDataTimer = Timings.ofSafe(name + "syncChunkLoad - Data");
+ syncChunkLoadStructuresTimer = Timings.ofSafe(name + "chunkLoad - recreateStructures");
+ syncChunkLoadPostTimer = Timings.ofSafe(name + "chunkLoad - Post");
+ syncChunkLoadPopulateTimer = Timings.ofSafe(name + "chunkLoad - Populate");
+ chunkLoadLevelTimer = Timings.ofSafe(name + "chunkLoad - Load Level");
+ chunkGeneration = Timings.ofSafe(name + "chunkGeneration");
+ chunkIOStage1 = Timings.ofSafe(name + "ChunkIO Stage 1 - DiskIO");
+ chunkIOStage2 = Timings.ofSafe(name + "ChunkIO Stage 2 - Post Load");
+ worldSave = Timings.ofSafe(name + "World Save");
+ worldSaveLevel = Timings.ofSafe(name + "World Save - Level");
+ worldSaveChunks = Timings.ofSafe(name + "World Save - Chunks");
+ chunkSaveData = Timings.ofSafe(name + "Chunk Save - Data");
+
+ tracker1 = Timings.ofSafe(name + "tracker stage 1");
+ tracker2 = Timings.ofSafe(name + "tracker stage 2");
+ doTick = Timings.ofSafe(name + "doTick");
+ tickEntities = Timings.ofSafe(name + "tickEntities");
+ }
+
+ public static Timing getTickList(WorldServer worldserver, String timingsType) {
+ return Timings.ofSafe(worldserver.getWorldData().getName() + " - Scheduled " + timingsType);
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index b89ec42525..e4ed7d674e 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -14,11 +14,14 @@ import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.regex.Pattern;
+import com.google.common.collect.Lists;
import net.minecraft.server.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
+import co.aikar.timings.Timings;
+import co.aikar.timings.TimingsManager;
public class PaperConfig {
@@ -180,4 +183,24 @@ public class PaperConfig {
config.addDefault(path, def);
return config.getString(path, config.getString(path));
}
+
+ private static void timings() {
+ boolean timings = getBoolean("timings.enabled", true);
+ boolean verboseTimings = getBoolean("timings.verbose", true);
+ TimingsManager.privacy = getBoolean("timings.server-name-privacy", false);
+ TimingsManager.hiddenConfigs = getList("timings.hidden-config-entries", Lists.newArrayList("database", "settings.bungeecord-addresses"));
+ int timingHistoryInterval = getInt("timings.history-interval", 300);
+ int timingHistoryLength = getInt("timings.history-length", 3600);
+
+
+ Timings.setVerboseTimingsEnabled(verboseTimings);
+ Timings.setTimingsEnabled(timings);
+ Timings.setHistoryInterval(timingHistoryInterval * 20);
+ Timings.setHistoryLength(timingHistoryLength * 20);
+
+ log("Timings: " + timings +
+ " - Verbose: " + verboseTimings +
+ " - Interval: " + timeSummary(Timings.getHistoryInterval() / 20) +
+ " - Length: " + timeSummary(Timings.getHistoryLength() / 20));
+ }
}
diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java
index 06f10e1e84..43feccef8f 100644
--- a/src/main/java/net/minecraft/server/Block.java
+++ b/src/main/java/net/minecraft/server/Block.java
@@ -28,8 +28,16 @@ public class Block implements IMaterial {
private IBlockData blockData;
protected final boolean o;
private final boolean p;
- @Nullable
- private String name;
+ @Nullable // Paper start
+ public String name;
+ public co.aikar.timings.Timing timing;
+ public co.aikar.timings.Timing getTiming() {
+ if (timing == null) {
+ timing = co.aikar.timings.MinecraftTimings.getBlockTiming(this);
+ }
+ return timing;
+ }
+ // Paper end
private static final ThreadLocal<Object2ByteLinkedOpenHashMap<Object>> r = ThreadLocal.withInitial(() -> {
Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap = new Object2ByteLinkedOpenHashMap(200) {
protected void rehash(int i) {}
diff --git a/src/main/java/net/minecraft/server/ChunkMap.java b/src/main/java/net/minecraft/server/ChunkMap.java
index 5164e5c928..0c2386f5ec 100644
--- a/src/main/java/net/minecraft/server/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/ChunkMap.java
@@ -14,6 +14,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
}
public Chunk a(long i, Chunk chunk) {
+ chunk.world.timings.syncChunkLoadPostTimer.startTiming(); // Paper
Chunk chunk1 = (Chunk) super.put(i, chunk);
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i);
@@ -55,8 +56,10 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
}
}
}
+ chunk.world.timings.syncChunkLoadPostTimer.stopTiming(); // Paper
if (chunk.newChunk) {
+ chunk.world.timings.syncChunkLoadPopulateTimer.startTiming(); // Paper
BlockSand.instaFall = true;
java.util.Random random = new java.util.Random();
random.setSeed(chunk.world.getSeed());
@@ -77,6 +80,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
}
BlockSand.instaFall = false;
chunk.world.getServer().getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(chunk.bukkitChunk));
+ chunk.world.timings.syncChunkLoadPopulateTimer.stopTiming(); // Paper
}
return chunk1;
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 00cd8d8cea..aabdc9e2f0 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -122,14 +122,13 @@ public class ChunkProviderServer implements IChunkProvider {
if (chunk != null) {
return chunk;
} else {
- try {
- world.timings.syncChunkLoadTimer.startTiming(); // Spigot
+ try (co.aikar.timings.Timing timing = world.timings.chunkGeneration.startTiming()) {
+ ; // Spigot
chunk = (Chunk) this.generateChunk(i, j).get();
return chunk;
} catch (ExecutionException | InterruptedException interruptedexception) {
throw this.a(i, j, (Throwable) interruptedexception);
}
- finally { world.timings.syncChunkLoadTimer.stopTiming(); } // Spigot
}
}
@@ -232,7 +231,7 @@ public class ChunkProviderServer implements IChunkProvider {
}
public void saveChunk(IChunkAccess ichunkaccess, boolean unloaded) { // Spigot
- try {
+ try (co.aikar.timings.Timing timed = world.timings.chunkSaveData.startTiming()) { // Paper - Timings
ichunkaccess.setLastSaved(this.world.getTime());
this.chunkLoader.saveChunk(this.world, ichunkaccess, unloaded); // Spigot
} catch (IOException ioexception) {
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index 88301ee61e..5001fd11dc 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -1,5 +1,6 @@
package net.minecraft.server;
+import co.aikar.timings.Timings;
import com.google.common.collect.Maps;
import com.mojang.datafixers.DataFixTypes;
import com.mojang.datafixers.DataFixer;
@@ -690,7 +691,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
public void loadEntities(NBTTagCompound nbttagcompound, Chunk chunk) {
NBTTagList nbttaglist = nbttagcompound.getList("Entities", 10);
World world = chunk.getWorld();
- world.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot
+ world.timings.chunkLoadLevelTimer.startTiming(); // Spigot
for (int i = 0; i < nbttaglist.size(); ++i) {
NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i);
@@ -699,8 +700,6 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
chunk.f(true);
}
- world.timings.syncChunkLoadEntitiesTimer.stopTiming(); // Spigot
- world.timings.syncChunkLoadTileEntitiesTimer.startTiming(); // Spigot
NBTTagList nbttaglist1 = nbttagcompound.getList("TileEntities", 10);
for (int j = 0; j < nbttaglist1.size(); ++j) {
@@ -717,8 +716,6 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
}
}
}
- world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot
- world.timings.syncChunkLoadTileTicksTimer.startTiming(); // Spigot
if (nbttagcompound.hasKeyOfType("TileTicks", 9) && world.I() instanceof TickListServer) {
((TickListServer) world.I()).a(nbttagcompound.getList("TileTicks", 10));
@@ -727,7 +724,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
if (nbttagcompound.hasKeyOfType("LiquidTicks", 9) && world.H() instanceof TickListServer) {
((TickListServer) world.H()).a(nbttagcompound.getList("LiquidTicks", 10));
}
- world.timings.syncChunkLoadTileTicksTimer.stopTiming(); // Spigot
+ world.timings.chunkLoadLevelTimer.stopTiming(); // Spigot
}
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
index 3706e44a34..bf1fffcfee 100644
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -29,7 +29,7 @@ import org.apache.logging.log4j.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.LoggerOutputStream;
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
+import co.aikar.timings.MinecraftTimings; // Paper
import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.craftbukkit.util.Waitable;
import org.bukkit.event.server.RemoteServerCommandEvent;
@@ -443,7 +443,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
}
public void aW() {
- SpigotTimings.serverCommandTimer.startTiming(); // Spigot
+ MinecraftTimings.serverCommandTimer.startTiming(); // Spigot
while (!this.serverCommandQueue.isEmpty()) {
ServerCommand servercommand = (ServerCommand) this.serverCommandQueue.remove(0);
@@ -458,7 +458,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
// CraftBukkit end
}
- SpigotTimings.serverCommandTimer.stopTiming(); // Spigot
+ MinecraftTimings.serverCommandTimer.stopTiming(); // Spigot
}
public boolean S() {
@@ -708,7 +708,20 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
return remoteControlCommandListener.getMessages();
}
};
- processQueue.add(waitable);
+ // Paper start
+ if (s.toLowerCase().startsWith("timings") && s.toLowerCase().matches("timings (report|paste|get|merged|seperate)")) {
+ org.bukkit.command.BufferedCommandSender sender = new org.bukkit.command.BufferedCommandSender();
+ waitable = new Waitable<String>() {
+ @Override
+ protected String evaluate() {
+ return sender.getBuffer();
+ }
+ };
+ co.aikar.timings.Timings.generateReport(new co.aikar.timings.TimingsReportListener(sender, waitable));
+ } else {
+ processQueue.add(waitable);
+ }
+ // Paper end
try {
return waitable.get();
} catch (java.util.concurrent.ExecutionException e) {
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 5451ab07f5..5c733506d5 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -29,7 +29,8 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Vehicle;
-import org.spigotmc.CustomTimingsHandler; // Spigot
+import co.aikar.timings.MinecraftTimings; // Paper
+import co.aikar.timings.Timing; // Paper
import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.vehicle.VehicleBlockCollisionEvent;
@@ -158,7 +159,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
public boolean valid;
public org.bukkit.projectiles.ProjectileSource projectileSource; // For projectiles only
public boolean forceExplosionKnockback; // SPIGOT-949
- public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot
+ public Timing tickTimer = MinecraftTimings.getEntityTimings(this); // Paper
// Spigot start
public final byte activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
public final boolean defaultActivationState;
@@ -539,7 +540,6 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
public void move(EnumMoveType enummovetype, double d0, double d1, double d2) {
- org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot
if (this.noclip) {
this.a(this.getBoundingBox().d(d0, d1, d2));
this.recalcPosition();
@@ -888,7 +888,6 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
this.world.methodProfiler.e();
}
- org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot
}
protected float ab() {
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index 514c951516..d6e9915c1f 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -32,7 +32,7 @@ import org.bukkit.event.entity.EntityTeleportEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
// CraftBukkit end
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
+import co.aikar.timings.MinecraftTimings; // Paper
public abstract class EntityLiving extends Entity {
@@ -1984,7 +1984,6 @@ public abstract class EntityLiving extends Entity {
}
public void tick() {
- SpigotTimings.timerEntityBaseTick.startTiming(); // Spigot
super.tick();
this.cV();
this.o();
@@ -2058,9 +2057,7 @@ public abstract class EntityLiving extends Entity {
}
}
- SpigotTimings.timerEntityBaseTick.stopTiming(); // Spigot
this.k();
- SpigotTimings.timerEntityTickRest.startTiming(); // Spigot
double d0 = this.locX - this.lastX;
double d1 = this.locZ - this.lastZ;
float f = (float) (d0 * d0 + d1 * d1);
@@ -2136,8 +2133,6 @@ public abstract class EntityLiving extends Entity {
} else {
this.bv = 0;
}
-
- SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot
}
protected float e(float f, float f1) {
@@ -2207,7 +2202,6 @@ public abstract class EntityLiving extends Entity {
}
this.world.methodProfiler.a("ai");
- SpigotTimings.timerEntityAI.startTiming(); // Spigot
if (this.isFrozen()) {
this.bg = false;
this.bh = 0.0F;
@@ -2218,7 +2212,6 @@ public abstract class EntityLiving extends Entity {
this.doTick();
this.world.methodProfiler.e();
}
- SpigotTimings.timerEntityAI.stopTiming(); // Spigot
this.world.methodProfiler.e();
this.world.methodProfiler.a("jump");
@@ -2243,9 +2236,7 @@ public abstract class EntityLiving extends Entity {
this.n();
AxisAlignedBB axisalignedbb = this.getBoundingBox();
- SpigotTimings.timerEntityAIMove.startTiming(); // Spigot
this.a(this.bh, this.bi, this.bj);
- SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot
this.world.methodProfiler.e();
this.world.methodProfiler.a("push");
if (this.bw > 0) {
@@ -2253,9 +2244,7 @@ public abstract class EntityLiving extends Entity {
this.a(axisalignedbb, this.getBoundingBox());
}
- SpigotTimings.timerEntityAICollision.startTiming(); // Spigot
this.cN();
- SpigotTimings.timerEntityAICollision.stopTiming(); // Spigot
this.world.methodProfiler.e();
}
diff --git a/src/main/java/net/minecraft/server/EntityTracker.java b/src/main/java/net/minecraft/server/EntityTracker.java
index ae31935c48..70c9b1f50c 100644
--- a/src/main/java/net/minecraft/server/EntityTracker.java
+++ b/src/main/java/net/minecraft/server/EntityTracker.java
@@ -168,7 +168,7 @@ public class EntityTracker {
public void updatePlayers() {
ArrayList arraylist = Lists.newArrayList();
Iterator iterator = this.c.iterator();
-
+ world.timings.tracker1.startTiming(); // Spigot
while (iterator.hasNext()) {
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
@@ -181,7 +181,9 @@ public class EntityTracker {
}
}
}
+ world.timings.tracker1.stopTiming(); // Spigot
+ world.timings.tracker2.startTiming(); // Spigot
for (int i = 0; i < arraylist.size(); ++i) {
EntityPlayer entityplayer = (EntityPlayer) arraylist.get(i);
Iterator iterator1 = this.c.iterator();
@@ -194,6 +196,7 @@ public class EntityTracker {
}
}
}
+ world.timings.tracker2.stopTiming(); // Spigot
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index d453d0c421..83a73b86ea 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1,5 +1,6 @@
package net.minecraft.server;
+import co.aikar.timings.Timings;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import com.google.common.collect.Queues;
@@ -62,8 +63,8 @@ import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.Main;
// CraftBukkit end
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
import org.spigotmc.SlackActivityAccountant; // Spigot
+import co.aikar.timings.MinecraftTimings; // Paper
public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStatistics, ICommandListener, Runnable {
@@ -599,6 +600,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
}
// CraftBukkit end
MinecraftServer.LOGGER.info("Stopping server");
+ MinecraftTimings.stopServer(); // Paper
// CraftBukkit start
if (this.server != null) {
this.server.disablePlugins();
@@ -805,7 +807,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
public void u() {}
protected void v() {
- SpigotTimings.serverTickTimer.startTiming(); // Spigot
+ co.aikar.timings.TimingsManager.FULL_SERVER_TICK.startTiming(); // Paper
this.slackActivityAccountant.tickStarted(); // Spigot
long i = SystemUtils.c();
@@ -832,7 +834,6 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
}
if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit
- SpigotTimings.worldSaveTimer.startTiming(); // Spigot
this.methodProfiler.a("save");
this.s.savePlayers();
// Spigot Start
@@ -847,7 +848,6 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
// this.saveChunks(true);
// Spigot End
this.methodProfiler.e();
- SpigotTimings.worldSaveTimer.stopTiming(); // Spigot
}
this.methodProfiler.a("snooper");
@@ -868,14 +868,14 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
this.methodProfiler.e();
org.spigotmc.WatchdogThread.tick(); // Spigot
this.slackActivityAccountant.tickEnded(l); // Spigot
- SpigotTimings.serverTickTimer.stopTiming(); // Spigot
- org.spigotmc.CustomTimingsHandler.tick(); // Spigot
+ co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTiming(); // Paper
}
public void w() {
- SpigotTimings.schedulerTimer.startTiming(); // Spigot
+ MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Paper
this.server.getScheduler().mainThreadHeartbeat(this.ticks); // CraftBukkit
- SpigotTimings.schedulerTimer.stopTiming(); // Spigot
+ MinecraftTimings.bukkitSchedulerTimer.stopTiming(); // Paper
+ MinecraftTimings.minecraftSchedulerTimer.startTiming(); // Paper
this.methodProfiler.a("jobs");
FutureTask futuretask;
@@ -883,26 +883,27 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
while ((futuretask = (FutureTask) this.g.poll()) != null) {
SystemUtils.a(futuretask, MinecraftServer.LOGGER);
}
+ MinecraftTimings.minecraftSchedulerTimer.stopTiming(); // Paper
this.methodProfiler.c("commandFunctions");
- SpigotTimings.commandFunctionsTimer.startTiming(); // Spigot
+ MinecraftTimings.commandFunctionsTimer.startTiming(); // Spigot
this.getFunctionData().Y_();
- SpigotTimings.commandFunctionsTimer.stopTiming(); // Spigot
+ MinecraftTimings.commandFunctionsTimer.stopTiming(); // Spigot
this.methodProfiler.c("levels");
// CraftBukkit start
// Run tasks that are waiting on processing
- SpigotTimings.processQueueTimer.startTiming(); // Spigot
+ MinecraftTimings.processQueueTimer.startTiming(); // Spigot
while (!processQueue.isEmpty()) {
processQueue.remove().run();
}
- SpigotTimings.processQueueTimer.stopTiming(); // Spigot
+ MinecraftTimings.processQueueTimer.stopTiming(); // Spigot
- SpigotTimings.chunkIOTickTimer.startTiming(); // Spigot
+ MinecraftTimings.chunkIOTickTimer.startTiming(); // Spigot
org.bukkit.craftbukkit.chunkio.ChunkIOExecutor.tick();
- SpigotTimings.chunkIOTickTimer.stopTiming(); // Spigot
+ MinecraftTimings.chunkIOTickTimer.stopTiming(); // Spigot
- SpigotTimings.timeUpdateTimer.startTiming(); // Spigot
+ MinecraftTimings.timeUpdateTimer.startTiming(); // Spigot
// Send time updates to everyone, it will get the right time from the world the player is in.
if (this.ticks % 20 == 0) {
for (int i = 0; i < this.getPlayerList().players.size(); ++i) {
@@ -910,7 +911,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(entityplayer.world.getTime(), entityplayer.getPlayerTime(), entityplayer.world.getGameRules().getBoolean("doDaylightCycle"))); // Add support for per player time
}
}
- SpigotTimings.timeUpdateTimer.stopTiming(); // Spigot
+ MinecraftTimings.timeUpdateTimer.stopTiming(); // Spigot
int i;
@@ -969,9 +970,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
this.methodProfiler.e();
this.methodProfiler.a("tracker");
- worldserver.timings.tracker.startTiming(); // Spigot
worldserver.getTracker().updatePlayers();
- worldserver.timings.tracker.stopTiming(); // Spigot
this.methodProfiler.e();
this.methodProfiler.e();
}
@@ -980,20 +979,19 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
}
this.methodProfiler.c("connection");
- SpigotTimings.connectionTimer.startTiming(); // Spigot
+ MinecraftTimings.connectionTimer.startTiming(); // Spigot
this.getServerConnection().c();
- SpigotTimings.connectionTimer.stopTiming(); // Spigot
+ MinecraftTimings.connectionTimer.stopTiming(); // Spigot
this.methodProfiler.c("players");
- SpigotTimings.playerListTimer.startTiming(); // Spigot
+ MinecraftTimings.playerListTimer.startTiming(); // Spigot
this.s.tick();
- SpigotTimings.playerListTimer.stopTiming(); // Spigot
+ MinecraftTimings.playerListTimer.stopTiming(); // Spigot
this.methodProfiler.c("tickables");
-
- SpigotTimings.tickablesTimer.startTiming(); // Spigot
+ MinecraftTimings.tickablesTimer.startTiming(); // Spigot
for (i = 0; i < this.l.size(); ++i) {
((ITickable) this.l.get(i)).Y_();
}
- SpigotTimings.tickablesTimer.stopTiming(); // Spigot
+ MinecraftTimings.tickablesTimer.stopTiming(); // Spigot
this.methodProfiler.e();
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index ac6d8cc6e6..d975c2ccf1 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -1,5 +1,6 @@
package net.minecraft.server;
+import co.aikar.timings.Timing;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Lists;
@@ -90,6 +91,7 @@ public class PlayerChunkMap {
PlayerChunk playerchunk;
if (i - this.k > 8000L) {
+ try (Timing ignored = world.timings.doChunkMapUpdate.startTiming()) { // Paper
this.k = i;
for (j = 0; j < this.i.size(); ++j) {
@@ -97,9 +99,11 @@ public class PlayerChunkMap {
playerchunk.d();
playerchunk.c();
}
+ } // Paper timing
}
if (!this.f.isEmpty()) {
+ try (Timing ignored = world.timings.doChunkMapToUpdate.startTiming()) { // Paper
Iterator iterator = this.f.iterator();
while (iterator.hasNext()) {
@@ -108,25 +112,31 @@ public class PlayerChunkMap {
}
this.f.clear();
+ } // Paper timing
}
if (this.l && i % 4L == 0L) {
this.l = false;
+ try (Timing ignored = world.timings.doChunkMapSortMissing.startTiming()) { // Paper
// CraftBukkit start
Collections.sort(this.h, (playerchunkx, playerchunk1x) -> {
return ComparisonChain.start().compare(playerchunkx.g(), playerchunk1x.g()).result();
});
+ } // Paper timing
}
if (this.m && i % 4L == 2L) {
this.m = false;
+ try (Timing ignored = world.timings.doChunkMapSortSendToPlayers.startTiming()) { // Paper
Collections.sort(this.g, (playerchunkx, playerchunk1x) -> {
return ComparisonChain.start().compare(playerchunkx.g(), playerchunk1x.g()).result();
});
+ } // Paper timing
// CraftBukkit end
}
if (!this.h.isEmpty()) {
+ try (Timing ignored = world.timings.doChunkMapPlayersNeedingChunks.startTiming()) { // Paper
// Spigot start
org.spigotmc.SlackActivityAccountant activityAccountant = this.world.getMinecraftServer().slackActivityAccountant;
activityAccountant.startActivity(0.5);
@@ -158,10 +168,12 @@ public class PlayerChunkMap {
}
activityAccountant.endActivity(); // Spigot
+ } // Paper timing
}
if (!this.g.isEmpty()) {
j = 81;
+ try (Timing ignored = world.timings.doChunkMapPendingSendToPlayers.startTiming()) { // Paper
Iterator iterator2 = this.g.iterator();
while (iterator2.hasNext()) {
@@ -175,14 +187,17 @@ public class PlayerChunkMap {
}
}
}
+ } // Paper timing
}
if (this.managedPlayers.isEmpty()) {
+ try (Timing ignored = world.timings.doChunkMapUnloadChunks.startTiming()) { // Paper
WorldProvider worldprovider = this.world.worldProvider;
if (!worldprovider.p()) {
this.world.getChunkProviderServer().b();
}
+ } // Paper timing
}
}
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index 42e0630e60..5d42cfe81c 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -57,6 +57,7 @@ import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.InventoryView;
import org.bukkit.util.NumberConversions;
+import co.aikar.timings.MinecraftTimings; // Paper
// CraftBukkit end
public class PlayerConnection implements PacketListenerPlayIn, ITickable {
@@ -1615,7 +1616,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
// CraftBukkit end
private void handleCommand(String s) {
- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot
+ MinecraftTimings.playerCommandTimer.startTiming(); // Paper
// CraftBukkit start - whole method
if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot
this.LOGGER.info(this.player.getName() + " issued server command: " + s);
@@ -1626,7 +1627,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
this.server.getPluginManager().callEvent(event);
if (event.isCancelled()) {
- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot
+ MinecraftTimings.playerCommandTimer.stopTiming(); // Paper
return;
}
@@ -1639,7 +1640,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
java.util.logging.Logger.getLogger(PlayerConnection.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
return;
} finally {
- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot
+ MinecraftTimings.playerCommandTimer.stopTiming(); // Paper
}
// this.minecraftServer.getCommandDispatcher().a(this.player.getCommandListener(), s);
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/PlayerConnectionUtils.java b/src/main/java/net/minecraft/server/PlayerConnectionUtils.java
index 889b32287e..69da194f52 100644
--- a/src/main/java/net/minecraft/server/PlayerConnectionUtils.java
+++ b/src/main/java/net/minecraft/server/PlayerConnectionUtils.java
@@ -1,11 +1,17 @@
package net.minecraft.server;
+import co.aikar.timings.MinecraftTimings; // Paper
+import co.aikar.timings.Timing; // Paper
+
public class PlayerConnectionUtils {
- public static <T extends PacketListener> void ensureMainThread(Packet<T> packet, T t0, IAsyncTaskHandler iasynctaskhandler) throws CancelledPacketHandleException {
+ public static <T extends PacketListener> void ensureMainThread(Packet<T> packet, T packetlistener, IAsyncTaskHandler iasynctaskhandler) throws CancelledPacketHandleException { // Paper fix name of param
if (!iasynctaskhandler.isMainThread()) {
+ Timing timing = MinecraftTimings.getPacketTiming(packet); // Paper
iasynctaskhandler.postToMainThread(() -> {
+ try (Timing ignored = timing.startTiming()) { // Paper
packet.a(packetlistener);
+ }
});
throw CancelledPacketHandleException.INSTANCE;
}
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index e476d3433b..9cef6b9af6 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -1,5 +1,6 @@
package net.minecraft.server;
+import co.aikar.timings.MinecraftTimings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -1179,10 +1180,11 @@ public abstract class PlayerList {
}
public void savePlayers() {
+ MinecraftTimings.savePlayers.startTiming(); // Paper
for (int i = 0; i < this.players.size(); ++i) {
this.savePlayerFile((EntityPlayer) this.players.get(i));
}
-
+ MinecraftTimings.savePlayers.stopTiming(); // Paper
}
public WhiteList getWhitelist() {
diff --git a/src/main/java/net/minecraft/server/TickListServer.java b/src/main/java/net/minecraft/server/TickListServer.java
index a07895935e..ee5c2421bb 100644
--- a/src/main/java/net/minecraft/server/TickListServer.java
+++ b/src/main/java/net/minecraft/server/TickListServer.java
@@ -24,13 +24,19 @@ public class TickListServer<T> implements TickList<T> {
private final List<NextTickListEntry<T>> g = Lists.newArrayList();
private final Consumer<NextTickListEntry<T>> h;
- public TickListServer(WorldServer worldserver, Predicate<T> predicate, Function<T, MinecraftKey> function, Function<MinecraftKey, T> function1, Consumer<NextTickListEntry<T>> consumer) {
+ public TickListServer(WorldServer worldserver, Predicate<T> predicate, Function<T, MinecraftKey> function, Function<MinecraftKey, T> function1, Consumer<NextTickListEntry<T>> consumer, String timingsType) { // Paper
this.a = predicate;
this.b = function;
this.c = function1;
this.f = worldserver;
this.h = consumer;
+ // Paper start
+ timingCleanup = co.aikar.timings.WorldTimingsHandler.getTickList(worldserver, timingsType + " - Cleanup");
+ timingTicking = co.aikar.timings.WorldTimingsHandler.getTickList(worldserver, timingsType + " - Ticking");
}
+ private final co.aikar.timings.Timing timingCleanup; // Paper
+ private final co.aikar.timings.Timing timingTicking; // Paper
+ // Paper end
public void a() {
int i = this.nextTickList.size();
@@ -49,7 +55,7 @@ public class TickListServer<T> implements TickList<T> {
}
this.f.methodProfiler.a("cleaning");
-
+ timingCleanup.startTiming(); // Paper
NextTickListEntry<T> nextticklistentry; // CraftBukkit - decompile error
for (int j = 0; j < i; ++j) {
@@ -62,9 +68,11 @@ public class TickListServer<T> implements TickList<T> {
// this.nextTickListHash.remove(nextticklistentry); // CraftBukkit - use nextTickList
this.g.add(nextticklistentry);
}
+ timingCleanup.stopTiming(); // Paper
this.f.methodProfiler.e();
this.f.methodProfiler.a("ticking");
+ timingTicking.startTiming(); // Paper
Iterator iterator = this.g.iterator();
while (iterator.hasNext()) {
@@ -89,6 +97,7 @@ public class TickListServer<T> implements TickList<T> {
this.f.methodProfiler.e();
this.g.clear();
+ timingTicking.stopTiming(); // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
index 9361667c3b..0d54513a44 100644
--- a/src/main/java/net/minecraft/server/TileEntity.java
+++ b/src/main/java/net/minecraft/server/TileEntity.java
@@ -4,12 +4,13 @@ import javax.annotation.Nullable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import org.spigotmc.CustomTimingsHandler; // Spigot
+import co.aikar.timings.MinecraftTimings; // Paper
+import co.aikar.timings.Timing; // Paper
import org.bukkit.inventory.InventoryHolder; // CraftBukkit
public abstract class TileEntity implements KeyedObject { // Paper
- public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot
+ public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper
private static final Logger a = LogManager.getLogger();
private final TileEntityTypes<?> e; public TileEntityTypes getTileEntityType() { return e; } // Paper - OBFHELPER
protected World world;
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index e1cf1e579a..3cb7c1d540 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1,5 +1,6 @@
package net.minecraft.server;
+import co.aikar.timings.Timings;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Lists;
import java.util.ArrayList;
@@ -20,13 +21,13 @@ import com.google.common.collect.Maps;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.block.BlockState;
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.block.CraftBlockState;
import org.bukkit.craftbukkit.block.data.CraftBlockData;
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
+import org.bukkit.craftbukkit.util.LongHashSet; // Paper
import org.bukkit.event.block.BlockCanBuildEvent;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
@@ -129,7 +130,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
public final com.destroystokyo.paper.PaperWorldConfig paperConfig; // Paper
- public final SpigotTimings.WorldTimingsHandler timings; // Spigot
+ public final co.aikar.timings.WorldTimingsHandler timings; // Paper
private boolean guardEntityList; // Spigot
public static boolean haveWeSilencedAPhysicsCrash;
public static String blockLocation;
@@ -197,7 +198,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
});
this.getServer().addWorld(this.world);
// CraftBukkit end
- timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings
+ timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - 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);
}
@@ -1110,6 +1111,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
}
this.methodProfiler.c("remove");
+ timings.entityRemoval.startTiming(); // Paper
this.entityList.removeAll(this.g);
int j;
@@ -1130,6 +1132,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
this.g.clear();
this.p_();
+ timings.entityRemoval.stopTiming(); // Paper
this.methodProfiler.c("regular");
CrashReportSystemDetails crashreportsystemdetails1;
@@ -1139,6 +1142,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
timings.entityTick.startTiming(); // Spigot
guardEntityList = true; // Spigot
// CraftBukkit start - Use field for loop variable
+ co.aikar.timings.TimingHistory.entityTicks += this.entityList.size(); // Paper
int entitiesThisCycle = 0;
if (tickPosition < 0) tickPosition = 0;
for (entityLimiter.initTick();
@@ -1160,10 +1164,11 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
this.methodProfiler.a("tick");
if (!entity.dead && !(entity instanceof EntityPlayer)) {
try {
- SpigotTimings.tickEntityTimer.startTiming(); // Spigot
+ entity.tickTimer.startTiming(); // Paper
this.g(entity);
- SpigotTimings.tickEntityTimer.stopTiming(); // Spigot
+ entity.tickTimer.stopTiming(); // Paper
} catch (Throwable throwable1) {
+ entity.tickTimer.stopTiming();
crashreport1 = CrashReport.a(throwable1, "Ticking entity");
crashreportsystemdetails1 = crashreport1.a("Entity being ticked");
entity.appendEntityCrashDetails(crashreportsystemdetails1);
@@ -1288,6 +1293,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
}
timings.tileEntityPending.stopTiming(); // Spigot
+ co.aikar.timings.TimingHistory.tileEntityTicks += this.tileEntityListTick.size(); // Paper
this.methodProfiler.e();
this.methodProfiler.e();
}
@@ -1346,7 +1352,6 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
}
// CraftBukkit end
- entity.tickTimer.startTiming(); // Spigot
entity.N = entity.locX;
entity.O = entity.locY;
entity.P = entity.locZ;
@@ -1354,6 +1359,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
entity.lastPitch = entity.pitch;
if (flag && entity.inChunk) {
++entity.ticksLived;
+ ++co.aikar.timings.TimingHistory.activatedEntityTicks; // Paper
if (entity.isPassenger()) {
entity.aH();
} else {
@@ -1417,8 +1423,6 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
}
}
}
- entity.tickTimer.stopTiming(); // Spigot
-
}
public boolean a(@Nullable Entity entity, VoxelShape voxelshape) {
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 2c6f6de4ce..f032ecab64 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -1,5 +1,6 @@
package net.minecraft.server;
+import co.aikar.timings.Timings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.ListenableFuture;
@@ -70,7 +71,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
RegistryBlocks<MinecraftKey, Block> registryblocks1 = Block.REGISTRY; // CraftBukkit - decompile error
Block.REGISTRY.getClass();
- this.nextTickListBlock = new TickListServer<>(this, predicate, function, registryblocks1::get, this::b); // CraftBukkit - decompile error
+ this.nextTickListBlock = new TickListServer<>(this, predicate, function, registryblocks1::get, this::b, "Blocks"); // CraftBukkit - decompile error // Paper - Timings v2
Predicate<FluidType> predicate2 = (fluidtype) -> {
return fluidtype == null || fluidtype == FluidTypes.a;
};
@@ -79,7 +80,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
function = registryblocks::b;
RegistryBlocks<MinecraftKey, FluidType> registryblocks2 = FluidType.c; // CraftBukkit - decompile error
FluidType.c.getClass();
- this.nextTickListFluid = new TickListServer<>(this, predicate2, function, registryblocks2::get, this::a); // CraftBukkit - decompile error
+ this.nextTickListFluid = new TickListServer<>(this, predicate2, function, registryblocks2::get, this::a, "Fluids"); // CraftBukkit - decompile error // Paper - Timings v2
this.siegeManager = new VillageSiege(this);
this.d = new ObjectLinkedOpenHashSet();
this.server = minecraftserver;
@@ -297,13 +298,13 @@ public class WorldServer extends World implements IAsyncTaskHandler {
timings.doChunkUnload.stopTiming(); // Spigot
this.methodProfiler.c("tickPending");
- timings.doTickPending.startTiming(); // Spigot
+ timings.scheduledBlocks.startTiming(); // Paper
this.p();
- timings.doTickPending.stopTiming(); // Spigot
+ timings.scheduledBlocks.stopTiming(); // Paper
this.methodProfiler.c("tickBlocks");
- timings.doTickTiles.startTiming(); // Spigot
+ timings.chunkTicks.startTiming(); // Paper
this.l();
- timings.doTickTiles.stopTiming(); // Spigot
+ timings.chunkTicks.stopTiming(); // Paper
this.methodProfiler.c("chunkMap");
timings.doChunkMap.startTiming(); // Spigot
this.manager.flush();
@@ -532,7 +533,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
}
- this.methodProfiler.c("tickBlocks");
+ timings.chunkTicksBlocks.startTiming(); // Paper
if (i > 0) {
ChunkSection[] achunksection = chunk.getSections();
int i1 = achunksection.length;
@@ -564,6 +565,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
}
}
+ timings.chunkTicksBlocks.stopTiming(); // Paper
}
this.methodProfiler.e();
@@ -717,7 +719,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
gen = new org.bukkit.craftbukkit.generator.NormalChunkGenerator(this, this.getSeed());
}
- return new ChunkProviderServer(this, ichunkloader, gen, this.server);
+ return new ChunkProviderServer(this, ichunkloader, new co.aikar.timings.TimedChunkGenerator(this, gen), this.server); // Paper
// CraftBukkit end
}
@@ -869,6 +871,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
if (chunkproviderserver.e()) {
org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit
+ timings.worldSave.startTiming(); // Paper
if (iprogressupdate != null) {
iprogressupdate.a(new ChatMessage("menu.savingLevel", new Object[0]));
}
@@ -878,7 +881,9 @@ public class WorldServer extends World implements IAsyncTaskHandler {
iprogressupdate.c(new ChatMessage("menu.savingChunks", new Object[0]));
}
+ timings.worldSaveChunks.startTiming(); // Paper
chunkproviderserver.a(flag);
+ timings.worldSaveChunks.stopTiming(); // Paper
// CraftBukkit - ArrayList -> Collection
Collection arraylist = chunkproviderserver.a();
Iterator iterator = arraylist.iterator();
@@ -890,7 +895,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
chunkproviderserver.unload(chunk);
}
}
-
+ timings.worldSave.stopTiming(); // Paper
}
}
@@ -903,6 +908,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
protected void a() throws ExceptionWorldConflict {
+ timings.worldSaveLevel.startTiming(); // Paper
this.checkSession();
WorldServer[] aworldserver = this.server.worldServer;
int i = aworldserver.length;
@@ -933,6 +939,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
this.worldData.c(this.server.aR().c());
this.dataManager.saveWorldData(this.worldData, this.server.getPlayerList().t());
this.worldMaps.a();
+ timings.worldSaveLevel.stopTiming(); // Paper
}
// CraftBukkit start
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 4c1486a38e..ebc2d690b0 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1839,12 +1839,31 @@ public final class CraftServer implements Server {
private final Spigot spigot = new Spigot()
{
+ @Deprecated
@Override
public YamlConfiguration getConfig()
{
return org.spigotmc.SpigotConfig.config;
}
+ @Override
+ public YamlConfiguration getBukkitConfig()
+ {
+ return configuration;
+ }
+
+ @Override
+ public YamlConfiguration getSpigotConfig()
+ {
+ return org.spigotmc.SpigotConfig.config;
+ }
+
+ @Override
+ public YamlConfiguration getPaperConfig()
+ {
+ return com.destroystokyo.paper.PaperConfig.config;
+ }
+
@Override
public void restart() {
org.spigotmc.RestartCommand.restart();
diff --git a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
deleted file mode 100644
index 4c8ab2bc97..0000000000
--- a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
+++ /dev/null
@@ -1,174 +0,0 @@
-package org.bukkit.craftbukkit;
-
-import com.google.common.collect.Maps;
-import net.minecraft.server.*;
-import org.bukkit.plugin.java.JavaPluginLoader;
-import org.spigotmc.CustomTimingsHandler;
-import org.bukkit.scheduler.BukkitTask;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.bukkit.craftbukkit.scheduler.CraftTask;
-
-public class SpigotTimings {
-
- public static final CustomTimingsHandler serverTickTimer = new CustomTimingsHandler("** Full Server Tick");
- public static final CustomTimingsHandler playerListTimer = new CustomTimingsHandler("Player List");
- public static final CustomTimingsHandler commandFunctionsTimer = new CustomTimingsHandler("Command Functions");
- public static final CustomTimingsHandler connectionTimer = new CustomTimingsHandler("Connection Handler");
- public static final CustomTimingsHandler tickablesTimer = new CustomTimingsHandler("Tickables");
- public static final CustomTimingsHandler schedulerTimer = new CustomTimingsHandler("Scheduler");
- public static final CustomTimingsHandler chunkIOTickTimer = new CustomTimingsHandler("ChunkIOTick");
- public static final CustomTimingsHandler timeUpdateTimer = new CustomTimingsHandler("Time Update");
- public static final CustomTimingsHandler serverCommandTimer = new CustomTimingsHandler("Server Command");
- public static final CustomTimingsHandler worldSaveTimer = new CustomTimingsHandler("World Save");
-
- public static final CustomTimingsHandler entityMoveTimer = new CustomTimingsHandler("** entityMove");
- public static final CustomTimingsHandler tickEntityTimer = new CustomTimingsHandler("** tickEntity");
- public static final CustomTimingsHandler activatedEntityTimer = new CustomTimingsHandler("** activatedTickEntity");
- public static final CustomTimingsHandler tickTileEntityTimer = new CustomTimingsHandler("** tickTileEntity");
-
- public static final CustomTimingsHandler timerEntityBaseTick = new CustomTimingsHandler("** livingEntityBaseTick");
- public static final CustomTimingsHandler timerEntityAI = new CustomTimingsHandler("** livingEntityAI");
- public static final CustomTimingsHandler timerEntityAICollision = new CustomTimingsHandler("** livingEntityAICollision");
- public static final CustomTimingsHandler timerEntityAIMove = new CustomTimingsHandler("** livingEntityAIMove");
- public static final CustomTimingsHandler timerEntityTickRest = new CustomTimingsHandler("** livingEntityTickRest");
-
- public static final CustomTimingsHandler processQueueTimer = new CustomTimingsHandler("processQueue");
- public static final CustomTimingsHandler schedulerSyncTimer = new CustomTimingsHandler("** Scheduler - Sync Tasks", JavaPluginLoader.pluginParentTimer);
-
- public static final CustomTimingsHandler playerCommandTimer = new CustomTimingsHandler("** playerCommand");
-
- public static final CustomTimingsHandler entityActivationCheckTimer = new CustomTimingsHandler("entityActivationCheck");
- public static final CustomTimingsHandler checkIfActiveTimer = new CustomTimingsHandler("** checkIfActive");
-
- public static final HashMap<String, CustomTimingsHandler> entityTypeTimingMap = new HashMap<String, CustomTimingsHandler>();
- public static final HashMap<String, CustomTimingsHandler> tileEntityTypeTimingMap = new HashMap<String, CustomTimingsHandler>();
- public static final HashMap<String, CustomTimingsHandler> pluginTaskTimingMap = new HashMap<String, CustomTimingsHandler>();
-
- /**
- * Gets a timer associated with a plugins tasks.
- * @param task
- * @param period
- * @return
- */
- public static CustomTimingsHandler getPluginTaskTimings(BukkitTask task, long period) {
- if (!task.isSync()) {
- return null;
- }
- String plugin;
- final CraftTask ctask = (CraftTask) task;
-
- if (task.getOwner() != null) {
- plugin = task.getOwner().getDescription().getFullName();
- } else if (ctask.timingName != null) {
- plugin = "CraftScheduler";
- } else {
- plugin = "Unknown";
- }
- String taskname = ctask.getTaskName();
-
- String name = "Task: " + plugin + " Runnable: " + taskname;
- if (period > 0) {
- name += "(interval:" + period +")";
- } else {
- name += "(Single)";
- }
- CustomTimingsHandler result = pluginTaskTimingMap.get(name);
- if (result == null) {
- result = new CustomTimingsHandler(name, SpigotTimings.schedulerSyncTimer);
- pluginTaskTimingMap.put(name, result);
- }
- return result;
- }
-
- /**
- * Get a named timer for the specified entity type to track type specific timings.
- * @param entity
- * @return
- */
- public static CustomTimingsHandler getEntityTimings(Entity entity) {
- String entityType = entity.getClass().getName();
- CustomTimingsHandler result = entityTypeTimingMap.get(entityType);
- if (result == null) {
- result = new CustomTimingsHandler("** tickEntity - " + entity.getClass().getSimpleName(), activatedEntityTimer);
- entityTypeTimingMap.put(entityType, result);
- }
- return result;
- }
-
- /**
- * Get a named timer for the specified tile entity type to track type specific timings.
- * @param entity
- * @return
- */
- public static CustomTimingsHandler getTileEntityTimings(TileEntity entity) {
- String entityType = entity.getClass().getName();
- CustomTimingsHandler result = tileEntityTypeTimingMap.get(entityType);
- if (result == null) {
- result = new CustomTimingsHandler("** tickTileEntity - " + entity.getClass().getSimpleName(), tickTileEntityTimer);
- tileEntityTypeTimingMap.put(entityType, result);
- }
- return result;
- }
-
- /**
- * Set of timers per world, to track world specific timings.
- */
- public static class WorldTimingsHandler {
- public final CustomTimingsHandler mobSpawn;
- public final CustomTimingsHandler doChunkUnload;
- public final CustomTimingsHandler doPortalForcer;
- public final CustomTimingsHandler doTickPending;
- public final CustomTimingsHandler doTickTiles;
- public final CustomTimingsHandler doVillages;
- public final CustomTimingsHandler doChunkMap;
- public final CustomTimingsHandler doChunkGC;
- public final CustomTimingsHandler doSounds;
- public final CustomTimingsHandler entityTick;
- public final CustomTimingsHandler tileEntityTick;
- public final CustomTimingsHandler tileEntityPending;
- public final CustomTimingsHandler tracker;
- public final CustomTimingsHandler doTick;
- public final CustomTimingsHandler tickEntities;
-
- public final CustomTimingsHandler syncChunkLoadTimer;
- public final CustomTimingsHandler syncChunkLoadDataTimer;
- public final CustomTimingsHandler syncChunkLoadStructuresTimer;
- public final CustomTimingsHandler syncChunkLoadEntitiesTimer;
- public final CustomTimingsHandler syncChunkLoadTileEntitiesTimer;
- public final CustomTimingsHandler syncChunkLoadTileTicksTimer;
- public final CustomTimingsHandler syncChunkLoadPostTimer;
-
- public WorldTimingsHandler(World server) {
- String name = server.worldData.getName() +" - ";
-
- mobSpawn = new CustomTimingsHandler("** " + name + "mobSpawn");
- doChunkUnload = new CustomTimingsHandler("** " + name + "doChunkUnload");
- doTickPending = new CustomTimingsHandler("** " + name + "doTickPending");
- doTickTiles = new CustomTimingsHandler("** " + name + "doTickTiles");
- doVillages = new CustomTimingsHandler("** " + name + "doVillages");
- doChunkMap = new CustomTimingsHandler("** " + name + "doChunkMap");
- doSounds = new CustomTimingsHandler("** " + name + "doSounds");
- doChunkGC = new CustomTimingsHandler("** " + name + "doChunkGC");
- doPortalForcer = new CustomTimingsHandler("** " + name + "doPortalForcer");
- entityTick = new CustomTimingsHandler("** " + name + "entityTick");
- tileEntityTick = new CustomTimingsHandler("** " + name + "tileEntityTick");
- tileEntityPending = new CustomTimingsHandler("** " + name + "tileEntityPending");
-
- syncChunkLoadTimer = new CustomTimingsHandler("** " + name + "syncChunkLoad");
- syncChunkLoadDataTimer = new CustomTimingsHandler("** " + name + "syncChunkLoad - Data");
- syncChunkLoadStructuresTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Structures");
- syncChunkLoadEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Entities");
- syncChunkLoadTileEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileEntities");
- syncChunkLoadTileTicksTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileTicks");
- syncChunkLoadPostTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Post");
-
-
- tracker = new CustomTimingsHandler(name + "tracker");
- doTick = new CustomTimingsHandler(name + "doTick");
- tickEntities = new CustomTimingsHandler(name + "tickEntities");
- }
- }
-}
diff --git a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java
index 413dd35f06..52a8c48fa4 100644
--- a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java
+++ b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java
@@ -1,6 +1,8 @@
package org.bukkit.craftbukkit.chunkio;
import java.io.IOException;
+
+import co.aikar.timings.Timing;
import net.minecraft.server.Chunk;
import net.minecraft.server.ChunkCoordIntPair;
import net.minecraft.server.ChunkRegionLoader;
@@ -16,7 +18,7 @@ class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChu
// async stuff
public Chunk callStage1(QueuedChunk queuedChunk) throws RuntimeException {
- try {
+ try (Timing ignored = queuedChunk.provider.world.timings.chunkIOStage1.startTimingIfSync()) { // Paper
ChunkRegionLoader loader = queuedChunk.loader;
Object[] data = loader.loadChunk(queuedChunk.world, queuedChunk.x, queuedChunk.z, (chunk) -> {});
@@ -38,11 +40,13 @@ class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChu
// queuedChunk.provider.originalGetChunkAt(queuedChunk.x, queuedChunk.z);
return;
}
+ try (Timing ignored = queuedChunk.provider.world.timings.chunkIOStage2.startTimingIfSync()) { // Paper
queuedChunk.loader.loadEntities(queuedChunk.compound.getCompound("Level"), chunk);
chunk.setLastSaved(queuedChunk.provider.world.getTime());
queuedChunk.provider.chunks.put(ChunkCoordIntPair.a(queuedChunk.x, queuedChunk.z), chunk);
chunk.addEntities();
+ } // Paper
}
public void callStage3(QueuedChunk queuedChunk, Chunk chunk, Runnable runnable) throws RuntimeException {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 2d09bb4fab..3dc76f7dd6 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1708,6 +1708,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
packet.components = components;
getHandle().playerConnection.sendPacket(packet);
}
+
+ @Override
+ public int getPing()
+ {
+ return getHandle().ping;
+ }
};
public Player.Spigot spigot()
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index f11bd7545f..93b9134d6e 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
+import co.aikar.timings.MinecraftTimings; // Paper
import org.apache.commons.lang.Validate;
import org.bukkit.plugin.IllegalPluginAccessException;
import org.bukkit.plugin.Plugin;
@@ -193,7 +194,7 @@ public class CraftScheduler implements BukkitScheduler {
}
}
return false;
- }});
+ }}){{this.timings=co.aikar.timings.MinecraftTimings.getCancelTasksTimer();}}; // Paper
handle(task, 0L);
for (CraftTask taskPending = head.getNext(); taskPending != null; taskPending = taskPending.getNext()) {
if (taskPending == task) {
@@ -226,7 +227,7 @@ public class CraftScheduler implements BukkitScheduler {
}
}
}
- });
+ }){{this.timings=co.aikar.timings.MinecraftTimings.getCancelTasksTimer(plugin);}}; // Paper
handle(task, 0L);
for (CraftTask taskPending = head.getNext(); taskPending != null; taskPending = taskPending.getNext()) {
if (taskPending == task) {
@@ -258,7 +259,7 @@ public class CraftScheduler implements BukkitScheduler {
CraftScheduler.this.pending.clear();
CraftScheduler.this.temp.clear();
}
- });
+ }){{this.timings=co.aikar.timings.MinecraftTimings.getCancelTasksTimer();}}; // Paper
handle(task, 0L);
for (CraftTask taskPending = head.getNext(); taskPending != null; taskPending = taskPending.getNext()) {
if (taskPending == task) {
@@ -357,9 +358,7 @@ public class CraftScheduler implements BukkitScheduler {
if (task.isSync()) {
currentTask = task;
try {
- task.timings.startTiming(); // Spigot
task.run();
- task.timings.stopTiming(); // Spigot
} catch (final Throwable throwable) {
task.getOwner().getLogger().log(
Level.WARNING,
@@ -386,8 +385,10 @@ public class CraftScheduler implements BukkitScheduler {
runners.remove(task.getTaskId());
}
}
+ MinecraftTimings.bukkitSchedulerFinishTimer.startTiming();
pending.addAll(temp);
temp.clear();
+ MinecraftTimings.bukkitSchedulerFinishTimer.stopTiming();
debugHead = debugHead.getNextHead(currentTick);
}
@@ -419,6 +420,7 @@ public class CraftScheduler implements BukkitScheduler {
}
private void parsePending() {
+ MinecraftTimings.bukkitSchedulerPendingTimer.startTiming();
CraftTask head = this.head;
CraftTask task = head.getNext();
CraftTask lastTask = head;
@@ -437,6 +439,7 @@ public class CraftScheduler implements BukkitScheduler {
task.setNext(null);
}
this.head = lastTask;
+ MinecraftTimings.bukkitSchedulerPendingTimer.stopTiming();
}
private boolean isReady(final int currentTick) {
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
index 7e7ce9a81b..46029ce246 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
@@ -1,8 +1,8 @@
package org.bukkit.craftbukkit.scheduler;
import org.bukkit.Bukkit;
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
-import org.spigotmc.CustomTimingsHandler; // Spigot
+import co.aikar.timings.MinecraftTimings; // Paper
+import co.aikar.timings.Timing; // Paper
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitTask;
@@ -25,11 +25,11 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
*/
private volatile long period;
private long nextRun;
- private final Runnable task;
+ public final Runnable task; // Paper
+ public Timing timings; // Paper
private final Plugin plugin;
private final int id;
- final CustomTimingsHandler timings; // Spigot
CraftTask() {
this(null, null, CraftTask.NO_REPEATING, CraftTask.NO_REPEATING);
}
@@ -38,26 +38,12 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
this(null, task, CraftTask.NO_REPEATING, CraftTask.NO_REPEATING);
}
- // Spigot start
- public String timingName = null;
- CraftTask(String timingName) {
- this(timingName, null, null, -1, -1);
- }
- CraftTask(String timingName, final Runnable task) {
- this(timingName, null, task, -1, -1);
- }
- CraftTask(String timingName, final Plugin plugin, final Runnable task, final int id, final long period) {
+ CraftTask(final Plugin plugin, final Runnable task, final int id, final long period) { // Paper
this.plugin = plugin;
this.task = task;
this.id = id;
this.period = period;
- this.timingName = timingName == null && task == null ? "Unknown" : timingName;
- timings = this.isSync() ? SpigotTimings.getPluginTaskTimings(this, period) : null;
- }
-
- CraftTask(final Plugin plugin, final Runnable task, final int id, final long period) {
- this(null, plugin, task, id, period);
- // Spigot end
+ timings = task != null ? MinecraftTimings.getPluginTaskTimings(this, period) : null; // Paper
}
public final int getTaskId() {
@@ -73,7 +59,9 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
}
public void run() {
+ if (timings != null && isSync()) timings.startTiming(); // Paper
task.run();
+ if (timings != null && isSync()) timings.stopTiming(); // Paper
}
long getPeriod() {
@@ -122,13 +110,4 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
setPeriod(CraftTask.CANCEL);
return true;
}
-
- // Spigot start
- public String getTaskName() {
- if (timingName != null) {
- return timingName;
- }
- return task.getClass().getName();
- }
- // Spigot end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java b/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java
index e52ef47b78..3d90b34268 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java
@@ -5,6 +5,7 @@ import org.bukkit.util.CachedServerIcon;
public class CraftIconCache implements CachedServerIcon {
public final String value;
+ public String getData() { return value; } // Paper
public CraftIconCache(final String value) {
this.value = value;
}
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
index e60fe5a920..f68e42c4d4 100644
--- a/src/main/java/org/spigotmc/ActivationRange.java
+++ b/src/main/java/org/spigotmc/ActivationRange.java
@@ -30,7 +30,7 @@ import net.minecraft.server.EntityWither;
import net.minecraft.server.MathHelper;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.World;
-import org.bukkit.craftbukkit.SpigotTimings;
+import co.aikar.timings.MinecraftTimings;
public class ActivationRange
{
@@ -64,8 +64,8 @@ public class ActivationRange
/**
* These entities are excluded from Activation range checks.
*
- * @param entity
- * @param world
+ * @param entity Entity to initialize
+ * @param config Spigot config to determine ranges
* @return boolean If it should always tick.
*/
public static boolean initializeEntityActivationState(Entity entity, SpigotWorldConfig config)
@@ -99,7 +99,7 @@ public class ActivationRange
*/
public static void activateEntities(World world)
{
- SpigotTimings.entityActivationCheckTimer.startTiming();
+ MinecraftTimings.entityActivationCheckTimer.startTiming();
final int miscActivationRange = world.spigotConfig.miscActivationRange;
final int animalActivationRange = world.spigotConfig.animalActivationRange;
final int monsterActivationRange = world.spigotConfig.monsterActivationRange;
@@ -133,7 +133,7 @@ public class ActivationRange
}
}
}
- SpigotTimings.entityActivationCheckTimer.stopTiming();
+ MinecraftTimings.entityActivationCheckTimer.stopTiming();
}
/**
@@ -247,10 +247,8 @@ public class ActivationRange
*/
public static boolean checkIfActive(Entity entity)
{
- SpigotTimings.checkIfActiveTimer.startTiming();
// Never safe to skip fireworks or entities not yet added to chunk
if ( !entity.inChunk || entity instanceof EntityFireworks ) {
- SpigotTimings.checkIfActiveTimer.stopTiming();
return true;
}
@@ -282,7 +280,6 @@ public class ActivationRange
{
isActive = false;
}
- SpigotTimings.checkIfActiveTimer.stopTiming();
return isActive;
}
}
--
2.18.0