2021-06-11 14:02:28 +02:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 3 Mar 2016 04:00:11 -0600
Subject: [PATCH] Timings v2
diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java
new file mode 100644
2023-03-28 04:58:46 +02:00
index 0000000000000000000000000000000000000000..59affb62cb487d60e8c3e32decf89d6cb7d22f8d
2021-06-11 14:02:28 +02:00
--- /dev/null
+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java
2023-03-28 04:58:46 +02:00
@@ -0,0 +1,169 @@
2021-06-11 14:02:28 +02:00
+package co.aikar.timings;
+
+import com.google.common.collect.MapMaker;
2022-06-09 10:51:45 +02:00
+import io.papermc.paper.configuration.GlobalConfiguration;
2021-06-11 14:02:28 +02:00
+import net.minecraft.commands.CommandFunction;
+import net.minecraft.network.protocol.Packet;
+import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.scheduler.BukkitTask;
+
+import org.bukkit.craftbukkit.scheduler.CraftTask;
+
+import java.util.Map;
+
+// TODO: Re-implement missing timers
2023-03-28 04:58:46 +02:00
+@Deprecated(forRemoval = true)
2021-06-11 14:02:28 +02:00
+public final class MinecraftTimings {
+
+ public static final Timing serverOversleep = Timings.ofSafe("Server Oversleep");
+ public static final Timing playerListTimer = Timings.ofSafe("Player List");
+ public static final Timing commandFunctionsTimer = Timings.ofSafe("Command Functions");
+ public static final Timing connectionTimer = Timings.ofSafe("Connection Handler");
+ public static final Timing tickablesTimer = Timings.ofSafe("Tickables");
+ public static final Timing minecraftSchedulerTimer = Timings.ofSafe("Minecraft Scheduler");
+ public static final Timing bukkitSchedulerTimer = Timings.ofSafe("Bukkit Scheduler");
+ public static final Timing bukkitSchedulerPendingTimer = Timings.ofSafe("Bukkit Scheduler - Pending");
+ public static final Timing bukkitSchedulerFinishTimer = Timings.ofSafe("Bukkit Scheduler - Finishing");
+ public static final Timing chunkIOTickTimer = Timings.ofSafe("ChunkIOTick");
+ public static final Timing timeUpdateTimer = Timings.ofSafe("Time Update");
+ public static final Timing serverCommandTimer = Timings.ofSafe("Server Command");
+ public static final Timing savePlayers = Timings.ofSafe("Save Players");
+
+ public static final Timing tickEntityTimer = Timings.ofSafe("## tickEntity");
+ public static final Timing tickTileEntityTimer = Timings.ofSafe("## tickTileEntity");
+ public static final Timing packetProcessTimer = Timings.ofSafe("## Packet Processing");
+ public static final Timing scheduledBlocksTimer = Timings.ofSafe("## Scheduled Blocks");
+ public static final Timing structureGenerationTimer = Timings.ofSafe("Structure Generation");
+
+ public static final Timing processQueueTimer = Timings.ofSafe("processQueue");
+ public static final Timing processTasksTimer = Timings.ofSafe("processTasks");
+
+ 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() {}
+
+ public static Timing getInternalTaskName(String taskName) {
+ return Timings.ofSafe(taskName);
+ }
+
+ /**
+ * 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;
+ }
+ Plugin plugin;
+
+ CraftTask craftTask = (CraftTask) bukkitTask;
+
+ final Class<?> taskClass = craftTask.getTaskClass();
+ 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";
+ }
+ });
+
+ StringBuilder name = new StringBuilder(64);
+ name.append("Task: ").append(taskname);
+ if (period > 0) {
+ name.append(" (interval:").append(period).append(")");
+ } else {
+ name.append(" (Single)");
+ }
+
+ if (plugin == null) {
+ return Timings.ofSafe(null, name.toString());
+ }
+
+ return Timings.ofSafe(plugin, name.toString());
+ }
+
+ /**
+ * Get a named timer for the specified entity type to track type specific timings.
+ * @param entityType
+ * @return
+ */
+ public static Timing getEntityTimings(String entityType, String type) {
+ return Timings.ofSafe("Minecraft", "## tickEntity - " + entityType + " - " + type, tickEntityTimer);
+ }
+
+ /**
+ * Get a named timer for the specified tile entity type to track type specific timings.
+ * @param entity
+ * @return
+ */
+ public static Timing getTileEntityTimings(BlockEntity entity) {
+ String entityType = entity.getClass().getName();
+ return Timings.ofSafe("Minecraft", "## tickTileEntity - " + entityType, tickTileEntityTimer);
+ }
+ public static Timing getCancelTasksTimer() {
+ return Timings.ofSafe("Cancel Tasks");
+ }
+ public static Timing getCancelTasksTimer(Plugin plugin) {
+ return Timings.ofSafe(plugin, "Cancel Tasks");
+ }
+
+ public static void stopServer() {
+ TimingsManager.stopServer();
+ }
+
+ public static Timing getBlockTiming(Block block) {
+ return Timings.ofSafe("## Scheduled Block: " + block.toString(), scheduledBlocksTimer);
+ }
+/*
+ public static Timing getStructureTiming(StructureGenerator structureGenerator) {
+ return Timings.ofSafe("Structure Generator - " + structureGenerator.getName(), structureGenerationTimer);
+ }*/
+
+ public static Timing getPacketTiming(Packet packet) {
+ return Timings.ofSafe("## Packet - " + packet.getClass().getName(), packetProcessTimer);
+ }
+
+ public static Timing getCommandFunctionTiming(CommandFunction function) {
2021-06-16 19:48:25 +02:00
+ return Timings.ofSafe("Command Function - " + function.getId());
2021-06-11 14:02:28 +02:00
+ }
2022-06-09 10:51:45 +02:00
+
+ public static void processConfig(GlobalConfiguration.Timings config) {
+ TimingsManager.url = config.url;
+ if (!TimingsManager.url.endsWith("/")) {
+ TimingsManager.url += "/";
+ }
+ TimingsManager.privacy = config.serverNamePrivacy;
+ if (!config.hiddenConfigEntries.contains("proxies.velocity.secret")) {
+ config.hiddenConfigEntries.add("proxies.velocity.secret");
+ }
2022-06-12 19:29:27 +02:00
+ TimingsManager.hiddenConfigs.addAll(config.hiddenConfigEntries);
2022-06-09 10:51:45 +02:00
+ co.aikar.timings.Timings.setVerboseTimingsEnabled(config.verbose);
+ co.aikar.timings.Timings.setTimingsEnabled(config.enabled);
+ co.aikar.timings.Timings.setHistoryInterval(config.historyInterval * 20);
+ co.aikar.timings.Timings.setHistoryLength(config.historyLength * 20);
+ }
2021-06-11 14:02:28 +02:00
+}
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
new file mode 100644
2023-03-28 04:58:46 +02:00
index 0000000000000000000000000000000000000000..38f01952153348d937e326da0ec102cd9b0f80af
2021-06-11 14:02:28 +02:00
--- /dev/null
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
2023-03-28 04:58:46 +02:00
@@ -0,0 +1,386 @@
2021-06-11 14:02:28 +02:00
+/*
+ * 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;
2022-06-03 06:26:56 +02:00
+import io.papermc.paper.adventure.PaperAdventure;
2022-06-08 22:27:24 +02:00
+import net.kyori.adventure.text.event.ClickEvent;
2022-06-03 06:26:56 +02:00
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
2021-06-11 14:02:28 +02:00
+import net.minecraft.server.MinecraftServer;
+import org.apache.commons.lang.StringUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.MemorySection;
+import org.bukkit.entity.EntityType;
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
2022-03-09 10:06:58 +01:00
+import oshi.SystemInfo;
+import oshi.hardware.HardwareAbstractionLayer;
2021-06-11 14:02:28 +02:00
+
+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;
2022-06-03 06:26:56 +02:00
+import static net.kyori.adventure.text.Component.text;
2021-06-11 14:02:28 +02:00
+
+@SuppressWarnings({"rawtypes", "SuppressionAnnotation"})
2023-03-28 04:58:46 +02:00
+@Deprecated(forRemoval = true)
2021-06-11 14:02:28 +02:00
+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) {
2022-06-03 06:26:56 +02:00
+ listeners.sendMessage(text("Please wait at least 1 minute in between Timings reports. (" + (int)((60000 - lastReportDiff) / 1000) + " seconds)", NamedTextColor.RED));
2021-06-11 14:02:28 +02:00
+ listeners.done();
+ return;
+ }
+ final long lastStartDiff = now - TimingsManager.timingStart;
+ if (lastStartDiff < 180000) {
2022-06-03 06:26:56 +02:00
+ listeners.sendMessage(text("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)", NamedTextColor.RED));
2021-06-11 14:02:28 +02:00
+ listeners.done();
+ return;
+ }
2022-06-03 06:26:56 +02:00
+ listeners.sendMessage(text("Preparing Timings Report...", NamedTextColor.GREEN));
2021-06-11 14:02:28 +02:00
+ 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),
2021-06-11 20:26:56 +02:00
+ pair("datapacks", toArrayMapper(MinecraftServer.getServer().getPackRepository().getSelectedPacks(), pack -> {
2022-06-03 06:26:56 +02:00
+ return PlainTextComponentSerializer.plainText().serialize(PaperAdventure.asAdventure(pack.getChatLink(true)));
2021-06-11 14:02:28 +02:00
+ }))
+ );
+ 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();
+
2022-03-09 10:06:58 +01:00
+ HardwareAbstractionLayer hardwareInfo = new SystemInfo().getHardware();
+
2021-06-11 14:02:28 +02:00
+ 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")),
2022-03-09 10:06:58 +01:00
+ pair("jvmvendor", System.getProperty("java.vendor")),
+ pair("jvmvendorversion", System.getProperty("java.vendor.version")),
2021-06-11 14:02:28 +02:00
+ 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()),
2022-03-09 10:06:58 +01:00
+ pair("cpuname", hardwareInfo.getProcessor().getProcessorIdentifier().getName().trim()),
2021-06-11 14:02:28 +02:00
+ 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().getAllLevels(), world -> {
2021-06-12 00:37:16 +02:00
+ if (world.getWorld().getName().equals("worldeditregentempworld")) return null;
+ return pair(world.getWorld().getName(), createObject(
2021-06-11 14:02:28 +02:00
+ pair("gamerules", toObjectMapper(world.getWorld().getGameRules(), rule -> {
+ return pair(rule, world.getWorld().getGameRuleValue(rule));
+ })),
2021-06-11 20:26:56 +02:00
+ pair("ticking-distance", world.getChunkSource().chunkMap.getEffectiveViewDistance())
2021-06-11 14:02:28 +02:00
+ ));
+ }));
+
+ 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 {
2021-07-25 09:10:30 +02:00
+ HttpURLConnection con = (HttpURLConnection) new URL(TimingsManager.url + "post").openConnection();
2021-06-11 14:02:28 +02:00
+ 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) {
2022-06-03 06:26:56 +02:00
+ listeners.sendMessage(text( "Upload Error: " + con.getResponseCode() + ": " + con.getResponseMessage(), NamedTextColor.RED));
+ listeners.sendMessage(text("Check your logs for more information", NamedTextColor.RED));
2021-06-11 14:02:28 +02:00
+ if (response != null) {
+ Bukkit.getLogger().log(Level.SEVERE, response);
+ }
+ return;
+ }
+
+ timingsURL = con.getHeaderField("Location");
2022-06-08 22:27:24 +02:00
+ listeners.sendMessage(text("View Timings Report: ", NamedTextColor.GREEN).append(text(timingsURL).clickEvent(ClickEvent.clickEvent(ClickEvent.Action.OPEN_URL, timingsURL))));
2021-06-11 14:02:28 +02:00
+
+ if (response != null && !response.isEmpty()) {
+ Bukkit.getLogger().log(Level.INFO, "Timing Response: " + response);
+ }
+ } catch (IOException ex) {
2022-06-03 06:26:56 +02:00
+ listeners.sendMessage(text("Error uploading timings, check your logs for more information", NamedTextColor.RED));
2021-06-11 14:02:28 +02:00
+ 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) {
2022-06-03 06:26:56 +02:00
+ listeners.sendMessage(text("Error uploading timings, check your logs for more information", NamedTextColor.RED));
2021-06-11 14:02:28 +02:00
+ Bukkit.getLogger().log(Level.WARNING, con.getResponseMessage(), ex);
+ return null;
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+}
diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java
new file mode 100644
2023-03-28 04:58:46 +02:00
index 0000000000000000000000000000000000000000..2f0d9b953802dee821cfde82d22b0567cce8ee91
2021-06-11 14:02:28 +02:00
--- /dev/null
+++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java
2023-03-28 04:58:46 +02:00
@@ -0,0 +1,120 @@
2021-06-11 14:02:28 +02:00
+package co.aikar.timings;
+
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.storage.PrimaryLevelData;
+
+/**
+ * Set of timers per world, to track world specific timings.
+ */
+// TODO: Re-implement missing timers
2023-03-28 04:58:46 +02:00
+@Deprecated(forRemoval = true)
2021-06-11 14:02:28 +02: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;
+ public final Timing chunkTicksBlocks;
+ public final Timing doVillages;
+ public final Timing doChunkMap;
+ public final Timing doChunkMapUpdate;
+ public final Timing doChunkMapToUpdate;
+ public final Timing doChunkMapSortMissing;
+ public final Timing doChunkMapSortSendToPlayers;
+ public final Timing doChunkMapPlayersNeedingChunks;
+ public final Timing doChunkMapPendingSendToPlayers;
+ public final Timing doChunkMapUnloadChunks;
+ public final Timing doChunkGC;
+ public final Timing doSounds;
+ public final Timing entityRemoval;
+ public final Timing entityTick;
+ public final Timing tileEntityTick;
+ public final Timing tileEntityPending;
+ public final Timing tracker1;
+ public final Timing tracker2;
+ public final Timing doTick;
+ public final Timing tickEntities;
+ public final Timing chunks;
+ public final Timing newEntities;
+ public final Timing raids;
+ public final Timing chunkProviderTick;
+ public final Timing broadcastChunkUpdates;
+ public final Timing countNaturalMobs;
+
+ 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;
+
+
+ public final Timing miscMobSpawning;
+
+ public WorldTimingsHandler(Level server) {
+ String name = ((PrimaryLevelData) server.getLevelData()).getLevelName() + " - ";
+
+ mobSpawn = Timings.ofSafe(name + "mobSpawn");
+ doChunkUnload = Timings.ofSafe(name + "doChunkUnload");
+ scheduledBlocks = Timings.ofSafe(name + "Scheduled Blocks");
+ scheduledBlocksCleanup = Timings.ofSafe(name + "Scheduled Blocks - Cleanup");
+ scheduledBlocksTicking = Timings.ofSafe(name + "Scheduled Blocks - Ticking");
+ chunkTicks = Timings.ofSafe(name + "Chunk Ticks");
+ lightChunk = Timings.ofSafe(name + "Light Chunk");
+ chunkTicksBlocks = Timings.ofSafe(name + "Chunk Ticks - Blocks");
+ doVillages = Timings.ofSafe(name + "doVillages");
+ doChunkMap = Timings.ofSafe(name + "doChunkMap");
+ doChunkMapUpdate = Timings.ofSafe(name + "doChunkMap - Update");
+ doChunkMapToUpdate = Timings.ofSafe(name + "doChunkMap - To Update");
+ doChunkMapSortMissing = Timings.ofSafe(name + "doChunkMap - Sort Missing");
+ doChunkMapSortSendToPlayers = Timings.ofSafe(name + "doChunkMap - Sort Send To Players");
+ doChunkMapPlayersNeedingChunks = Timings.ofSafe(name + "doChunkMap - Players Needing Chunks");
+ doChunkMapPendingSendToPlayers = Timings.ofSafe(name + "doChunkMap - Pending Send To Players");
+ doChunkMapUnloadChunks = Timings.ofSafe(name + "doChunkMap - Unload Chunks");
+ doSounds = Timings.ofSafe(name + "doSounds");
+ doChunkGC = Timings.ofSafe(name + "doChunkGC");
+ doPortalForcer = Timings.ofSafe(name + "doPortalForcer");
+ entityTick = Timings.ofSafe(name + "entityTick");
+ entityRemoval = Timings.ofSafe(name + "entityRemoval");
+ tileEntityTick = Timings.ofSafe(name + "tileEntityTick");
+ tileEntityPending = Timings.ofSafe(name + "tileEntityPending");
+
+ 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");
+
+ tracker1 = Timings.ofSafe(name + "tracker stage 1");
+ tracker2 = Timings.ofSafe(name + "tracker stage 2");
+ 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");
+ }
+
+ public static Timing getTickList(ServerLevel worldserver, String timingsType) {
+ return Timings.ofSafe(((PrimaryLevelData) worldserver.getLevelData()).getLevelName() + " - Scheduled " + timingsType);
+ }
+}
diff --git a/src/main/java/net/minecraft/commands/CommandFunction.java b/src/main/java/net/minecraft/commands/CommandFunction.java
2022-12-07 17:46:46 +01:00
index 3ceeddf4c2898172d24db9ee1bab8d6b17e36128..8273ee1c5e513f02c9743ee38c9b7cf700e2ecad 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/commands/CommandFunction.java
+++ b/src/main/java/net/minecraft/commands/CommandFunction.java
2021-06-16 19:48:25 +02:00
@@ -16,6 +16,15 @@ import net.minecraft.server.ServerFunctionManager;
2021-06-11 20:02:16 +02:00
public class CommandFunction {
2021-06-11 14:02:28 +02:00
private final CommandFunction.Entry[] entries;
2021-06-11 20:02:16 +02:00
final ResourceLocation id;
2021-06-11 14:02:28 +02:00
+ // 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 CommandFunction(ResourceLocation id, CommandFunction.Entry[] elements) {
this.id = id;
diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java
2023-03-14 19:05:23 +01:00
index fc4dcd801480fe6d89a985de411baa9a3a66f6ef..4a1148a76020089caf01f888f87afdbb35788dc0 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java
+++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java
2022-03-01 06:43:03 +01:00
@@ -26,7 +26,8 @@ public class PacketUtils {
engine.executeIfPossible(() -> {
2021-06-11 14:02:28 +02:00
if (MinecraftServer.getServer().hasStopped() || (listener instanceof ServerGamePacketListenerImpl && ((ServerGamePacketListenerImpl) listener).processedDisconnect)) return; // CraftBukkit, MC-142590
2023-03-14 19:05:23 +01:00
if (listener.isAcceptingMessages()) {
2022-03-01 06:43:03 +01:00
- try {
+ co.aikar.timings.Timing timing = co.aikar.timings.MinecraftTimings.getPacketTiming(packet); // Paper - timings
+ try (co.aikar.timings.Timing ignored = timing.startTiming()) { // Paper - timings
packet.handle(listener);
} catch (Exception exception) {
if (listener.shouldPropagateHandlingExceptions()) {
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
2023-06-13 01:51:45 +02:00
index 3250a9310b57351d6d832a8ef42837d990cf6c99..f0cd94f877a83485ab8e96e1c4e00bf658f227b7 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
2022-12-07 18:53:34 +01:00
@@ -189,7 +189,7 @@ import org.bukkit.event.player.AsyncPlayerChatPreviewEvent;
2021-06-11 14:02:28 +02:00
import org.bukkit.event.server.ServerLoadEvent;
// CraftBukkit end
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
+import co.aikar.timings.MinecraftTimings; // Paper
2021-11-23 11:51:25 +01:00
public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTask> implements CommandSource, AutoCloseable {
2022-03-13 08:47:54 +01:00
2023-06-13 01:51:45 +02:00
@@ -861,6 +861,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2021-06-11 14:02:28 +02:00
}
2022-06-07 21:15:06 +02:00
2021-06-11 14:02:28 +02:00
MinecraftServer.LOGGER.info("Stopping server");
+ MinecraftTimings.stopServer(); // Paper
// CraftBukkit start
if (this.server != null) {
this.server.disablePlugins();
2023-06-13 01:51:45 +02:00
@@ -1099,9 +1100,21 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2021-06-11 14:02:28 +02:00
private boolean haveTime() {
// CraftBukkit start
+ if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken
return this.forceTicks || this.runningTask() || Util.getMillis() < (this.mayHaveDelayedTasks ? this.delayedTasksMaxNextTickTime : this.nextTickTime);
}
+ // Paper start
+ boolean isOversleep = false;
+ private boolean canOversleep() {
2021-06-17 23:39:36 +02:00
+ return this.mayHaveDelayedTasks && Util.getMillis() < this.delayedTasksMaxNextTickTime;
2021-06-11 14:02:28 +02:00
+ }
+
+ private boolean canSleepForTickNoOversleep() {
+ return this.forceTicks || this.runningTask() || Util.getMillis() < this.nextTickTime;
+ }
+ // Paper end
+
private void executeModerately() {
this.runAllTasks();
java.util.concurrent.locks.LockSupport.parkNanos("executing tasks", 1000L);
2023-06-13 01:51:45 +02:00
@@ -1109,9 +1122,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2021-06-11 14:02:28 +02:00
// CraftBukkit end
protected void waitUntilNextTick() {
- this.runAllTasks();
+ //this.executeAll(); // Paper - move this into the tick method for timings
this.managedBlock(() -> {
- return !this.haveTime();
+ return !this.canSleepForTickNoOversleep(); // Paper - move oversleep into full server tick
});
}
2023-06-13 01:51:45 +02:00
@@ -1196,9 +1209,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2021-06-11 20:02:16 +02:00
public void onServerExit() {}
2021-06-11 14:02:28 +02:00
2021-06-11 20:02:16 +02:00
public void tickServer(BooleanSupplier shouldKeepTicking) {
2021-06-11 14:02:28 +02:00
- SpigotTimings.serverTickTimer.startTiming(); // Spigot
+ co.aikar.timings.TimingsManager.FULL_SERVER_TICK.startTiming(); // Paper
long i = Util.getNanos();
+ // Paper start - move oversleep into full server tick
+ isOversleep = true;MinecraftTimings.serverOversleep.startTiming();
+ this.managedBlock(() -> {
+ return !this.canOversleep();
+ });
+ isOversleep = false;MinecraftTimings.serverOversleep.stopTiming();
+ // Paper end
+
++this.tickCount;
this.tickChildren(shouldKeepTicking);
if (i - this.lastServerStatus >= 5000000000L) {
2023-06-13 01:51:45 +02:00
@@ -1207,15 +1228,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2021-06-11 14:02:28 +02:00
}
2021-06-11 20:02:16 +02:00
if (this.autosavePeriod > 0 && this.tickCount % this.autosavePeriod == 0) { // CraftBukkit
2021-06-11 14:02:28 +02:00
- SpigotTimings.worldSaveTimer.startTiming(); // Spigot
MinecraftServer.LOGGER.debug("Autosave started");
this.profiler.push("save");
2021-11-23 11:51:25 +01:00
this.saveEverything(true, false, false);
2021-06-11 14:02:28 +02:00
this.profiler.pop();
MinecraftServer.LOGGER.debug("Autosave finished");
- SpigotTimings.worldSaveTimer.stopTiming(); // Spigot
}
Merge tuinity (#6413)
This PR contains all of Tuinity's patches. Very notable ones are:
- Highly optimised collisions
- Optimised entity lookups by bounding box (Mojang made regressions in 1.17, this brings it back to 1.16)
- Starlight https://github.com/PaperMC/Starlight
- Rewritten dataconverter system https://github.com/PaperMC/DataConverter
- Random block ticking optimisation (wrongly dropped from Paper 1.17)
- Chunk ticking optimisations
- Anything else I've forgotten in the 60 or so patches
If you are a previous Tuinity user, your config will not migrate. You must do it yourself. The config options have simply been moved into paper.yml, so it will be an easy migration. However, please note that the chunk loading options in tuinity.yml are NOT compatible with the options in paper.yml.
* Port tuinity, initial patchset
* Update gradle to 7.2
jmp said it fixes rebuildpatches not working for me. it fucking better
* Completely clean apply
* Remove tuinity config, add per player api patch
* Remove paper reobf mappings patch
* Properly update gradlew
* Force clean rebuild
* Mark fixups
Comments and ATs still need to be done
* grep -r "Tuinity"
* Fixup
* Ensure gameprofile lastaccess is written only under the state lock
* update URL for dataconverter
* Only clean rebuild tuinity patches
might fix merge conflicts
* Use UTF-8 for gradlew
* Clean rb patches again
* Convert block ids used as item ids
Neither the converters of pre 1.13 nor DFU handled these cases,
as by the time they were written the game at the time didn't
consider these ids valid - they would be air. Because of this,
some worlds have logspam since only DataConverter (not DFU or
legacy converters) will warn when an invalid id has been
seen.
While quite a few do need to now be considered as air, quite a lot
do not. So it makes sense to add conversion for these items, instead
of simply suppressing or ignoring the logs. I've now added id -> string conversion
for all block ids that could be used as items that existed in the game
before 1.7.10 (I have no interest in tracking down the
exact version block ids stopped working) that were on
https://minecraft-ids.grahamedgecombe.com/
Items that did not directly convert to new items will
be instead converted to air: stems, wheat crops, piston head,
tripwire wire block
* Fix LightPopulated parsing in V1466
The DFU code was checking if the number existed, not if it
didn't exist. I misread the original code.
* Always parse protochunk light sources unless it is marked as non-lit
Chunks not marked as lit will always go through the light engine,
so they should always have their block sources parsed.
* Update custom names to JSON for players
Missed this fix from CB, as it was inside
the DataFixers class.
I decided to double check all of the CB changes again:
DataFixers.java was the only area I missed, as I had inspected all
datafixer diffs and implemented them all into DataConverter. I also
checked Bootstrap.java again, and re-evaluated their changes. I had
previously done this, but determined that they were all bad.
The changes to make standing_sign block map to oak_sign block in
V1450 is bad, because that's not the item id V1450 accepts. Only
in 1.14 did oak_sign even exist, and as expected there is a converter
to rename all existing sign items/blocks.
The fix to register the portal block under id 1440 is useless, as
the flattenning logic will default to the lowest registered id - which
is the exact blockstate that CB registers into 1440. So it just
doesn't do anything.
The extra item ids in the id -> string converter are already added,
but I found this from EMC originally.
The change for the spawn egg id 23 -> Arrow is just wrong,
that id DOES correspond to TippedArrow, NOT Arrow. As
expected, the spawn egg already has a dedicated mapping for
Arrow, which is id 10 - which was Arrow's entity id.
I also ported a fix for the cooked_fished id update. This doesn't
really matter since there is already a dataconverter to fix this,
but the game didn't accept cooked_fished at the time. So I see
no harm.
* Review all converters and walkers
- Refactor V99 to have helper methods for defining entity/tile
entity types
- Automatically namespace all ids that should be namespaced.
While vanilla never saved non-namespaced data for things that
are namespaced, plugins/users might have.
- Synchronised the identity ensure map in HelperBlockFlatteningV1450
- Code style consistency
- Add missing log warning in V102 for ITEM_NAME type conversion
- Use getBoolean instead of getByte
- Use ConverterAbstractEntityRename for V143 TippedArrow -> Arrow
rename, as it will affect ENTITY_NAME type
- Always set isVillager to false in V502 for Zombie
- Register V808's converter under subversion 1 like DFU
- Register a breakpoint for V1.17.1. In the future, all final
versions of major releases will have a breakpoint so that
the work required to determine if a converter needs a breakpoint
is minimal
- Validate that a dataconverter is only registered for a version
that is registered
- ConverterFlattenTileEntity is actually ConverterFlattenEntity
It even registered the converters under TILE_ENTITY, instead of
ENTITY.
- Fix id comparison in V1492 STRUCTURE_FEATURE renamer
- Use ConverterAbstractStatsRename for V1510 stats renamer
At the time I had written that class, the abstract renamer didn't
exist.
- Ensure OwnerUUID is at least set to empty string in
V1904 if the ocelot is converted to a cat (this is
likely so that it retains a collar)
- Use generic read/write for Records in V1946
Records is actually a list, not a map. So reading map was
invalid.
* Always set light to zero when propagating decrease
This fixes an almost infinite loop where light values
would be spam queued on a very small subset on blocks.
This also likely fixes the memory issues people were
seeing.
* re-organize patches
* Apply and fix conflicts
* Revert some patches
getChunkAt retains chunks so that plugins don't spam loads
revert mc-4 fix will remain unless issues pop up
* Shuffle iterated chunks if per player is not enabled
Can help with some mob spawning stacking up at locations
* Make per player default, migrate all configs
* Adjust comments in fixups
* Rework config for player chunk loader
Old config is not compatible. Move all configs to be
under `settings` in paper.yml
The player chunk loader has been modified to
less aggressively load chunks, but to send
chunks at higher rates compared to tuinity. There are
new config entries to tune this behavior.
* Add back old constructor to CompressionEncoder/Decoder (fixes
Tuinity #358)
* Raise chunk loading default limits
* Reduce worldgen thread workers for lower core count cpus
* Raise limits for chunk loading config
Also place it under `chunk-loading`
* Disable max chunk send rate by default
* Fix conflicts and rebuild patches
* Drop default send rate again
Appears to be still causing problems for no known reason
* Raise chunk send limits to 100 per player
While a low limit fixes ping issues for some people, most people
do not suffer from this issue and thus should not suffer from
an extremely slow load-in rate.
* Rebase part 1
Autosquash the fixups
* Move not implemented up
* Fixup mc-dev fixes
Missed this one
* Rebase per player viewdistance api into the original api patch
* Remove old light engine patch part 1
The prioritisation must be kept from it, so that part
has been rebased into the priority patch.
Part 2 will deal with rebasing all of the patches _after_
* Rebase remaining patches for old light patch removal
* Remove other mid tick patch
* Remove Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch
Replaced by `Do not copy visible chunks`
* Revert AT for Vec3i setX/Y/Z
The class is immutable. set should not be exposed
* Remove old IntegerUtil class
* Replace old CraftChunk#getEntities patch
* Remove import for SWMRNibbleArray in ChunkAccess
* Finished merge checklist
* Remove ensureTickThread impl in urgency patch
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
2021-08-31 13:02:11 +02:00
io.papermc.paper.util.CachedLists.reset(); // Paper
2021-06-11 14:02:28 +02:00
+ // Paper start - move executeAll() into full server tick timing
+ try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) {
+ this.runAllTasks();
+ }
+ // Paper end
this.profiler.push("tallying");
2023-03-14 19:05:23 +01:00
long j = this.tickTimes[this.tickCount % 100] = Util.getNanos() - i;
2021-06-11 14:02:28 +02:00
2023-06-13 01:51:45 +02:00
@@ -1225,8 +1249,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2023-03-14 19:05:23 +01:00
this.frameTimer.logFrameDuration(k - i);
2021-06-11 14:02:28 +02:00
this.profiler.pop();
org.spigotmc.WatchdogThread.tick(); // Spigot
- SpigotTimings.serverTickTimer.stopTiming(); // Spigot
- org.spigotmc.CustomTimingsHandler.tick(); // Spigot
+ co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTiming(); // Paper
}
2023-03-14 19:05:23 +01:00
private ServerStatus buildServerStatus() {
2023-06-13 01:51:45 +02:00
@@ -1258,26 +1281,26 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2023-03-14 19:05:23 +01:00
}
2021-06-11 20:02:16 +02:00
public void tickChildren(BooleanSupplier shouldKeepTicking) {
2021-06-11 14:02:28 +02:00
- SpigotTimings.schedulerTimer.startTiming(); // Spigot
+ MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Spigot // Paper
this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit
- SpigotTimings.schedulerTimer.stopTiming(); // Spigot
+ MinecraftTimings.bukkitSchedulerTimer.stopTiming(); // Spigot // Paper
2023-03-15 13:19:54 +01:00
io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.handleQueue(this.tickCount); // Paper
2021-06-11 14:02:28 +02:00
this.profiler.push("commandFunctions");
- SpigotTimings.commandFunctionsTimer.startTiming(); // Spigot
+ MinecraftTimings.commandFunctionsTimer.startTiming(); // Spigot // Paper
this.getFunctions().tick();
- SpigotTimings.commandFunctionsTimer.stopTiming(); // Spigot
+ MinecraftTimings.commandFunctionsTimer.stopTiming(); // Spigot // Paper
this.profiler.popPush("levels");
Iterator iterator = this.getAllLevels().iterator();
// CraftBukkit start
// Run tasks that are waiting on processing
- SpigotTimings.processQueueTimer.startTiming(); // Spigot
+ MinecraftTimings.processQueueTimer.startTiming(); // Spigot
2021-06-11 20:02:16 +02:00
while (!this.processQueue.isEmpty()) {
this.processQueue.remove().run();
2021-06-11 14:02:28 +02:00
}
- SpigotTimings.processQueueTimer.stopTiming(); // Spigot
+ MinecraftTimings.processQueueTimer.stopTiming(); // Spigot
- SpigotTimings.timeUpdateTimer.startTiming(); // Spigot
+ 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.tickCount % 20 == 0) {
for (int i = 0; i < this.getPlayerList().players.size(); ++i) {
2023-06-13 01:51:45 +02:00
@@ -1285,7 +1308,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2023-06-07 19:18:05 +02:00
entityplayer.connection.send(new ClientboundSetTimePacket(entityplayer.level().getGameTime(), entityplayer.getPlayerTime(), entityplayer.level().getGameRules().getBoolean(GameRules.RULE_DAYLIGHT))); // Add support for per player time
2021-06-11 14:02:28 +02:00
}
}
- SpigotTimings.timeUpdateTimer.stopTiming(); // Spigot
+ MinecraftTimings.timeUpdateTimer.stopTiming(); // Spigot // Paper
while (iterator.hasNext()) {
ServerLevel worldserver = (ServerLevel) iterator.next();
2023-06-13 01:51:45 +02:00
@@ -1331,24 +1354,24 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2021-06-11 14:02:28 +02:00
}
this.profiler.popPush("connection");
- SpigotTimings.connectionTimer.startTiming(); // Spigot
+ MinecraftTimings.connectionTimer.startTiming(); // Spigot
this.getConnection().tick();
- SpigotTimings.connectionTimer.stopTiming(); // Spigot
+ MinecraftTimings.connectionTimer.stopTiming(); // Spigot
this.profiler.popPush("players");
- SpigotTimings.playerListTimer.startTiming(); // Spigot
+ MinecraftTimings.playerListTimer.startTiming(); // Spigot // Paper
this.playerList.tick();
- SpigotTimings.playerListTimer.stopTiming(); // Spigot
+ MinecraftTimings.playerListTimer.stopTiming(); // Spigot // Paper
if (SharedConstants.IS_RUNNING_IN_IDE) {
2021-06-11 20:02:16 +02:00
GameTestTicker.SINGLETON.tick();
2021-06-11 14:02:28 +02:00
}
this.profiler.popPush("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.profiler.pop();
}
diff --git a/src/main/java/net/minecraft/server/ServerFunctionManager.java b/src/main/java/net/minecraft/server/ServerFunctionManager.java
2023-06-07 19:18:05 +02:00
index 009ef03e520aeb57b29b5375a65634ed76aa9163..4a610b712acfe0b1b4dcf4988bc22c6a71616050 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/server/ServerFunctionManager.java
+++ b/src/main/java/net/minecraft/server/ServerFunctionManager.java
2023-06-07 19:18:05 +02:00
@@ -89,7 +89,7 @@ public class ServerFunctionManager {
2021-06-11 14:02:28 +02:00
} else {
2021-06-11 20:02:16 +02:00
int i;
2021-06-11 14:02:28 +02:00
- try {
+ try (co.aikar.timings.Timing timing = function.getTiming().startTiming()) { // Paper
2021-06-11 20:02:16 +02:00
this.context = new ServerFunctionManager.ExecutionContext(tracer);
i = this.context.runTopCommand(function, source);
} finally {
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
2023-06-07 19:18:05 +02:00
index 59eed41e1c6012650597f1faa85063a2d536873f..51eac8b7177db66c005e4eaca689cf96d10edeaa 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
2022-12-07 18:53:34 +01:00
@@ -58,8 +58,9 @@ import org.apache.logging.log4j.Level;
2022-03-01 06:43:03 +01:00
import org.apache.logging.log4j.LogManager;
2021-06-11 14:02:28 +02:00
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
2022-12-07 18:53:34 +01:00
@@ -404,7 +405,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
2021-06-11 14:02:28 +02:00
}
public void handleConsoleInputs() {
- SpigotTimings.serverCommandTimer.startTiming(); // Spigot
+ MinecraftTimings.serverCommandTimer.startTiming(); // Spigot
while (!this.consoleInput.isEmpty()) {
ConsoleInput servercommand = (ConsoleInput) this.consoleInput.remove(0);
2022-12-07 18:53:34 +01:00
@@ -419,7 +420,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
2021-06-11 14:02:28 +02:00
// CraftBukkit end
}
- SpigotTimings.serverCommandTimer.stopTiming(); // Spigot
+ MinecraftTimings.serverCommandTimer.stopTiming(); // Spigot
}
@Override
2023-06-07 19:18:05 +02:00
@@ -667,6 +668,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
2021-06-11 14:02:28 +02:00
@Override
public String runCommand(String command) {
+ Waitable[] waitableArray = new Waitable[1];
this.rconConsoleSource.prepareForCommand();
this.executeBlocking(() -> {
// CraftBukkit start - fire RemoteServerCommandEvent
2023-06-07 19:18:05 +02:00
@@ -675,10 +677,39 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
2021-06-11 14:02:28 +02:00
if (event.isCancelled()) {
return;
}
+ // Paper start
+ if (command.toLowerCase().startsWith("timings") && command.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
2021-06-11 20:02:16 +02:00
ConsoleInput serverCommand = new ConsoleInput(event.getCommand(), this.rconConsoleSource.createCommandSourceStack());
2021-06-11 14:02:28 +02:00
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 " + command, e.getCause());
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt(); // Maintain interrupted state
+ throw new RuntimeException("Interrupted processing rcon command " + command, e);
+ }
+
+ }
+ // Paper end
return this.rconConsoleSource.getCommandResponse();
}
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
2023-06-07 19:18:05 +02:00
index c943e64d70bab240f8dc733e78a185172664c5e4..a645263f148a25e5b4baeed51775eb8e7f596fe8 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
2021-11-23 11:51:25 +01:00
@@ -1,8 +1,10 @@
2021-06-11 14:02:28 +02:00
package net.minecraft.server.level;
+import co.aikar.timings.Timing; // Paper
import com.google.common.collect.ImmutableList;
2021-11-23 11:51:25 +01:00
import com.google.common.collect.ImmutableList.Builder;
2021-06-11 14:02:28 +02:00
import com.google.common.collect.Iterables;
+import com.google.common.collect.ComparisonChain; // Paper
import com.google.common.collect.Lists;
import com.google.common.collect.Queues;
import com.google.common.collect.Sets;
2023-06-07 19:18:05 +02:00
@@ -886,6 +888,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
ChunkStatus chunkstatus = ChunkLevel.generationStatus(chunkHolder.getTicketLevel());
2021-06-11 14:02:28 +02:00
return !chunkstatus.isOrAfter(ChunkStatus.FULL) ? ChunkHolder.UNLOADED_CHUNK : either.mapLeft((ichunkaccess) -> {
2021-11-23 11:51:25 +01:00
+ try (Timing ignored = level.timings.chunkPostLoad.startTimingIfSync()) { // Paper
ChunkPos chunkcoordintpair = chunkHolder.getPos();
2021-06-11 20:02:16 +02:00
ProtoChunk protochunk = (ProtoChunk) ichunkaccess;
2021-06-11 14:02:28 +02:00
LevelChunk chunk;
2023-06-07 19:18:05 +02:00
@@ -910,6 +913,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
2021-06-11 14:02:28 +02:00
}
return chunk;
+ } // Paper
});
}, (runnable) -> {
ProcessorHandle mailbox = this.mainThreadMailbox;
2023-06-07 19:18:05 +02:00
@@ -1465,6 +1469,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
2021-11-23 11:51:25 +01:00
List<ServerPlayer> list = Lists.newArrayList();
List<ServerPlayer> list1 = this.level.players();
ObjectIterator objectiterator = this.entityMap.values().iterator();
+ level.timings.tracker1.startTiming(); // Paper
2021-06-11 14:02:28 +02:00
ChunkMap.TrackedEntity playerchunkmap_entitytracker;
2023-06-07 19:18:05 +02:00
@@ -1489,14 +1494,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
2021-11-23 11:51:25 +01:00
playerchunkmap_entitytracker.serverEntity.sendChanges();
2021-06-11 14:02:28 +02:00
}
}
+ level.timings.tracker1.stopTiming(); // Paper
if (!list.isEmpty()) {
objectiterator = this.entityMap.values().iterator();
+ level.timings.tracker2.startTiming(); // Paper
while (objectiterator.hasNext()) {
playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) objectiterator.next();
playerchunkmap_entitytracker.updatePlayers(list);
}
+ level.timings.tracker2.stopTiming(); // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
2023-06-08 22:56:13 +02:00
index 5115342b51ccefe4430df47a498bc59b1d96bb0e..6d5a160a9fdaa04bb930afae8a0765910f631d23 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
2022-12-07 18:53:34 +01:00
@@ -415,13 +415,15 @@ public class ServerChunkCache extends ChunkSource {
2021-06-11 14:02:28 +02:00
}
gameprofilerfiller.incrementCounter("getChunkCacheMiss");
- level.timings.syncChunkLoadTimer.startTiming(); // Spigot
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create);
2021-11-23 11:51:25 +01:00
ServerChunkCache.MainThreadExecutor chunkproviderserver_b = this.mainThreadProcessor;
2021-06-11 14:02:28 +02:00
2021-06-11 20:02:16 +02:00
Objects.requireNonNull(completablefuture);
2021-06-11 14:02:28 +02:00
+ if (!completablefuture.isDone()) { // Paper
+ this.level.timings.syncChunkLoad.startTiming(); // Paper
2021-11-23 11:51:25 +01:00
chunkproviderserver_b.managedBlock(completablefuture::isDone);
2021-06-11 14:02:28 +02:00
- level.timings.syncChunkLoadTimer.stopTiming(); // Spigot
+ this.level.timings.syncChunkLoad.stopTiming(); // Paper
+ } // Paper
ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> {
return ichunkaccess1;
}, (playerchunk_failure) -> {
2023-06-07 19:18:05 +02:00
@@ -620,7 +622,9 @@ public class ServerChunkCache extends ChunkSource {
2021-06-11 14:02:28 +02:00
public void save(boolean flush) {
this.runDistanceManagerUpdates();
+ try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings
this.chunkMap.saveAllChunks(flush);
+ } // Paper - Timings
}
@Override
2023-06-07 19:18:05 +02:00
@@ -659,7 +663,9 @@ public class ServerChunkCache extends ChunkSource {
2021-06-11 14:02:28 +02:00
this.level.timings.doChunkMap.stopTiming(); // Spigot
this.level.getProfiler().popPush("chunks");
2022-03-01 06:43:03 +01:00
if (tickChunks) {
+ this.level.timings.chunks.startTiming(); // Paper - timings
this.tickChunks();
+ this.level.timings.chunks.stopTiming(); // Paper - timings
}
2021-06-11 14:02:28 +02:00
this.level.timings.doChunkUnload.startTiming(); // Spigot
2023-06-07 19:18:05 +02:00
@@ -688,13 +694,16 @@ public class ServerChunkCache extends ChunkSource {
2022-02-12 14:20:33 +01:00
boolean flag1 = level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && worlddata.getGameTime() % level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit
2021-06-11 14:02:28 +02:00
2021-11-23 11:51:25 +01:00
gameprofilerfiller.push("naturalSpawnCount");
2021-06-11 14:02:28 +02:00
+ this.level.timings.countNaturalMobs.startTiming(); // Paper - timings
int l = this.distanceManager.getNaturalSpawnChunkCount();
2021-11-23 11:51:25 +01:00
NaturalSpawner.SpawnState spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap));
2021-06-11 14:02:28 +02:00
+ this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings
this.lastSpawnState = spawnercreature_d;
2021-11-23 11:51:25 +01:00
gameprofilerfiller.popPush("filteringLoadedChunks");
List<ServerChunkCache.ChunkAndHolder> list = Lists.newArrayListWithCapacity(l);
Iterator iterator = this.chunkMap.getChunks().iterator();
2021-06-11 14:02:28 +02:00
+ this.level.timings.chunkTicks.startTiming(); // Paper
2021-11-23 11:51:25 +01:00
while (iterator.hasNext()) {
ChunkHolder playerchunk = (ChunkHolder) iterator.next();
2023-06-07 19:18:05 +02:00
@@ -723,27 +732,27 @@ public class ServerChunkCache extends ChunkSource {
2021-11-23 11:51:25 +01:00
}
2021-06-11 20:02:16 +02:00
2021-11-23 11:51:25 +01:00
if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) {
2021-06-11 20:02:16 +02:00
- this.level.timings.doTickTiles.startTiming(); // Spigot
2021-11-23 11:51:25 +01:00
this.level.tickChunk(chunk1, k);
2021-06-11 20:02:16 +02:00
- this.level.timings.doTickTiles.stopTiming(); // Spigot
2021-06-11 14:02:28 +02:00
}
}
2021-11-23 11:51:25 +01:00
}
-
2021-06-11 14:02:28 +02:00
+ this.level.timings.chunkTicks.stopTiming(); // Paper
2021-11-23 11:51:25 +01:00
gameprofilerfiller.popPush("customSpawners");
if (flag2) {
2021-06-11 14:02:28 +02:00
+ try (co.aikar.timings.Timing ignored = this.level.timings.miscMobSpawning.startTiming()) { // Paper - timings
this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies);
+ } // Paper - timings
}
2021-11-23 11:51:25 +01:00
gameprofilerfiller.popPush("broadcast");
list.forEach((chunkproviderserver_a1) -> {
+ this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing
chunkproviderserver_a1.holder.broadcastChanges(chunkproviderserver_a1.chunk);
+ this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing
2021-07-07 08:52:40 +02:00
});
2021-11-23 11:51:25 +01:00
gameprofilerfiller.pop();
gameprofilerfiller.pop();
- this.level.timings.tracker.startTiming(); // Spigot
this.chunkMap.tick();
- this.level.timings.tracker.stopTiming(); // Spigot
2021-06-11 14:02:28 +02:00
}
}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
2023-06-07 19:18:05 +02:00
index 7be97441aed66fa3a21d13ad2211b3e0e08120c0..7cb5abfa89f842194325d26c6e95b49460c5968f 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
2021-06-11 20:02:16 +02:00
@@ -1,6 +1,8 @@
package net.minecraft.server.level;
2021-06-11 14:02:28 +02:00
import com.google.common.annotations.VisibleForTesting;
+import co.aikar.timings.TimingHistory; // Paper
+import co.aikar.timings.Timings; // Paper
import com.google.common.collect.Lists;
2021-06-11 20:02:16 +02:00
import com.mojang.datafixers.DataFixer;
2022-03-01 06:43:03 +01:00
import com.mojang.datafixers.util.Pair;
2023-06-07 19:18:05 +02:00
@@ -165,7 +167,6 @@ import org.slf4j.Logger;
2021-06-11 14:02:28 +02:00
import org.bukkit.Bukkit;
2022-06-07 21:15:06 +02:00
import org.bukkit.Location;
2021-06-11 14:02:28 +02:00
import org.bukkit.WeatherType;
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
import org.bukkit.craftbukkit.event.CraftEventFactory;
2022-06-07 21:15:06 +02:00
import org.bukkit.craftbukkit.generator.CustomWorldChunkManager;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
2023-06-07 19:18:05 +02:00
@@ -469,7 +470,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
2021-06-11 14:02:28 +02:00
this.updateSkyBrightness();
this.tickTime();
gameprofilerfiller.popPush("tickPending");
- timings.doTickPending.startTiming(); // Spigot
+ timings.scheduledBlocks.startTiming(); // Paper
if (!this.isDebug()) {
2021-11-23 11:51:25 +01:00
j = this.getGameTime();
gameprofilerfiller.push("blockTicks");
2023-06-07 19:18:05 +02:00
@@ -478,12 +479,16 @@ public class ServerLevel extends Level implements WorldGenLevel {
2021-11-23 11:51:25 +01:00
this.fluidTicks.tick(j, 65536, this::tickFluid);
gameprofilerfiller.pop();
2021-06-11 14:02:28 +02:00
}
- timings.doTickPending.stopTiming(); // Spigot
+ timings.scheduledBlocks.stopTiming(); // Paper
gameprofilerfiller.popPush("raid");
+ this.timings.raids.startTiming(); // Paper - timings
this.raids.tick();
+ this.timings.raids.stopTiming(); // Paper - timings
2021-07-07 08:52:40 +02:00
gameprofilerfiller.popPush("chunkSource");
+ this.timings.chunkProviderTick.startTiming(); // Paper - timings
2022-03-01 06:43:03 +01:00
this.getChunkSource().tick(shouldKeepTicking, true);
2021-07-07 08:52:40 +02:00
+ this.timings.chunkProviderTick.stopTiming(); // Paper - timings
2021-06-11 14:02:28 +02:00
gameprofilerfiller.popPush("blockEvents");
timings.doSounds.startTiming(); // Spigot
this.runBlockEvents();
2023-06-07 19:18:05 +02:00
@@ -667,6 +672,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
2021-06-11 14:02:28 +02:00
}
gameprofilerfiller.popPush("tickBlocks");
+ timings.chunkTicksBlocks.startTiming(); // Paper
if (randomTickSpeed > 0) {
LevelChunkSection[] achunksection = chunk.getSections();
2023-06-07 19:18:05 +02:00
@@ -699,6 +705,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
2021-06-11 14:02:28 +02:00
}
}
2021-08-30 09:02:24 +02:00
2021-06-11 14:02:28 +02:00
+ timings.chunkTicksBlocks.stopTiming(); // Paper
gameprofilerfiller.pop();
}
2023-06-07 19:18:05 +02:00
@@ -933,14 +940,22 @@ public class ServerLevel extends Level implements WorldGenLevel {
2021-06-11 20:02:16 +02:00
}
public void tickNonPassenger(Entity entity) {
+ ++TimingHistory.entityTicks; // Paper - timings
// Spigot start
+ co.aikar.timings.Timing timer; // Paper
if (!org.spigotmc.ActivationRange.checkIfActive(entity)) {
entity.tickCount++;
+ timer = entity.getType().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.getType().passengerTickTimer.startTiming() : entity.getType().tickTimer.startTiming();
+ try {
+ // Paper end - timings
2021-06-17 14:50:16 +02:00
entity.setOldPosAndRot();
2021-06-11 20:02:16 +02:00
ProfilerFiller gameprofilerfiller = this.getProfiler();
2023-06-07 19:18:05 +02:00
@@ -959,7 +974,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
2021-06-11 14:02:28 +02:00
2021-06-11 20:02:16 +02:00
this.tickPassenger(entity, entity1);
2021-06-11 14:02:28 +02:00
}
2021-06-11 20:02:16 +02:00
- entity.tickTimer.stopTiming(); // Spigot
+ } finally { timer.stopTiming(); } // Paper - timings
2021-06-11 14:02:28 +02:00
}
2021-06-11 20:02:16 +02:00
2023-06-07 19:18:05 +02:00
@@ -1001,6 +1016,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
2021-06-11 14:02:28 +02:00
2021-11-24 23:26:32 +01:00
if (!savingDisabled) {
2021-06-11 14:02:28 +02:00
org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit
+ try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper
if (progressListener != null) {
2022-06-07 21:15:06 +02:00
progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel"));
2021-06-11 14:02:28 +02:00
}
2023-06-07 19:18:05 +02:00
@@ -1010,7 +1026,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
2022-06-07 21:15:06 +02:00
progressListener.progressStage(Component.translatable("menu.savingChunks"));
2021-06-11 14:02:28 +02:00
}
2021-06-11 20:02:16 +02:00
+ timings.worldSaveChunks.startTiming(); // Paper
2021-06-11 14:02:28 +02:00
chunkproviderserver.save(flush);
2021-06-11 20:02:16 +02:00
+ timings.worldSaveChunks.stopTiming(); // Paper
+ }// Paper
if (flush) {
this.entityManager.saveAll();
} else {
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
2023-06-13 01:51:45 +02:00
index fa3d02895d57c17416e742d2ea1e51253bce4fad..527654df6628b70fd380ccfd3890c27c7a490ef0 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
2023-05-12 13:10:08 +02:00
@@ -339,7 +339,6 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
2021-06-11 14:02:28 +02:00
2022-07-27 21:18:51 +02:00
@Override
2021-06-11 14:02:28 +02:00
public void tick() {
- org.bukkit.craftbukkit.SpigotTimings.playerConnectionTimer.startTiming(); // Spigot
2022-06-07 21:15:06 +02:00
if (this.ackBlockChangesUpTo > -1) {
this.send(new ClientboundBlockChangedAckPacket(this.ackBlockChangesUpTo));
this.ackBlockChangesUpTo = -1;
2023-05-12 13:10:08 +02:00
@@ -420,7 +419,6 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
2021-06-11 14:02:28 +02:00
this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854
2022-06-07 21:15:06 +02:00
this.disconnect(Component.translatable("multiplayer.disconnect.idling"));
2021-06-11 14:02:28 +02:00
}
- org.bukkit.craftbukkit.SpigotTimings.playerConnectionTimer.stopTiming(); // Spigot
2022-06-07 21:15:06 +02:00
}
2022-12-07 18:53:34 +01:00
2023-06-13 01:51:45 +02:00
@@ -2147,7 +2145,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
2021-06-11 14:02:28 +02:00
}
2022-06-07 21:15:06 +02:00
private void handleCommand(String s) {
2021-06-11 14:02:28 +02:00
- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot
2022-06-07 21:15:06 +02:00
+ co.aikar.timings.MinecraftTimings.playerCommandTimer.startTiming(); // Paper
2021-06-11 14:02:28 +02:00
if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot
2022-06-07 21:15:06 +02:00
this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s);
2023-06-13 01:51:45 +02:00
@@ -2157,7 +2155,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
2021-06-11 20:02:16 +02:00
this.cserver.getPluginManager().callEvent(event);
2021-06-11 14:02:28 +02:00
if (event.isCancelled()) {
- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot
2022-06-07 21:15:06 +02:00
+ co.aikar.timings.MinecraftTimings.playerCommandTimer.stopTiming(); // Paper
2021-06-11 14:02:28 +02:00
return;
}
2023-06-13 01:51:45 +02:00
@@ -2170,7 +2168,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
2021-06-11 14:02:28 +02:00
java.util.logging.Logger.getLogger(ServerGamePacketListenerImpl.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
return;
} finally {
- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot
2022-06-07 21:15:06 +02:00
+ co.aikar.timings.MinecraftTimings.playerCommandTimer.stopTiming(); // Paper
2021-06-11 14:02:28 +02:00
}
2022-06-07 21:15:06 +02:00
}
// CraftBukkit end
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
2023-06-13 01:51:45 +02:00
index d3dc7752aadf36985660d04dcb4377a69dfeddff..b922654c0b0b1b0d03beb20bb1944b817907f929 100644
2021-06-11 14:02:28 +02:00
--- 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;
2023-06-07 19:18:05 +02:00
@@ -1046,10 +1047,11 @@ public abstract class PlayerList {
2021-06-11 14:02:28 +02:00
}
public void saveAll() {
+ MinecraftTimings.savePlayers.startTiming(); // Paper
for (int i = 0; i < this.players.size(); ++i) {
this.save((ServerPlayer) this.players.get(i));
}
-
+ MinecraftTimings.savePlayers.stopTiming(); // Paper
}
public UserWhiteList getWhiteList() {
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
2023-06-13 01:51:45 +02:00
index a4e5961991a6debff959d63d70b71b1ded76e72a..fd81979963c3a7e2e03a53d6493ec4e48cad3e70 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
2023-03-14 19:05:23 +01:00
@@ -134,7 +134,6 @@ import org.bukkit.craftbukkit.event.CraftPortalEvent;
2021-06-11 14:02:28 +02:00
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;
2023-06-07 19:18:05 +02:00
@@ -307,7 +306,6 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
2022-01-09 06:12:05 +01:00
public boolean lastDamageCancelled; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled
2021-06-11 14:02:28 +02:00
public boolean persistentInvisibility = false;
2021-12-03 22:28:15 +01:00
public BlockPos lastLavaContact;
2021-06-11 14:02:28 +02:00
- 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;
2023-06-07 19:18:05 +02:00
@@ -804,7 +802,6 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
2021-06-11 14:02:28 +02:00
}
2021-06-11 20:02:16 +02:00
public void move(MoverType movementType, Vec3 movement) {
2021-06-11 14:02:28 +02:00
- org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot
if (this.noPhysics) {
2021-06-11 20:02:16 +02:00
this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z);
} else {
2023-06-07 19:18:05 +02:00
@@ -965,7 +962,6 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
this.level().getProfiler().pop();
2021-06-11 20:02:16 +02:00
}
2021-06-11 14:02:28 +02:00
}
- org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot
}
2023-06-07 19:18:05 +02:00
private boolean isStateClimbable(BlockState state) {
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
2023-06-07 19:18:05 +02:00
index 1d40d2f70ad72aa392b3699d71f20f69d3820696..93a43ef867d0961b46f9ecadc2c7be6a4b17c72b 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
2023-03-14 19:05:23 +01:00
@@ -322,6 +322,15 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
2021-06-11 14:02:28 +02:00
}
2022-12-07 18:53:34 +01:00
public EntityType(EntityType.EntityFactory<T> factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet<Block> canSpawnInside, EntityDimensions dimensions, int maxTrackDistance, int trackTickInterval, FeatureFlagSet requiredFeatures) {
+ // Paper start
+ this(factory, spawnGroup, saveable, summonable, fireImmune, spawnableFarFromPlayer, canSpawnInside, dimensions, maxTrackDistance, trackTickInterval, requiredFeatures, "custom");
2021-08-30 09:02:24 +02:00
+ }
2022-12-07 18:53:34 +01:00
+ public EntityType(EntityType.EntityFactory<T> factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet<Block> canSpawnInside, EntityDimensions dimensions, int maxTrackDistance, int trackTickInterval, FeatureFlagSet requiredFeatures, String id) {
2021-06-11 14:02:28 +02:00
+ 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
2022-12-07 18:53:34 +01:00
this.builtInRegistryHolder = BuiltInRegistries.ENTITY_TYPE.createIntrusiveHolder(this);
this.factory = factory;
this.category = spawnGroup;
2023-03-14 19:05:23 +01:00
@@ -643,6 +652,12 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
2021-06-11 14:02:28 +02:00
return this.updateInterval;
}
+ // 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 trackDeltas() {
2021-06-11 20:02:16 +02:00
return this != EntityType.PLAYER && this != EntityType.LLAMA_SPIT && this != EntityType.WITHER && this != EntityType.BAT && this != EntityType.ITEM_FRAME && this != EntityType.GLOW_ITEM_FRAME && this != EntityType.LEASH_KNOT && this != EntityType.PAINTING && this != EntityType.END_CRYSTAL && this != EntityType.EVOKER_FANGS;
2021-06-11 14:02:28 +02:00
}
2023-03-14 19:05:23 +01:00
@@ -748,7 +763,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
2023-01-14 02:03:13 +01:00
Util.fetchChoiceType(References.ENTITY_TREE, id);
}
- return new EntityType<>(this.factory, this.category, this.serialize, this.summon, this.fireImmune, this.canSpawnFarFromPlayer, this.immuneTo, this.dimensions, this.clientTrackingRange, this.updateInterval, this.requiredFeatures);
+ return new EntityType<>(this.factory, this.category, this.serialize, this.summon, this.fireImmune, this.canSpawnFarFromPlayer, this.immuneTo, this.dimensions, this.clientTrackingRange, this.updateInterval, this.requiredFeatures, id); // Paper - add id
}
}
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
2023-06-07 19:18:05 +02:00
index 0a070ff26a1e9b2583e95adac0b2dd85b567c8d1..3fa9f639a598294b4956c6525fc8a630ae10da2d 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
2023-06-07 19:18:05 +02:00
@@ -141,7 +141,7 @@ import org.bukkit.event.entity.EntityTeleportEvent;
2021-06-11 14:02:28 +02:00
import org.bukkit.event.player.PlayerItemConsumeEvent;
// CraftBukkit end
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
+import co.aikar.timings.MinecraftTimings; // Paper
2023-03-14 19:05:23 +01:00
public abstract class LivingEntity extends Entity implements Attackable {
2021-06-11 14:02:28 +02:00
2023-06-07 19:18:05 +02:00
@@ -2844,7 +2844,6 @@ public abstract class LivingEntity extends Entity implements Attackable {
2021-06-11 14:02:28 +02:00
@Override
public void tick() {
- SpigotTimings.timerEntityBaseTick.startTiming(); // Spigot
super.tick();
this.updatingUsingItem();
this.updateSwimAmount();
2023-06-07 19:18:05 +02:00
@@ -2886,9 +2885,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
2021-06-11 14:02:28 +02:00
}
2022-07-27 21:22:02 +02:00
if (!this.isRemoved()) {
2022-07-27 21:18:51 +02:00
- SpigotTimings.timerEntityBaseTick.stopTiming(); // Spigot
2022-07-27 21:22:02 +02:00
this.aiStep();
2022-07-27 21:18:51 +02:00
- SpigotTimings.timerEntityTickRest.startTiming(); // Spigot
2022-07-27 21:22:02 +02:00
}
2021-06-11 14:02:28 +02:00
double d0 = this.getX() - this.xo;
2023-06-07 19:18:05 +02:00
@@ -2970,8 +2967,6 @@ public abstract class LivingEntity extends Entity implements Attackable {
2021-06-11 14:02:28 +02:00
if (this.isSleeping()) {
2021-06-11 20:02:16 +02:00
this.setXRot(0.0F);
2021-06-11 14:02:28 +02:00
}
-
- SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot
}
public void detectEquipmentUpdates() {
2023-06-07 19:18:05 +02:00
@@ -3149,7 +3144,6 @@ public abstract class LivingEntity extends Entity implements Attackable {
2021-06-11 14:02:28 +02:00
this.setDeltaMovement(d4, d5, d6);
2023-06-07 19:18:05 +02:00
this.level().getProfiler().push("ai");
2021-06-11 14:02:28 +02:00
- SpigotTimings.timerEntityAI.startTiming(); // Spigot
if (this.isImmobile()) {
this.jumping = false;
this.xxa = 0.0F;
2023-06-07 19:18:05 +02:00
@@ -3159,7 +3153,6 @@ public abstract class LivingEntity extends Entity implements Attackable {
2021-06-11 14:02:28 +02:00
this.serverAiStep();
2023-06-07 19:18:05 +02:00
this.level().getProfiler().pop();
2021-06-11 14:02:28 +02:00
}
- SpigotTimings.timerEntityAI.stopTiming(); // Spigot
2023-06-07 19:18:05 +02:00
this.level().getProfiler().pop();
this.level().getProfiler().push("jump");
@@ -3199,7 +3192,6 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.resetFallDistance();
}
2021-06-11 14:02:28 +02:00
- SpigotTimings.timerEntityAIMove.startTiming(); // Spigot
2023-06-07 19:18:05 +02:00
label104:
{
LivingEntity entityliving = this.getControllingPassenger();
@@ -3215,7 +3207,6 @@ public abstract class LivingEntity extends Entity implements Attackable {
2023-03-14 19:05:23 +01:00
this.travel(vec3d1);
}
2021-06-11 14:02:28 +02:00
- SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot
2023-03-14 19:05:23 +01:00
2023-06-07 19:18:05 +02:00
this.level().getProfiler().pop();
this.level().getProfiler().push("freezing");
@@ -3242,9 +3233,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
2021-06-11 14:02:28 +02:00
this.checkAutoSpinAttack(axisalignedbb, this.getBoundingBox());
}
- SpigotTimings.timerEntityAICollision.startTiming(); // Spigot
this.pushEntities();
- SpigotTimings.timerEntityAICollision.stopTiming(); // Spigot
2023-06-07 19:18:05 +02:00
this.level().getProfiler().pop();
if (!this.level().isClientSide && this.isSensitiveToWater() && this.isInWaterRainOrBubble()) {
2023-03-14 19:05:23 +01:00
this.hurt(this.damageSources().drown(), 1.0F);
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
2023-06-07 19:18:05 +02:00
index 003e2064f64115d1f5c48ac97e16100d4c10c5d7..d87f02c748fe2e5b4ea251f6691e8907a152cb6d 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
2023-03-14 19:05:23 +01:00
@@ -88,7 +88,6 @@ import org.bukkit.Bukkit;
2021-06-11 20:33:36 +02:00
import org.bukkit.Location;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
-import org.bukkit.craftbukkit.SpigotTimings; // Spigot
import org.bukkit.craftbukkit.block.CapturedBlockState;
import org.bukkit.craftbukkit.block.CraftBlockState;
import org.bukkit.craftbukkit.block.data.CraftBlockData;
2023-06-07 19:18:05 +02:00
@@ -163,7 +162,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
2022-06-09 10:51:45 +02:00
}
// Paper end
2021-06-11 14:02:28 +02:00
- public final SpigotTimings.WorldTimingsHandler timings; // Spigot
+ public final co.aikar.timings.WorldTimingsHandler timings; // Paper
public static BlockPos lastPhysicsProblem; // Spigot
private org.spigotmc.TickLimiter entityLimiter;
private org.spigotmc.TickLimiter tileLimiter;
2023-06-07 19:18:05 +02:00
@@ -261,7 +260,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
2021-11-23 11:51:25 +01:00
public void onBorderSetDamageSafeZOne(WorldBorder border, double safeZoneRadius) {}
2021-06-11 14:02:28 +02:00
});
// CraftBukkit end
2021-06-11 20:02:16 +02:00
- this.timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings
2021-06-11 14:02:28 +02:00
+ timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings
this.entityLimiter = new org.spigotmc.TickLimiter(spigotConfig.entityMaxTickTime);
this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime);
}
2023-06-07 19:18:05 +02:00
@@ -714,15 +713,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
2021-06-11 14:02:28 +02:00
2021-06-11 20:02:16 +02:00
timings.tileEntityTick.stopTiming(); // Spigot
this.tickingBlockEntities = false;
2021-06-22 20:52:45 +02:00
+ co.aikar.timings.TimingHistory.tileEntityTicks += this.blockEntityTickers.size(); // Paper
2021-06-11 14:02:28 +02:00
gameprofilerfiller.pop();
spigotConfig.currentPrimedTnt = 0; // Spigot
}
2021-06-11 20:02:16 +02:00
public <T extends Entity> void guardEntityTick(Consumer<T> tickConsumer, T entity) {
2021-06-11 14:02:28 +02:00
try {
- SpigotTimings.tickEntityTimer.startTiming(); // Spigot
tickConsumer.accept(entity);
- SpigotTimings.tickEntityTimer.stopTiming(); // Spigot
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking entity");
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being ticked");
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
2023-06-07 19:18:05 +02:00
index 96ff9373e89a3f0b174c82a75e09dd91a3639508..7ed82beb538a25a5246f6288c1dddb4f5f85e997 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/level/block/Block.java
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
2023-06-07 19:18:05 +02:00
@@ -87,6 +87,15 @@ public class Block extends BlockBehaviour implements ItemLike {
2021-06-11 20:02:16 +02:00
public static final int UPDATE_LIMIT = 512;
2021-06-11 14:02:28 +02:00
protected final StateDefinition<Block, BlockState> stateDefinition;
private BlockState defaultBlockState;
+ // 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 descriptionId;
@Nullable
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
2022-12-07 18:53:34 +01:00
index c02fa35cefc9194d1838abbe4f2dc2b226a41e41..b300d12e9e00519028b53aca9c3fb01f589eaa91 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
2021-11-23 11:51:25 +01:00
@@ -22,10 +22,12 @@ import org.bukkit.inventory.InventoryHolder;
2021-06-11 14:02:28 +02:00
// CraftBukkit end
import org.spigotmc.CustomTimingsHandler; // Spigot
+import co.aikar.timings.MinecraftTimings; // Paper
+import co.aikar.timings.Timing; // Paper
2022-03-30 22:28:38 +02:00
public abstract class BlockEntity {
2021-06-11 14:02:28 +02:00
- 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/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
2023-06-08 07:03:07 +02:00
index e4deb276f956c5f292ab8bf7836eeeffd6ed59d5..4185d524f61e87a469d563c938f742f63dad3c2f 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
2023-06-07 19:18:05 +02:00
@@ -682,6 +682,7 @@ public class LevelChunk extends ChunkAccess {
2023-04-07 20:39:13 +02:00
server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(bukkitChunk, this.needsDecoration));
2021-06-11 14:02:28 +02:00
if (this.needsDecoration) {
2021-06-11 20:33:36 +02:00
+ try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper
2021-06-11 14:02:28 +02:00
this.needsDecoration = false;
java.util.Random random = new java.util.Random();
2021-06-11 20:02:16 +02:00
random.setSeed(this.level.getSeed());
2023-06-07 19:18:05 +02:00
@@ -701,6 +702,7 @@ public class LevelChunk extends ChunkAccess {
2021-06-11 14:02:28 +02:00
}
}
2023-04-07 20:39:13 +02:00
server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk));
2021-06-11 14:02:28 +02:00
+ } // Paper
}
}
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
2023-06-07 19:18:05 +02:00
index 0eb09ce5c850d85ffd7229d27cf06b3e0edda11b..cc1d7626a82881c4410d65c6a33dadae7ab07172 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
2023-06-07 19:18:05 +02:00
@@ -483,13 +483,10 @@ public class ChunkSerializer {
2021-11-23 11:51:25 +01:00
ListTag nbttaglist1 = ChunkSerializer.getListOfCompoundsOrNull(nbt, "block_entities");
2021-06-11 14:02:28 +02:00
2021-11-23 11:51:25 +01:00
return nbttaglist == null && nbttaglist1 == null ? null : (chunk) -> {
- world.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot
if (nbttaglist != null) {
world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(nbttaglist, world));
}
- world.timings.syncChunkLoadEntitiesTimer.stopTiming(); // Spigot
2021-06-11 14:02:28 +02:00
2021-11-23 11:51:25 +01:00
- world.timings.syncChunkLoadTileEntitiesTimer.startTiming(); // Spigot
if (nbttaglist1 != null) {
for (int i = 0; i < nbttaglist1.size(); ++i) {
CompoundTag nbttagcompound1 = nbttaglist1.getCompound(i);
2023-06-07 19:18:05 +02:00
@@ -507,7 +504,6 @@ public class ChunkSerializer {
2021-11-23 11:51:25 +01:00
}
2021-06-11 14:02:28 +02:00
}
}
2021-11-23 11:51:25 +01:00
- world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot
2021-06-11 14:02:28 +02:00
2021-11-29 00:46:53 +01:00
};
}
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
2023-06-13 01:51:45 +02:00
index 5efe98cbcb44727fbbb195ff7007d01c823372b6..3338b424ca228693c199d022c01a81f9e2f9af0b 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
2023-06-13 01:51:45 +02:00
@@ -368,7 +368,7 @@ public final class CraftServer implements Server {
2023-03-31 06:47:59 +02:00
this.saveCommandsConfig();
this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
- this.pluginManager.useTimings(this.configuration.getBoolean("settings.plugin-profiling"));
+ //this.pluginManager.useTimings(this.configuration.getBoolean("settings.plugin-profiling")); // Paper - we already moved this
this.overrideSpawnLimits();
console.autosavePeriod = this.configuration.getInt("ticks-per.autosave");
this.warningState = WarningState.value(this.configuration.getString("settings.deprecated-verbose"));
2023-06-13 01:51:45 +02:00
@@ -2433,12 +2433,31 @@ public final class CraftServer implements Server {
2021-06-11 14:02:28 +02:00
private final org.bukkit.Server.Spigot spigot = new org.bukkit.Server.Spigot()
{
+ @Deprecated
@Override
public YamlConfiguration getConfig()
{
return org.spigotmc.SpigotConfig.config;
}
+ @Override
+ public YamlConfiguration getBukkitConfig()
+ {
+ return configuration;
+ }
+
+ @Override
+ public YamlConfiguration getSpigotConfig()
+ {
+ return org.spigotmc.SpigotConfig.config;
+ }
+
+ @Override
+ public YamlConfiguration getPaperConfig()
+ {
2022-06-09 10:51:45 +02:00
+ return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console);
2021-06-11 14:02:28 +02:00
+ }
+
@Override
public void restart() {
org.spigotmc.RestartCommand.restart();
2021-06-11 20:33:36 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
deleted file mode 100644
index b0ffa23faf62629043dfd613315eaf9c5fcc2cfe..0000000000000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package org.bukkit.craftbukkit;
-
-import java.util.HashMap;
-import net.minecraft.world.entity.Entity;
-import net.minecraft.world.level.Level;
-import net.minecraft.world.level.block.entity.BlockEntity;
-import net.minecraft.world.level.storage.PrimaryLevelData;
-import org.bukkit.craftbukkit.scheduler.CraftTask;
-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");
- public static final CustomTimingsHandler commandFunctionsTimer = new CustomTimingsHandler("Command Functions");
- public static final CustomTimingsHandler connectionTimer = new CustomTimingsHandler("Connection Handler");
- 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) {
- name += "(interval:" + period + ")";
- } else {
- name += "(Single)";
- }
- CustomTimingsHandler result = SpigotTimings.pluginTaskTimingMap.get(name);
- if (result == null) {
- result = new CustomTimingsHandler(name, SpigotTimings.schedulerSyncTimer);
- SpigotTimings.pluginTaskTimingMap.put(name, result);
- }
- return result;
- }
-
- /**
- * Get a named timer for the specified entity type to track type specific timings.
- * @param entity
- * @return
- */
- public static CustomTimingsHandler getEntityTimings(Entity entity) {
- String entityType = entity.getClass().getName();
- CustomTimingsHandler result = SpigotTimings.entityTypeTimingMap.get(entityType);
- if (result == null) {
- result = new CustomTimingsHandler("** tickEntity - " + entity.getClass().getSimpleName(), SpigotTimings.activatedEntityTimer);
- SpigotTimings.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(BlockEntity entity) {
- String entityType = entity.getClass().getName();
- CustomTimingsHandler result = SpigotTimings.tileEntityTypeTimingMap.get(entityType);
- if (result == null) {
- result = new CustomTimingsHandler("** tickTileEntity - " + entity.getClass().getSimpleName(), SpigotTimings.tickTileEntityTimer);
- SpigotTimings.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(Level server) {
- String name = ((PrimaryLevelData) server.levelData).getLevelName() + " - ";
-
- this.mobSpawn = new CustomTimingsHandler("** " + name + "mobSpawn");
- this.doChunkUnload = new CustomTimingsHandler("** " + name + "doChunkUnload");
- this.doTickPending = new CustomTimingsHandler("** " + name + "doTickPending");
- this.doTickTiles = new CustomTimingsHandler("** " + name + "doTickTiles");
- this.doChunkMap = new CustomTimingsHandler("** " + name + "doChunkMap");
- this.doSounds = new CustomTimingsHandler("** " + name + "doSounds");
- this.entityTick = new CustomTimingsHandler("** " + name + "entityTick");
- this.tileEntityTick = new CustomTimingsHandler("** " + name + "tileEntityTick");
- this.tileEntityPending = new CustomTimingsHandler("** " + name + "tileEntityPending");
-
- this.syncChunkLoadTimer = new CustomTimingsHandler("** " + name + "syncChunkLoad");
- this.syncChunkLoadStructuresTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Structures");
- this.syncChunkLoadEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Entities");
- this.syncChunkLoadTileEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileEntities");
- this.syncChunkLoadTileTicksTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileTicks");
- this.syncChunkLoadPostTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Post");
-
-
- this.tracker = new CustomTimingsHandler(name + "tracker");
- this.doTick = new CustomTimingsHandler(name + "doTick");
- this.tickEntities = new CustomTimingsHandler(name + "tickEntities");
- }
- }
-}
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
2023-06-13 01:51:45 +02:00
index e37f69880c4b439245d7edb4c35418ed3da27a5f..3c6617170c618800940d5826c7e73a3ac7f32e19 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
2023-06-13 01:51:45 +02:00
@@ -2470,6 +2470,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
2022-06-07 21:15:06 +02:00
2022-07-27 21:18:51 +02:00
CraftPlayer.this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(components, position == net.md_5.bungee.api.ChatMessageType.ACTION_BAR));
2021-06-11 14:02:28 +02:00
}
+
+ // Paper start
+ @Override
+ public int getPing()
+ {
+ return getHandle().latency;
+ }
+ // 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
2023-06-13 01:51:45 +02:00
index 4d94c3a19f98f78476ecc403f410d75a6ea57c2d..fcbf32a233c240dd45f75ee736bd102ce9f79332 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -1,5 +1,6 @@
package org.bukkit.craftbukkit.scheduler;
+import co.aikar.timings.MinecraftTimings; // Paper
2023-06-13 01:51:45 +02:00
import com.google.common.base.Preconditions;
2021-06-11 14:02:28 +02:00
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.ArrayList;
2021-07-18 09:41:53 +02:00
@@ -194,7 +195,8 @@ public class CraftScheduler implements BukkitScheduler {
2021-06-11 14:02:28 +02:00
}
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);
}
2021-07-18 09:41:53 +02:00
@@ -275,7 +277,7 @@ public class CraftScheduler implements BukkitScheduler {
2021-06-11 14:02:28 +02:00
}
return false;
}
- });
+ }){{this.timings=co.aikar.timings.MinecraftTimings.getCancelTasksTimer();}}; // Paper
2021-06-11 20:02:16 +02:00
this.handle(task, 0L);
for (CraftTask taskPending = this.head.getNext(); taskPending != null; taskPending = taskPending.getNext()) {
2021-06-11 14:02:28 +02:00
if (taskPending == task) {
2021-07-18 09:41:53 +02:00
@@ -310,7 +312,7 @@ public class CraftScheduler implements BukkitScheduler {
2021-06-11 14:02:28 +02:00
}
}
}
- });
+ }){{this.timings=co.aikar.timings.MinecraftTimings.getCancelTasksTimer(plugin);}}; // Paper
2021-06-11 20:02:16 +02:00
this.handle(task, 0L);
for (CraftTask taskPending = this.head.getNext(); taskPending != null; taskPending = taskPending.getNext()) {
2021-06-11 14:02:28 +02:00
if (taskPending == task) {
2021-07-18 09:41:53 +02:00
@@ -417,9 +419,7 @@ public class CraftScheduler implements BukkitScheduler {
2021-06-11 14:02:28 +02:00
if (task.isSync()) {
2021-06-11 20:02:16 +02:00
this.currentTask = task;
2021-06-11 14:02:28 +02:00
try {
- task.timings.startTiming(); // Spigot
task.run();
- task.timings.stopTiming(); // Spigot
} catch (final Throwable throwable) {
// Paper start
String msg = String.format(
2021-07-18 09:41:53 +02:00
@@ -453,8 +453,10 @@ public class CraftScheduler implements BukkitScheduler {
2021-06-11 20:02:16 +02:00
this.runners.remove(task.getTaskId());
2021-06-11 14:02:28 +02:00
}
}
2021-06-11 20:02:16 +02:00
+ MinecraftTimings.bukkitSchedulerFinishTimer.startTiming(); // Paper
this.pending.addAll(temp);
2021-06-11 14:02:28 +02:00
temp.clear();
2021-06-11 20:02:16 +02:00
+ MinecraftTimings.bukkitSchedulerFinishTimer.stopTiming(); // Paper
this.debugHead = this.debugHead.getNextHead(currentTick);
2021-06-11 14:02:28 +02:00
}
2023-06-13 01:51:45 +02:00
@@ -491,6 +493,7 @@ public class CraftScheduler implements BukkitScheduler {
2021-06-11 14:02:28 +02:00
}
private void parsePending() {
+ MinecraftTimings.bukkitSchedulerPendingTimer.startTiming();
CraftTask head = this.head;
CraftTask task = head.getNext();
CraftTask lastTask = head;
2023-06-13 01:51:45 +02:00
@@ -509,6 +512,7 @@ public class CraftScheduler implements BukkitScheduler {
2021-06-11 14:02:28 +02:00
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
2021-07-18 09:41:53 +02:00
index b89846e0f645c79afec018dae1d64a1bda043ed9..3f45bab0e9f7b3697e6d9d1092a1e6e579f7066f 100644
2021-06-11 14:02:28 +02:00
--- 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;
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
+import co.aikar.timings.Timing; // Paper
public class CraftTask implements BukkitTask, Runnable { // Spigot
2021-07-18 09:41:53 +02:00
@@ -26,13 +29,13 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
2021-06-11 14:02:28 +02:00
*/
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
+ public Timing timings; // Paper
private final Plugin plugin;
private final int id;
2021-07-18 09:41:53 +02:00
private final long createdAt = System.nanoTime();
2021-06-11 14:02:28 +02:00
- final CustomTimingsHandler timings; // Spigot
CraftTask() {
this(null, null, CraftTask.NO_REPEATING, CraftTask.NO_REPEATING);
}
2021-07-18 09:41:53 +02:00
@@ -52,7 +55,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
2021-06-11 14:02:28 +02:00
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
2021-07-18 09:41:53 +02:00
@@ -73,7 +76,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
2021-06-11 14:02:28 +02:00
}
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
2021-07-18 09:41:53 +02:00
@@ -93,11 +96,13 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
2021-06-11 14:02:28 +02:00
@Override
public void run() {
+ try (Timing ignored = timings.startTiming()) { // Paper
2021-06-11 20:02:16 +02:00
if (this.rTask != null) {
this.rTask.run();
2021-06-11 14:02:28 +02:00
} else {
2021-06-11 20:02:16 +02:00
this.cTask.accept(this);
2021-06-11 14:02:28 +02:00
}
+ } // Paper
}
2021-07-18 09:41:53 +02:00
long getCreatedAt() {
@@ -128,7 +133,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
2021-06-11 14:02:28 +02:00
this.next = next;
}
- Class<?> getTaskClass() {
2021-06-11 20:02:16 +02:00
+ public Class<?> getTaskClass() { // Paper
return (this.rTask != null) ? this.rTask.getClass() : ((this.cTask != null) ? this.cTask.getClass() : null);
2021-06-11 14:02:28 +02:00
}
2021-07-18 09:41:53 +02:00
@@ -152,9 +157,4 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
2021-06-11 14:02:28 +02:00
return true;
}
- // Spigot start
- public String getTaskName() {
2021-06-11 20:02:16 +02:00
- return (this.getTaskClass() == null) ? "Unknown" : this.getTaskClass().getName();
2021-06-11 14:02:28 +02:00
- }
- // Spigot end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java b/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java
2023-03-15 00:44:53 +01:00
index f97eccb6a17c7876e1e002d798eb67bbe80571a0..76effc345d362047e64d064eb64a5222612aec14 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java
2023-03-15 00:44:53 +01:00
@@ -8,4 +8,11 @@ public class CraftIconCache implements CachedServerIcon {
2023-03-14 19:05:23 +01:00
public CraftIconCache(final byte[] value) {
2021-06-11 14:02:28 +02:00
this.value = value;
}
2023-03-14 19:05:23 +01:00
+
2023-03-15 00:44:53 +01:00
+ public String getData() {
+ if (value == null) {
+ return null;
+ }
+ return "data:image/png;base64," + new String(java.util.Base64.getEncoder().encode(value), java.nio.charset.StandardCharsets.UTF_8);
+ } // Paper
2023-03-14 19:05:23 +01:00
}
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
2023-06-13 09:10:07 +02:00
index 0d5202f6bc14bc0cec77f86bed2f1f590e0fffeb..3a7a498003d70cf9e31acffee70b23dec0be6845 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
2023-06-06 11:09:19 +02:00
@@ -224,6 +224,12 @@ public final class CraftMagicNumbers implements UnsafeValues {
2021-06-11 14:02:28 +02:00
}
2021-11-24 20:02:36 +01:00
// Paper end
2021-06-11 14:02:28 +02:00
// ========================================================================
+ // Paper start
+ @Override
+ public void reportTimings() {
+ co.aikar.timings.TimingsExport.reportTimings();
+ }
+ // Paper end
public static byte toLegacyData(BlockState data) {
return CraftLegacy.toLegacyData(data);
2023-06-13 01:51:45 +02:00
@@ -450,6 +456,13 @@ public final class CraftMagicNumbers implements UnsafeValues {
2023-06-06 11:09:19 +02:00
return CraftFeatureFlag.getFromNMS(namespacedKey);
2021-06-11 14:02:28 +02:00
}
+ // Paper start
+ @Override
+ public String getTimingsServerName() {
2022-06-09 10:51:45 +02:00
+ return io.papermc.paper.configuration.GlobalConfiguration.get().timings.serverName;
2021-06-11 14:02:28 +02:00
+ }
+ // 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
2023-06-13 01:51:45 +02:00
index 7cdfd82fdef19d5732ebc2126e2c377b441de596..ebd48f9977553174b14bdc7429c07d8352f5a297 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/org/spigotmc/ActivationRange.java
+++ b/src/main/java/org/spigotmc/ActivationRange.java
2022-01-09 06:12:05 +01:00
@@ -27,7 +27,7 @@ import net.minecraft.world.entity.projectile.ThrownTrident;
2021-06-11 20:02:16 +02:00
import net.minecraft.world.entity.raid.Raider;
2021-06-11 14:02:28 +02:00
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
-import org.bukkit.craftbukkit.SpigotTimings;
+import co.aikar.timings.MinecraftTimings;
public class ActivationRange
{
2022-01-09 06:12:05 +01:00
@@ -71,8 +71,8 @@ public class ActivationRange
2021-06-11 14:02:28 +02:00
/**
* 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)
2022-01-09 06:12:05 +01:00
@@ -107,7 +107,7 @@ public class ActivationRange
2021-06-11 14:02:28 +02:00
*/
public static void activateEntities(Level 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;
2022-01-09 06:12:05 +01:00
@@ -134,7 +134,7 @@ public class ActivationRange
2021-06-11 20:02:16 +02:00
world.getEntities().get(maxBB, ActivationRange::activateEntity);
2021-06-11 14:02:28 +02:00
}
- SpigotTimings.entityActivationCheckTimer.stopTiming();
+ MinecraftTimings.entityActivationCheckTimer.stopTiming();
}
/**
2022-01-09 06:12:05 +01:00
@@ -229,10 +229,8 @@ public class ActivationRange
2021-06-11 14:02:28 +02:00
*/
public static boolean checkIfActive(Entity entity)
{
- SpigotTimings.checkIfActiveTimer.startTiming();
// Never safe to skip fireworks or entities not yet added to chunk
2021-06-11 20:02:16 +02:00
if ( entity instanceof FireworkRocketEntity ) {
2021-06-11 14:02:28 +02:00
- SpigotTimings.checkIfActiveTimer.stopTiming();
return true;
}
2022-01-09 06:12:05 +01:00
@@ -256,7 +254,6 @@ public class ActivationRange
2021-06-11 14:02:28 +02:00
{
isActive = false;
}
- SpigotTimings.checkIfActiveTimer.stopTiming();
return isActive;
}
}