Paper/Spigot-Server-Patches/0009-Timings-v2.patch

2310 lines
109 KiB
Diff
Raw Normal View History

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
2016-03-03 10:46:26 +01:00
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
2016-01-10 08:33:27 +01:00
new file mode 100644
index 0000000000000000000000000000000000000000..fed920e5ec65409377f181d74dcf9274d45aadc1
2016-01-10 08:33:27 +01:00
--- /dev/null
+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java
@@ -0,0 +1,151 @@
2018-09-03 16:38:28 +02:00
+package co.aikar.timings;
2016-01-10 08:33:27 +01:00
+
+import com.google.common.collect.MapMaker;
+import net.minecraft.commands.CustomFunction;
+import net.minecraft.network.protocol.Packet;
+import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.block.entity.TileEntity;
2016-01-10 08:33:27 +01:00
+import org.bukkit.plugin.Plugin;
+import org.bukkit.scheduler.BukkitTask;
+
+import org.bukkit.craftbukkit.scheduler.CraftTask;
+
+import java.util.Map;
+
2019-04-24 03:00:24 +02:00
+// TODO: Re-implement missing timers
+public final class MinecraftTimings {
2016-01-10 08:33:27 +01:00
+
+ public static final Timing serverOversleep = Timings.ofSafe("Server Oversleep");
2016-01-10 08:33:27 +01:00
+ public static final Timing playerListTimer = Timings.ofSafe("Player List");
2017-05-14 20:05:01 +02:00
+ public static final Timing commandFunctionsTimer = Timings.ofSafe("Command Functions");
2016-01-10 08:33:27 +01:00
+ public static final Timing connectionTimer = Timings.ofSafe("Connection Handler");
+ public static final Timing tickablesTimer = Timings.ofSafe("Tickables");
2016-02-24 05:35:34 +01:00
+ 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");
2016-01-10 08:33:27 +01:00
+ 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");
2016-01-10 08:33:27 +01:00
+
+ 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");
2016-01-10 08:33:27 +01:00
+
+ public static final Timing processQueueTimer = Timings.ofSafe("processQueue");
+ public static final Timing processTasksTimer = Timings.ofSafe("processTasks");
2016-01-10 08:33:27 +01:00
+
+ 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 static final Map<Class<?>, String> taskNameCache = new MapMaker().weakKeys().makeMap();
+
+ private MinecraftTimings() {}
2016-01-10 08:33:27 +01:00
+
+ public static Timing getInternalTaskName(String taskName) {
+ return Timings.ofSafe(taskName);
+ }
+
2016-01-10 08:33:27 +01:00
+ /**
+ * 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 NullTimingHandler.NULL;
2016-01-10 08:33:27 +01:00
+ }
+ Plugin plugin;
+
+ CraftTask craftTask = (CraftTask) bukkitTask;
2016-01-10 08:33:27 +01:00
+
+ final Class<?> taskClass = craftTask.getTaskClass();
2016-01-10 08:33:27 +01:00
+ if (bukkitTask.getOwner() != null) {
+ plugin = bukkitTask.getOwner();
+ } else {
+ plugin = TimingsManager.getPluginByClassloader(taskClass);
+ }
+
+ final String taskname = taskNameCache.computeIfAbsent(taskClass, clazz -> {
+ try {
+ String clsName = !clazz.isMemberClass()
+ ? clazz.getName()
+ : clazz.getCanonicalName();
+ if (clsName != null && clsName.contains("$Lambda$")) {
+ clsName = clsName.replaceAll("(Lambda\\$.*?)/.*", "$1");
+ }
+ return clsName != null ? clsName : "UnknownTask";
+ } catch (Throwable ex) {
+ new Exception("Error occurred detecting class name", ex).printStackTrace();
+ return "MangledClassFile";
+ }
+ });
2016-01-10 08:33:27 +01:00
+
+ StringBuilder name = new StringBuilder(64);
+ name.append("Task: ").append(taskname);
2016-01-10 08:33:27 +01:00
+ if (period > 0) {
+ name.append(" (interval:").append(period).append(")");
2016-01-10 08:33:27 +01:00
+ } else {
+ name.append(" (Single)");
2016-01-10 08:33:27 +01:00
+ }
+
+ if (plugin == null) {
+ return Timings.ofSafe(null, name.toString());
2016-01-10 08:33:27 +01:00
+ }
+
+ return Timings.ofSafe(plugin, name.toString());
2016-01-10 08:33:27 +01:00
+ }
+
+ /**
+ * Get a named timer for the specified entity type to track type specific timings.
+ * @param entityType
2016-01-10 08:33:27 +01:00
+ * @return
+ */
+ public static Timing getEntityTimings(String entityType, String type) {
+ return Timings.ofSafe("Minecraft", "## tickEntity - " + entityType + " - " + type, tickEntityTimer);
2016-01-10 08:33:27 +01:00
+ }
+
+ /**
+ * 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);
2016-01-10 08:33:27 +01:00
+ }
+/*
+ public static Timing getStructureTiming(StructureGenerator structureGenerator) {
+ return Timings.ofSafe("Structure Generator - " + structureGenerator.getName(), structureGenerationTimer);
+ }*/
+
+ public static Timing getPacketTiming(Packet packet) {
Improve mid tick chunk loading, Fix Oversleep, other improvements Process loads outside of any canSleep check. Original intent was to only apply those restrictions to generations but realized I had some checks higher up the call chain. Reworked the back off strategy to just run every 1 millisecond per world, and to apply the per tick limit to generations only. This guarantees that your chunk will load with at most around 1ms delay. Additionally, fire midTick processing in a few more places, notably the oversleep section so we can keep processing loads here too which has a large up to 50ms window... Speaking of oversleep, we had a bug in our implementation changes for Timings that caused oversleep to not sleep the correct amount. Because we now moved it into the NEXT tick instead of THIS tick, the value of nextTick had already been increased to +50ms, resulting in the risk of sleeping more than it should, but, more importantly, this caused every task that was trying to NOT run during oversleep to actually run during oversleep. This is now fixed. Another small tweak is to the /tps command, to no longer show the star when TPS is right at 20. Due to ineffeciencies in the sleep precision, TPS is commonly 20.02. This causes the star to show up almost constantly, so now only show it if we actually hit a real "catchup". This commit also improves the changes to the CallbackExecutor, in that it now is also recursion safe. It was possible that the executor could run tasks out of desired order if the executor task scheduled more executor tasks. We solve this by ensuring new additions do not enter the currently iterated queue. Each depth level will have its own queue. Fixes #3220
2020-04-26 05:47:29 +02:00
+ return Timings.ofSafe("## Packet - " + packet.getClass().getName(), packetProcessTimer);
+ }
+
+ public static Timing getCommandFunctionTiming(CustomFunction function) {
+ return Timings.ofSafe("Command Function - " + function.getMinecraftKey().toString());
+ }
+}
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4ebcf8f66197299256bd6b65710a1488c90ea41
--- /dev/null
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
@@ -0,0 +1,377 @@
+/*
+ * This file is licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2014 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 com.google.common.collect.Sets;
+import net.minecraft.server.MinecraftServer;
+import org.apache.commons.lang.StringUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.MemorySection;
+import org.bukkit.craftbukkit.util.CraftChatMessage;
+import org.bukkit.entity.EntityType;
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.management.ManagementFactory;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.net.HttpURLConnection;
+import java.net.InetAddress;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.zip.GZIPOutputStream;
+
+import static co.aikar.timings.TimingsManager.HISTORY;
+import static co.aikar.util.JSONUtil.appendObjectData;
+import static co.aikar.util.JSONUtil.createObject;
+import static co.aikar.util.JSONUtil.pair;
+import static co.aikar.util.JSONUtil.toArray;
+import static co.aikar.util.JSONUtil.toArrayMapper;
+import static co.aikar.util.JSONUtil.toObjectMapper;
+
+@SuppressWarnings({"rawtypes", "SuppressionAnnotation"})
+public class TimingsExport extends Thread {
+
+ private final TimingsReportListener listeners;
+ private final Map out;
+ private final TimingHistory[] history;
+ private static long lastReport = 0;
+
+ private TimingsExport(TimingsReportListener listeners, Map out, TimingHistory[] history) {
+ super("Timings paste thread");
+ this.listeners = listeners;
+ this.out = out;
+ this.history = history;
+ }
+
+ /**
+ * Checks if any pending reports are being requested, and builds one if needed.
+ */
+ public static void reportTimings() {
+ if (Timings.requestingReport.isEmpty()) {
+ return;
+ }
+ TimingsReportListener listeners = new TimingsReportListener(Timings.requestingReport);
+ listeners.addConsoleIfNeeded();
+
+ Timings.requestingReport.clear();
+ long now = System.currentTimeMillis();
+ final long lastReportDiff = now - lastReport;
+ if (lastReportDiff < 60000) {
+ listeners.sendMessage(ChatColor.RED + "Please wait at least 1 minute in between Timings reports. (" + (int)((60000 - lastReportDiff) / 1000) + " seconds)");
+ listeners.done();
+ return;
+ }
+ final long lastStartDiff = now - TimingsManager.timingStart;
+ if (lastStartDiff < 180000) {
+ listeners.sendMessage(ChatColor.RED + "Please wait at least 3 minutes before generating a Timings report. Unlike Timings v1, v2 benefits from longer timings and is not as useful with short timings. (" + (int)((180000 - lastStartDiff) / 1000) + " seconds)");
+ listeners.done();
+ return;
+ }
+ listeners.sendMessage(ChatColor.GREEN + "Preparing Timings Report...");
+ lastReport = now;
+ Map parent = createObject(
+ // Get some basic system details about the server
+ pair("version", Bukkit.getVersion()),
+ pair("maxplayers", Bukkit.getMaxPlayers()),
+ pair("start", TimingsManager.timingStart / 1000),
+ pair("end", System.currentTimeMillis() / 1000),
+ pair("online-mode", Bukkit.getServer().getOnlineMode()),
+ pair("sampletime", (System.currentTimeMillis() - TimingsManager.timingStart) / 1000),
+ pair("datapacks", toArrayMapper(MinecraftServer.getServer().getResourcePackRepository().d(), pack -> {
+ // Don't feel like obf helper'ing these, non fatal if its temp missed.
+ return ChatColor.stripColor(CraftChatMessage.fromComponent(pack.a(true)));
+ }))
+ );
+ if (!TimingsManager.privacy) {
+ appendObjectData(parent,
+ pair("server", Bukkit.getUnsafe().getTimingsServerName()),
+ pair("motd", Bukkit.getServer().getMotd()),
+ pair("icon", Bukkit.getServer().getServerIcon().getData())
+ );
+ }
+
+ final Runtime runtime = Runtime.getRuntime();
+ RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
+
+ OperatingSystemMXBean osInfo = ManagementFactory.getOperatingSystemMXBean();
+
+ parent.put("system", createObject(
+ pair("timingcost", getCost()),
+ pair("loadavg", osInfo.getSystemLoadAverage()),
+ pair("name", System.getProperty("os.name")),
+ pair("version", System.getProperty("os.version")),
+ pair("jvmversion", System.getProperty("java.version")),
+ pair("arch", System.getProperty("os.arch")),
+ pair("maxmem", runtime.maxMemory()),
+ pair("memory", createObject(
+ pair("heap", ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().toString()),
+ pair("nonheap", ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().toString()),
+ pair("finalizing", ManagementFactory.getMemoryMXBean().getObjectPendingFinalizationCount())
+ )),
+ pair("cpu", runtime.availableProcessors()),
+ pair("runtime", runtimeBean.getUptime()),
+ pair("flags", StringUtils.join(runtimeBean.getInputArguments(), " ")),
+ pair("gc", toObjectMapper(ManagementFactory.getGarbageCollectorMXBeans(), input -> pair(input.getName(), toArray(input.getCollectionCount(), input.getCollectionTime()))))
+ )
+ );
+
+ parent.put("worlds", toObjectMapper(MinecraftServer.getServer().getWorlds(), world -> {
+ if (world.getWorldData().getName().equals("worldeditregentempworld")) return null;
+ return pair(world.getWorldData().getName(), createObject(
+ pair("gamerules", toObjectMapper(world.getWorld().getGameRules(), rule -> {
+ return pair(rule, world.getWorld().getGameRuleValue(rule));
+ })),
+ pair("ticking-distance", world.getChunkProvider().playerChunkMap.getEffectiveViewDistance())
+ ));
+ }));
+
+ Set<Material> tileEntityTypeSet = Sets.newHashSet();
+ Set<EntityType> entityTypeSet = Sets.newHashSet();
+
+ int size = HISTORY.size();
+ TimingHistory[] history = new TimingHistory[size + 1];
+ int i = 0;
+ for (TimingHistory timingHistory : HISTORY) {
+ tileEntityTypeSet.addAll(timingHistory.tileEntityTypeSet);
+ entityTypeSet.addAll(timingHistory.entityTypeSet);
+ history[i++] = timingHistory;
+ }
+
+ history[i] = new TimingHistory(); // Current snapshot
+ tileEntityTypeSet.addAll(history[i].tileEntityTypeSet);
+ entityTypeSet.addAll(history[i].entityTypeSet);
+
+
+ Map handlers = createObject();
+ Map groupData;
+ synchronized (TimingIdentifier.GROUP_MAP) {
+ for (TimingIdentifier.TimingGroup group : TimingIdentifier.GROUP_MAP.values()) {
+ synchronized (group.handlers) {
+ for (TimingHandler id : group.handlers) {
+
+ if (!id.isTimed() && !id.isSpecial()) {
+ continue;
+ }
+
+ String name = id.identifier.name;
+ if (name.startsWith("##")) {
+ name = name.substring(3);
+ }
+ handlers.put(id.id, toArray(
+ group.id,
+ name
+ ));
+ }
+ }
+ }
+
+ groupData = toObjectMapper(
+ TimingIdentifier.GROUP_MAP.values(), group -> pair(group.id, group.name));
+ }
+
+ parent.put("idmap", createObject(
+ pair("groups", groupData),
+ pair("handlers", handlers),
+ pair("worlds", toObjectMapper(TimingHistory.worldMap.entrySet(), input -> pair(input.getValue(), input.getKey()))),
+ pair("tileentity",
+ toObjectMapper(tileEntityTypeSet, input -> pair(input.ordinal(), input.name()))),
+ pair("entity",
+ toObjectMapper(entityTypeSet, input -> pair(input.ordinal(), input.name())))
+ ));
+
+ // Information about loaded plugins
+
+ parent.put("plugins", toObjectMapper(Bukkit.getPluginManager().getPlugins(),
+ plugin -> pair(plugin.getName(), createObject(
+ pair("version", plugin.getDescription().getVersion()),
+ pair("description", String.valueOf(plugin.getDescription().getDescription()).trim()),
+ pair("website", plugin.getDescription().getWebsite()),
+ pair("authors", StringUtils.join(plugin.getDescription().getAuthors(), ", "))
+ ))));
+
+
+
+ // Information on the users Config
+
+ parent.put("config", createObject(
+ pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)),
+ pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)),
+ pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null))
+ ));
+
+ new TimingsExport(listeners, parent, history).start();
+ }
+
+ static long getCost() {
+ // Benchmark the users System.nanotime() for cost basis
+ int passes = 100;
+ TimingHandler SAMPLER1 = Timings.ofSafe("Timings Sampler 1");
+ TimingHandler SAMPLER2 = Timings.ofSafe("Timings Sampler 2");
+ TimingHandler SAMPLER3 = Timings.ofSafe("Timings Sampler 3");
+ TimingHandler SAMPLER4 = Timings.ofSafe("Timings Sampler 4");
+ TimingHandler SAMPLER5 = Timings.ofSafe("Timings Sampler 5");
+ TimingHandler SAMPLER6 = Timings.ofSafe("Timings Sampler 6");
+
+ long start = System.nanoTime();
+ for (int i = 0; i < passes; i++) {
+ SAMPLER1.startTiming();
+ SAMPLER2.startTiming();
+ SAMPLER3.startTiming();
+ SAMPLER3.stopTiming();
+ SAMPLER4.startTiming();
+ SAMPLER5.startTiming();
+ SAMPLER6.startTiming();
+ SAMPLER6.stopTiming();
+ SAMPLER5.stopTiming();
+ SAMPLER4.stopTiming();
+ SAMPLER2.stopTiming();
+ SAMPLER1.stopTiming();
+ }
+ long timingsCost = (System.nanoTime() - start) / passes / 6;
+ SAMPLER1.reset(true);
+ SAMPLER2.reset(true);
+ SAMPLER3.reset(true);
+ SAMPLER4.reset(true);
+ SAMPLER5.reset(true);
+ SAMPLER6.reset(true);
+ return timingsCost;
+ }
+
+ private static JSONObject mapAsJSON(ConfigurationSection config, String parentKey) {
+
+ JSONObject object = new JSONObject();
+ for (String key : config.getKeys(false)) {
+ String fullKey = (parentKey != null ? parentKey + "." + key : key);
+ if (fullKey.equals("database") || fullKey.equals("settings.bungeecord-addresses") || TimingsManager.hiddenConfigs.contains(fullKey) || key.startsWith("seed-") || key.equals("worldeditregentempworld")) {
+ continue;
+ }
+ final Object val = config.get(key);
+
+ object.put(key, valAsJSON(val, fullKey));
+ }
+ return object;
+ }
+
+ private static Object valAsJSON(Object val, final String parentKey) {
+ if (!(val instanceof MemorySection)) {
+ if (val instanceof List) {
+ Iterable<Object> v = (Iterable<Object>) val;
+ return toArrayMapper(v, input -> valAsJSON(input, parentKey));
+ } else {
+ return String.valueOf(val);
+ }
+ } else {
+ return mapAsJSON((ConfigurationSection) val, parentKey);
+ }
+ }
+
+ @Override
+ public void run() {
+ out.put("data", toArrayMapper(history, TimingHistory::export));
+
+
+ String response = null;
+ String timingsURL = null;
+ try {
+ HttpURLConnection con = (HttpURLConnection) new URL("http://timings.aikar.co/post").openConnection();
+ con.setDoOutput(true);
+ String hostName = "BrokenHost";
+ try {
+ hostName = InetAddress.getLocalHost().getHostName();
+ } catch (Exception ignored) {}
+ con.setRequestProperty("User-Agent", "Paper/" + Bukkit.getUnsafe().getTimingsServerName() + "/" + hostName);
+ con.setRequestMethod("POST");
+ con.setInstanceFollowRedirects(false);
+
+ OutputStream request = new GZIPOutputStream(con.getOutputStream()) {{
+ this.def.setLevel(7);
+ }};
+
+ request.write(JSONValue.toJSONString(out).getBytes("UTF-8"));
+ request.close();
+
+ response = getResponse(con);
+
+ if (con.getResponseCode() != 302) {
+ listeners.sendMessage(
+ ChatColor.RED + "Upload Error: " + con.getResponseCode() + ": " + con.getResponseMessage());
+ listeners.sendMessage(ChatColor.RED + "Check your logs for more information");
+ if (response != null) {
+ Bukkit.getLogger().log(Level.SEVERE, response);
+ }
+ return;
+ }
+
+ timingsURL = con.getHeaderField("Location");
+ listeners.sendMessage(ChatColor.GREEN + "View Timings Report: " + timingsURL);
+
+ if (response != null && !response.isEmpty()) {
+ Bukkit.getLogger().log(Level.INFO, "Timing Response: " + response);
+ }
+ } catch (IOException ex) {
+ listeners.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information");
+ if (response != null) {
+ Bukkit.getLogger().log(Level.SEVERE, response);
+ }
+ Bukkit.getLogger().log(Level.SEVERE, "Could not paste timings", ex);
+ } finally {
+ this.listeners.done(timingsURL);
+ }
+ }
+
+ private String getResponse(HttpURLConnection con) throws IOException {
+ InputStream is = null;
+ try {
+ is = con.getInputStream();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ byte[] b = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = is.read(b)) != -1) {
+ bos.write(b, 0, bytesRead);
+ }
+ return bos.toString();
+
+ } catch (IOException ex) {
+ listeners.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information");
+ Bukkit.getLogger().log(Level.WARNING, con.getResponseMessage(), ex);
+ return null;
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+}
2016-01-10 08:33:27 +01:00
diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java
new file mode 100644
2021-03-16 14:04:28 +01:00
index 0000000000000000000000000000000000000000..fa154ed68187a2020e814db6345a8cc1119ab4ba
2016-01-10 08:33:27 +01:00
--- /dev/null
+++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java
@@ -0,0 +1,119 @@
2016-01-10 08:33:27 +01:00
+package co.aikar.timings;
+
2021-03-16 14:04:28 +01:00
+import net.minecraft.server.level.WorldServer;
+import net.minecraft.world.level.World;
+import net.minecraft.world.level.storage.WorldDataServer;
2016-01-10 08:33:27 +01:00
+
+/**
+ * Set of timers per world, to track world specific timings.
+ */
2019-04-24 03:00:24 +02:00
+// TODO: Re-implement missing timers
2016-01-10 08:33:27 +01:00
+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;
2016-01-10 08:33:27 +01:00
+ public final Timing chunkTicksBlocks;
+ public final Timing doVillages;
+ public final Timing doChunkMap;
2016-06-05 06:10:50 +02:00
+ 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;
2016-01-10 08:33:27 +01:00
+ 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;
2016-01-10 08:33:27 +01:00
+ public final Timing doTick;
+ public final Timing tickEntities;
+ public final Timing chunks;
+ public final Timing newEntities;
+ public final Timing raids;
+ public final Timing chunkProviderTick;
+ public final Timing broadcastChunkUpdates;
+ public final Timing countNaturalMobs;
2016-01-10 08:33:27 +01:00
+
+ public final Timing chunkLoad;
+ public final Timing chunkLoadPopulate;
+ public final Timing syncChunkLoad;
+ public final Timing chunkLoadLevelTimer;
+ public final Timing chunkIO;
+ public final Timing chunkPostLoad;
+ public final Timing worldSave;
+ public final Timing worldSaveChunks;
+ public final Timing worldSaveLevel;
+ public final Timing chunkSaveData;
2016-01-10 08:33:27 +01:00
+
+
+ public final Timing miscMobSpawning;
+
2016-01-10 08:33:27 +01:00
+ public WorldTimingsHandler(World server) {
+ String name = ((WorldDataServer) server.getWorldData()).getName() + " - ";
2016-01-10 08:33:27 +01:00
+
+ 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");
2016-01-10 08:33:27 +01:00
+ chunkTicksBlocks = Timings.ofSafe(name + "Chunk Ticks - Blocks");
+ doVillages = Timings.ofSafe(name + "doVillages");
+ doChunkMap = Timings.ofSafe(name + "doChunkMap");
2016-06-05 06:10:50 +02:00
+ 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");
2016-01-10 08:33:27 +01:00
+ 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");
+
+ chunkLoad = Timings.ofSafe(name + "Chunk Load");
+ chunkLoadPopulate = Timings.ofSafe(name + "Chunk Load - Populate");
+ syncChunkLoad = Timings.ofSafe(name + "Sync Chunk Load");
+ chunkLoadLevelTimer = Timings.ofSafe(name + "Chunk Load - Load Level");
+ chunkIO = Timings.ofSafe(name + "Chunk Load - DiskIO");
+ chunkPostLoad = Timings.ofSafe(name + "Chunk Load - 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");
2016-01-10 08:33:27 +01:00
+
+ tracker1 = Timings.ofSafe(name + "tracker stage 1");
+ tracker2 = Timings.ofSafe(name + "tracker stage 2");
2016-01-10 08:33:27 +01:00
+ doTick = Timings.ofSafe(name + "doTick");
+ tickEntities = Timings.ofSafe(name + "tickEntities");
+
+ chunks = Timings.ofSafe(name + "Chunks");
+ newEntities = Timings.ofSafe(name + "New entity registration");
+ raids = Timings.ofSafe(name + "Raids");
+ chunkProviderTick = Timings.ofSafe(name + "Chunk provider tick");
+ broadcastChunkUpdates = Timings.ofSafe(name + "Broadcast chunk updates");
+ countNaturalMobs = Timings.ofSafe(name + "Count natural mobs");
+
+
+ miscMobSpawning = Timings.ofSafe(name + "Mob spawning - Misc");
2016-01-10 08:33:27 +01:00
+ }
+
+ public static Timing getTickList(WorldServer worldserver, String timingsType) {
+ return Timings.ofSafe(((WorldDataServer) worldserver.getWorldData()).getName() + " - Scheduled " + timingsType);
+ }
2016-01-10 08:33:27 +01:00
+}
2016-03-01 00:09:49 +01:00
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index da922f395f0fff0881ead893c900c5b2623f48f0..1d03a79e9010bc514b72a81ba0ad4a62aeff1bb7 100644
2016-03-01 00:09:49 +01:00
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -14,12 +14,15 @@ import java.util.concurrent.TimeUnit;
2016-03-01 00:09:49 +01:00
import java.util.logging.Level;
import java.util.regex.Pattern;
2016-03-01 00:09:49 +01:00
+import com.google.common.collect.Lists;
import net.minecraft.server.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.configuration.ConfigurationSection;
2016-03-01 00:09:49 +01:00
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
+import co.aikar.timings.Timings;
+import co.aikar.timings.TimingsManager;
public class PaperConfig {
@@ -188,4 +191,30 @@ public class PaperConfig {
2016-03-25 05:59:37 +01:00
config.addDefault(path, def);
return config.getString(path, config.getString(path));
2016-03-01 00:09:49 +01:00
}
+
+ public static String timingsServerName;
2016-03-01 00:09:49 +01:00
+ 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", "settings.velocity-support.secret"));
+ if (!TimingsManager.hiddenConfigs.contains("settings.velocity-support.secret")) {
+ TimingsManager.hiddenConfigs.add("settings.velocity-support.secret");
+ }
2016-03-01 00:09:49 +01:00
+ int timingHistoryInterval = getInt("timings.history-interval", 300);
+ int timingHistoryLength = getInt("timings.history-length", 3600);
+ timingsServerName = getString("timings.server-name", "Unknown Server");
2016-03-01 00:09:49 +01:00
+
+
+ Timings.setVerboseTimingsEnabled(verboseTimings);
+ Timings.setTimingsEnabled(timings);
+ Timings.setHistoryInterval(timingHistoryInterval * 20);
+ Timings.setHistoryLength(timingHistoryLength * 20);
+
+ log("Timings: " + timings +
2016-03-01 00:09:49 +01:00
+ " - Verbose: " + verboseTimings +
+ " - Interval: " + timeSummary(Timings.getHistoryInterval() / 20) +
+ " - Length: " + timeSummary(Timings.getHistoryLength() / 20) +
+ " - Server Name: " + timingsServerName);
2016-03-01 00:09:49 +01:00
+ }
}
diff --git a/src/main/java/net/minecraft/commands/CustomFunction.java b/src/main/java/net/minecraft/commands/CustomFunction.java
index f96b132bb51c2d97703964a70fcb058f0649ac13..4c146ac041332230f6d9a01be28b6852c7624416 100644
--- a/src/main/java/net/minecraft/commands/CustomFunction.java
+++ b/src/main/java/net/minecraft/commands/CustomFunction.java
@@ -15,12 +15,22 @@ public class CustomFunction {
private final CustomFunction.c[] a;
private final MinecraftKey b;
+ // Paper start
+ public co.aikar.timings.Timing timing;
+ public co.aikar.timings.Timing getTiming() {
+ if (timing == null) {
+ timing = co.aikar.timings.MinecraftTimings.getCommandFunctionTiming(this);
+ }
+ return timing;
+ }
+ // Paper end
public CustomFunction(MinecraftKey minecraftkey, CustomFunction.c[] acustomfunction_c) {
this.b = minecraftkey;
this.a = acustomfunction_c;
}
+ public final MinecraftKey getMinecraftKey() { return this.a(); } // Paper - OBFHELPER
public MinecraftKey a() {
return this.b;
}
diff --git a/src/main/java/net/minecraft/network/protocol/PlayerConnectionUtils.java b/src/main/java/net/minecraft/network/protocol/PlayerConnectionUtils.java
index 989683265a99fc51607aa130733e00033b444a6a..e47da20ab8ce4da34755e105bf55d8542fb50138 100644
--- a/src/main/java/net/minecraft/network/protocol/PlayerConnectionUtils.java
+++ b/src/main/java/net/minecraft/network/protocol/PlayerConnectionUtils.java
@@ -6,6 +6,8 @@ import net.minecraft.server.level.WorldServer;
import net.minecraft.util.thread.IAsyncTaskHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import co.aikar.timings.MinecraftTimings; // Paper
+import co.aikar.timings.Timing; // Paper
// CraftBukkit start
import net.minecraft.server.MinecraftServer;
@@ -22,10 +24,13 @@ public class PlayerConnectionUtils {
public static <T extends PacketListener> void ensureMainThread(Packet<T> packet, T t0, IAsyncTaskHandler<?> iasynctaskhandler) throws CancelledPacketHandleException {
if (!iasynctaskhandler.isMainThread()) {
+ Timing timing = MinecraftTimings.getPacketTiming(packet); // Paper - timings
iasynctaskhandler.execute(() -> {
if (MinecraftServer.getServer().hasStopped() || (t0 instanceof PlayerConnection && ((PlayerConnection) t0).processedDisconnect)) return; // CraftBukkit, MC-142590
if (t0.a().isConnected()) {
+ try (Timing ignored = timing.startTiming()) { // Paper - timings
packet.a(t0);
+ } // Paper - timings
} else {
PlayerConnectionUtils.LOGGER.debug("Ignoring packet due to disconnection: " + packet);
}
diff --git a/src/main/java/net/minecraft/server/CustomFunctionData.java b/src/main/java/net/minecraft/server/CustomFunctionData.java
index 21f5474a1cd60168ca059da542a432d40d88b514..07ca1234ad6ffa797003f7317fb88abf732bc159 100644
--- a/src/main/java/net/minecraft/server/CustomFunctionData.java
+++ b/src/main/java/net/minecraft/server/CustomFunctionData.java
@@ -75,7 +75,7 @@ public class CustomFunctionData {
} else {
int j;
- try {
+ try (co.aikar.timings.Timing timing = customfunction.getTiming().startTiming()) { // Paper
2020-06-25 11:27:25 +02:00
this.d = true;
int k = 0;
CustomFunction.c[] acustomfunction_c = customfunction.b();
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 5ce0dfade68257b51ad4a19a829e1fc0a0bbc3db..85c96e3f70a3ffecb6195a1d83053412eb180d78 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -174,7 +174,7 @@ import org.bukkit.craftbukkit.Main;
import org.bukkit.event.server.ServerLoadEvent;
// CraftBukkit end
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
+import co.aikar.timings.MinecraftTimings; // Paper
import org.spigotmc.SlackActivityAccountant; // Spigot
public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTask> implements IMojangStatistics, ICommandListener, AutoCloseable {
@@ -228,8 +228,8 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
private long T;
public final Thread serverThread;
private long nextTick;
- private long W;
- private boolean X;
+ private long W; final long getTickOversleepMaxTime() { return this.W; } // Paper - OBFHELPER
+ private boolean X; final boolean hasExecutedTask() { return this.X; } // Paper - OBFHELPER
private final ResourcePackRepository resourcePackRepository;
private final ScoreboardServer scoreboardServer;
@Nullable
@@ -830,6 +830,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
// CraftBukkit end
MinecraftServer.LOGGER.info("Stopping server");
+ MinecraftTimings.stopServer(); // Paper
// CraftBukkit start
if (this.server != null) {
this.server.disablePlugins();
@@ -1027,9 +1028,21 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
private boolean canSleepForTick() {
// CraftBukkit start
+ if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken
return this.forceTicks || this.isEntered() || SystemUtils.getMonotonicMillis() < (this.X ? this.W : this.nextTick);
}
+ // Paper start
+ boolean isOversleep = false;
+ private boolean canOversleep() {
+ return this.hasExecutedTask() && SystemUtils.getMonotonicMillis() < this.getTickOversleepMaxTime();
+ }
+
+ private boolean canSleepForTickNoOversleep() {
+ return this.forceTicks || this.isEntered() || SystemUtils.getMonotonicMillis() < this.nextTick;
+ }
+ // Paper end
+
private void executeModerately() {
this.executeAll();
java.util.concurrent.locks.LockSupport.parkNanos("executing tasks", 1000L);
@@ -1037,9 +1050,9 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
// CraftBukkit end
protected void sleepForTick() {
- this.executeAll();
+ //this.executeAll(); // Paper - move this into the tick method for timings
this.awaitTasks(() -> {
- return !this.canSleepForTick();
+ return !this.canSleepForTickNoOversleep(); // Paper - move oversleep into full server tick
});
}
@@ -1122,10 +1135,18 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
2019-04-24 03:00:24 +02:00
protected void exit() {}
protected void a(BooleanSupplier booleansupplier) {
- SpigotTimings.serverTickTimer.startTiming(); // Spigot
2016-03-01 00:09:49 +01:00
+ co.aikar.timings.TimingsManager.FULL_SERVER_TICK.startTiming(); // Paper
this.slackActivityAccountant.tickStarted(); // Spigot
long i = SystemUtils.getMonotonicNanos();
+ // Paper start - move oversleep into full server tick
Improve mid tick chunk loading, Fix Oversleep, other improvements Process loads outside of any canSleep check. Original intent was to only apply those restrictions to generations but realized I had some checks higher up the call chain. Reworked the back off strategy to just run every 1 millisecond per world, and to apply the per tick limit to generations only. This guarantees that your chunk will load with at most around 1ms delay. Additionally, fire midTick processing in a few more places, notably the oversleep section so we can keep processing loads here too which has a large up to 50ms window... Speaking of oversleep, we had a bug in our implementation changes for Timings that caused oversleep to not sleep the correct amount. Because we now moved it into the NEXT tick instead of THIS tick, the value of nextTick had already been increased to +50ms, resulting in the risk of sleeping more than it should, but, more importantly, this caused every task that was trying to NOT run during oversleep to actually run during oversleep. This is now fixed. Another small tweak is to the /tps command, to no longer show the star when TPS is right at 20. Due to ineffeciencies in the sleep precision, TPS is commonly 20.02. This causes the star to show up almost constantly, so now only show it if we actually hit a real "catchup". This commit also improves the changes to the CallbackExecutor, in that it now is also recursion safe. It was possible that the executor could run tasks out of desired order if the executor task scheduled more executor tasks. We solve this by ensuring new additions do not enter the currently iterated queue. Each depth level will have its own queue. Fixes #3220
2020-04-26 05:47:29 +02:00
+ isOversleep = true;MinecraftTimings.serverOversleep.startTiming();
+ this.awaitTasks(() -> {
+ return !this.canOversleep();
+ });
Improve mid tick chunk loading, Fix Oversleep, other improvements Process loads outside of any canSleep check. Original intent was to only apply those restrictions to generations but realized I had some checks higher up the call chain. Reworked the back off strategy to just run every 1 millisecond per world, and to apply the per tick limit to generations only. This guarantees that your chunk will load with at most around 1ms delay. Additionally, fire midTick processing in a few more places, notably the oversleep section so we can keep processing loads here too which has a large up to 50ms window... Speaking of oversleep, we had a bug in our implementation changes for Timings that caused oversleep to not sleep the correct amount. Because we now moved it into the NEXT tick instead of THIS tick, the value of nextTick had already been increased to +50ms, resulting in the risk of sleeping more than it should, but, more importantly, this caused every task that was trying to NOT run during oversleep to actually run during oversleep. This is now fixed. Another small tweak is to the /tps command, to no longer show the star when TPS is right at 20. Due to ineffeciencies in the sleep precision, TPS is commonly 20.02. This causes the star to show up almost constantly, so now only show it if we actually hit a real "catchup". This commit also improves the changes to the CallbackExecutor, in that it now is also recursion safe. It was possible that the executor could run tasks out of desired order if the executor task scheduled more executor tasks. We solve this by ensuring new additions do not enter the currently iterated queue. Each depth level will have its own queue. Fixes #3220
2020-04-26 05:47:29 +02:00
+ isOversleep = false;MinecraftTimings.serverOversleep.stopTiming();
+ // Paper end
+
++this.ticks;
this.b(booleansupplier);
2020-06-25 11:27:25 +02:00
if (i - this.T >= 5000000000L) {
@@ -1143,14 +1164,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit
- SpigotTimings.worldSaveTimer.startTiming(); // Spigot
2019-04-24 03:00:24 +02:00
MinecraftServer.LOGGER.debug("Autosave started");
this.methodProfiler.enter("save");
this.playerList.savePlayers();
2019-04-24 03:00:24 +02:00
this.saveChunks(true, false, false);
this.methodProfiler.exit();
2019-04-24 03:00:24 +02:00
MinecraftServer.LOGGER.debug("Autosave finished");
- SpigotTimings.worldSaveTimer.stopTiming(); // Spigot
}
this.methodProfiler.enter("snooper");
@@ -1163,6 +1182,13 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
this.methodProfiler.exit();
+
+ // Paper start - move executeAll() into full server tick timing
+ try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) {
+ this.executeAll();
+ }
+ // Paper end
+
this.methodProfiler.enter("tallying");
2020-06-25 11:27:25 +02:00
long l = this.h[this.ticks % 100] = SystemUtils.getMonotonicNanos() - i;
@@ -1173,30 +1199,29 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.methodProfiler.exit();
org.spigotmc.WatchdogThread.tick(); // Spigot
this.slackActivityAccountant.tickEnded(l); // Spigot
- SpigotTimings.serverTickTimer.stopTiming(); // Spigot
- org.spigotmc.CustomTimingsHandler.tick(); // Spigot
2016-03-01 00:09:49 +01:00
+ co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTiming(); // Paper
}
2019-04-24 03:00:24 +02:00
protected void b(BooleanSupplier booleansupplier) {
2016-06-30 07:38:53 +02:00
- SpigotTimings.schedulerTimer.startTiming(); // Spigot
2019-04-24 03:00:24 +02:00
+ MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Spigot // Paper
2016-06-30 07:38:53 +02:00
this.server.getScheduler().mainThreadHeartbeat(this.ticks); // CraftBukkit
- SpigotTimings.schedulerTimer.stopTiming(); // Spigot
2019-04-24 03:00:24 +02:00
+ MinecraftTimings.bukkitSchedulerTimer.stopTiming(); // Spigot // Paper
this.methodProfiler.enter("commandFunctions");
- SpigotTimings.commandFunctionsTimer.startTiming(); // Spigot
2019-04-24 03:00:24 +02:00
+ MinecraftTimings.commandFunctionsTimer.startTiming(); // Spigot // Paper
this.getFunctionData().tick();
- SpigotTimings.commandFunctionsTimer.stopTiming(); // Spigot
2019-04-24 03:00:24 +02:00
+ MinecraftTimings.commandFunctionsTimer.stopTiming(); // Spigot // Paper
this.methodProfiler.exitEnter("levels");
Iterator iterator = this.getWorlds().iterator();
2016-02-24 05:35:34 +01:00
// 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.timeUpdateTimer.startTiming(); // Spigot
2019-04-24 03:00:24 +02:00
+ MinecraftTimings.timeUpdateTimer.startTiming(); // Spigot // Paper
// 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) {
@@ -1204,7 +1229,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(entityplayer.world.getTime(), entityplayer.getPlayerTime(), entityplayer.world.getGameRules().getBoolean(GameRules.DO_DAYLIGHT_CYCLE))); // Add support for per player time
}
}
- SpigotTimings.timeUpdateTimer.stopTiming(); // Spigot
2019-04-24 03:00:24 +02:00
+ MinecraftTimings.timeUpdateTimer.stopTiming(); // Spigot // Paper
while (iterator.hasNext()) {
WorldServer worldserver = (WorldServer) iterator.next();
@@ -1245,24 +1270,24 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
this.methodProfiler.exitEnter("connection");
- SpigotTimings.connectionTimer.startTiming(); // Spigot
+ MinecraftTimings.connectionTimer.startTiming(); // Spigot
this.getServerConnection().c();
- SpigotTimings.connectionTimer.stopTiming(); // Spigot
+ MinecraftTimings.connectionTimer.stopTiming(); // Spigot
this.methodProfiler.exitEnter("players");
- SpigotTimings.playerListTimer.startTiming(); // Spigot
+ MinecraftTimings.playerListTimer.startTiming(); // Spigot // Paper
this.playerList.tick();
- SpigotTimings.playerListTimer.stopTiming(); // Spigot
+ MinecraftTimings.playerListTimer.stopTiming(); // Spigot // Paper
if (SharedConstants.d) {
GameTestHarnessTicker.a.b();
}
this.methodProfiler.exitEnter("server gui refresh");
- SpigotTimings.tickablesTimer.startTiming(); // Spigot
+ MinecraftTimings.tickablesTimer.startTiming(); // Spigot // Paper
for (int i = 0; i < this.tickables.size(); ++i) {
((Runnable) this.tickables.get(i)).run();
}
- SpigotTimings.tickablesTimer.stopTiming(); // Spigot
+ MinecraftTimings.tickablesTimer.stopTiming(); // Spigot // Paper
this.methodProfiler.exit();
}
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 8e2e415a022ccd486465f19d9bbf1f287b21fb95..59942eb6bb6e8e1e9a988bce0d09757e575018b9 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -65,8 +65,9 @@ import net.minecraft.world.level.DataPackConfiguration;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.io.IoBuilder;
import org.bukkit.command.CommandSender;
-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;
// CraftBukkit end
@@ -421,7 +422,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
}
public void handleCommandQueue() {
- SpigotTimings.serverCommandTimer.startTiming(); // Spigot
+ MinecraftTimings.serverCommandTimer.startTiming(); // Spigot
while (!this.serverCommandQueue.isEmpty()) {
ServerCommand servercommand = (ServerCommand) this.serverCommandQueue.remove(0);
@@ -436,7 +437,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
// CraftBukkit end
}
- SpigotTimings.serverCommandTimer.stopTiming(); // Spigot
+ MinecraftTimings.serverCommandTimer.stopTiming(); // Spigot
}
@Override
@@ -672,6 +673,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
@Override
public String executeRemoteCommand(String s) {
+ Waitable[] waitableArray = new Waitable[1];
this.remoteControlCommandListener.clearMessages();
this.executeSync(() -> {
// CraftBukkit start - fire RemoteServerCommandEvent
@@ -680,10 +682,39 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
if (event.isCancelled()) {
return;
}
+ // 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<String> waitable = new Waitable<String>() {
+ @Override
+ protected String evaluate() {
+ return sender.getBuffer();
+ }
+ };
+ waitableArray[0] = waitable;
+ co.aikar.timings.Timings.generateReport(new co.aikar.timings.TimingsReportListener(sender, waitable));
+ } else {
+ // Paper end
ServerCommand serverCommand = new ServerCommand(event.getCommand(), remoteControlCommandListener.getWrapper());
server.dispatchServerCommand(remoteConsole, serverCommand);
+ } // Paper
// CraftBukkit end
});
+ // Paper start
+ if (waitableArray[0] != null) {
+ //noinspection unchecked
+ Waitable<String> waitable = waitableArray[0];
+ try {
+ return waitable.get();
+ } catch (java.util.concurrent.ExecutionException e) {
+ throw new RuntimeException("Exception processing rcon command " + s, e.getCause());
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt(); // Maintain interrupted state
+ throw new RuntimeException("Interrupted processing rcon command " + s, e);
+ }
+
+ }
+ // Paper end
return this.remoteControlCommandListener.getMessages();
}
diff --git a/src/main/java/net/minecraft/server/level/ChunkProviderServer.java b/src/main/java/net/minecraft/server/level/ChunkProviderServer.java
index 0b5bcb60472c778574702a5ac26a6d02d54bfeac..3351c6bcc5244fd7565ba7af08f63ea4d999ce97 100644
--- a/src/main/java/net/minecraft/server/level/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/level/ChunkProviderServer.java
@@ -344,11 +344,13 @@ public class ChunkProviderServer extends IChunkProvider {
}
gameprofilerfiller.c("getChunkCacheMiss");
- world.timings.syncChunkLoadTimer.startTiming(); // Spigot
CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> completablefuture = this.getChunkFutureMainThread(i, j, chunkstatus, flag);
+ if (!completablefuture.isDone()) { // Paper
+ this.world.timings.syncChunkLoad.startTiming(); // Paper
this.serverThreadQueue.awaitTasks(completablefuture::isDone);
- world.timings.syncChunkLoadTimer.stopTiming(); // Spigot
+ this.world.timings.syncChunkLoad.stopTiming(); // Paper
+ } // Paper
ichunkaccess = (IChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> {
return ichunkaccess1;
}, (playerchunk_failure) -> {
@@ -535,7 +537,9 @@ public class ChunkProviderServer extends IChunkProvider {
public void save(boolean flag) {
this.tickDistanceManager();
+ try (co.aikar.timings.Timing timed = world.timings.chunkSaveData.startTiming()) { // Paper - Timings
this.playerChunkMap.save(flag);
+ } // Paper - Timings
}
@Override
@@ -572,7 +576,9 @@ public class ChunkProviderServer extends IChunkProvider {
this.tickDistanceManager();
this.world.timings.doChunkMap.stopTiming(); // Spigot
this.world.getMethodProfiler().exitEnter("chunks");
+ this.world.timings.chunks.startTiming(); // Paper - timings
this.tickChunks();
+ this.world.timings.chunks.stopTiming(); // Paper - timings
this.world.timings.doChunkUnload.startTiming(); // Spigot
this.world.getMethodProfiler().exitEnter("unload");
this.playerChunkMap.unloadChunks(booleansupplier);
@@ -596,19 +602,24 @@ public class ChunkProviderServer extends IChunkProvider {
boolean flag2 = world.ticksPerAnimalSpawns != 0L && worlddata.getTime() % world.ticksPerAnimalSpawns == 0L; // CraftBukkit
this.world.getMethodProfiler().enter("naturalSpawnCount");
+ this.world.timings.countNaturalMobs.startTiming(); // Paper - timings
int l = this.chunkMapDistance.b();
SpawnerCreature.d spawnercreature_d = SpawnerCreature.a(l, this.world.A(), this::a);
+ this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings
this.p = spawnercreature_d;
this.world.getMethodProfiler().exit();
//List<PlayerChunk> list = Lists.newArrayList(this.playerChunkMap.f()); // Paper
//Collections.shuffle(list); // Paper
+ this.world.timings.chunkTicks.startTiming(); // Paper
this.playerChunkMap.f().forEach((playerchunk) -> { // Paper - no... just no...
Optional<Chunk> optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
if (optional.isPresent()) {
this.world.getMethodProfiler().enter("broadcast");
+ this.world.timings.broadcastChunkUpdates.startTiming(); // Paper - timings
playerchunk.a((Chunk) optional.get());
+ this.world.timings.broadcastChunkUpdates.stopTiming(); // Paper - timings
this.world.getMethodProfiler().exit();
Optional<Chunk> optional1 = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
@@ -622,25 +633,26 @@ public class ChunkProviderServer extends IChunkProvider {
SpawnerCreature.a(this.world, chunk, spawnercreature_d, this.allowAnimals, this.allowMonsters, flag2);
}
2019-12-11 01:56:03 +01:00
- this.world.timings.doTickTiles.startTiming(); // Spigot
+ //this.world.timings.chunkTicks.startTiming(); // Spigot // Paper
this.world.a(chunk, k);
- this.world.timings.doTickTiles.stopTiming(); // Spigot
+ //this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper
}
}
}
});
+ this.world.timings.chunkTicks.stopTiming(); // Paper
this.world.getMethodProfiler().enter("customSpawners");
if (flag1) {
+ try (co.aikar.timings.Timing ignored = this.world.timings.miscMobSpawning.startTiming()) { // Paper - timings
this.world.doMobSpawning(this.allowMonsters, this.allowAnimals);
+ } // Paper - timings
}
this.world.getMethodProfiler().exit();
this.world.getMethodProfiler().exit();
}
- this.world.timings.tracker.startTiming(); // Spigot
this.playerChunkMap.g();
- this.world.timings.tracker.stopTiming(); // Spigot
}
private void a(long i, Consumer<Chunk> consumer) {
diff --git a/src/main/java/net/minecraft/server/level/PlayerChunkMap.java b/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
index 19856555793f742abb1178ede72dea5623f0e383..62245fa420390dc0a70ba9a95505dc46cd8aa64a 100644
--- a/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
@@ -1,7 +1,9 @@
package net.minecraft.server.level;
2016-06-05 06:10:50 +02:00
+import co.aikar.timings.Timing; // Paper
2019-04-24 03:00:24 +02:00
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
+import com.google.common.collect.ComparisonChain; // Paper
import com.google.common.collect.Lists;
2019-05-28 01:01:45 +02:00
import com.google.common.collect.Queues;
2019-04-24 03:00:24 +02:00
import com.google.common.collect.Sets;
2021-03-16 14:04:28 +01:00
@@ -554,11 +556,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
private CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> f(ChunkCoordIntPair chunkcoordintpair) {
return CompletableFuture.supplyAsync(() -> {
- try {
+ try (Timing ignored = this.world.timings.chunkLoad.startTimingIfSync()) { // Paper
this.world.getMethodProfiler().c("chunkLoad");
- NBTTagCompound nbttagcompound = this.readChunkData(chunkcoordintpair);
+ NBTTagCompound nbttagcompound; // Paper
+ try (Timing ignored2 = this.world.timings.chunkIO.startTimingIfSync()) { // Paper start - timings
+ nbttagcompound = this.readChunkData(chunkcoordintpair);
+ } // Paper end
- if (nbttagcompound != null) {
+ if (nbttagcompound != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings
boolean flag = nbttagcompound.hasKeyOfType("Level", 10) && nbttagcompound.getCompound("Level").hasKeyOfType("Status", 8);
if (flag) {
2021-03-16 14:04:28 +01:00
@@ -570,7 +575,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
PlayerChunkMap.LOGGER.error("Chunk file at {} is missing level data, skipping", chunkcoordintpair);
- }
+ }} // Paper
} catch (ReportedException reportedexception) {
Throwable throwable = reportedexception.getCause();
2021-03-16 14:04:28 +01:00
@@ -607,7 +612,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return "chunkGenerate " + chunkstatus.d();
2019-05-28 01:01:45 +02:00
});
return completablefuture.thenComposeAsync((either) -> {
- return (CompletableFuture) either.map((list) -> {
+ return either.map((list) -> { // Paper - Shut up.
try {
CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> completablefuture1 = chunkstatus.a(this.world, this.chunkGenerator, this.definedStructureManager, this.lightEngine, (ichunkaccess) -> {
return this.c(playerchunk);
2021-03-16 14:04:28 +01:00
@@ -660,6 +665,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
ChunkStatus chunkstatus = PlayerChunk.getChunkStatus(playerchunk.getTicketLevel());
return !chunkstatus.b(ChunkStatus.FULL) ? PlayerChunk.UNLOADED_CHUNK_ACCESS : either.mapLeft((ichunkaccess) -> {
+ try (Timing ignored = world.timings.chunkPostLoad.startTimingIfSync()) { // Paper
ChunkCoordIntPair chunkcoordintpair = playerchunk.i();
Chunk chunk;
@@ -719,6 +725,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
return chunk;
+ } // Paper
});
}, (runnable) -> {
Mailbox mailbox = this.mailboxMain;
@@ -1177,6 +1184,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
2016-06-05 06:10:50 +02:00
2019-04-24 03:00:24 +02:00
PlayerChunkMap.EntityTracker playerchunkmap_entitytracker;
ObjectIterator objectiterator;
+ world.timings.tracker1.startTiming(); // Paper
2016-06-05 06:10:50 +02:00
2019-04-24 03:00:24 +02:00
for (objectiterator = this.trackedEntities.values().iterator(); objectiterator.hasNext(); playerchunkmap_entitytracker.trackerEntry.a()) {
playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next();
@@ -1194,16 +1202,20 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
2019-04-24 03:00:24 +02:00
playerchunkmap_entitytracker.e = sectionposition1;
2016-06-05 06:10:50 +02:00
}
}
2019-04-24 03:00:24 +02:00
+ world.timings.tracker1.stopTiming(); // Paper
2016-06-05 06:10:50 +02:00
2019-12-11 01:56:03 +01:00
if (!list.isEmpty()) {
objectiterator = this.trackedEntities.values().iterator();
2016-06-05 06:10:50 +02:00
2019-12-11 01:56:03 +01:00
+ world.timings.tracker2.startTiming(); // Paper
while (objectiterator.hasNext()) {
playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next();
playerchunkmap_entitytracker.track(list);
}
+ world.timings.tracker2.stopTiming(); // Paper
2019-05-06 22:45:02 +02:00
}
2019-12-11 01:56:03 +01:00
+
2019-05-06 22:45:02 +02:00
}
2019-12-11 01:56:03 +01:00
protected void broadcast(Entity entity, Packet<?> packet) {
diff --git a/src/main/java/net/minecraft/server/level/WorldServer.java b/src/main/java/net/minecraft/server/level/WorldServer.java
index 780e541b8d594a8a6dc3a8626a82218f2502a5c7..cf38d517821659e25e786a805e229ef2d626d75f 100644
--- a/src/main/java/net/minecraft/server/level/WorldServer.java
+++ b/src/main/java/net/minecraft/server/level/WorldServer.java
@@ -2,6 +2,8 @@ package net.minecraft.server.level;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Iterables;
+import co.aikar.timings.TimingHistory; // Paper
+import co.aikar.timings.Timings; // Paper
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Queues;
@@ -153,7 +155,6 @@ import net.minecraft.world.level.block.ITileEntity;
import net.minecraft.world.level.storage.WorldDataServer;
import org.bukkit.Bukkit;
import org.bukkit.WeatherType;
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.craftbukkit.util.WorldUUID;
import org.bukkit.event.entity.CreatureSpawnEvent;
@@ -209,10 +210,10 @@ public class WorldServer extends World implements GeneratorAccessSeed {
// CraftBukkit end
this.nextTickListBlock = new TickListServer<>(this, (block) -> {
return block == null || block.getBlockData().isAir();
- }, IRegistry.BLOCK::getKey, this::b);
+ }, IRegistry.BLOCK::getKey, this::b, "Blocks"); // Paper - Timings
this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> {
return fluidtype == null || fluidtype == FluidTypes.EMPTY;
- }, IRegistry.FLUID::getKey, this::a);
+ }, IRegistry.FLUID::getKey, this::a, "Fluids"); // Paper - Timings
this.navigators = Sets.newHashSet();
this.L = new ObjectLinkedOpenHashSet();
this.Q = flag1;
@@ -442,17 +443,21 @@ public class WorldServer extends World implements GeneratorAccessSeed {
this.Q();
this.b();
gameprofilerfiller.exitEnter("chunkSource");
+ this.timings.chunkProviderTick.startTiming(); // Paper - timings
this.getChunkProvider().tick(booleansupplier);
+ this.timings.chunkProviderTick.stopTiming(); // Paper - timings
gameprofilerfiller.exitEnter("tickPending");
- timings.doTickPending.startTiming(); // Spigot
+ timings.scheduledBlocks.startTiming(); // Paper
if (!this.isDebugWorld()) {
this.nextTickListBlock.b();
this.nextTickListFluid.b();
}
- timings.doTickPending.stopTiming(); // Spigot
+ timings.scheduledBlocks.stopTiming(); // Paper
gameprofilerfiller.exitEnter("raid");
+ this.timings.raids.startTiming(); // Paper - timings
this.persistentRaid.a();
+ this.timings.raids.stopTiming(); // Paper - timings
gameprofilerfiller.exitEnter("blockEvents");
timings.doSounds.startTiming(); // Spigot
this.ak();
@@ -624,6 +629,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
}
gameprofilerfiller.exitEnter("tickBlocks");
+ timings.chunkTicksBlocks.startTiming(); // Paper
if (i > 0) {
ChunkSection[] achunksection = chunk.getSections();
int l = achunksection.length;
@@ -655,7 +661,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
}
}
}
-
+ timings.chunkTicksBlocks.stopTiming(); // Paper
gameprofilerfiller.exit();
}
@@ -753,14 +759,22 @@ public class WorldServer extends World implements GeneratorAccessSeed {
if (!(entity instanceof EntityHuman) && !this.getChunkProvider().a(entity)) {
this.chunkCheck(entity);
} else {
+ ++TimingHistory.entityTicks; // Paper - timings
// Spigot start
+ co.aikar.timings.Timing timer; // Paper
if (!org.spigotmc.ActivationRange.checkIfActive(entity)) {
entity.ticksLived++;
+ timer = entity.getEntityType().inactiveTickTimer.startTiming(); try { // Paper - timings
entity.inactiveTick();
+ } finally { timer.stopTiming(); } // Paper
return;
}
// Spigot end
- entity.tickTimer.startTiming(); // Spigot
+ // Paper start- timings
+ TimingHistory.activatedEntityTicks++;
+ timer = entity.getVehicle() != null ? entity.getEntityType().passengerTickTimer.startTiming() : entity.getEntityType().tickTimer.startTiming();
+ try {
+ // Paper end - timings
entity.g(entity.locX(), entity.locY(), entity.locZ());
entity.lastYaw = entity.yaw;
entity.lastPitch = entity.pitch;
@@ -787,7 +801,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
this.a(entity, entity1);
}
}
- entity.tickTimer.stopTiming(); // Spigot
+ } finally { timer.stopTiming(); } // Paper - timings
}
}
@@ -865,6 +879,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
if (!flag1) {
org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit
+ try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper
if (iprogressupdate != null) {
iprogressupdate.a(new ChatMessage("menu.savingLevel"));
}
@@ -874,7 +889,10 @@ public class WorldServer extends World implements GeneratorAccessSeed {
iprogressupdate.c(new ChatMessage("menu.savingChunks"));
}
+ timings.worldSaveChunks.startTiming(); // Paper
chunkproviderserver.save(flag);
+ timings.worldSaveChunks.stopTiming(); // Paper
+ } // Paper
}
// CraftBukkit start - moved from MinecraftServer.saveChunks
diff --git a/src/main/java/net/minecraft/server/network/PlayerConnection.java b/src/main/java/net/minecraft/server/network/PlayerConnection.java
index 265004691f12b3476f3892f5555768717e9c6d19..536a351e1879fcb8066546d1179ad1af034b95da 100644
--- a/src/main/java/net/minecraft/server/network/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/network/PlayerConnection.java
@@ -211,6 +211,7 @@ import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.SmithingInventory;
import org.bukkit.util.NumberConversions;
+import co.aikar.timings.MinecraftTimings; // Paper
// CraftBukkit end
2019-04-24 03:00:24 +02:00
public class PlayerConnection implements PacketListenerPlayIn {
@@ -293,7 +294,6 @@ public class PlayerConnection implements PacketListenerPlayIn {
2018-10-28 23:08:08 +01:00
// CraftBukkit end
public void tick() {
2018-10-28 23:08:08 +01:00
- org.bukkit.craftbukkit.SpigotTimings.playerConnectionTimer.startTiming(); // Spigot
this.syncPosition();
2019-12-11 01:56:03 +01:00
this.player.lastX = this.player.locX();
this.player.lastY = this.player.locY();
@@ -369,7 +369,6 @@ public class PlayerConnection implements PacketListenerPlayIn {
2018-10-28 23:08:08 +01:00
this.player.resetIdleTimer(); // CraftBukkit - SPIGOT-854
2020-06-25 11:27:25 +02:00
this.disconnect(new ChatMessage("multiplayer.disconnect.idling"));
2018-10-28 23:08:08 +01:00
}
- org.bukkit.craftbukkit.SpigotTimings.playerConnectionTimer.stopTiming(); // Spigot
}
@@ -1917,7 +1916,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
// CraftBukkit end
2017-05-14 20:05:01 +02:00
private void handleCommand(String s) {
- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot
2017-05-14 20:05:01 +02:00
+ MinecraftTimings.playerCommandTimer.startTiming(); // Paper
// CraftBukkit start - whole method
if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot
2016-03-01 00:09:49 +01:00
this.LOGGER.info(this.player.getName() + " issued server command: " + s);
@@ -1928,7 +1927,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
this.server.getPluginManager().callEvent(event);
if (event.isCancelled()) {
- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot
+ MinecraftTimings.playerCommandTimer.stopTiming(); // Paper
return;
}
@@ -1941,7 +1940,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
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/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 5d1bbc42b4d65aa735570c53e4e6bc9e08899749..c601a5c577e438a3fa8dd4c5f36dbe9494b03d52 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -1,5 +1,6 @@
package net.minecraft.server.players;
+import co.aikar.timings.MinecraftTimings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -1022,10 +1023,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/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 2bea2f4748cadf479dd4f89792ef5ffdd88e9cab..306f6c0db2333cce5dfc4bf1c09bfef05119a28b 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -116,7 +116,6 @@ import org.bukkit.craftbukkit.event.CraftPortalEvent;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Vehicle;
-import org.spigotmc.CustomTimingsHandler; // Spigot
import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.vehicle.VehicleBlockCollisionEvent;
@@ -248,7 +247,6 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
public org.bukkit.projectiles.ProjectileSource projectileSource; // For projectiles only
public boolean forceExplosionKnockback; // SPIGOT-949
public boolean persistentInvisibility = false;
- public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot
// Spigot start
public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
public final boolean defaultActivationState;
@@ -617,7 +615,6 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
}
public void move(EnumMoveType enummovetype, Vec3D vec3d) {
- org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot
if (this.noclip) {
this.a(this.getBoundingBox().c(vec3d));
this.recalcPosition();
@@ -753,7 +750,6 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
this.world.getMethodProfiler().exit();
}
- org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot
}
protected BlockPosition ap() {
diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java
index f88c3dfecdce58fbdb695103fd481e9cbd0c266c..e771d84c972cea4ca1b4b5d25cd573cfcbce4579 100644
--- a/src/main/java/net/minecraft/world/entity/EntityLiving.java
+++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java
@@ -135,7 +135,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 {
@@ -2458,7 +2458,6 @@ public abstract class EntityLiving extends Entity {
@Override
public void tick() {
- SpigotTimings.timerEntityBaseTick.startTiming(); // Spigot
super.tick();
this.t();
this.v();
@@ -2507,9 +2506,7 @@ public abstract class EntityLiving extends Entity {
}
}
- SpigotTimings.timerEntityBaseTick.stopTiming(); // Spigot
this.movementTick();
- SpigotTimings.timerEntityTickRest.startTiming(); // Spigot
double d0 = this.locX() - this.lastX;
double d1 = this.locZ() - this.lastZ;
float f = (float) (d0 * d0 + d1 * d1);
@@ -2589,8 +2586,6 @@ public abstract class EntityLiving extends Entity {
if (this.isSleeping()) {
this.pitch = 0.0F;
}
-
- SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot
}
public void updateEquipment() {
@@ -2772,7 +2767,6 @@ public abstract class EntityLiving extends Entity {
this.setMot(d4, d5, d6);
this.world.getMethodProfiler().enter("ai");
- SpigotTimings.timerEntityAI.startTiming(); // Spigot
if (this.isFrozen()) {
this.jumping = false;
this.aR = 0.0F;
@@ -2782,7 +2776,6 @@ public abstract class EntityLiving extends Entity {
this.doTick();
this.world.getMethodProfiler().exit();
}
- SpigotTimings.timerEntityAI.stopTiming(); // Spigot
this.world.getMethodProfiler().exit();
this.world.getMethodProfiler().enter("jump");
@@ -2817,9 +2810,9 @@ public abstract class EntityLiving extends Entity {
this.r();
AxisAlignedBB axisalignedbb = this.getBoundingBox();
2019-07-20 06:01:24 +02:00
- SpigotTimings.timerEntityAIMove.startTiming(); // Spigot
+ // SpigotTimings.timerEntityAIMove.startTiming(); // Spigot // Paper
this.g(new Vec3D((double) this.aR, (double) this.aS, (double) this.aT));
- SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot
+ // SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot // Paper
this.world.getMethodProfiler().exit();
this.world.getMethodProfiler().enter("push");
if (this.bf > 0) {
@@ -2827,9 +2820,7 @@ public abstract class EntityLiving extends Entity {
this.a(axisalignedbb, this.getBoundingBox());
}
Updated Upstream (Bukkit/CraftBukkit/Spigot) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Warning: this commit contains more mapping changes from upstream, As always, ensure that you have working backups and test this build before deployment; Developers working on paper will, yet again, need to delete their work/Minecraft/1.13.2 folder Bukkit Changes: 7fca5fd4 SPIGOT-4558: Preserve user order in the face of copied defaults in configurations 15c9b1eb Ignore spurious slot IDs sent by client, e.g. in enchanting tables 5d2a10c5 SPIGOT-3747: Add API for force loaded chunks d6dd2bb3 SPIGOT-3538: Add getHitBlockFace for ProjectileHitEvent 771db4aa SPIGOT-794: Call EntityPlaceEvent for Minecart placement 55462509 Add InventoryView#getSlotType 2f3ce5b6 Remove EntityTransformEvent and CustomItemTagContainer from draft API f04ad7b6 Make ProjectileLaunchEvent extend EntitySpawnEvent ccb85808 Define EntitySpawnEvent b8cc3ebe Add PlayerItemDamageEvent 184a495d Ease ClassLoader Deadlocks Where Possible 11ac4728 Expand Boolean Prompt Values in Conversation API aae62d51 Added getAllSessionData() to the Conversation API. 9290ff91 Add InventoryView#getInventory API 995e530f Add API to get / set base arrow damage CraftBukkit Changes: c4a67eed SPIGOT-4556: Fix plugins closing inventory during drop events 5be2ddcb Replace version constants with methods to prevent compiler inlining a5b9c7b3 Use API method to create offset command completions 2bc7d1df SPIGOT-3747: Add API for force loaded chunks a408f375 SPIGOT-3538: Add getHitBlockFace for ProjectileHitEvent b54b9409 SPIGOT-2864: Make Arrow / Item setTicksLived behave like FallingBlock 79ded7a8 SPIGOT-1811: Death message not shown on respawn screen b4a4f15d SPIGOT-943: InventoryCloseEvent called on death regardless of open inventory 0afed592 SPIGOT-794: Call EntityPlaceEvent for Minecart placement 2b2d084a Add InventoryView#getSlotType 01a9959a Do not use deprecated ItemSpawnEvent constructor 9642498d SPIGOT-4547: Call EntitySpawnEvent as general spawn fallback event 963f4a5f Add PlayerItemDamageEvent 63db0445 Add API to get / set base arrow damage 531c25d7 Add CraftMagicNumbers.MAPPINGS_VERSION for use by NMS plugins d05c8b14 Mappings Update bd36e200 SPIGOT-4551: Ignore invalid attribute modifier slots Spigot Changes: 518206a1 Remove redundant trove depend 1959ad21 MC-11211,SPIGOT-4552: Fix placing double slabs at y = 255 29ab5e43 SPIGOT-3661: Allow arguments in restart-script 7cc46316 SPIGOT-852: Growth modifiers for beetroots, potatoes, carrots 82e117e1 Squelch "fatal: Resolve operation not in progress" message 0a1a68e7 Mappings Update & Patch Rebuild
2019-01-01 04:15:55 +01:00
- SpigotTimings.timerEntityAICollision.startTiming(); // Spigot
this.collideNearby();
- SpigotTimings.timerEntityAICollision.stopTiming(); // Spigot
this.world.getMethodProfiler().exit();
if (!this.world.isClientSide && this.dO() && this.aG()) {
this.damageEntity(DamageSource.DROWN, 1.0F);
diff --git a/src/main/java/net/minecraft/world/entity/EntityTypes.java b/src/main/java/net/minecraft/world/entity/EntityTypes.java
index dc92b112770955f9fa49a408262da2e5bbc4bf98..a707ba365e25ea15e2e9d22110696b6136aa0c6f 100644
--- a/src/main/java/net/minecraft/world/entity/EntityTypes.java
+++ b/src/main/java/net/minecraft/world/entity/EntityTypes.java
@@ -281,7 +281,9 @@ public class EntityTypes<T extends Entity> {
return IRegistry.ENTITY_TYPE.getOptional(MinecraftKey.a(s));
}
2019-04-24 03:00:24 +02:00
- public EntityTypes(EntityTypes.b<T> entitytypes_b, EnumCreatureType enumcreaturetype, boolean flag, boolean flag1, boolean flag2, boolean flag3, ImmutableSet<Block> immutableset, EntitySize entitysize, int i, int j) {
+ public final String id;
+ public EntityTypes(EntityTypes.b<T> entitytypes_b, EnumCreatureType enumcreaturetype, boolean flag, boolean flag1, boolean flag2, boolean flag3, ImmutableSet<Block> immutableset, EntitySize entitysize, int i, int j) { this(entitytypes_b, enumcreaturetype, flag, flag1, flag2, flag3, immutableset, entitysize, i, j, "custom"); } // Paper - old signature
+ public EntityTypes(EntityTypes.b<T> entitytypes_b, EnumCreatureType enumcreaturetype, boolean flag, boolean flag1, boolean flag2, boolean flag3, ImmutableSet<Block> immutableset, EntitySize entitysize, int i, int j, String id) { // Paper - add id
this.bf = entitytypes_b;
this.bg = enumcreaturetype;
this.bl = flag3;
@@ -292,6 +294,14 @@ public class EntityTypes<T extends Entity> {
this.br = entitysize;
this.bm = i;
this.bn = j;
+
+ // Paper start - timings
+ this.id = id;
+ this.tickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "tick");
+ this.inactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "inactiveTick");
+ this.passengerTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerTick");
+ this.passengerInactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerInactiveTick");
+ // Paper end
}
@Nullable
@@ -512,6 +522,12 @@ public class EntityTypes<T extends Entity> {
return this.bn;
}
+ // Paper start - timings
+ public final co.aikar.timings.Timing tickTimer;
+ public final co.aikar.timings.Timing inactiveTickTimer;
+ public final co.aikar.timings.Timing passengerTickTimer;
+ public final co.aikar.timings.Timing passengerInactiveTickTimer;
+ // Paper end
public boolean isDeltaTracking() {
return this != EntityTypes.PLAYER && this != EntityTypes.LLAMA_SPIT && this != EntityTypes.WITHER && this != EntityTypes.BAT && this != EntityTypes.ITEM_FRAME && this != EntityTypes.LEASH_KNOT && this != EntityTypes.PAINTING && this != EntityTypes.END_CRYSTAL && this != EntityTypes.EVOKER_FANGS;
}
@@ -599,7 +615,7 @@ public class EntityTypes<T extends Entity> {
SystemUtils.a(DataConverterTypes.ENTITY_TREE, s);
}
- return new EntityTypes<>(this.a, this.b, this.d, this.e, this.f, this.g, this.c, this.j, this.h, this.i);
+ return new EntityTypes<>(this.a, this.b, this.d, this.e, this.f, this.g, this.c, this.j, this.h, this.i, s); // Paper - add id
}
}
diff --git a/src/main/java/net/minecraft/world/level/TickListServer.java b/src/main/java/net/minecraft/world/level/TickListServer.java
index e7296b8684d6d8c2f256d4a9da87f408a198c331..c221e5caf518b8c588390e438346fa58fa8c5a38 100644
--- a/src/main/java/net/minecraft/world/level/TickListServer.java
+++ b/src/main/java/net/minecraft/world/level/TickListServer.java
@@ -38,12 +38,17 @@ public class TickListServer<T> implements TickList<T> {
2020-06-25 11:27:25 +02:00
private final List<NextTickListEntry<T>> g = Lists.newArrayList();
private final Consumer<NextTickListEntry<T>> h;
2020-06-25 11:27:25 +02:00
- public TickListServer(WorldServer worldserver, Predicate<T> predicate, Function<T, MinecraftKey> function, Consumer<NextTickListEntry<T>> consumer) {
+ public TickListServer(WorldServer worldserver, Predicate<T> predicate, Function<T, MinecraftKey> function, Consumer<NextTickListEntry<T>> consumer, String timingsType) { // Paper
this.a = predicate;
this.b = function;
2020-06-25 11:27:25 +02:00
this.e = worldserver;
this.h = consumer;
2019-05-28 01:01:45 +02:00
+ this.timingCleanup = co.aikar.timings.WorldTimingsHandler.getTickList(worldserver, timingsType + " - Cleanup");
+ this.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
2019-07-20 06:01:24 +02:00
public void b() {
2019-05-28 01:01:45 +02:00
int i = this.nextTickList.size();
@@ -66,6 +71,7 @@ public class TickListServer<T> implements TickList<T> {
2020-06-25 11:27:25 +02:00
this.e.getMethodProfiler().enter("cleaning");
2019-05-28 01:01:45 +02:00
+ this.timingCleanup.startTiming(); // Paper
2019-05-14 04:20:58 +02:00
NextTickListEntry nextticklistentry;
2019-05-28 01:01:45 +02:00
while (i > 0 && iterator.hasNext()) {
@@ -81,7 +87,9 @@ public class TickListServer<T> implements TickList<T> {
2019-05-14 04:20:58 +02:00
--i;
}
}
2019-05-28 01:01:45 +02:00
+ this.timingCleanup.stopTiming(); // Paper
+ this.timingTicking.startTiming(); // Paper
2020-06-25 11:27:25 +02:00
this.e.getMethodProfiler().exitEnter("ticking");
2020-06-25 11:27:25 +02:00
while ((nextticklistentry = (NextTickListEntry) this.f.poll()) != null) {
@@ -101,6 +109,7 @@ public class TickListServer<T> implements TickList<T> {
2020-06-25 11:27:25 +02:00
}
2019-05-28 01:01:45 +02:00
}
2019-05-28 01:01:45 +02:00
+ this.timingTicking.stopTiming(); // Paper
2020-06-25 11:27:25 +02:00
this.e.getMethodProfiler().exit();
this.g.clear();
2020-06-25 11:27:25 +02:00
this.f.clear();
diff --git a/src/main/java/net/minecraft/world/level/World.java b/src/main/java/net/minecraft/world/level/World.java
index 0cbebc2095489c240fecd3fd32f5373be2a3d684..1b03c69fa7ffeca4083470a179e18be828b0a957 100644
--- a/src/main/java/net/minecraft/world/level/World.java
+++ b/src/main/java/net/minecraft/world/level/World.java
@@ -70,7 +70,6 @@ import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.item.EntityItem;
import net.minecraft.world.level.border.IWorldBorderListener;
2016-03-01 00:09:49 +01:00
import org.bukkit.Bukkit;
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
Updated Upstream (Bukkit/CraftBukkit/Spigot) Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 93e39ce1 Clarify documentation regarding getMaterial with legacyName = true c3aeaea0 Improve dependency tracker 14c9d275 Add support for transitive depends in load access warning c8afe560 SPIGOT-5526: Add EntityEnterBlockEvent 6bb6f07d SPIGOT-5548: Show error that hints towards plugins misusing reflection ed75537d SPIGOT-5546: Fix bad depend access using wrong provider in message 4e4c0ee9 Fix buggy classloader warning triggering for all classes 89586a4c Print warning when loading classes from depends that have not been specified d4fe9680 Fix bug where disablePlugin could remove ConfigurationSerializable classes from other plugins 85e683b7 Add additional checkstyle checks 612fd8e1 Correct max page count in BookMeta docs fa8a9781 Correct max title length in BookMeta docs CraftBukkit Changes: ab13a117 SPIGOT-5550: Cancelled ProjectileLaunchEvent still plays sound for eggs 44016b1d SPIGOT-5538: Using javaw to run GUI prints input error e653ae76 SPIGOT-5526: Call EntityEnterBlockEvent for bees trying to enter hives 6515ea49 SPIGOT-5537: Bee nests generated by growing trees near flower have no bees d82b3149 Remove unused CraftWorld.getId method 10763a88 Change some block == AIR checks to isAir to catch CAVE_AIR Spigot Changes: f2c1cd15 Rebuild patches bcd458ad Reformat patches
2020-01-28 20:43:57 +01:00
import org.bukkit.craftbukkit.block.CapturedBlockState;
@@ -132,7 +131,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
2016-03-01 00:09:49 +01:00
public final com.destroystokyo.paper.PaperWorldConfig paperConfig; // Paper
- public final SpigotTimings.WorldTimingsHandler timings; // Spigot
2016-03-01 00:09:49 +01:00
+ public final co.aikar.timings.WorldTimingsHandler timings; // Paper
public static BlockPosition lastPhysicsProblem; // Spigot
private org.spigotmc.TickLimiter entityLimiter;
2019-04-24 03:00:24 +02:00
private org.spigotmc.TickLimiter tileLimiter;
@@ -217,7 +216,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
2019-04-24 03:00:24 +02:00
public void c(WorldBorder worldborder, double d0) {}
2016-03-25 05:59:37 +01:00
});
2016-03-03 10:46:26 +01:00
// CraftBukkit end
2016-03-01 00:09:49 +01:00
- 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
2019-04-24 03:00:24 +02:00
this.entityLimiter = new org.spigotmc.TickLimiter(spigotConfig.entityMaxTickTime);
this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime);
}
@@ -797,15 +796,14 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
}
timings.tileEntityPending.stopTiming(); // Spigot
2016-03-01 00:09:49 +01:00
+ co.aikar.timings.TimingHistory.tileEntityTicks += this.tileEntityListTick.size(); // Paper
2019-04-24 03:00:24 +02:00
gameprofilerfiller.exit();
spigotConfig.currentPrimedTnt = 0; // Spigot
}
2018-04-22 16:40:36 +02:00
2019-04-24 03:00:24 +02:00
public void a(Consumer<Entity> consumer, Entity entity) {
try {
2019-05-14 04:20:58 +02:00
- SpigotTimings.tickEntityTimer.startTiming(); // Spigot
2019-04-24 03:00:24 +02:00
consumer.accept(entity);
2019-05-14 04:20:58 +02:00
- SpigotTimings.tickEntityTimer.stopTiming(); // Spigot
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.a(throwable, "Ticking entity");
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being ticked");
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
index bab55395ba92d0f3788e798ae0e154d62c4ec2fa..d285c4e3d9f938973bf7fb904680044b414e6236 100644
--- a/src/main/java/net/minecraft/world/level/block/Block.java
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
@@ -61,6 +61,15 @@ public class Block extends BlockBase implements IMaterial {
});
protected final BlockStateList<Block, IBlockData> blockStateList;
private IBlockData blockData;
+ // Paper start
+ 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
@Nullable
private String name;
@Nullable
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntity.java
2021-03-16 14:04:28 +01:00
index 75110c41af3e0097aef65091a2497dd87d08b4b2..9ebd91e1309938f81583eb3d4dd97fd39bcc930a 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntity.java
2021-03-16 14:04:28 +01:00
@@ -23,10 +23,12 @@ import org.bukkit.inventory.InventoryHolder;
// CraftBukkit end
import org.spigotmc.CustomTimingsHandler; // Spigot
+import co.aikar.timings.MinecraftTimings; // Paper
+import co.aikar.timings.Timing; // Paper
public abstract class TileEntity implements net.minecraft.server.KeyedObject { // Paper
- public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot
+ public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper
// CraftBukkit start - data containers
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
public CraftPersistentDataContainer persistentDataContainer;
diff --git a/src/main/java/net/minecraft/world/level/chunk/Chunk.java b/src/main/java/net/minecraft/world/level/chunk/Chunk.java
index acdcece38a4b30d6c89eb4342918ae8997db9f0b..ac576d268b23148089d404cb22d8c2f9d1a79d6e 100644
--- a/src/main/java/net/minecraft/world/level/chunk/Chunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/Chunk.java
@@ -733,6 +733,7 @@ public class Chunk implements IChunkAccess {
server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(this.bukkitChunk, this.needsDecoration));
if (this.needsDecoration) {
+ try (co.aikar.timings.Timing ignored = this.world.timings.chunkLoadPopulate.startTiming()) { // Paper
this.needsDecoration = false;
java.util.Random random = new java.util.Random();
random.setSeed(world.getSeed());
@@ -752,6 +753,7 @@ public class Chunk implements IChunkAccess {
}
}
server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk));
+ } // Paper
}
2019-04-24 03:00:24 +02:00
}
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkRegionLoader.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkRegionLoader.java
index 27703b807735d52313b93f8f606aa263571525d2..f301c7ba4b17b92c6cf2fcee6da1e67081dad4fa 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkRegionLoader.java
@@ -1,5 +1,6 @@
package net.minecraft.world.level.chunk.storage;
+import co.aikar.timings.Timings;
import com.google.common.collect.Maps;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
@@ -446,7 +447,6 @@ public class ChunkRegionLoader {
private static void loadEntities(NBTTagCompound nbttagcompound, Chunk chunk) {
NBTTagList nbttaglist = nbttagcompound.getList("Entities", 10);
World world = chunk.getWorld();
- world.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot
for (int i = 0; i < nbttaglist.size(); ++i) {
NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i);
@@ -458,8 +458,6 @@ public class ChunkRegionLoader {
chunk.d(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) {
@@ -477,8 +475,6 @@ public class ChunkRegionLoader {
}
}
}
- world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot
-
}
private static NBTTagCompound a(ChunkCoordIntPair chunkcoordintpair, Map<StructureGenerator<?>, StructureStart<?>> map, Map<StructureGenerator<?>, LongSet> map1) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 82f5b3387f9e71ae258111b7196986623452dc02..0c1e12b0b43f949d4ace600b2ccdffe52faab1e6 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2074,12 +2074,31 @@ public final class CraftServer implements Server {
private final org.bukkit.Server.Spigot spigot = new org.bukkit.Server.Spigot()
2016-03-01 00:09:49 +01:00
{
+ @Deprecated
@Override
public YamlConfiguration getConfig()
{
return org.spigotmc.SpigotConfig.config;
2016-03-01 00:09:49 +01:00
}
+ @Override
+ public YamlConfiguration getBukkitConfig()
+ {
+ return configuration;
+ }
+
+ @Override
+ public YamlConfiguration getSpigotConfig()
+ {
2016-03-01 00:09:49 +01:00
+ return org.spigotmc.SpigotConfig.config;
+ }
+
+ @Override
+ public YamlConfiguration getPaperConfig()
+ {
2016-03-01 00:09:49 +01:00
+ 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
index ebf2c62e9ea126577a6cbcbbeb3f3aba259a1f63..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
2021-02-21 21:55:01 +01:00
+++ b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
2020-06-25 11:27:25 +02:00
@@ -1,163 +0,0 @@
-package org.bukkit.craftbukkit;
-
-import java.util.HashMap;
-import net.minecraft.world.entity.Entity;
-import net.minecraft.world.level.World;
-import net.minecraft.world.level.block.entity.TileEntity;
-import net.minecraft.world.level.storage.WorldDataServer;
-import org.bukkit.craftbukkit.scheduler.CraftTask;
2019-04-24 03:00:24 +02:00
-import org.bukkit.plugin.java.JavaPluginLoader;
-import org.bukkit.scheduler.BukkitTask;
-import org.spigotmc.CustomTimingsHandler;
-
-public class SpigotTimings {
-
- public static final CustomTimingsHandler serverTickTimer = new CustomTimingsHandler("** Full Server Tick");
- public static final CustomTimingsHandler playerListTimer = new CustomTimingsHandler("Player List");
2017-05-14 20:05:01 +02:00
- public static final CustomTimingsHandler commandFunctionsTimer = new CustomTimingsHandler("Command Functions");
- public static final CustomTimingsHandler connectionTimer = new CustomTimingsHandler("Connection Handler");
2018-10-28 23:08:08 +01:00
- public static final CustomTimingsHandler playerConnectionTimer = new CustomTimingsHandler("** PlayerConnection");
- public static final CustomTimingsHandler tickablesTimer = new CustomTimingsHandler("Tickables");
- public static final CustomTimingsHandler schedulerTimer = new CustomTimingsHandler("Scheduler");
- 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 {
- plugin = "Unknown";
- }
- String taskname = ctask.getTaskName();
-
- String name = "Task: " + plugin + " Runnable: " + taskname;
- if (period > 0) {
2021-02-21 21:55:01 +01:00
- 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) {
2017-10-29 16:19:21 +01:00
- String entityType = entity.getClass().getName();
- CustomTimingsHandler result = entityTypeTimingMap.get(entityType);
- if (result == null) {
2017-10-29 16:19:21 +01:00
- 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) {
2017-10-29 16:19:21 +01:00
- String entityType = entity.getClass().getName();
- CustomTimingsHandler result = tileEntityTypeTimingMap.get(entityType);
- if (result == null) {
2017-10-29 16:19:21 +01:00
- 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 doTickPending;
- public final CustomTimingsHandler doTickTiles;
- public final CustomTimingsHandler doChunkMap;
- 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 syncChunkLoadStructuresTimer;
- public final CustomTimingsHandler syncChunkLoadEntitiesTimer;
- public final CustomTimingsHandler syncChunkLoadTileEntitiesTimer;
- public final CustomTimingsHandler syncChunkLoadTileTicksTimer;
- public final CustomTimingsHandler syncChunkLoadPostTimer;
-
- public WorldTimingsHandler(World server) {
2020-06-25 11:27:25 +02:00
- String name = ((WorldDataServer) server.worldData).getName() + " - ";
-
- mobSpawn = new CustomTimingsHandler("** " + name + "mobSpawn");
- doChunkUnload = new CustomTimingsHandler("** " + name + "doChunkUnload");
- doTickPending = new CustomTimingsHandler("** " + name + "doTickPending");
- doTickTiles = new CustomTimingsHandler("** " + name + "doTickTiles");
- doChunkMap = new CustomTimingsHandler("** " + name + "doChunkMap");
- doSounds = new CustomTimingsHandler("** " + name + "doSounds");
- entityTick = new CustomTimingsHandler("** " + name + "entityTick");
- tileEntityTick = new CustomTimingsHandler("** " + name + "tileEntityTick");
- tileEntityPending = new CustomTimingsHandler("** " + name + "tileEntityPending");
-
- syncChunkLoadTimer = new CustomTimingsHandler("** " + name + "syncChunkLoad");
- 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/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index c3a06eabbff3c37c88b1f09fe4bf806418e3a4d4..b51a874e4665f977a154792e6216e03e04525f39 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1808,6 +1808,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
2016-03-01 00:09:49 +01:00
packet.components = components;
getHandle().playerConnection.sendPacket(packet);
}
+
+ // Paper start
+ @Override
+ public int getPing()
+ {
+ return getHandle().ping;
+ }
+ // Paper end
};
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 4bf48f77f3f7cd62a91590543f5af441c8268029..ffe9cc1011226d604dc5499e7692e9a9a5132b72 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
2019-04-24 03:00:24 +02:00
@@ -1,5 +1,6 @@
package org.bukkit.craftbukkit.scheduler;
+import co.aikar.timings.MinecraftTimings; // Paper
2019-04-24 03:00:24 +02:00
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.ArrayList;
import java.util.Comparator;
@@ -179,7 +180,8 @@ public class CraftScheduler implements BukkitScheduler {
}
public BukkitTask scheduleInternalTask(Runnable run, int delay, String taskName) {
- final CraftTask task = new CraftTask(run, nextId(), taskName);
+ final CraftTask task = new CraftTask(run, nextId(), "Internal - " + (taskName != null ? taskName : "Unknown"));
+ task.internal = true;
return handle(task, delay);
}
@@ -260,7 +262,7 @@ public class CraftScheduler implements BukkitScheduler {
}
return false;
}
- });
+ }){{this.timings=co.aikar.timings.MinecraftTimings.getCancelTasksTimer();}}; // Paper
2018-03-31 11:34:25 +02:00
handle(task, 0L);
for (CraftTask taskPending = head.getNext(); taskPending != null; taskPending = taskPending.getNext()) {
if (taskPending == task) {
@@ -295,7 +297,7 @@ public class CraftScheduler implements BukkitScheduler {
}
}
}
- });
+ }){{this.timings=co.aikar.timings.MinecraftTimings.getCancelTasksTimer(plugin);}}; // Paper
2018-03-31 11:34:25 +02:00
handle(task, 0L);
for (CraftTask taskPending = head.getNext(); taskPending != null; taskPending = taskPending.getNext()) {
if (taskPending == task) {
@@ -402,9 +404,7 @@ public class CraftScheduler implements BukkitScheduler {
if (task.isSync()) {
2018-06-21 05:29:33 +02:00
currentTask = task;
try {
- task.timings.startTiming(); // Spigot
task.run();
- task.timings.stopTiming(); // Spigot
} catch (final Throwable throwable) {
// Paper start
String msg = String.format(
@@ -438,8 +438,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);
}
@@ -472,6 +474,7 @@ public class CraftScheduler implements BukkitScheduler {
}
private void parsePending() {
+ MinecraftTimings.bukkitSchedulerPendingTimer.startTiming();
CraftTask head = this.head;
CraftTask task = head.getNext();
CraftTask lastTask = head;
@@ -490,6 +493,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 09aa6809c5400ce8548ac902908b750ce7c964ec..3c96807e97657502849093e4371e9fef3584a346 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
@@ -1,12 +1,15 @@
package org.bukkit.craftbukkit.scheduler;
import java.util.function.Consumer;
+
+import co.aikar.timings.NullTimingHandler;
import org.bukkit.Bukkit;
2021-02-21 21:55:01 +01:00
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitTask;
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
import org.spigotmc.CustomTimingsHandler; // Spigot
+import co.aikar.timings.MinecraftTimings; // Paper
2016-03-01 00:09:49 +01:00
+import co.aikar.timings.Timing; // Paper
2021-02-21 21:55:01 +01:00
public class CraftTask implements BukkitTask, Runnable { // Spigot
@@ -26,12 +29,12 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
*/
private volatile long period;
private long nextRun;
- private final Runnable rTask;
- private final Consumer<BukkitTask> cTask;
+ public final Runnable rTask; // Paper
+ public final Consumer<BukkitTask> cTask; // Paper
2016-03-01 00:09:49 +01:00
+ public Timing timings; // Paper
private final Plugin plugin;
private final int id;
- final CustomTimingsHandler timings; // Spigot
CraftTask() {
2018-03-31 11:34:25 +02:00
this(null, null, CraftTask.NO_REPEATING, CraftTask.NO_REPEATING);
}
@@ -51,7 +54,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
this.id = id;
this.period = CraftTask.NO_REPEATING;
this.taskName = taskName;
- this.timings = null; // Will be changed in later patch
+ this.timings = MinecraftTimings.getInternalTaskName(taskName);
}
// Paper end
@@ -72,7 +75,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
}
this.id = id;
this.period = period;
- this.timings = this.isSync() ? SpigotTimings.getPluginTaskTimings(this, period) : null; // Spigot
+ timings = task != null ? MinecraftTimings.getPluginTaskTimings(this, period) : NullTimingHandler.NULL; // Paper
}
@Override
@@ -92,11 +95,13 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
@Override
public void run() {
+ try (Timing ignored = timings.startTiming()) { // Paper
if (rTask != null) {
rTask.run();
} else {
cTask.accept(this);
}
+ } // Paper
}
long getPeriod() {
@@ -123,7 +128,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
this.next = next;
}
- Class<?> getTaskClass() {
+ public Class<?> getTaskClass() {
return (rTask != null) ? rTask.getClass() : ((cTask != null) ? cTask.getClass() : null);
}
@@ -147,9 +152,4 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
return true;
}
- // Spigot start
- public String getTaskName() {
- return (getTaskClass() == null) ? "Unknown" : getTaskClass().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 e52ef47b783785dc214746b678e7b549aea9a274..3d90b3426873a3528af14f7f1ab0adae0027da2e 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;
2016-03-01 00:09:49 +01:00
+ public String getData() { return value; } // Paper
public CraftIconCache(final String value) {
this.value = value;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index 972840fd32cd4b6cb73b7f97d06dcd5699c28ba4..65131f0977fa55c4761c34ce52720170feb61a72 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -158,6 +158,12 @@ public final class CraftMagicNumbers implements UnsafeValues {
return CraftNamespacedKey.toMinecraft(mat.getKey());
}
// ========================================================================
+ // Paper start
+ @Override
+ public void reportTimings() {
+ co.aikar.timings.TimingsExport.reportTimings();
+ }
+ // Paper end
public static byte toLegacyData(IBlockData data) {
return CraftLegacy.toLegacyData(data);
@@ -332,6 +338,13 @@ public final class CraftMagicNumbers implements UnsafeValues {
return clazz;
}
+ // Paper start
+ @Override
+ public String getTimingsServerName() {
+ return com.destroystokyo.paper.PaperConfig.timingsServerName;
+ }
+ // Paper end
+
/**
* This helper class represents the different NBT Tags.
* <p>
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
index 44a7323ffbdf91f8e0672e0fadf0d3d26ed9a290..69c5d4e51ebf747d931fadc819973e36f001f5bc 100644
--- a/src/main/java/org/spigotmc/ActivationRange.java
+++ b/src/main/java/org/spigotmc/ActivationRange.java
@@ -29,7 +29,7 @@ import net.minecraft.world.entity.raid.EntityRaider;
import net.minecraft.world.level.World;
import net.minecraft.world.level.chunk.Chunk;
import net.minecraft.world.phys.AxisAlignedBB;
-import org.bukkit.craftbukkit.SpigotTimings;
+import co.aikar.timings.MinecraftTimings;
public class ActivationRange
{
2021-02-21 21:55:01 +01:00
@@ -73,8 +73,8 @@ public class ActivationRange
/**
* These entities are excluded from Activation range checks.
*
- * @param entity
- * @param config
+ * @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)
2021-02-21 21:55:01 +01:00
@@ -109,7 +109,7 @@ public class ActivationRange
*/
public static void activateEntities(World world)
{
- SpigotTimings.entityActivationCheckTimer.startTiming();
+ MinecraftTimings.entityActivationCheckTimer.startTiming();
final int miscActivationRange = world.spigotConfig.miscActivationRange;
final int raiderActivationRange = world.spigotConfig.raiderActivationRange;
final int animalActivationRange = world.spigotConfig.animalActivationRange;
2021-02-21 21:55:01 +01:00
@@ -146,7 +146,7 @@ public class ActivationRange
}
}
}
- SpigotTimings.entityActivationCheckTimer.stopTiming();
+ MinecraftTimings.entityActivationCheckTimer.stopTiming();
}
/**
2021-02-21 21:55:01 +01:00
@@ -243,10 +243,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;
}
2021-02-21 21:55:01 +01:00
@@ -270,7 +268,6 @@ public class ActivationRange
{
isActive = false;
}
- SpigotTimings.checkIfActiveTimer.stopTiming();
return isActive;
}
}