diff --git a/patches/api/0003-Leaf-config-files.patch b/patches/api/0001-Leaf-config-files.patch similarity index 79% rename from patches/api/0003-Leaf-config-files.patch rename to patches/api/0001-Leaf-config-files.patch index 2ab8e109..47bb9603 100644 --- a/patches/api/0003-Leaf-config-files.patch +++ b/patches/api/0001-Leaf-config-files.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Leaf config files diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index bd93eb61669a014054cb1ba71f99d74ba8463622..c55819f56b4a3850496feef6900c1ec8a0bb1a9d 100644 +index 9ff34994f2a4dcf0b10262aacc912d7d283c121e..a5938b0a960121bd77a13e4c8fc8a053bea481c5 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2186,6 +2186,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi - } - // Purpur end +@@ -2174,6 +2174,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + + // Paper end + // Leaf start + @NotNull diff --git a/patches/api/0001-Pufferfish-Sentry.patch b/patches/api/0002-Pufferfish-Sentry.patch similarity index 100% rename from patches/api/0001-Pufferfish-Sentry.patch rename to patches/api/0002-Pufferfish-Sentry.patch diff --git a/patches/api/0002-Purpur-API-Changes.patch b/patches/api/0003-Purpur-API-Changes.patch similarity index 99% rename from patches/api/0002-Purpur-API-Changes.patch rename to patches/api/0003-Purpur-API-Changes.patch index 1344b4b6..b595aeea 100644 --- a/patches/api/0002-Purpur-API-Changes.patch +++ b/patches/api/0003-Purpur-API-Changes.patch @@ -439,12 +439,12 @@ index bce07d84cafca677bb6fad78c21b82097f06430c..4ef0fa4f1ef72bb784674671473c6a32 + // Purpur end - OfflinePlayer API } diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 9ff34994f2a4dcf0b10262aacc912d7d283c121e..bd93eb61669a014054cb1ba71f99d74ba8463622 100644 +index a5938b0a960121bd77a13e4c8fc8a053bea481c5..43a57c9e32e5a51140e784a4a5a44c0b0b752133 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2174,6 +2174,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi - - // Paper end +@@ -2182,6 +2182,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + } + // Leaf end + // Purpur start + @NotNull @@ -461,7 +461,7 @@ index 9ff34994f2a4dcf0b10262aacc912d7d283c121e..bd93eb61669a014054cb1ba71f99d74b /** * Sends the component to the player * -@@ -2483,4 +2495,111 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2491,4 +2503,111 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi long getLastTickOversleepTime(); // Gale end - YAPFA - last tick time - API diff --git a/patches/api/0008-Revert-Purpur-Fire-Immunity-API.patch b/patches/api/0004-Revert-Purpur-Fire-Immunity-API.patch similarity index 100% rename from patches/api/0008-Revert-Purpur-Fire-Immunity-API.patch rename to patches/api/0004-Revert-Purpur-Fire-Immunity-API.patch diff --git a/patches/api/0005-Remove-Timings.patch b/patches/api/0005-Remove-Timings.patch new file mode 100644 index 00000000..b11a020b --- /dev/null +++ b/patches/api/0005-Remove-Timings.patch @@ -0,0 +1,3267 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> +Date: Sat, 23 Sep 2023 03:38:21 -0400 +Subject: [PATCH] Remove Timings + +Completely remove the Timings, since it wastes too much performance. Use Spark instead. + +diff --git a/src/main/java/co/aikar/timings/FullServerTickHandler.java b/src/main/java/co/aikar/timings/FullServerTickHandler.java +deleted file mode 100644 +index 16040016d7de911eddec278ec2adc2b856df9bcd..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/FullServerTickHandler.java ++++ /dev/null +@@ -1,84 +0,0 @@ +-package co.aikar.timings; +- +-import static co.aikar.timings.TimingsManager.*; +- +-import org.bukkit.Bukkit; +-import org.jetbrains.annotations.NotNull; +- +-@Deprecated(forRemoval = true) +-public class FullServerTickHandler extends TimingHandler { +- private static final TimingIdentifier IDENTITY = new TimingIdentifier("Minecraft", "Full Server Tick", null); +- final TimingData minuteData; +- double avgFreeMemory = -1D; +- double avgUsedMemory = -1D; +- FullServerTickHandler() { +- super(IDENTITY); +- minuteData = new TimingData(id); +- +- TIMING_MAP.put(IDENTITY, this); +- } +- +- @NotNull +- public Timing startTimingFullServerTick() { // Gale - final timings calls +- if (TimingsManager.needsFullReset) { +- TimingsManager.resetTimings(); +- } else if (TimingsManager.needsRecheckEnabled) { +- TimingsManager.recheckEnabled(); +- } +- return super.startTiming(); +- } +- +- public void stopTimingFullServerTick() { // Gale - final timings calls +- super.stopTiming(); +- if (!isEnabled()) { +- return; +- } +- if (TimingHistory.timedTicks % 20 == 0) { +- final Runtime runtime = Runtime.getRuntime(); +- double usedMemory = runtime.totalMemory() - runtime.freeMemory(); +- double freeMemory = runtime.maxMemory() - usedMemory; +- if (this.avgFreeMemory == -1) { +- this.avgFreeMemory = freeMemory; +- } else { +- this.avgFreeMemory = (this.avgFreeMemory * (59 / 60D)) + (freeMemory * (1 / 60D)); +- } +- +- if (this.avgUsedMemory == -1) { +- this.avgUsedMemory = usedMemory; +- } else { +- this.avgUsedMemory = (this.avgUsedMemory * (59 / 60D)) + (usedMemory * (1 / 60D)); +- } +- } +- +- long start = System.nanoTime(); +- TimingsManager.tick(); +- long diff = System.nanoTime() - start; +- TIMINGS_TICK.addDiff(diff, null); +- // addDiff for TIMINGS_TICK incremented this, bring it back down to 1 per tick. +- record.setCurTickCount(record.getCurTickCount()-1); +- +- minuteData.setCurTickTotal(record.getCurTickTotal()); +- minuteData.setCurTickCount(1); +- +- boolean violated = isViolated(); +- minuteData.processTick(violated); +- TIMINGS_TICK.processTick(violated); +- processTick(violated); +- +- +- if (TimingHistory.timedTicks % 1200 == 0) { +- MINUTE_REPORTS.add(new TimingHistory.MinuteReport()); +- TimingHistory.resetTicks(false); +- minuteData.reset(); +- } +- if (TimingHistory.timedTicks % Timings.getHistoryInterval() == 0) { +- TimingsManager.HISTORY.add(new TimingHistory()); +- TimingsManager.resetTimings(); +- } +- Bukkit.getUnsafe().reportTimings(); +- } +- +- boolean isViolated() { +- return record.getCurTickTotal() > 50000000; +- } +-} +diff --git a/src/main/java/co/aikar/timings/NullTimingHandler.java b/src/main/java/co/aikar/timings/NullTimingHandler.java +deleted file mode 100644 +index 81671cf40feeed2844ee8d92348d48062aaf2c46..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/NullTimingHandler.java ++++ /dev/null +@@ -1,69 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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 org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-@Deprecated(forRemoval = true) +-public final class NullTimingHandler implements Timing { +- public static final Timing NULL = new NullTimingHandler(); +- @NotNull +- @Override +- public Timing startTiming() { +- return this; +- } +- +- @Override +- public void stopTiming() { +- +- } +- +- @NotNull +- @Override +- public Timing startTimingIfSync() { +- return this; +- } +- +- @Override +- public void stopTimingIfSync() { +- +- } +- +- @Override +- public void abort() { +- +- } +- +- @Nullable +- @Override +- public TimingHandler getTimingHandler() { +- return null; +- } +- +- @Override +- public void close() { +- +- } +-} +diff --git a/src/main/java/co/aikar/timings/TimedEventExecutor.java b/src/main/java/co/aikar/timings/TimedEventExecutor.java +deleted file mode 100644 +index 8f29c1561ba5916cb5634392edd8bd2a5a294a51..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/TimedEventExecutor.java ++++ /dev/null +@@ -1,90 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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 org.bukkit.Bukkit; +-import org.bukkit.event.Event; +-import org.bukkit.event.EventException; +-import org.bukkit.event.Listener; +-import org.bukkit.plugin.EventExecutor; +-import org.bukkit.plugin.Plugin; +- +-import java.lang.reflect.Method; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-@Deprecated(forRemoval = true) +-public class TimedEventExecutor implements EventExecutor { +- +- private final EventExecutor executor; +- private final Timing timings; +- +- /** +- * Wraps an event executor and associates a timing handler to it. +- * +- * @param executor Executor to wrap +- * @param plugin Owning plugin +- * @param method EventHandler method +- * @param eventClass Owning class +- */ +- public TimedEventExecutor(@NotNull EventExecutor executor, @NotNull Plugin plugin, @Nullable Method method, @NotNull Class eventClass) { +- this.executor = executor; +- String id; +- +- if (method == null) { +- if (executor.getClass().getEnclosingClass() != null) { // Oh Skript, how we love you +- method = executor.getClass().getEnclosingMethod(); +- } +- } +- +- if (method != null) { +- id = method.getDeclaringClass().getName(); +- } else { +- id = executor.getClass().getName(); +- } +- +- +- final String eventName = eventClass.getSimpleName(); +- boolean verbose = "BlockPhysicsEvent".equals(eventName); +- this.timings = Timings.ofSafe(plugin, (verbose ? "## " : "") + +- "Event: " + id + " (" + eventName + ")"); +- } +- +- @Override +- public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException { +- if (event.isAsynchronous() || !Timings.timingsEnabled || !Bukkit.isPrimaryThread()) { +- executor.execute(listener, event); +- return; +- } +- try (Timing ignored = timings.startTiming()){ +- executor.execute(listener, event); +- } +- } +- +- @Override +- @NotNull +- public String toString() { +- return "TimedEventExecutor['" + this.executor.toString() + "']"; +- } +-} +diff --git a/src/main/java/co/aikar/timings/Timing.java b/src/main/java/co/aikar/timings/Timing.java +deleted file mode 100644 +index 7514fad26f955329f8bf17ff17db75f0c8301ee5..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/Timing.java ++++ /dev/null +@@ -1,86 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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 org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-/** +- * Provides an ability to time sections of code within the Minecraft Server +- * +- * @deprecated Timings will likely be replaced with Spark in the future +- */ +-@Deprecated(forRemoval = true) +-public interface Timing extends AutoCloseable { +- /** +- * Starts timing the execution until {@link #stopTiming()} is called. +- * +- * @return Timing +- */ +- @NotNull +- Timing startTiming(); +- +- /** +- *

Stops timing and records the data. Propagates the data up to group handlers.

+- * +- * Will automatically be called when this Timing is used with try-with-resources +- */ +- void stopTiming(); +- +- /** +- * Starts timing the execution until {@link #stopTiming()} is called. +- * +- * But only if we are on the primary thread. +- * +- * @return Timing +- */ +- @NotNull +- Timing startTimingIfSync(); +- +- /** +- *

Stops timing and records the data. Propagates the data up to group handlers.

+- * +- *

Will automatically be called when this Timing is used with try-with-resources

+- * +- * But only if we are on the primary thread. +- */ +- void stopTimingIfSync(); +- +- /** +- * @deprecated Doesn't do anything - Removed +- */ +- @Deprecated +- void abort(); +- +- /** +- * Used internally to get the actual backing Handler in the case of delegated Handlers +- * +- * @return TimingHandler +- */ +- @Nullable +- TimingHandler getTimingHandler(); +- +- @Override +- void close(); +-} +diff --git a/src/main/java/co/aikar/timings/TimingData.java b/src/main/java/co/aikar/timings/TimingData.java +deleted file mode 100644 +index a5d13a1e44edb861f45c83a9b4309fbf799d407d..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/TimingData.java ++++ /dev/null +@@ -1,122 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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 java.util.List; +-import org.jetbrains.annotations.NotNull; +- +-import static co.aikar.util.JSONUtil.toArray; +- +-/** +- *

Lightweight object for tracking timing data

+- * +- * This is broken out to reduce memory usage +- */ +-class TimingData { +- private final int id; +- private int count = 0; +- private int lagCount = 0; +- private long totalTime = 0; +- private long lagTotalTime = 0; +- private int curTickCount = 0; +- private long curTickTotal = 0; +- +- TimingData(int id) { +- this.id = id; +- } +- +- private TimingData(TimingData data) { +- this.id = data.id; +- this.totalTime = data.totalTime; +- this.lagTotalTime = data.lagTotalTime; +- this.count = data.count; +- this.lagCount = data.lagCount; +- } +- +- void add(long diff) { +- ++curTickCount; +- curTickTotal += diff; +- } +- +- void processTick(boolean violated) { +- totalTime += curTickTotal; +- count += curTickCount; +- if (violated) { +- lagTotalTime += curTickTotal; +- lagCount += curTickCount; +- } +- curTickTotal = 0; +- curTickCount = 0; +- } +- +- void reset() { +- count = 0; +- lagCount = 0; +- curTickTotal = 0; +- curTickCount = 0; +- totalTime = 0; +- lagTotalTime = 0; +- } +- +- protected TimingData clone() { +- return new TimingData(this); +- } +- +- @NotNull +- List export() { +- List list = toArray( +- id, +- count, +- totalTime); +- if (lagCount > 0) { +- list.add(lagCount); +- list.add(lagTotalTime); +- } +- return list; +- } +- +- boolean hasData() { +- return count > 0; +- } +- +- long getTotalTime() { +- return totalTime; +- } +- +- int getCurTickCount() { +- return curTickCount; +- } +- +- void setCurTickCount(int curTickCount) { +- this.curTickCount = curTickCount; +- } +- +- long getCurTickTotal() { +- return curTickTotal; +- } +- +- void setCurTickTotal(long curTickTotal) { +- this.curTickTotal = curTickTotal; +- } +-} +diff --git a/src/main/java/co/aikar/timings/TimingHandler.java b/src/main/java/co/aikar/timings/TimingHandler.java +deleted file mode 100644 +index 51d54b87106aa17c2de9ab22eae22d176c7d0bfc..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/TimingHandler.java ++++ /dev/null +@@ -1,226 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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 co.aikar.util.LoadingIntMap; +-import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +- +-import java.util.ArrayDeque; +-import java.util.Deque; +-import java.util.concurrent.atomic.AtomicInteger; +-import java.util.logging.Level; +-import java.util.logging.Logger; +- +-import org.bukkit.Bukkit; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-class TimingHandler implements Timing { +- +- private static AtomicInteger idPool = new AtomicInteger(1); +- private static Deque TIMING_STACK = new ArrayDeque<>(); +- final int id = idPool.getAndIncrement(); +- +- final TimingIdentifier identifier; +- private final boolean verbose; +- +- private final Int2ObjectOpenHashMap children = new LoadingIntMap<>(TimingData::new); +- +- final TimingData record; +- private TimingHandler startParent; +- private final TimingHandler groupHandler; +- +- private long start = 0; +- private int timingDepth = 0; +- private boolean added; +- private boolean timed; +- private boolean enabled; +- +- TimingHandler(@NotNull TimingIdentifier id) { +- this.identifier = id; +- this.verbose = id.name.startsWith("##"); +- this.record = new TimingData(this.id); +- this.groupHandler = id.groupHandler; +- +- TimingIdentifier.getGroup(id.group).handlers.add(this); +- checkEnabled(); +- } +- +- final void checkEnabled() { +- enabled = Timings.timingsEnabled && (!verbose || Timings.verboseEnabled); +- } +- +- void processTick(boolean violated) { +- if (timingDepth != 0 || record.getCurTickCount() == 0) { +- timingDepth = 0; +- start = 0; +- return; +- } +- +- record.processTick(violated); +- for (TimingData handler : children.values()) { +- handler.processTick(violated); +- } +- } +- +- @NotNull +- @Override +- public Timing startTimingIfSync() { +- startTiming(); +- return this; +- } +- +- @Override +- public void stopTimingIfSync() { +- stopTiming(); +- } +- +- @NotNull +- public final Timing startTiming() { // Gale - final timings calls +- if (!enabled || !Bukkit.isPrimaryThread()) { +- return this; +- } +- if (++timingDepth == 1) { +- startParent = TIMING_STACK.peekLast(); +- start = System.nanoTime(); +- } +- TIMING_STACK.addLast(this); +- return this; +- } +- +- public final void stopTiming() { // Gale - final timings calls +- if (!enabled || timingDepth <= 0 || start == 0 || !Bukkit.isPrimaryThread()) { +- return; +- } +- +- popTimingStack(); +- if (--timingDepth == 0) { +- addDiff(System.nanoTime() - start, startParent); +- startParent = null; +- start = 0; +- } +- } +- +- private void popTimingStack() { +- TimingHandler last; +- while ((last = TIMING_STACK.removeLast()) != this) { +- last.timingDepth = 0; +- if ("Minecraft".equalsIgnoreCase(last.identifier.group)) { +- Logger.getGlobal().log(Level.SEVERE, "TIMING_STACK_CORRUPTION - Look above this for any errors and report this to Paper unless it has a plugin in the stack trace (" + last.identifier + " did not stopTiming)"); +- } else { +- Logger.getGlobal().log(Level.SEVERE, "TIMING_STACK_CORRUPTION - Report this to the plugin " + last.identifier.group + " (Look for errors above this in the logs) (" + last.identifier + " did not stopTiming)", new Throwable()); +- } +- +- boolean found = TIMING_STACK.contains(this); +- if (!found) { +- // We aren't even in the stack... Don't pop everything +- TIMING_STACK.addLast(last); +- break; +- } +- } +- } +- +- @Override +- public final void abort() { +- +- } +- +- void addDiff(long diff, @Nullable TimingHandler parent) { +- if (parent != null) { +- parent.children.get(id).add(diff); +- } +- +- record.add(diff); +- if (!added) { +- added = true; +- timed = true; +- TimingsManager.HANDLERS.add(this); +- } +- if (groupHandler != null) { +- groupHandler.addDiff(diff, parent); +- groupHandler.children.get(id).add(diff); +- } +- } +- +- /** +- * Reset this timer, setting all values to zero. +- */ +- void reset(boolean full) { +- record.reset(); +- if (full) { +- timed = false; +- } +- start = 0; +- timingDepth = 0; +- added = false; +- children.clear(); +- checkEnabled(); +- } +- +- @NotNull +- @Override +- public TimingHandler getTimingHandler() { +- return this; +- } +- +- @Override +- public boolean equals(Object o) { +- return (this == o); +- } +- +- @Override +- public int hashCode() { +- return id; +- } +- +- /** +- * This is simply for the Closeable interface so it can be used with try-with-resources () +- */ +- @Override +- public void close() { +- stopTimingIfSync(); +- } +- +- public boolean isSpecial() { +- return this == TimingsManager.FULL_SERVER_TICK || this == TimingsManager.TIMINGS_TICK; +- } +- +- boolean isTimed() { +- return timed; +- } +- +- public boolean isEnabled() { +- return enabled; +- } +- +- @NotNull +- TimingData[] cloneChildren() { +- final TimingData[] clonedChildren = new TimingData[children.size()]; +- int i = 0; +- for (TimingData child : children.values()) { +- clonedChildren[i++] = child.clone(); +- } +- return clonedChildren; +- } +-} +diff --git a/src/main/java/co/aikar/timings/TimingHistory.java b/src/main/java/co/aikar/timings/TimingHistory.java +deleted file mode 100644 +index 02e88db63be2d5e31da6b65157ba7b971b1f10f3..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/TimingHistory.java ++++ /dev/null +@@ -1,355 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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 co.aikar.timings.TimingHistory.RegionData.RegionId; +-import com.google.common.base.Function; +-import com.google.common.collect.Sets; +-import org.bukkit.Bukkit; +-import org.bukkit.Chunk; +-import org.bukkit.Material; +-import org.bukkit.World; +-import org.bukkit.block.BlockState; +-import org.bukkit.entity.Entity; +-import org.bukkit.entity.EntityType; +-import org.bukkit.entity.Player; +-import co.aikar.util.LoadingMap; +-import co.aikar.util.MRUMapCache; +- +-import java.lang.management.ManagementFactory; +-import java.util.Collection; +-import java.util.EnumMap; +-import java.util.List; +-import java.util.Map; +-import java.util.Set; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-import static co.aikar.timings.TimingsManager.FULL_SERVER_TICK; +-import static co.aikar.timings.TimingsManager.MINUTE_REPORTS; +-import static co.aikar.util.JSONUtil.*; +- +-@Deprecated(forRemoval = true) +-@SuppressWarnings({"deprecation", "SuppressionAnnotation", "Convert2Lambda", "Anonymous2MethodRef"}) +-public class TimingHistory { +- public static long lastMinuteTime; +- public static long timedTicks; +- public static long playerTicks; +- public static long entityTicks; +- public static long tileEntityTicks; +- public static long activatedEntityTicks; +- private static int worldIdPool = 1; +- static Map worldMap = LoadingMap.newHashMap(new Function() { +- @NotNull +- @Override +- public Integer apply(@Nullable String input) { +- return worldIdPool++; +- } +- }); +- private final long endTime; +- private final long startTime; +- private final long totalTicks; +- private final long totalTime; // Represents all time spent running the server this history +- private final MinuteReport[] minuteReports; +- +- private final TimingHistoryEntry[] entries; +- final Set tileEntityTypeSet = Sets.newHashSet(); +- final Set entityTypeSet = Sets.newHashSet(); +- private final Map worlds; +- +- TimingHistory() { +- this.endTime = System.currentTimeMillis() / 1000; +- this.startTime = TimingsManager.historyStart / 1000; +- if (timedTicks % 1200 != 0 || MINUTE_REPORTS.isEmpty()) { +- this.minuteReports = MINUTE_REPORTS.toArray(new MinuteReport[MINUTE_REPORTS.size() + 1]); +- this.minuteReports[this.minuteReports.length - 1] = new MinuteReport(); +- } else { +- this.minuteReports = MINUTE_REPORTS.toArray(new MinuteReport[MINUTE_REPORTS.size()]); +- } +- long ticks = 0; +- for (MinuteReport mp : this.minuteReports) { +- ticks += mp.ticksRecord.timed; +- } +- this.totalTicks = ticks; +- this.totalTime = FULL_SERVER_TICK.record.getTotalTime(); +- this.entries = new TimingHistoryEntry[TimingsManager.HANDLERS.size()]; +- +- int i = 0; +- for (TimingHandler handler : TimingsManager.HANDLERS) { +- entries[i++] = new TimingHistoryEntry(handler); +- } +- +- // Information about all loaded chunks/entities +- //noinspection unchecked +- this.worlds = toObjectMapper(Bukkit.getWorlds(), new Function() { +- @NotNull +- @Override +- public JSONPair apply(World world) { +- Map regions = LoadingMap.newHashMap(RegionData.LOADER); +- +- for (Chunk chunk : world.getLoadedChunks()) { +- RegionData data = regions.get(new RegionId(chunk.getX(), chunk.getZ())); +- +- for (Entity entity : chunk.getEntities()) { +- if (entity == null) { +- Bukkit.getLogger().warning("Null entity detected in chunk at position x: " + chunk.getX() + ", z: " + chunk.getZ()); +- continue; +- } +- +- data.entityCounts.get(entity.getType()).increment(); +- } +- +- for (BlockState tileEntity : chunk.getTileEntities(false)) { +- if (tileEntity == null) { +- Bukkit.getLogger().warning("Null tileentity detected in chunk at position x: " + chunk.getX() + ", z: " + chunk.getZ()); +- continue; +- } +- +- data.tileEntityCounts.get(tileEntity.getBlock().getType()).increment(); +- } +- } +- return pair( +- worldMap.get(world.getName()), +- toArrayMapper(regions.values(),new Function() { +- @NotNull +- @Override +- public Object apply(RegionData input) { +- return toArray( +- input.regionId.x, +- input.regionId.z, +- toObjectMapper(input.entityCounts.entrySet(), +- new Function, JSONPair>() { +- @NotNull +- @Override +- public JSONPair apply(Map.Entry entry) { +- entityTypeSet.add(entry.getKey()); +- return pair( +- String.valueOf(entry.getKey().ordinal()), +- entry.getValue().count() +- ); +- } +- } +- ), +- toObjectMapper(input.tileEntityCounts.entrySet(), +- new Function, JSONPair>() { +- @NotNull +- @Override +- public JSONPair apply(Map.Entry entry) { +- tileEntityTypeSet.add(entry.getKey()); +- return pair( +- String.valueOf(entry.getKey().ordinal()), +- entry.getValue().count() +- ); +- } +- } +- ) +- ); +- } +- }) +- ); +- } +- }); +- } +- static class RegionData { +- final RegionId regionId; +- @SuppressWarnings("Guava") +- static Function LOADER = new Function() { +- @NotNull +- @Override +- public RegionData apply(@NotNull RegionId id) { +- return new RegionData(id); +- } +- }; +- RegionData(@NotNull RegionId id) { +- this.regionId = id; +- } +- +- @Override +- public boolean equals(Object o) { +- if (this == o) { +- return true; +- } +- if (o == null || getClass() != o.getClass()) { +- return false; +- } +- +- RegionData that = (RegionData) o; +- +- return regionId.equals(that.regionId); +- +- } +- +- @Override +- public int hashCode() { +- return regionId.hashCode(); +- } +- +- @SuppressWarnings("unchecked") +- final Map entityCounts = MRUMapCache.of(LoadingMap.of( +- new EnumMap(EntityType.class), k -> new Counter() +- )); +- @SuppressWarnings("unchecked") +- final Map tileEntityCounts = MRUMapCache.of(LoadingMap.of( +- new EnumMap(Material.class), k -> new Counter() +- )); +- +- static class RegionId { +- final int x, z; +- final long regionId; +- RegionId(int x, int z) { +- this.x = x >> 5 << 5; +- this.z = z >> 5 << 5; +- this.regionId = ((long) (this.x) << 32) + (this.z >> 5 << 5) - Integer.MIN_VALUE; +- } +- +- @Override +- public boolean equals(Object o) { +- if (this == o) return true; +- if (o == null || getClass() != o.getClass()) return false; +- +- RegionId regionId1 = (RegionId) o; +- +- return regionId == regionId1.regionId; +- +- } +- +- @Override +- public int hashCode() { +- return (int) (regionId ^ (regionId >>> 32)); +- } +- } +- } +- static void resetTicks(boolean fullReset) { +- if (fullReset) { +- // Non full is simply for 1 minute reports +- timedTicks = 0; +- } +- lastMinuteTime = System.nanoTime(); +- playerTicks = 0; +- tileEntityTicks = 0; +- entityTicks = 0; +- activatedEntityTicks = 0; +- } +- +- @NotNull +- Object export() { +- return createObject( +- pair("s", startTime), +- pair("e", endTime), +- pair("tk", totalTicks), +- pair("tm", totalTime), +- pair("w", worlds), +- pair("h", toArrayMapper(entries, new Function() { +- @Nullable +- @Override +- public Object apply(TimingHistoryEntry entry) { +- TimingData record = entry.data; +- if (!record.hasData()) { +- return null; +- } +- return entry.export(); +- } +- })), +- pair("mp", toArrayMapper(minuteReports, new Function() { +- @NotNull +- @Override +- public Object apply(MinuteReport input) { +- return input.export(); +- } +- })) +- ); +- } +- +- static class MinuteReport { +- final long time = System.currentTimeMillis() / 1000; +- +- final TicksRecord ticksRecord = new TicksRecord(); +- final PingRecord pingRecord = new PingRecord(); +- final TimingData fst = TimingsManager.FULL_SERVER_TICK.minuteData.clone(); +- final double tps = 1E9 / ( System.nanoTime() - lastMinuteTime ) * ticksRecord.timed; +- final double usedMemory = TimingsManager.FULL_SERVER_TICK.avgUsedMemory; +- final double freeMemory = TimingsManager.FULL_SERVER_TICK.avgFreeMemory; +- final double loadAvg = ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage(); +- +- @NotNull +- List export() { +- return toArray( +- time, +- Math.round(tps * 100D) / 100D, +- Math.round(pingRecord.avg * 100D) / 100D, +- fst.export(), +- toArray(ticksRecord.timed, +- ticksRecord.player, +- ticksRecord.entity, +- ticksRecord.activatedEntity, +- ticksRecord.tileEntity +- ), +- usedMemory, +- freeMemory, +- loadAvg +- ); +- } +- } +- +- private static class TicksRecord { +- final long timed; +- final long player; +- final long entity; +- final long tileEntity; +- final long activatedEntity; +- +- TicksRecord() { +- timed = timedTicks - (TimingsManager.MINUTE_REPORTS.size() * 1200); +- player = playerTicks; +- entity = entityTicks; +- tileEntity = tileEntityTicks; +- activatedEntity = activatedEntityTicks; +- } +- +- } +- +- private static class PingRecord { +- final double avg; +- +- PingRecord() { +- final Collection onlinePlayers = Bukkit.getOnlinePlayers(); +- int totalPing = 0; +- for (Player player : onlinePlayers) { +- totalPing += player.spigot().getPing(); +- } +- avg = onlinePlayers.isEmpty() ? 0 : totalPing / onlinePlayers.size(); +- } +- } +- +- +- private static class Counter { +- private int count = 0; +- public int increment() { +- return ++count; +- } +- public int count() { +- return count; +- } +- } +-} +diff --git a/src/main/java/co/aikar/timings/TimingHistoryEntry.java b/src/main/java/co/aikar/timings/TimingHistoryEntry.java +deleted file mode 100644 +index 86d5ac6bd0d7d0003688761aceb3f3343575319f..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/TimingHistoryEntry.java ++++ /dev/null +@@ -1,58 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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.base.Function; +- +-import java.util.List; +-import org.jetbrains.annotations.NotNull; +- +-import static co.aikar.util.JSONUtil.toArrayMapper; +- +-class TimingHistoryEntry { +- final TimingData data; +- private final TimingData[] children; +- +- TimingHistoryEntry(@NotNull TimingHandler handler) { +- this.data = handler.record.clone(); +- children = handler.cloneChildren(); +- } +- +- @NotNull +- List export() { +- List result = data.export(); +- if (children.length > 0) { +- result.add( +- toArrayMapper(children, new Function() { +- @NotNull +- @Override +- public Object apply(TimingData child) { +- return child.export(); +- } +- }) +- ); +- } +- return result; +- } +-} +diff --git a/src/main/java/co/aikar/timings/TimingIdentifier.java b/src/main/java/co/aikar/timings/TimingIdentifier.java +deleted file mode 100644 +index df142a89b8c43acb81eb383eac0ef048a1f49a6e..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/TimingIdentifier.java ++++ /dev/null +@@ -1,116 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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 co.aikar.util.LoadingMap; +- +-import java.util.ArrayList; +-import java.util.Collections; +-import java.util.List; +-import java.util.Map; +-import java.util.Objects; +-import java.util.concurrent.ConcurrentHashMap; +-import java.util.concurrent.atomic.AtomicInteger; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-/** +- *

Used as a basis for fast HashMap key comparisons for the Timing Map.

+- * +- * This class uses interned strings giving us the ability to do an identity check instead of equals() on the strings +- */ +-final class TimingIdentifier { +- /** +- * Holds all groups. Autoloads on request for a group by name. +- */ +- static final Map GROUP_MAP = LoadingMap.of(new ConcurrentHashMap<>(64, .5F), TimingGroup::new); +- private static final TimingGroup DEFAULT_GROUP = getGroup("Minecraft"); +- final String group; +- final String name; +- final TimingHandler groupHandler; +- private final int hashCode; +- +- TimingIdentifier(@Nullable String group, @NotNull String name, @Nullable Timing groupHandler) { +- this.group = group != null ? group: DEFAULT_GROUP.name; +- this.name = name; +- this.groupHandler = groupHandler != null ? groupHandler.getTimingHandler() : null; +- this.hashCode = (31 * this.group.hashCode()) + this.name.hashCode(); +- } +- +- @NotNull +- static TimingGroup getGroup(@Nullable String groupName) { +- if (groupName == null) { +- //noinspection ConstantConditions +- return DEFAULT_GROUP; +- } +- +- return GROUP_MAP.get(groupName); +- } +- +- @Override +- public boolean equals(Object o) { +- if (o == null) { +- return false; +- } +- +- TimingIdentifier that = (TimingIdentifier) o; +- return Objects.equals(group, that.group) && Objects.equals(name, that.name); +- } +- +- @Override +- public int hashCode() { +- return hashCode; +- } +- +- @Override +- public String toString() { +- return "TimingIdentifier{id=" + group + ":" + name +'}'; +- } +- +- static class TimingGroup { +- +- private static AtomicInteger idPool = new AtomicInteger(1); +- final int id = idPool.getAndIncrement(); +- +- final String name; +- final List handlers = Collections.synchronizedList(new ArrayList<>(64)); +- +- private TimingGroup(String name) { +- this.name = name; +- } +- +- @Override +- public boolean equals(Object o) { +- if (this == o) return true; +- if (o == null || getClass() != o.getClass()) return false; +- TimingGroup that = (TimingGroup) o; +- return id == that.id; +- } +- +- @Override +- public int hashCode() { +- return id; +- } +- } +-} +diff --git a/src/main/java/co/aikar/timings/Timings.java b/src/main/java/co/aikar/timings/Timings.java +deleted file mode 100644 +index 9812d668ad945aba486fbf6d5bf83c4292cb5d03..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/Timings.java ++++ /dev/null +@@ -1,337 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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.base.Preconditions; +-import com.google.common.collect.EvictingQueue; +-import com.google.common.collect.Lists; +-import net.kyori.adventure.text.Component; +-import net.kyori.adventure.text.event.ClickEvent; +-import net.kyori.adventure.text.format.TextColor; +-import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +-import org.bukkit.Bukkit; +-import org.bukkit.command.CommandSender; +-import org.bukkit.plugin.Plugin; +- +-import java.util.List; +-import java.util.Queue; +-import java.util.logging.Level; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-/** +- * @deprecated Timings will likely be replaced with Spark in the future +- */ +-@Deprecated(forRemoval = true) +-@SuppressWarnings({"UnusedDeclaration", "WeakerAccess", "SameParameterValue"}) +-public final class Timings { +- +- final static List requestingReport = Lists.newArrayList(); +- private static final int MAX_HISTORY_FRAMES = 12; +- public static final Timing NULL_HANDLER = new NullTimingHandler(); +- static boolean timingsEnabled = false; +- static boolean verboseEnabled = false; +- private static int historyInterval = -1; +- private static int historyLength = -1; +- private static boolean warnedAboutDeprecationOnEnable; +- +- private Timings() {} +- +- /** +- * Returns a Timing for a plugin corresponding to a name. +- * +- * @param plugin Plugin to own the Timing +- * @param name Name of Timing +- * @return Handler +- */ +- @NotNull +- public static Timing of(@NotNull Plugin plugin, @NotNull String name) { +- Timing pluginHandler = null; +- if (plugin != null) { +- pluginHandler = ofSafe(plugin.getName(), "Combined Total", TimingsManager.PLUGIN_GROUP_HANDLER); +- } +- return of(plugin, name, pluginHandler); +- } +- +- /** +- *

Returns a handler that has a groupHandler timer handler. Parent timers should not have their +- * start/stop methods called directly, as the children will call it for you.

+- * +- * Parent Timers are used to group multiple subsections together and get a summary of them combined +- * Parent Handler can not be changed after first call +- * +- * @param plugin Plugin to own the Timing +- * @param name Name of Timing +- * @param groupHandler Parent handler to mirror .start/stop calls to +- * @return Timing Handler +- */ +- @NotNull +- public static Timing of(@NotNull Plugin plugin, @NotNull String name, @Nullable Timing groupHandler) { +- Preconditions.checkNotNull(plugin, "Plugin can not be null"); +- Bukkit.getLogger().warning(String.format("Plugin '%s' is creating timing '%s' - this is deprecated behavior, please report it to the authors: %s", plugin.getName(), name, String.join(", ", plugin.getDescription().getAuthors()))); +- return TimingsManager.getHandler(plugin.getName(), name, groupHandler); +- } +- +- /** +- * Returns a Timing object after starting it, useful for Java7 try-with-resources. +- * +- * try (Timing ignored = Timings.ofStart(plugin, someName)) { +- * // timed section +- * } +- * +- * @param plugin Plugin to own the Timing +- * @param name Name of Timing +- * @return Timing Handler +- */ +- @NotNull +- public static Timing ofStart(@NotNull Plugin plugin, @NotNull String name) { +- return ofStart(plugin, name, null); +- } +- +- /** +- * Returns a Timing object after starting it, useful for Java7 try-with-resources. +- * +- * try (Timing ignored = Timings.ofStart(plugin, someName, groupHandler)) { +- * // timed section +- * } +- * +- * @param plugin Plugin to own the Timing +- * @param name Name of Timing +- * @param groupHandler Parent handler to mirror .start/stop calls to +- * @return Timing Handler +- */ +- @NotNull +- public static Timing ofStart(@NotNull Plugin plugin, @NotNull String name, @Nullable Timing groupHandler) { +- Timing timing = of(plugin, name, groupHandler); +- timing.startTiming(); +- return timing; +- } +- +- /** +- * Gets whether or not the Spigot Timings system is enabled +- * +- * @return Enabled or not +- */ +- public static boolean isTimingsEnabled() { +- return timingsEnabled; +- } +- +- /** +- *

Sets whether or not the Spigot Timings system should be enabled

+- * +- * Calling this will reset timing data. +- * +- * @param enabled Should timings be reported +- */ +- public static void setTimingsEnabled(boolean enabled) { +- timingsEnabled = enabled; +- warnAboutDeprecationOnEnable(); +- reset(); +- } +- +- private static void warnAboutDeprecationOnEnable() { +- if (timingsEnabled && !warnedAboutDeprecationOnEnable) { +- Bukkit.getLogger().warning(PlainTextComponentSerializer.plainText().serialize(deprecationMessage())); +- warnedAboutDeprecationOnEnable = true; +- } +- } +- +- public static Component deprecationMessage() { +- return Component.text() +- .color(TextColor.color(0xf3ef91)) +- .append(Component.text("[!] The timings profiler has been enabled but has been scheduled for removal from Paper in the future.")) +- .append(Component.newline()) +- .append( +- Component.text(" We recommend installing the spark profiler as a replacement: ") +- .append( +- Component.text() +- .content("https://spark.lucko.me/") +- .clickEvent(ClickEvent.openUrl("https://spark.lucko.me/"))) +- ) +- .append(Component.newline()) +- .append( +- Component.text(" For more information please visit: ") +- .append( +- Component.text() +- .content("https://github.com/PaperMC/Paper/issues/8948") +- .clickEvent(ClickEvent.openUrl("https://github.com/PaperMC/Paper/issues/8948"))) +- ) +- .build(); +- } +- +- /** +- *

Sets whether or not the Timings should monitor at Verbose level.

+- * +- *

When Verbose is disabled, high-frequency timings will not be available.

+- * +- * @return Enabled or not +- */ +- public static boolean isVerboseTimingsEnabled() { +- return verboseEnabled; +- } +- +- /** +- *

Sets whether or not the Timings should monitor at Verbose level.

+- * +- * When Verbose is disabled, high-frequency timings will not be available. +- * Calling this will reset timing data. +- * +- * @param enabled Should high-frequency timings be reported +- */ +- public static void setVerboseTimingsEnabled(boolean enabled) { +- verboseEnabled = enabled; +- TimingsManager.needsRecheckEnabled = true; +- } +- +- /** +- *

Gets the interval between Timing History report generation.

+- * +- * Defaults to 5 minutes (6000 ticks) +- * +- * @return Interval in ticks +- */ +- public static int getHistoryInterval() { +- return historyInterval; +- } +- +- /** +- *

Sets the interval between Timing History report generations.

+- * +- *

Defaults to 5 minutes (6000 ticks)

+- * +- * This will recheck your history length, so lowering this value will lower your +- * history length if you need more than 60 history windows. +- * +- * @param interval Interval in ticks +- */ +- public static void setHistoryInterval(int interval) { +- historyInterval = Math.max(20*60, interval); +- // Recheck the history length with the new Interval +- if (historyLength != -1) { +- setHistoryLength(historyLength); +- } +- } +- +- /** +- * Gets how long in ticks Timings history is kept for the server. +- * +- * Defaults to 1 hour (72000 ticks) +- * +- * @return Duration in Ticks +- */ +- public static int getHistoryLength() { +- return historyLength; +- } +- +- /** +- * Sets how long Timing History reports are kept for the server. +- * +- * Defaults to 1 hours(72000 ticks) +- * +- * This value is capped at a maximum of getHistoryInterval() * MAX_HISTORY_FRAMES (12) +- * +- * Will not reset Timing Data but may truncate old history if the new length is less than old length. +- * +- * @param length Duration in ticks +- */ +- public static void setHistoryLength(int length) { +- // Cap at 12 History Frames, 1 hour at 5 minute frames. +- int maxLength = historyInterval * MAX_HISTORY_FRAMES; +- // For special cases of servers with special permission to bypass the max. +- // This max helps keep data file sizes reasonable for processing on Aikar's Timing parser side. +- // Setting this will not help you bypass the max unless Aikar has added an exception on the API side. +- if (System.getProperty("timings.bypassMax") != null) { +- maxLength = Integer.MAX_VALUE; +- } +- historyLength = Math.max(Math.min(maxLength, length), historyInterval); +- Queue oldQueue = TimingsManager.HISTORY; +- int frames = (getHistoryLength() / getHistoryInterval()); +- if (length > maxLength) { +- Bukkit.getLogger().log(Level.WARNING, "Timings Length too high. Requested " + length + ", max is " + maxLength + ". To get longer history, you must increase your interval. Set Interval to " + Math.ceil(length / MAX_HISTORY_FRAMES) + " to achieve this length."); +- } +- TimingsManager.HISTORY = EvictingQueue.create(frames); +- TimingsManager.HISTORY.addAll(oldQueue); +- } +- +- /** +- * Resets all Timing Data +- */ +- public static void reset() { +- TimingsManager.reset(); +- } +- +- /** +- * Generates a report and sends it to the specified command sender. +- * +- * If sender is null, ConsoleCommandSender will be used. +- * @param sender The sender to send to, or null to use the ConsoleCommandSender +- */ +- public static void generateReport(@Nullable CommandSender sender) { +- if (sender == null) { +- sender = Bukkit.getConsoleSender(); +- } +- requestingReport.add(sender); +- } +- +- /** +- * Generates a report and sends it to the specified listener. +- * Use with {@link org.bukkit.command.BufferedCommandSender} to get full response when done! +- * @param sender The listener to send responses too. +- */ +- public static void generateReport(@NotNull TimingsReportListener sender) { +- Preconditions.checkNotNull(sender); +- requestingReport.add(sender); +- } +- +- /* +- ================= +- Protected API: These are for internal use only in Bukkit/CraftBukkit +- These do not have isPrimaryThread() checks in the startTiming/stopTiming +- ================= +- */ +- @NotNull +- static TimingHandler ofSafe(@NotNull String name) { +- return ofSafe(null, name, null); +- } +- +- @NotNull +- static Timing ofSafe(@Nullable Plugin plugin, @NotNull String name) { +- Timing pluginHandler = null; +- if (plugin != null) { +- pluginHandler = ofSafe(plugin.getName(), "Combined Total", TimingsManager.PLUGIN_GROUP_HANDLER); +- } +- return ofSafe(plugin != null ? plugin.getName() : "Minecraft - Invalid Plugin", name, pluginHandler); +- } +- +- @NotNull +- static TimingHandler ofSafe(@NotNull String name, @Nullable Timing groupHandler) { +- return ofSafe(null, name, groupHandler); +- } +- +- @NotNull +- static TimingHandler ofSafe(@Nullable String groupName, @NotNull String name, @Nullable Timing groupHandler) { +- return TimingsManager.getHandler(groupName, name, groupHandler); +- } +-} +- +diff --git a/src/main/java/co/aikar/timings/TimingsCommand.java b/src/main/java/co/aikar/timings/TimingsCommand.java +deleted file mode 100644 +index e801e79fa57c44b2e5d359647c920f88064826f1..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/TimingsCommand.java ++++ /dev/null +@@ -1,124 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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.base.Preconditions; +-import com.google.common.collect.ImmutableList; +-import net.kyori.adventure.text.format.NamedTextColor; +-import org.bukkit.command.CommandSender; +-import org.bukkit.command.defaults.BukkitCommand; +-import org.bukkit.util.StringUtil; +- +-import java.util.ArrayList; +-import java.util.List; +-import org.jetbrains.annotations.NotNull; +- +-import static net.kyori.adventure.text.Component.text; +- +- +-@Deprecated(forRemoval = true) +-public class TimingsCommand extends BukkitCommand { +- private static final List TIMINGS_SUBCOMMANDS = ImmutableList.of("report", "reset", "on", "off", "paste", "verbon", "verboff"); +- private long lastResetAttempt = 0; +- +- public TimingsCommand(@NotNull String name) { +- super(name); +- this.description = "Manages Spigot Timings data to see performance of the server."; +- this.usageMessage = "/timings "; +- this.setPermission("bukkit.command.timings"); +- } +- +- @Override +- public boolean execute(@NotNull CommandSender sender, @NotNull String currentAlias, @NotNull String[] args) { +- if (!testPermission(sender)) { +- return true; +- } +- if (false) { +- sender.sendMessage(Timings.deprecationMessage()); +- } +- if (args.length < 1) { +- sender.sendMessage(text("Usage: " + this.usageMessage, NamedTextColor.RED)); +- return true; +- } +- final String arg = args[0]; +- if ("on".equalsIgnoreCase(arg)) { +- Timings.setTimingsEnabled(true); +- sender.sendMessage(text("Enabled Timings & Reset")); +- return true; +- } else if ("off".equalsIgnoreCase(arg)) { +- Timings.setTimingsEnabled(false); +- sender.sendMessage(text("Disabled Timings")); +- return true; +- } +- +- if (!Timings.isTimingsEnabled()) { +- sender.sendMessage(text("Please enable timings by typing /timings on")); +- return true; +- } +- +- long now = System.currentTimeMillis(); +- if ("verbon".equalsIgnoreCase(arg)) { +- Timings.setVerboseTimingsEnabled(true); +- sender.sendMessage(text("Enabled Verbose Timings")); +- return true; +- } else if ("verboff".equalsIgnoreCase(arg)) { +- Timings.setVerboseTimingsEnabled(false); +- sender.sendMessage(text("Disabled Verbose Timings")); +- return true; +- } else if ("reset".equalsIgnoreCase(arg)) { +- if (now - lastResetAttempt < 30000) { +- TimingsManager.reset(); +- sender.sendMessage(text("Timings reset. Please wait 5-10 minutes before using /timings report.", NamedTextColor.RED)); +- } else { +- lastResetAttempt = now; +- sender.sendMessage(text("WARNING: Timings v2 should not be reset. If you are experiencing lag, please wait 3 minutes and then issue a report. The best timings will include 10+ minutes, with data before and after your lag period. If you really want to reset, run this command again within 30 seconds.", NamedTextColor.RED)); +- } +- } else if ( +- "paste".equalsIgnoreCase(arg) || +- "report".equalsIgnoreCase(arg) || +- "get".equalsIgnoreCase(arg) || +- "merged".equalsIgnoreCase(arg) || +- "separate".equalsIgnoreCase(arg) +- ) { +- Timings.generateReport(sender); +- } else { +- sender.sendMessage(text("Usage: " + this.usageMessage, NamedTextColor.RED)); +- } +- return true; +- } +- +- @NotNull +- @Override +- public List tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) { +- Preconditions.checkNotNull(sender, "Sender cannot be null"); +- Preconditions.checkNotNull(args, "Arguments cannot be null"); +- Preconditions.checkNotNull(alias, "Alias cannot be null"); +- +- if (args.length == 1) { +- return StringUtil.copyPartialMatches(args[0], TIMINGS_SUBCOMMANDS, +- new ArrayList(TIMINGS_SUBCOMMANDS.size())); +- } +- return ImmutableList.of(); +- } +-} +diff --git a/src/main/java/co/aikar/timings/TimingsManager.java b/src/main/java/co/aikar/timings/TimingsManager.java +deleted file mode 100644 +index 5e1558ca3ffeeaf2645fa003965474a442d650bf..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/TimingsManager.java ++++ /dev/null +@@ -1,192 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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 co.aikar.util.LoadingMap; +-import com.google.common.collect.EvictingQueue; +-import org.bukkit.Bukkit; +-import org.bukkit.Server; +-import org.bukkit.command.Command; +-import org.bukkit.plugin.Plugin; +-import org.bukkit.plugin.java.PluginClassLoader; +- +-import java.util.ArrayList; +-import java.util.List; +-import java.util.Map; +-import java.util.concurrent.ConcurrentHashMap; +-import java.util.logging.Level; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-/** +- * @deprecated Timings will likely be replaced with Spark in the future +- */ +-@Deprecated(forRemoval = true) +-public final class TimingsManager { +- static final Map TIMING_MAP = LoadingMap.of( +- new ConcurrentHashMap<>(4096, .5F), TimingHandler::new +- ); +- public static final FullServerTickHandler FULL_SERVER_TICK = new FullServerTickHandler(); +- public static final TimingHandler TIMINGS_TICK = Timings.ofSafe("Timings Tick", FULL_SERVER_TICK); +- public static final Timing PLUGIN_GROUP_HANDLER = Timings.ofSafe("Plugins"); +- public static String url = "https://timings.aikar.co/"; +- public static List hiddenConfigs = new ArrayList(); +- public static boolean privacy = false; +- +- static final List HANDLERS = new ArrayList<>(1024); +- static final List MINUTE_REPORTS = new ArrayList<>(64); +- +- static EvictingQueue HISTORY = EvictingQueue.create(12); +- static long timingStart = 0; +- static long historyStart = 0; +- static boolean needsFullReset = false; +- static boolean needsRecheckEnabled = false; +- +- private TimingsManager() {} +- +- /** +- * Resets all timing data on the next tick +- */ +- static void reset() { +- needsFullReset = true; +- } +- +- /** +- * Ticked every tick by CraftBukkit to count the number of times a timer +- * caused TPS loss. +- */ +- static void tick() { +- if (Timings.timingsEnabled) { +- boolean violated = FULL_SERVER_TICK.isViolated(); +- +- for (TimingHandler handler : HANDLERS) { +- if (handler.isSpecial()) { +- // We manually call this +- continue; +- } +- handler.processTick(violated); +- } +- +- TimingHistory.playerTicks += Bukkit.getOnlinePlayers().size(); +- TimingHistory.timedTicks++; +- // Generate TPS/Ping/Tick reports every minute +- } +- } +- static void stopServer() { +- Timings.timingsEnabled = false; +- recheckEnabled(); +- } +- static void recheckEnabled() { +- synchronized (TIMING_MAP) { +- for (TimingHandler timings : TIMING_MAP.values()) { +- timings.checkEnabled(); +- } +- } +- needsRecheckEnabled = false; +- } +- static void resetTimings() { +- if (needsFullReset) { +- // Full resets need to re-check every handlers enabled state +- // Timing map can be modified from async so we must sync on it. +- synchronized (TIMING_MAP) { +- for (TimingHandler timings : TIMING_MAP.values()) { +- timings.reset(true); +- } +- } +- Bukkit.getLogger().log(Level.INFO, "Timings Reset"); +- HISTORY.clear(); +- needsFullReset = false; +- needsRecheckEnabled = false; +- timingStart = System.currentTimeMillis(); +- } else { +- // Soft resets only need to act on timings that have done something +- // Handlers can only be modified on main thread. +- for (TimingHandler timings : HANDLERS) { +- timings.reset(false); +- } +- } +- +- HANDLERS.clear(); +- MINUTE_REPORTS.clear(); +- +- TimingHistory.resetTicks(true); +- historyStart = System.currentTimeMillis(); +- } +- +- @NotNull +- static TimingHandler getHandler(@Nullable String group, @NotNull String name, @Nullable Timing parent) { +- return TIMING_MAP.get(new TimingIdentifier(group, name, parent)); +- } +- +- +- /** +- *

Due to access restrictions, we need a helper method to get a Command TimingHandler with String group

+- * +- * Plugins should never call this +- * +- * @param pluginName Plugin this command is associated with +- * @param command Command to get timings for +- * @return TimingHandler +- */ +- @NotNull +- public static Timing getCommandTiming(@Nullable String pluginName, @NotNull Command command) { +- Plugin plugin = null; +- final Server server = Bukkit.getServer(); +- if (!( server == null || pluginName == null || +- "minecraft".equals(pluginName) || "bukkit".equals(pluginName) || +- "spigot".equalsIgnoreCase(pluginName) || "paper".equals(pluginName) +- )) { +- plugin = server.getPluginManager().getPlugin(pluginName); +- } +- if (plugin == null) { +- // Plugin is passing custom fallback prefix, try to look up by class loader +- plugin = getPluginByClassloader(command.getClass()); +- } +- if (plugin == null) { +- return Timings.ofSafe("Command: " + pluginName + ":" + command.getTimingName()); +- } +- +- return Timings.ofSafe(plugin, "Command: " + pluginName + ":" + command.getTimingName()); +- } +- +- /** +- * Looks up the class loader for the specified class, and if it is a PluginClassLoader, return the +- * Plugin that created this class. +- * +- * @param clazz Class to check +- * @return Plugin if created by a plugin +- */ +- @Nullable +- public static Plugin getPluginByClassloader(@Nullable Class clazz) { +- if (clazz == null) { +- return null; +- } +- final ClassLoader classLoader = clazz.getClassLoader(); +- if (classLoader instanceof PluginClassLoader) { +- PluginClassLoader pluginClassLoader = (PluginClassLoader) classLoader; +- return pluginClassLoader.getPlugin(); +- } +- return null; +- } +-} +diff --git a/src/main/java/co/aikar/timings/TimingsReportListener.java b/src/main/java/co/aikar/timings/TimingsReportListener.java +deleted file mode 100644 +index 3af5b8ea795311582044c712de50d29412024b77..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/TimingsReportListener.java ++++ /dev/null +@@ -1,87 +0,0 @@ +-package co.aikar.timings; +- +-import com.google.common.base.Preconditions; +-import com.google.common.collect.Lists; +-import org.bukkit.Bukkit; +-import org.bukkit.command.CommandSender; +-import org.bukkit.command.ConsoleCommandSender; +-import org.bukkit.command.MessageCommandSender; +-import org.bukkit.command.RemoteConsoleCommandSender; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-import java.util.List; +- +-@Deprecated(forRemoval = true) +-@SuppressWarnings("WeakerAccess") +-public class TimingsReportListener implements net.kyori.adventure.audience.ForwardingAudience, MessageCommandSender { +- private final List senders; +- private final Runnable onDone; +- private String timingsURL; +- +- public TimingsReportListener(@NotNull CommandSender senders) { +- this(senders, null); +- } +- public TimingsReportListener(@NotNull CommandSender sender, @Nullable Runnable onDone) { +- this(Lists.newArrayList(sender), onDone); +- } +- public TimingsReportListener(@NotNull List senders) { +- this(senders, null); +- } +- public TimingsReportListener(@NotNull List senders, @Nullable Runnable onDone) { +- Preconditions.checkNotNull(senders); +- Preconditions.checkArgument(!senders.isEmpty(), "senders is empty"); +- +- this.senders = Lists.newArrayList(senders); +- this.onDone = onDone; +- } +- +- @Nullable +- public String getTimingsURL() { +- return timingsURL; +- } +- +- public void done() { +- done(null); +- } +- +- public void done(@Nullable String url) { +- this.timingsURL = url; +- if (onDone != null) { +- onDone.run(); +- } +- for (CommandSender sender : senders) { +- if (sender instanceof TimingsReportListener) { +- ((TimingsReportListener) sender).done(); +- } +- } +- } +- +- @Override +- public void sendMessage(final @NotNull net.kyori.adventure.identity.Identity source, final @NotNull net.kyori.adventure.text.Component message, final @NotNull net.kyori.adventure.audience.MessageType type) { +- net.kyori.adventure.audience.ForwardingAudience.super.sendMessage(source, message, type); +- } +- +- @NotNull +- @Override +- public Iterable audiences() { +- return this.senders; +- } +- +- @Override +- public void sendMessage(@NotNull String message) { +- senders.forEach((sender) -> sender.sendMessage(message)); +- } +- +- public void addConsoleIfNeeded() { +- boolean hasConsole = false; +- for (CommandSender sender : this.senders) { +- if (sender instanceof ConsoleCommandSender || sender instanceof RemoteConsoleCommandSender) { +- hasConsole = true; +- } +- } +- if (!hasConsole) { +- this.senders.add(Bukkit.getConsoleSender()); +- } +- } +-} +diff --git a/src/main/java/co/aikar/timings/UnsafeTimingHandler.java b/src/main/java/co/aikar/timings/UnsafeTimingHandler.java +deleted file mode 100644 +index 49180ea7879c64af3cd5143a34783d564746b504..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/UnsafeTimingHandler.java ++++ /dev/null +@@ -1,26 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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; +- +-class UnsafeTimingHandler {} // Gale - final timings calls +diff --git a/src/main/java/co/aikar/util/Counter.java b/src/main/java/co/aikar/util/Counter.java +deleted file mode 100644 +index dae84243804b4b076cafb3e1b29bdcf614efc93f..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/util/Counter.java ++++ /dev/null +@@ -1,39 +0,0 @@ +-package co.aikar.util; +- +-import com.google.common.collect.ForwardingMap; +- +-import java.util.HashMap; +-import java.util.Map; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-@Deprecated(forRemoval = true) +-public class Counter extends ForwardingMap { +- private final Map counts = new HashMap<>(); +- +- public long decrement(@Nullable T key) { +- return increment(key, -1); +- } +- public long increment(@Nullable T key) { +- return increment(key, 1); +- } +- public long decrement(@Nullable T key, long amount) { +- return increment(key, -amount); +- } +- public long increment(@Nullable T key, long amount) { +- Long count = this.getCount(key); +- count += amount; +- this.counts.put(key, count); +- return count; +- } +- +- public long getCount(@Nullable T key) { +- return this.counts.getOrDefault(key, 0L); +- } +- +- @NotNull +- @Override +- protected Map delegate() { +- return this.counts; +- } +-} +diff --git a/src/main/java/co/aikar/util/JSONUtil.java b/src/main/java/co/aikar/util/JSONUtil.java +deleted file mode 100644 +index c105a1429ca58b37be265708ec345e00f0d43ed8..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/util/JSONUtil.java ++++ /dev/null +@@ -1,141 +0,0 @@ +-package co.aikar.util; +- +-import com.google.common.base.Function; +-import com.google.common.collect.Lists; +-import com.google.common.collect.Maps; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +-import org.json.simple.JSONArray; +-import org.json.simple.JSONObject; +- +-import java.util.ArrayList; +-import java.util.LinkedHashMap; +-import java.util.List; +-import java.util.Map; +- +-/** +- * Provides Utility methods that assist with generating JSON Objects +- */ +-@SuppressWarnings({"rawtypes", "SuppressionAnnotation"}) +-@Deprecated(forRemoval = true) +-public final class JSONUtil { +- private JSONUtil() {} +- +- /** +- * Creates a key/value "JSONPair" object +- * +- * @param key Key to use +- * @param obj Value to use +- * @return JSONPair +- */ +- @NotNull +- public static JSONPair pair(@NotNull String key, @Nullable Object obj) { +- return new JSONPair(key, obj); +- } +- +- @NotNull +- public static JSONPair pair(long key, @Nullable Object obj) { +- return new JSONPair(String.valueOf(key), obj); +- } +- +- /** +- * Creates a new JSON object from multiple JSONPair key/value pairs +- * +- * @param data JSONPairs +- * @return Map +- */ +- @NotNull +- public static Map createObject(@NotNull JSONPair... data) { +- return appendObjectData(new LinkedHashMap(), data); +- } +- +- /** +- * This appends multiple key/value Obj pairs into a JSON Object +- * +- * @param parent Map to be appended to +- * @param data Data to append +- * @return Map +- */ +- @NotNull +- public static Map appendObjectData(@NotNull Map parent, @NotNull JSONPair... data) { +- for (JSONPair JSONPair : data) { +- parent.put(JSONPair.key, JSONPair.val); +- } +- return parent; +- } +- +- /** +- * This builds a JSON array from a set of data +- * +- * @param data Data to build JSON array from +- * @return List +- */ +- @NotNull +- public static List toArray(@NotNull Object... data) { +- return Lists.newArrayList(data); +- } +- +- /** +- * These help build a single JSON array using a mapper function +- * +- * @param collection Collection to apply to +- * @param mapper Mapper to apply +- * @param Element Type +- * @return List +- */ +- @NotNull +- public static List toArrayMapper(@NotNull E[] collection, @NotNull Function mapper) { +- return toArrayMapper(Lists.newArrayList(collection), mapper); +- } +- +- @NotNull +- public static List toArrayMapper(@NotNull Iterable collection, @NotNull Function mapper) { +- List array = Lists.newArrayList(); +- for (E e : collection) { +- Object object = mapper.apply(e); +- if (object != null) { +- array.add(object); +- } +- } +- return array; +- } +- +- /** +- * These help build a single JSON Object from a collection, using a mapper function +- * +- * @param collection Collection to apply to +- * @param mapper Mapper to apply +- * @param Element Type +- * @return Map +- */ +- @NotNull +- public static Map toObjectMapper(@NotNull E[] collection, @NotNull Function mapper) { +- return toObjectMapper(Lists.newArrayList(collection), mapper); +- } +- +- @NotNull +- public static Map toObjectMapper(@NotNull Iterable collection, @NotNull Function mapper) { +- Map object = Maps.newLinkedHashMap(); +- for (E e : collection) { +- JSONPair JSONPair = mapper.apply(e); +- if (JSONPair != null) { +- object.put(JSONPair.key, JSONPair.val); +- } +- } +- return object; +- } +- +- /** +- * Simply stores a key and a value, used internally by many methods below. +- */ +- @SuppressWarnings("PublicInnerClass") +- public static class JSONPair { +- final String key; +- final Object val; +- +- JSONPair(@NotNull String key, @NotNull Object val) { +- this.key = key; +- this.val = val; +- } +- } +-} +diff --git a/src/main/java/co/aikar/util/LoadingIntMap.java b/src/main/java/co/aikar/util/LoadingIntMap.java +deleted file mode 100644 +index 5753b9bce89db2ac378ec41f1b61907cc2e23335..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/util/LoadingIntMap.java ++++ /dev/null +@@ -1,77 +0,0 @@ +-/* +- * Copyright (c) 2015. Starlis LLC / dba Empire Minecraft +- * +- * This source code is proprietary software and must not be redistributed without Starlis LLC's approval +- * +- */ +-package co.aikar.util; +- +- +-import com.google.common.base.Function; +-import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-/** +- * Allows you to pass a Loader function that when a key is accessed that doesn't exist, +- * automatically loads the entry into the map by calling the loader Function. +- * +- * .get() Will only return null if the Loader can return null. +- * +- * You may pass any backing Map to use. +- * +- * This class is not thread safe and should be wrapped with Collections.synchronizedMap on the OUTSIDE of the LoadingMap if needed. +- * +- * Do not wrap the backing map with Collections.synchronizedMap. +- * +- * @param Value +- */ +-@Deprecated(forRemoval = true) +-public class LoadingIntMap extends Int2ObjectOpenHashMap { +- private final Function loader; +- +- public LoadingIntMap(@NotNull Function loader) { +- super(); +- this.loader = loader; +- } +- +- public LoadingIntMap(int expectedSize, @NotNull Function loader) { +- super(expectedSize); +- this.loader = loader; +- } +- +- public LoadingIntMap(int expectedSize, float loadFactor, @NotNull Function loader) { +- super(expectedSize, loadFactor); +- this.loader = loader; +- } +- +- +- @Nullable +- @Override +- public V get(int key) { +- V res = super.get(key); +- if (res == null) { +- res = loader.apply(key); +- if (res != null) { +- put(key, res); +- } +- } +- return res; +- } +- +- /** +- * Due to java stuff, you will need to cast it to (Function) for some cases +- * +- * @param Type +- */ +- public abstract static class Feeder implements Function { +- @Nullable +- @Override +- public T apply(@Nullable Object input) { +- return apply(); +- } +- +- @Nullable +- public abstract T apply(); +- } +-} +diff --git a/src/main/java/co/aikar/util/LoadingMap.java b/src/main/java/co/aikar/util/LoadingMap.java +deleted file mode 100644 +index 1786eeb5cbeaad75602c9c5649bbcd9b2af5cf81..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/util/LoadingMap.java ++++ /dev/null +@@ -1,369 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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.util; +- +-import com.google.common.base.Preconditions; +-import java.lang.reflect.Constructor; +-import java.util.AbstractMap; +-import java.util.Collection; +-import java.util.HashMap; +-import java.util.IdentityHashMap; +-import java.util.Map; +-import java.util.Set; +-import java.util.function.Function; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-/** +- * Allows you to pass a Loader function that when a key is accessed that doesn't exists, +- * automatically loads the entry into the map by calling the loader Function. +- * +- * .get() Will only return null if the Loader can return null. +- * +- * You may pass any backing Map to use. +- * +- * This class is not thread safe and should be wrapped with Collections.synchronizedMap on the OUTSIDE of the LoadingMap if needed. +- * +- * Do not wrap the backing map with Collections.synchronizedMap. +- * +- * @param Key +- * @param Value +- */ +-@Deprecated(forRemoval = true) +-public class LoadingMap extends AbstractMap { +- private final Map backingMap; +- private final java.util.function.Function loader; +- +- /** +- * Initializes an auto loading map using specified loader and backing map +- * @param backingMap Map to wrap +- * @param loader Loader +- */ +- public LoadingMap(@NotNull Map backingMap, @NotNull java.util.function.Function loader) { +- this.backingMap = backingMap; +- this.loader = loader; +- } +- +- /** +- * Creates a new LoadingMap with the specified map and loader +- * +- * @param backingMap Actual map being used. +- * @param loader Loader to use +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map +- */ +- @NotNull +- public static Map of(@NotNull Map backingMap, @NotNull Function loader) { +- return new LoadingMap<>(backingMap, loader); +- } +- +- /** +- * Creates a LoadingMap with an auto instantiating loader. +- * +- * Will auto construct class of of Value when not found +- * +- * Since this uses Reflection, It is more effecient to define your own static loader +- * than using this helper, but if performance is not critical, this is easier. +- * +- * @param backingMap Actual map being used. +- * @param keyClass Class used for the K generic +- * @param valueClass Class used for the V generic +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map that auto instantiates on .get() +- */ +- @NotNull +- public static Map newAutoMap(@NotNull Map backingMap, @Nullable final Class keyClass, +- @NotNull final Class valueClass) { +- return new LoadingMap<>(backingMap, new AutoInstantiatingLoader<>(keyClass, valueClass)); +- } +- /** +- * Creates a LoadingMap with an auto instantiating loader. +- * +- * Will auto construct class of of Value when not found +- * +- * Since this uses Reflection, It is more effecient to define your own static loader +- * than using this helper, but if performance is not critical, this is easier. +- * +- * @param backingMap Actual map being used. +- * @param valueClass Class used for the V generic +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map that auto instantiates on .get() +- */ +- @NotNull +- public static Map newAutoMap(@NotNull Map backingMap, +- @NotNull final Class valueClass) { +- return newAutoMap(backingMap, null, valueClass); +- } +- +- /** +- * @see #newAutoMap +- * +- * new Auto initializing map using a HashMap. +- * +- * @param keyClass Class used for the K generic +- * @param valueClass Class used for the V generic +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map that auto instantiates on .get() +- */ +- @NotNull +- public static Map newHashAutoMap(@Nullable final Class keyClass, @NotNull final Class valueClass) { +- return newAutoMap(new HashMap<>(), keyClass, valueClass); +- } +- +- /** +- * @see #newAutoMap +- * +- * new Auto initializing map using a HashMap. +- * +- * @param valueClass Class used for the V generic +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map that auto instantiates on .get() +- */ +- @NotNull +- public static Map newHashAutoMap(@NotNull final Class valueClass) { +- return newHashAutoMap(null, valueClass); +- } +- +- /** +- * @see #newAutoMap +- * +- * new Auto initializing map using a HashMap. +- * +- * @param keyClass Class used for the K generic +- * @param valueClass Class used for the V generic +- * @param initialCapacity Initial capacity to use +- * @param loadFactor Load factor to use +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map that auto instantiates on .get() +- */ +- @NotNull +- public static Map newHashAutoMap(@Nullable final Class keyClass, @NotNull final Class valueClass, int initialCapacity, float loadFactor) { +- return newAutoMap(new HashMap<>(initialCapacity, loadFactor), keyClass, valueClass); +- } +- +- /** +- * @see #newAutoMap +- * +- * new Auto initializing map using a HashMap. +- * +- * @param valueClass Class used for the V generic +- * @param initialCapacity Initial capacity to use +- * @param loadFactor Load factor to use +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map that auto instantiates on .get() +- */ +- @NotNull +- public static Map newHashAutoMap(@NotNull final Class valueClass, int initialCapacity, float loadFactor) { +- return newHashAutoMap(null, valueClass, initialCapacity, loadFactor); +- } +- +- /** +- * Initializes an auto loading map using a HashMap +- * +- * @param loader Loader to use +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map +- */ +- @NotNull +- public static Map newHashMap(@NotNull Function loader) { +- return new LoadingMap<>(new HashMap<>(), loader); +- } +- +- /** +- * Initializes an auto loading map using a HashMap +- * +- * @param loader Loader to use +- * @param initialCapacity Initial capacity to use +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map +- */ +- @NotNull +- public static Map newHashMap(@NotNull Function loader, int initialCapacity) { +- return new LoadingMap<>(new HashMap<>(initialCapacity), loader); +- } +- /** +- * Initializes an auto loading map using a HashMap +- * +- * @param loader Loader to use +- * @param initialCapacity Initial capacity to use +- * @param loadFactor Load factor to use +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map +- */ +- @NotNull +- public static Map newHashMap(@NotNull Function loader, int initialCapacity, float loadFactor) { +- return new LoadingMap<>(new HashMap<>(initialCapacity, loadFactor), loader); +- } +- +- /** +- * Initializes an auto loading map using an Identity HashMap +- * +- * @param loader Loader to use +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map +- */ +- @NotNull +- public static Map newIdentityHashMap(@NotNull Function loader) { +- return new LoadingMap<>(new IdentityHashMap<>(), loader); +- } +- +- /** +- * Initializes an auto loading map using an Identity HashMap +- * +- * @param loader Loader to use +- * @param initialCapacity Initial capacity to use +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map +- */ +- @NotNull +- public static Map newIdentityHashMap(@NotNull Function loader, int initialCapacity) { +- return new LoadingMap<>(new IdentityHashMap<>(initialCapacity), loader); +- } +- +- @Override +- public int size() {return backingMap.size();} +- +- @Override +- public boolean isEmpty() {return backingMap.isEmpty();} +- +- @Override +- public boolean containsKey(@Nullable Object key) {return backingMap.containsKey(key);} +- +- @Override +- public boolean containsValue(@Nullable Object value) {return backingMap.containsValue(value);} +- +- @Nullable +- @Override +- public V get(@Nullable Object key) { +- V v = backingMap.get(key); +- if (v != null) { +- return v; +- } +- return backingMap.computeIfAbsent((K) key, loader); +- } +- +- @Nullable +- public V put(@Nullable K key, @Nullable V value) {return backingMap.put(key, value);} +- +- @Nullable +- @Override +- public V remove(@Nullable Object key) {return backingMap.remove(key);} +- +- public void putAll(@NotNull Map m) {backingMap.putAll(m);} +- +- @Override +- public void clear() {backingMap.clear();} +- +- @NotNull +- @Override +- public Set keySet() {return backingMap.keySet();} +- +- @NotNull +- @Override +- public Collection values() {return backingMap.values();} +- +- @Override +- public boolean equals(@Nullable Object o) {return backingMap.equals(o);} +- +- @Override +- public int hashCode() {return backingMap.hashCode();} +- +- @NotNull +- @Override +- public Set> entrySet() { +- return backingMap.entrySet(); +- } +- +- @NotNull +- public LoadingMap clone() { +- return new LoadingMap<>(backingMap, loader); +- } +- +- private static class AutoInstantiatingLoader implements Function { +- final Constructor constructor; +- private final Class valueClass; +- +- AutoInstantiatingLoader(@Nullable Class keyClass, @NotNull Class valueClass) { +- try { +- this.valueClass = valueClass; +- if (keyClass != null) { +- constructor = valueClass.getConstructor(keyClass); +- } else { +- constructor = null; +- } +- } catch (NoSuchMethodException e) { +- throw new IllegalStateException( +- valueClass.getName() + " does not have a constructor for " + (keyClass != null ? keyClass.getName() : null)); +- } +- } +- +- @NotNull +- @Override +- public V apply(@Nullable K input) { +- try { +- return (constructor != null ? constructor.newInstance(input) : valueClass.newInstance()); +- } catch (Exception e) { +- throw new ExceptionInInitializerError(e); +- } +- } +- +- @Override +- public int hashCode() { +- return super.hashCode(); +- } +- +- @Override +- public boolean equals(Object object) { +- return false; +- } +- } +- +- /** +- * Due to java stuff, you will need to cast it to (Function) for some cases +- * +- * @param Type +- */ +- public abstract static class Feeder implements Function { +- @Nullable +- @Override +- public T apply(@Nullable Object input) { +- return apply(); +- } +- +- @Nullable +- public abstract T apply(); +- } +-} +diff --git a/src/main/java/co/aikar/util/MRUMapCache.java b/src/main/java/co/aikar/util/MRUMapCache.java +deleted file mode 100644 +index 3e61a926620a67daec3af54b72a1b911eaef2ed4..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/util/MRUMapCache.java ++++ /dev/null +@@ -1,112 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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.util; +- +-import java.util.AbstractMap; +-import java.util.Collection; +-import java.util.Map; +-import java.util.Set; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-/** +- * Implements a Most Recently Used cache in front of a backing map, to quickly access the last accessed result. +- * +- * @param Key Type of the Map +- * @param Value Type of the Map +- */ +-@Deprecated(forRemoval = true) +-public class MRUMapCache extends AbstractMap { +- final Map backingMap; +- Object cacheKey; +- V cacheValue; +- public MRUMapCache(@NotNull final Map backingMap) { +- this.backingMap = backingMap; +- } +- +- public int size() {return backingMap.size();} +- +- public boolean isEmpty() {return backingMap.isEmpty();} +- +- public boolean containsKey(@Nullable Object key) { +- return key != null && key.equals(cacheKey) || backingMap.containsKey(key); +- } +- +- public boolean containsValue(@Nullable Object value) { +- return value != null && value == cacheValue || backingMap.containsValue(value); +- } +- +- @Nullable +- public V get(@Nullable Object key) { +- if (cacheKey != null && cacheKey.equals(key)) { +- return cacheValue; +- } +- cacheKey = key; +- return cacheValue = backingMap.get(key); +- } +- +- @Nullable +- public V put(@Nullable K key, @Nullable V value) { +- cacheKey = key; +- return cacheValue = backingMap.put(key, value); +- } +- +- @Nullable +- public V remove(@Nullable Object key) { +- if (key != null && key.equals(cacheKey)) { +- cacheKey = null; +- } +- return backingMap.remove(key); +- } +- +- public void putAll(@NotNull Map m) {backingMap.putAll(m);} +- +- public void clear() { +- cacheKey = null; +- cacheValue = null; +- backingMap.clear(); +- } +- +- @NotNull +- public Set keySet() {return backingMap.keySet();} +- +- @NotNull +- public Collection values() {return backingMap.values();} +- +- @NotNull +- public Set> entrySet() {return backingMap.entrySet();} +- +- /** +- * Wraps the specified map with a most recently used cache +- * +- * @param map Map to be wrapped +- * @param Key Type of the Map +- * @param Value Type of the Map +- * @return Map +- */ +- @NotNull +- public static Map of(@NotNull Map map) { +- return new MRUMapCache(map); +- } +-} +diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java +index de36dab37d3af249cf51573d163731c12346066a..aa3f38adb930bb06f4131a5a9b9b1c0d8a97b999 100644 +--- a/src/main/java/org/bukkit/UnsafeValues.java ++++ b/src/main/java/org/bukkit/UnsafeValues.java +@@ -35,7 +35,6 @@ public interface UnsafeValues { + net.kyori.adventure.text.Component resolveWithContext(net.kyori.adventure.text.Component component, org.bukkit.command.CommandSender context, org.bukkit.entity.Entity scoreboardSubject, boolean bypassPermissions) throws java.io.IOException; + // Paper end + +- void reportTimings(); // Paper + Material toLegacy(Material material); + + Material fromLegacy(Material material); +@@ -114,11 +113,6 @@ public interface UnsafeValues { + // Paper end + + // Paper start +- /** +- * Server name to report to timings v2 +- * @return name +- */ +- String getTimingsServerName(); + + /** + * Called once by the version command on first use, then cached. +diff --git a/src/main/java/org/bukkit/command/BufferedCommandSender.java b/src/main/java/org/bukkit/command/BufferedCommandSender.java +deleted file mode 100644 +index f9a00aecca5ec41b460bf41dfe1c69694768cf98..0000000000000000000000000000000000000000 +--- a/src/main/java/org/bukkit/command/BufferedCommandSender.java ++++ /dev/null +@@ -1,21 +0,0 @@ +-package org.bukkit.command; +- +-import org.jetbrains.annotations.NotNull; +- +-public class BufferedCommandSender implements MessageCommandSender { +- private final StringBuffer buffer = new StringBuffer(); +- @Override +- public void sendMessage(@NotNull String message) { +- buffer.append(message); +- buffer.append("\n"); +- } +- +- @NotNull +- public String getBuffer() { +- return buffer.toString(); +- } +- +- public void reset() { +- this.buffer.setLength(0); +- } +-} +diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java +index b791358f90fe92bc2264d9a26492245763813af3..dc5860f9735ec4767ef9f6ee013006a3da0c67dd 100644 +--- a/src/main/java/org/bukkit/command/Command.java ++++ b/src/main/java/org/bukkit/command/Command.java +@@ -33,8 +33,6 @@ public abstract class Command { + protected String usageMessage; + private String permission; + private net.kyori.adventure.text.Component permissionMessage; // Paper +- public co.aikar.timings.Timing timings; // Paper +- @NotNull public String getTimingName() {return getName();} // Paper + + protected Command(@NotNull String name) { + this(name, "", "/" + name, new ArrayList()); +diff --git a/src/main/java/org/bukkit/command/FormattedCommandAlias.java b/src/main/java/org/bukkit/command/FormattedCommandAlias.java +index 9d4f553c04784cca63901a56a7aea62a5cae1d72..0f96873eff87ea267f9c1875b3893f357fab03f3 100644 +--- a/src/main/java/org/bukkit/command/FormattedCommandAlias.java ++++ b/src/main/java/org/bukkit/command/FormattedCommandAlias.java +@@ -12,7 +12,6 @@ public class FormattedCommandAlias extends Command { + + public FormattedCommandAlias(@NotNull String alias, @NotNull String[] formatStrings) { + super(alias); +- timings = co.aikar.timings.TimingsManager.getCommandTiming("minecraft", this); // Spigot + this.formatStrings = formatStrings; + } + +@@ -120,10 +119,6 @@ public class FormattedCommandAlias extends Command { + return formatString; + } + +- @NotNull +- @Override // Paper +- public String getTimingName() {return "Command Forwarder - " + super.getTimingName();} // Paper +- + private static boolean inRange(int i, int j, int k) { + return i >= j && i <= k; + } +diff --git a/src/main/java/org/bukkit/command/MessageCommandSender.java b/src/main/java/org/bukkit/command/MessageCommandSender.java +index 9d263ab3afb938c215c0b64d9171345fca6ceb2c..b2c9d86956179b77a43f95f13727a79c114476a7 100644 +--- a/src/main/java/org/bukkit/command/MessageCommandSender.java ++++ b/src/main/java/org/bukkit/command/MessageCommandSender.java +@@ -1,5 +1,5 @@ + package org.bukkit.command; +- ++// Dreeam - TODO: need check + import org.bukkit.Bukkit; + import org.bukkit.Server; + import org.bukkit.permissions.Permission; +diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java +index e43d0e0a2c5edfcc82a677b6c4db9314006c9bf4..68fafa73d2e8d832acc7ce47591477749128b007 100644 +--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java ++++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java +@@ -34,7 +34,6 @@ public class SimpleCommandMap implements CommandMap { + register("bukkit", new VersionCommand("version")); + register("bukkit", new ReloadCommand("reload")); + //register("bukkit", new PluginsCommand("plugins")); // Paper +- register("bukkit", new co.aikar.timings.TimingsCommand("timings")); // Paper + } + + public void setFallbackCommands() { +@@ -66,7 +65,6 @@ public class SimpleCommandMap implements CommandMap { + */ + @Override + public boolean register(@NotNull String label, @NotNull String fallbackPrefix, @NotNull Command command) { +- command.timings = co.aikar.timings.TimingsManager.getCommandTiming(fallbackPrefix, command); // Paper + label = label.toLowerCase(java.util.Locale.ENGLISH).trim(); + fallbackPrefix = fallbackPrefix.toLowerCase(java.util.Locale.ENGLISH).trim(); + boolean registered = register(label, command, false, fallbackPrefix); +@@ -156,23 +154,13 @@ public class SimpleCommandMap implements CommandMap { + parsedArgs = event.getArgs(); + // Purpur end + +- // Paper start - Plugins do weird things to workaround normal registration +- if (target.timings == null) { +- target.timings = co.aikar.timings.TimingsManager.getCommandTiming(null, target); +- } +- // Paper end +- + try { +- try (co.aikar.timings.Timing ignored = target.timings.startTiming()) { // Paper - use try with resources + // Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false) + target.execute(sender, sentCommandLabel, Arrays.copyOfRange(args, 1, args.length)); +- } // target.timings.stopTiming(); // Spigot // Paper + } catch (CommandException ex) { + server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper +- //target.timings.stopTiming(); // Spigot // Paper + throw ex; + } catch (Throwable ex) { +- //target.timings.stopTiming(); // Spigot // Paper + String msg = "Unhandled exception executing '" + commandLine + "' in " + target; + server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper + throw new CommandException(msg, ex); +diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java +index 899d67fa782fac639fe7fb096e05c551d75bd647..cb01547706de416dd41879bf479d93fa0e7e23c9 100644 +--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java ++++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java +@@ -60,7 +60,6 @@ public final class SimplePluginManager implements PluginManager { + public final Map> defSubs = new HashMap>(); + public PluginManager paperPluginManager; + // Paper end +- private boolean useTimings = false; + + public SimplePluginManager(@NotNull Server instance, @NotNull SimpleCommandMap commandMap) { + server = instance; +@@ -711,12 +710,7 @@ public final class SimplePluginManager implements PluginManager { + throw new IllegalPluginAccessException("Plugin attempted to register " + event + " while not enabled"); + } + +- executor = new co.aikar.timings.TimedEventExecutor(executor, plugin, null, event); // Paper +- if (false) { // Spigot - RL handles useTimings check now // Paper +- getEventListeners(event).register(new TimedRegisteredListener(listener, executor, priority, plugin, ignoreCancelled)); +- } else { + getEventListeners(event).register(new RegisteredListener(listener, executor, priority, plugin, ignoreCancelled)); +- } + } + + @NotNull +@@ -946,17 +940,7 @@ public final class SimplePluginManager implements PluginManager { + + @Override + public boolean useTimings() { +- if (true) {return this.paperPluginManager.useTimings();} // Paper +- return co.aikar.timings.Timings.isTimingsEnabled(); // Spigot +- } +- +- /** +- * Sets whether or not per event timing code should be used +- * +- * @param use True if per event timing code should be used +- */ +- public void useTimings(boolean use) { +- co.aikar.timings.Timings.setTimingsEnabled(use); // Paper ++ return this.paperPluginManager.useTimings(); // Paper // Leaf - Remove Timings + } + + // Paper start +diff --git a/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java b/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java +deleted file mode 100644 +index 1d76e30b82ca56bb4cf3b9a33f5a129ab829e3f0..0000000000000000000000000000000000000000 +--- a/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java ++++ /dev/null +@@ -1,101 +0,0 @@ +-package org.bukkit.plugin; +- +-import org.bukkit.event.Event; +-import org.bukkit.event.EventException; +-import org.bukkit.event.EventPriority; +-import org.bukkit.event.Listener; +-import org.jetbrains.annotations.NotNull; +-import org.jetbrains.annotations.Nullable; +- +-/** +- * Extends RegisteredListener to include timing information +- */ +-public class TimedRegisteredListener extends RegisteredListener { +- private int count; +- private long totalTime; +- private Class eventClass; +- private boolean multiple = false; +- +- public TimedRegisteredListener(@NotNull final Listener pluginListener, @NotNull final EventExecutor eventExecutor, @NotNull final EventPriority eventPriority, @NotNull final Plugin registeredPlugin, final boolean listenCancelled) { +- super(pluginListener, eventExecutor, eventPriority, registeredPlugin, listenCancelled); +- } +- +- @Override +- public void callEvent(@NotNull Event event) throws EventException { +- if (event.isAsynchronous()) { +- super.callEvent(event); +- return; +- } +- count++; +- Class newEventClass = event.getClass(); +- if (this.eventClass == null) { +- this.eventClass = newEventClass; +- } else if (!this.eventClass.equals(newEventClass)) { +- multiple = true; +- this.eventClass = getCommonSuperclass(newEventClass, this.eventClass).asSubclass(Event.class); +- } +- long start = System.nanoTime(); +- super.callEvent(event); +- totalTime += System.nanoTime() - start; +- } +- +- @NotNull +- private static Class getCommonSuperclass(@NotNull Class class1, @NotNull Class class2) { +- while (!class1.isAssignableFrom(class2)) { +- class1 = class1.getSuperclass(); +- } +- return class1; +- } +- +- /** +- * Resets the call count and total time for this listener +- */ +- public void reset() { +- count = 0; +- totalTime = 0; +- } +- +- /** +- * Gets the total times this listener has been called +- * +- * @return Times this listener has been called +- */ +- public int getCount() { +- return count; +- } +- +- /** +- * Gets the total time calls to this listener have taken +- * +- * @return Total time for all calls of this listener +- */ +- public long getTotalTime() { +- return totalTime; +- } +- +- /** +- * Gets the class of the events this listener handled. If it handled +- * multiple classes of event, the closest shared superclass will be +- * returned, such that for any event this listener has handled, +- * this.getEventClass().isAssignableFrom(event.getClass()) +- * and no class this.getEventClass().isAssignableFrom(clazz) +- * {@literal && this.getEventClass() != clazz &&} +- * event.getClass().isAssignableFrom(clazz) for all handled events. +- * +- * @return the event class handled by this RegisteredListener +- */ +- @Nullable +- public Class getEventClass() { +- return eventClass; +- } +- +- /** +- * Gets whether this listener has handled multiple events, such that for +- * some two events, eventA.getClass() != eventB.getClass(). +- * +- * @return true if this listener has handled multiple events +- */ +- public boolean hasMultiple() { +- return multiple; +- } +-} +diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +index f7266e3991d991e7d7b38752ed472bc9cfa5f43c..d0b97df06a3fb5b05592f1d8204358e8f6e4d459 100644 +--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java ++++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +@@ -39,11 +39,9 @@ import org.bukkit.plugin.PluginDescriptionFile; + import org.bukkit.plugin.PluginLoader; + import org.bukkit.plugin.RegisteredListener; + import org.bukkit.plugin.SimplePluginManager; +-import org.bukkit.plugin.TimedRegisteredListener; + import org.bukkit.plugin.UnknownDependencyException; + import org.jetbrains.annotations.NotNull; + import org.jetbrains.annotations.Nullable; +-import org.spigotmc.CustomTimingsHandler; // Spigot + import org.yaml.snakeyaml.error.YAMLException; + + /** +@@ -239,7 +237,6 @@ public final class JavaPluginLoader implements PluginLoader { + Preconditions.checkArgument(plugin != null, "Plugin can not be null"); + Preconditions.checkArgument(listener != null, "Listener can not be null"); + +- boolean useTimings = server.getPluginManager().useTimings(); + Map, Set> ret = new HashMap, Set>(); + Set methods; + try { +@@ -300,9 +297,9 @@ public final class JavaPluginLoader implements PluginLoader { + } + } + +- EventExecutor executor = new co.aikar.timings.TimedEventExecutor(new EventExecutor() { // Paper ++ EventExecutor executor = new EventExecutor() { + @Override +- public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException { // Paper ++ public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException { + try { + if (!eventClass.isAssignableFrom(event.getClass())) { + return; +@@ -314,12 +311,8 @@ public final class JavaPluginLoader implements PluginLoader { + throw new EventException(t); + } + } +- }, plugin, method, eventClass); // Paper +- if (false) { // Spigot - RL handles useTimings check now +- eventSet.add(new TimedRegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled())); +- } else { ++ }; + eventSet.add(new RegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled())); +- } + } + return ret; + } +diff --git a/src/main/java/org/spigotmc/CustomTimingsHandler.java b/src/main/java/org/spigotmc/CustomTimingsHandler.java +deleted file mode 100644 +index 12946bd55fcf7c40d39081779a7fa30049ee6165..0000000000000000000000000000000000000000 +--- a/src/main/java/org/spigotmc/CustomTimingsHandler.java ++++ /dev/null +@@ -1,67 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * 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 org.spigotmc; +- +-import org.bukkit.Bukkit; +-import org.jetbrains.annotations.NotNull; +-import org.bukkit.plugin.AuthorNagException; +-import co.aikar.timings.Timing; +-import co.aikar.timings.Timings; +-import co.aikar.timings.TimingsManager; +- +-import java.lang.reflect.Method; +-import java.util.logging.Level; +- +-/** +- * This is here for legacy purposes incase any plugin used it. +- * +- * If you use this, migrate ASAP as this will be removed in the future! +- * +- * @deprecated +- * @see co.aikar.timings.Timings#of +- */ +-@Deprecated(forRemoval = true) +-public final class CustomTimingsHandler { +- private final Timing handler; +- +- public CustomTimingsHandler(@NotNull String name) { +- Timing timing; +- +- new AuthorNagException("Deprecated use of CustomTimingsHandler. Please Switch to Timings.of ASAP").printStackTrace(); +- try { +- final Method ofSafe = TimingsManager.class.getDeclaredMethod("getHandler", String.class, String.class, Timing.class); +- ofSafe.setAccessible(true); +- timing = (Timing) ofSafe.invoke(null,"Minecraft", "(Deprecated API) " + name, null); +- } catch (Exception e) { +- e.printStackTrace(); +- Bukkit.getLogger().log(Level.SEVERE, "This handler could not be registered"); +- timing = Timings.NULL_HANDLER; +- } +- handler = timing; +- } +- +- public void startTiming() { handler.startTiming(); } +- public void stopTiming() { handler.stopTiming(); } +- +-} +diff --git a/src/test/java/org/bukkit/AnnotationTest.java b/src/test/java/org/bukkit/AnnotationTest.java +index 49bba9a7a02b9cf3a552583315eff2b7dbe060c0..e57a67328941c08d0d3a61fddcefc4d6fa0b93d4 100644 +--- a/src/test/java/org/bukkit/AnnotationTest.java ++++ b/src/test/java/org/bukkit/AnnotationTest.java +@@ -54,15 +54,6 @@ public class AnnotationTest { + // Paper start + "io/papermc/paper/util/TransformingRandomAccessList", + "io/papermc/paper/util/TransformingRandomAccessList$TransformedListIterator", +- // Timings history is broken in terms of nullability due to guavas Function defining that the param is NonNull +- "co/aikar/timings/TimingHistory$2", +- "co/aikar/timings/TimingHistory$2$1", +- "co/aikar/timings/TimingHistory$2$1$1", +- "co/aikar/timings/TimingHistory$2$1$2", +- "co/aikar/timings/TimingHistory$3", +- "co/aikar/timings/TimingHistory$4", +- "co/aikar/timings/TimingHistoryEntry$1" +- // Paper end + }; + + @Test diff --git a/patches/api/0004-Bump-Dependencies.patch b/patches/api/0006-Bump-Dependencies.patch similarity index 100% rename from patches/api/0004-Bump-Dependencies.patch rename to patches/api/0006-Bump-Dependencies.patch diff --git a/patches/api/0005-KTP-Optimize-Spigot-event-bus.patch b/patches/api/0007-KTP-Optimize-Spigot-event-bus.patch similarity index 100% rename from patches/api/0005-KTP-Optimize-Spigot-event-bus.patch rename to patches/api/0007-KTP-Optimize-Spigot-event-bus.patch diff --git a/patches/api/0006-KeYi-Player-Skull-API.patch b/patches/api/0008-KeYi-Player-Skull-API.patch similarity index 100% rename from patches/api/0006-KeYi-Player-Skull-API.patch rename to patches/api/0008-KeYi-Player-Skull-API.patch diff --git a/patches/api/0007-Slice-Smooth-Teleports.patch b/patches/api/0009-Slice-Smooth-Teleports.patch similarity index 100% rename from patches/api/0007-Slice-Smooth-Teleports.patch rename to patches/api/0009-Slice-Smooth-Teleports.patch diff --git a/patches/server/0010-Remove-Timings.patch b/patches/server/0010-Remove-Timings.patch new file mode 100644 index 00000000..d147faf0 --- /dev/null +++ b/patches/server/0010-Remove-Timings.patch @@ -0,0 +1,2307 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> +Date: Sat, 23 Sep 2023 03:12:14 -0400 +Subject: [PATCH] Remove Timings + +Completely remove the Timings, since it wastes too much performance. Use Spark instead. + +diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java +deleted file mode 100644 +index 112029cb275d45dced60807820f1bfe9f394496d..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/MinecraftTimings.java ++++ /dev/null +@@ -1,181 +0,0 @@ +-package co.aikar.timings; +- +-import com.google.common.collect.MapMaker; +-import io.papermc.paper.configuration.GlobalConfiguration; +-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 +-@Deprecated(forRemoval = true) +-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"); +- public static final Timing distanceManagerTick = Timings.ofSafe("Distance Manager Tick"); // Paper - add timings for distance manager +- public static final Timing scoreboardScoreSearch = Timings.ofSafe("Scoreboard score search"); // Paper - add timings for scoreboard search +- +- public static final Timing midTickChunkTasks = Timings.ofSafe("Mid Tick Chunk Tasks"); +- +- private static final Map, 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); +- } +- +- public static Timing getBehaviorTimings(String type) { +- return Timings.ofSafe("## Behavior - " + type); +- } +- +- public static Timing getSensorTimings(String type, int rate) { +- return Timings.ofSafe("## Sensor - " + type + " (Default rate: " + rate + ")"); +- } +- +- /** +- * 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) { +- return Timings.ofSafe("Command Function - " + function.getId()); +- } +- +- 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"); +- } +- TimingsManager.hiddenConfigs.addAll(config.hiddenConfigEntries); +- 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); +- } +-} +diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java +deleted file mode 100644 +index 61fc65624f7d9a3bfa399a58112efb7f55b31652..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/TimingsExport.java ++++ /dev/null +@@ -1,453 +0,0 @@ +-/* +- * This file is licensed under the MIT License (MIT). +- * +- * Copyright (c) 2014 Daniel Ennis +- * +- * Permission is hereby granted, free of charge, to any person obtaining a copy +- * of this software and associated documentation files (the "Software"), to deal +- * in the Software without restriction, including without limitation the rights +- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +- * copies of the Software, and to permit persons to whom the Software is +- * furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice shall be included in +- * all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +- * THE SOFTWARE. +- */ +-package co.aikar.timings; +- +-import com.google.common.collect.Sets; +-import io.papermc.paper.adventure.PaperAdventure; +-import net.kyori.adventure.text.event.ClickEvent; +-import net.kyori.adventure.text.format.NamedTextColor; +-import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +-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.galemc.gale.configuration.GaleGlobalConfiguration; +-import org.galemc.gale.configuration.timingsexport.VanillaServerPropertiesTimingsExport; +-import org.json.simple.JSONObject; +-import org.json.simple.JSONValue; +-import oshi.SystemInfo; +-import oshi.hardware.HardwareAbstractionLayer; +- +-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.Arrays; +-import java.util.LinkedHashMap; +-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; +-import static net.kyori.adventure.text.Component.text; +- +-@SuppressWarnings({"rawtypes", "SuppressionAnnotation"}) +-@Deprecated(forRemoval = true) +-public class TimingsExport extends Thread { +- +- private final TimingsReportListener listeners; +- private final Map out; +- private final TimingHistory[] history; +- private static long lastReport = 0; +- +- private TimingsExport(TimingsReportListener listeners, Map out, TimingHistory[] history) { +- super("Timings paste thread"); +- this.listeners = listeners; +- this.out = out; +- this.history = history; +- } +- +- /** +- * Checks if any pending reports are being requested, and builds one if needed. +- */ +- public static void reportTimings() { +- if (Timings.requestingReport.isEmpty()) { +- return; +- } +- TimingsReportListener listeners = new TimingsReportListener(Timings.requestingReport); +- listeners.addConsoleIfNeeded(); +- +- Timings.requestingReport.clear(); +- long now = System.currentTimeMillis(); +- final long lastReportDiff = now - lastReport; +- if (lastReportDiff < 60000) { +- listeners.sendMessage(text("Please wait at least 1 minute in between Timings reports. (" + (int)((60000 - lastReportDiff) / 1000) + " seconds)", NamedTextColor.RED)); +- listeners.done(); +- return; +- } +- final long lastStartDiff = now - TimingsManager.timingStart; +- if (lastStartDiff < 180000) { +- 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)); +- listeners.done(); +- return; +- } +- listeners.sendMessage(text("Preparing Timings Report...", NamedTextColor.GREEN)); +- lastReport = now; +- Map parent = createObject( +- // Get some basic system details about the server +- pair("version", Bukkit.getVersion()), +- pair("maxplayers", Bukkit.getMaxPlayers()), +- pair("start", TimingsManager.timingStart / 1000), +- pair("end", System.currentTimeMillis() / 1000), +- pair("online-mode", Bukkit.getServer().getOnlineMode()), +- pair("sampletime", (System.currentTimeMillis() - TimingsManager.timingStart) / 1000), +- pair("datapacks", toArrayMapper(MinecraftServer.getServer().getPackRepository().getSelectedPacks(), pack -> { +- return PlainTextComponentSerializer.plainText().serialize(PaperAdventure.asAdventure(pack.getChatLink(true))); +- })) +- ); +- if (!TimingsManager.privacy) { +- appendObjectData(parent, +- pair("server", Bukkit.getUnsafe().getTimingsServerName()), +- pair("motd", Bukkit.getServer().getMotd()), +- pair("icon", Bukkit.getServer().getServerIcon().getData()) +- ); +- } +- +- final Runtime runtime = Runtime.getRuntime(); +- RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean(); +- +- OperatingSystemMXBean osInfo = ManagementFactory.getOperatingSystemMXBean(); +- +- HardwareAbstractionLayer hardwareInfo = new SystemInfo().getHardware(); +- +- // Gale start - include hardware specs in timings +- var processor = hardwareInfo.getProcessor(); +- var processorIdentifier = processor.getProcessorIdentifier(); +- var memory = hardwareInfo.getMemory(); +- +- Map hardwareSpecsMap = new LinkedHashMap<>(); +- if (GaleGlobalConfiguration.get().misc.includeInTimingsReport.hardwareSpecs.cpu) { +- hardwareSpecsMap.put("cpu", createObject( +- pair("logicalprocessorcount", processor.getLogicalProcessorCount()), +- pair("physicalprocessorcount", processor.getPhysicalProcessorCount()), +- pair("physicalpackagecount", processor.getPhysicalPackageCount()), +- pair("contextswitches", processor.getContextSwitches()), +- pair("interrupts", processor.getInterrupts()), +- pair("maxfreq", processor.getMaxFreq()), +- pair("currentfreq", Arrays.toString(processor.getCurrentFreq())), +- pair("identifier", createObject( +- pair("vendor", String.valueOf(processorIdentifier.getVendor()).trim()), +- pair("name", String.valueOf(processorIdentifier.getName()).trim()), +- pair("family", String.valueOf(processorIdentifier.getFamily()).trim()), +- pair("model", String.valueOf(processorIdentifier.getModel()).trim()), +- pair("vendor", String.valueOf(processorIdentifier.getVendor()).trim()), +- pair("cpu64bit", processorIdentifier.isCpu64bit()), +- pair("vendorfreq", processorIdentifier.getVendorFreq()), +- pair("microarchitecture", String.valueOf(processorIdentifier.getMicroarchitecture()).trim()) +- )) +- )); +- } +- if (GaleGlobalConfiguration.get().misc.includeInTimingsReport.hardwareSpecs.disks) { +- hardwareSpecsMap.put("diskstores", toArrayMapper(hardwareInfo.getDiskStores(), disk -> createObject( +- pair("name", String.valueOf(disk.getName()).trim()), +- pair("model", String.valueOf(disk.getModel()).trim()), +- pair("serial", String.valueOf(disk.getSerial()).trim()), +- pair("size", disk.getSize()) +- ))); +- } +- if (GaleGlobalConfiguration.get().misc.includeInTimingsReport.hardwareSpecs.gpus) { +- hardwareSpecsMap.put("gpus", toArrayMapper(hardwareInfo.getGraphicsCards(), gpu -> createObject( +- pair("name", String.valueOf(gpu.getName()).trim()), +- pair("deviceid", String.valueOf(gpu.getDeviceId()).trim()), +- pair("vendor", String.valueOf(gpu.getVendor()).trim()), +- pair("versioninfo", String.valueOf(gpu.getVersionInfo()).trim()), +- pair("vram", gpu.getVRam()) +- ))); +- } +- if (GaleGlobalConfiguration.get().misc.includeInTimingsReport.hardwareSpecs.memory) { +- hardwareSpecsMap.put("memory", createObject( +- pair("total", memory.getTotal()), +- pair("available", memory.getAvailable()), +- pair("pagesize", memory.getPageSize()) +- )); +- } +- // Gale end - include hardware specs in timings +- +- parent.put("system", createObject( +- pair("timingcost", getCost()), +- pair("loadavg", osInfo.getSystemLoadAverage()), +- pair("name", System.getProperty("os.name")), +- pair("version", System.getProperty("os.version")), +- pair("jvmversion", System.getProperty("java.version")), +- pair("jvmvendor", System.getProperty("java.vendor")), +- pair("jvmvendorversion", System.getProperty("java.vendor.version")), +- pair("arch", System.getProperty("os.arch")), +- pair("maxmem", runtime.maxMemory()), +- pair("memory", createObject( +- pair("heap", ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().toString()), +- pair("nonheap", ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().toString()), +- pair("finalizing", ManagementFactory.getMemoryMXBean().getObjectPendingFinalizationCount()) +- )), +- pair("cpu", runtime.availableProcessors()), +- pair("cpuname", hardwareInfo.getProcessor().getProcessorIdentifier().getName().trim()), +- pair("hardwarespecs", hardwareSpecsMap), // Gale - include hardware specs in timings +- 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 -> { +- if (world.getWorld().getName().equals("worldeditregentempworld")) return null; +- return pair(world.getWorld().getName(), createObject( +- pair("gamerules", toObjectMapper(world.getWorld().getGameRules(), rule -> { +- return pair(rule, world.getWorld().getGameRuleValue(rule)); +- })), +- // Paper start - replace chunk loader system +- pair("ticking-distance", world.getWorld().getSimulationDistance()), +- pair("no-ticking-distance", world.getWorld().getViewDistance()), +- pair("sending-distance", world.getWorld().getSendViewDistance()) +- // Paper end - replace chunk loader system +- )); +- })); +- +- Set tileEntityTypeSet = Sets.newHashSet(); +- Set 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("server.properties", VanillaServerPropertiesTimingsExport.get()), // Gale - include server.properties in timings +- pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)), +- pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)), +- // Gale start - Gale configuration - include in timings +- pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)), +- pair("gale", mapAsJSON(Bukkit.spigot().getGaleConfig(), null)), +- // Gale end - Gale configuration - include in timings +- pair("leaf", mapAsJSON(org.dreeam.leaf.LeafConfig.getConfigCopy(), null)) // Leaf +- )); +- +- 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; +- } +- +- public static JSONObject mapAsJSON(ConfigurationSection config, String parentKey) { // Gale - Gale configuration +- +- 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") || key.equals("feature-seeds")) { +- 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 v = (Iterable) val; +- return toArrayMapper(v, input -> valAsJSON(input, parentKey)); +- } else { +- return String.valueOf(val); +- } +- } else { +- return mapAsJSON((ConfigurationSection) val, parentKey); +- } +- } +- +- @Override +- public void run() { +- out.put("data", toArrayMapper(history, TimingHistory::export)); +- +- +- String response = null; +- String timingsURL = null; +- try { +- HttpURLConnection con = (HttpURLConnection) new URL(TimingsManager.url + "post").openConnection(); +- con.setDoOutput(true); +- String hostName = "BrokenHost"; +- try { +- hostName = InetAddress.getLocalHost().getHostName(); +- } catch (Exception ignored) {} +- con.setRequestProperty("User-Agent", "Paper/" + Bukkit.getUnsafe().getTimingsServerName() + "/" + hostName); +- con.setRequestMethod("POST"); +- con.setInstanceFollowRedirects(false); +- +- OutputStream request = new GZIPOutputStream(con.getOutputStream()) {{ +- this.def.setLevel(7); +- }}; +- +- request.write(JSONValue.toJSONString(out).getBytes("UTF-8")); +- request.close(); +- +- response = getResponse(con); +- +- if (con.getResponseCode() != 302) { +- listeners.sendMessage(text( "Upload Error: " + con.getResponseCode() + ": " + con.getResponseMessage(), NamedTextColor.RED)); +- listeners.sendMessage(text("Check your logs for more information", NamedTextColor.RED)); +- if (response != null) { +- Bukkit.getLogger().log(Level.SEVERE, response); +- } +- return; +- } +- +- timingsURL = con.getHeaderField("Location"); +- listeners.sendMessage(text("View Timings Report: ", NamedTextColor.GREEN).append(text(timingsURL).clickEvent(ClickEvent.clickEvent(ClickEvent.Action.OPEN_URL, timingsURL)))); +- +- if (response != null && !response.isEmpty()) { +- Bukkit.getLogger().log(Level.INFO, "Timing Response: " + response); +- } +- } catch (IOException ex) { +- listeners.sendMessage(text("Error uploading timings, check your logs for more information", NamedTextColor.RED)); +- if (response != null) { +- Bukkit.getLogger().log(Level.SEVERE, response); +- } +- Bukkit.getLogger().log(Level.SEVERE, "Could not paste timings", ex); +- } finally { +- this.listeners.done(timingsURL); +- } +- } +- +- private String getResponse(HttpURLConnection con) throws IOException { +- InputStream is = null; +- try { +- is = con.getInputStream(); +- ByteArrayOutputStream bos = new ByteArrayOutputStream(); +- +- byte[] b = new byte[1024]; +- int bytesRead; +- while ((bytesRead = is.read(b)) != -1) { +- bos.write(b, 0, bytesRead); +- } +- return bos.toString(); +- +- } catch (IOException ex) { +- listeners.sendMessage(text("Error uploading timings, check your logs for more information", NamedTextColor.RED)); +- 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 +deleted file mode 100644 +index 22687667ec69a954261e55e59261286ac1b8b8cd..0000000000000000000000000000000000000000 +--- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java ++++ /dev/null +@@ -1,140 +0,0 @@ +-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 +-@Deprecated(forRemoval = true) +-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 final Timing poiUnload; +- public final Timing chunkUnload; +- public final Timing poiSaveDataSerialization; +- public final Timing chunkSave; +- public final Timing chunkSaveDataSerialization; +- public final Timing chunkSaveIOWait; +- public final Timing chunkUnloadPrepareSave; +- public final Timing chunkUnloadPOISerialization; +- public final Timing chunkUnloadDataSave; +- +- 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"); +- +- poiUnload = Timings.ofSafe(name + "Chunk unload - POI"); +- chunkUnload = Timings.ofSafe(name + "Chunk unload - Chunk"); +- poiSaveDataSerialization = Timings.ofSafe(name + "Chunk save - POI Data serialization"); +- chunkSave = Timings.ofSafe(name + "Chunk save - Chunk"); +- chunkSaveDataSerialization = Timings.ofSafe(name + "Chunk save - Chunk Data serialization"); +- chunkSaveIOWait = Timings.ofSafe(name + "Chunk save - Chunk IO Wait"); +- chunkUnloadPrepareSave = Timings.ofSafe(name + "Chunk unload - Async Save Prepare"); +- chunkUnloadPOISerialization = Timings.ofSafe(name + "Chunk unload - POI Data Serialization"); +- chunkUnloadDataSave = Timings.ofSafe(name + "Chunk unload - Data Serialization"); +- } +- +- public static Timing getTickList(ServerLevel worldserver, String timingsType) { +- return Timings.ofSafe(((PrimaryLevelData) worldserver.getLevelData()).getLevelName() + " - Scheduled " + timingsType); +- } +-} +diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java +index abd0217cf0bff183c8e262edc173a53403797c1a..8e52ebe8d12f5da3d877b0e4ff3723229fb47db1 100644 +--- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java ++++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java +@@ -1315,9 +1315,7 @@ public final class ChunkHolderManager { + } + + public boolean processTicketUpdates() { +- co.aikar.timings.MinecraftTimings.distanceManagerTick.startTiming(); try { // Paper - add timings for distance manager + return this.processTicketUpdates(true, true, null); +- } finally { co.aikar.timings.MinecraftTimings.distanceManagerTick.stopTiming(); } // Paper - add timings for distance manager + } + + private static final ThreadLocal> CURRENT_TICKET_UPDATE_SCHEDULING = new ThreadLocal<>(); +diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java +index 51304c5cf4b0ac7646693ef97ef4a3847d3342b5..27e0fa7d032dc34a379e6a6a0855546c50917658 100644 +--- a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java ++++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java +@@ -1779,7 +1779,6 @@ public final class NewChunkHolder { + boolean canSavePOI = !(chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave) && (poi != null && poi.isDirty()); + boolean canSaveEntities = entities != null; + +- try (co.aikar.timings.Timing ignored = this.world.timings.chunkSave.startTiming()) { // Paper + if (canSaveChunk) { + canSaveChunk = this.saveChunk(chunk, unloading); + } +@@ -1793,7 +1792,6 @@ public final class NewChunkHolder { + this.lastEntityUnload = null; + } + } +- } + + return executedUnloadTask | canSaveChunk | canSaveEntities | canSavePOI ? new SaveStat(executedUnloadTask || canSaveChunk, canSaveEntities, canSavePOI): null; + } +diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +index 3810cae80cb2dcb721ed25d566b1fe3fb87db4c2..26d2e3efdc6f5a59cea30807bbd1f87573f2cef7 100644 +--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java ++++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +@@ -1,6 +1,5 @@ + package io.papermc.paper.configuration; + +-import co.aikar.timings.MinecraftTimings; + import io.papermc.paper.configuration.constraint.Constraint; + import io.papermc.paper.configuration.constraint.Constraints; + import io.papermc.paper.configuration.type.IntOr; +@@ -87,37 +86,6 @@ public class GlobalConfiguration extends ConfigurationPart { + public boolean useDisplayNameInQuitMessage = false; + } + +- public Timings timings; +- +- public class Timings extends ConfigurationPart.Post { +- // Gale start - recommend disabling timings on startup +- public boolean enabled = false; // Gale - set default value to false +- public boolean warnIfEnabled = true; +- // Gale end - recommend disabling timings on startup +- public boolean verbose = true; +- public String url = "https://timin.gs/"; // Gale - use timin.gs by default +- public boolean serverNamePrivacy = false; +- public List hiddenConfigEntries = List.of( +- "database", +- "proxies.velocity.secret" +- ); +- public int historyInterval = 300; +- public int historyLength = 3600; +- public String serverName = "Unknown Server"; +- +- @Override +- public void postProcess() { +- // Gale start - recommend disabling timings on startup +- if (enabled && warnIfEnabled) { +- net.minecraft.server.MinecraftServer.LOGGER.warn("To improve performance, we recommend setting timings.enabled to false in paper-global.yml"); +- net.minecraft.server.MinecraftServer.LOGGER.warn("(If you do this, timings will not start on server startup, but you can still start timings later by using /timings on)"); +- net.minecraft.server.MinecraftServer.LOGGER.warn("If you would like to disable this message, set timings.warn-if-enabled to false in paper-global.yml."); +- } +- // Gale end - recommend disabling timings on startup +- MinecraftTimings.processConfig(this); +- } +- } +- + public Proxies proxies; + + public class Proxies extends ConfigurationPart { +diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +index 7ce9ebba8ce304d1f3f21d4f15ee5f3560d7700b..a1c9726d25479b5326fe2fa2b0f5a98d6b2da4c5 100644 +--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java ++++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +@@ -1,6 +1,5 @@ + package io.papermc.paper.plugin.manager; + +-import co.aikar.timings.TimedEventExecutor; + import com.destroystokyo.paper.event.server.ServerExceptionEvent; + import com.destroystokyo.paper.exception.ServerEventException; + import com.google.common.collect.Sets; +@@ -95,7 +94,6 @@ class PaperEventManager { + throw new IllegalPluginAccessException("Plugin attempted to register " + event + " while not enabled"); + } + +- executor = new TimedEventExecutor(executor, plugin, null, event); + this.getEventListeners(event).register(new RegisteredListener(listener, executor, priority, plugin, ignoreCancelled)); + } + +@@ -182,7 +180,7 @@ class PaperEventManager { + } + } + +- EventExecutor executor = new TimedEventExecutor(EventExecutor.create(method, eventClass), plugin, method, eventClass); ++ EventExecutor executor = EventExecutor.create(method, eventClass); + eventSet.add(new RegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled())); + } + return ret; +diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginManagerImpl.java b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginManagerImpl.java +index dab211c458311869c61779305580a1c7da830f71..0ddcf3652a2cc9e0cc28f672f103ec7e271fc1fb 100644 +--- a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginManagerImpl.java ++++ b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginManagerImpl.java +@@ -227,7 +227,7 @@ public class PaperPluginManagerImpl implements PluginManager, DependencyContext + + @Override + public boolean useTimings() { +- return co.aikar.timings.Timings.isTimingsEnabled(); ++ return false; // Leaf - Remove Timings + } + + @Override +diff --git a/src/main/java/net/minecraft/commands/CommandFunction.java b/src/main/java/net/minecraft/commands/CommandFunction.java +index 8273ee1c5e513f02c9743ee38c9b7cf700e2ecad..3ceeddf4c2898172d24db9ee1bab8d6b17e36128 100644 +--- a/src/main/java/net/minecraft/commands/CommandFunction.java ++++ b/src/main/java/net/minecraft/commands/CommandFunction.java +@@ -16,15 +16,6 @@ import net.minecraft.server.ServerFunctionManager; + public class CommandFunction { + private final CommandFunction.Entry[] entries; + final ResourceLocation id; +- // 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 +index d2f0a0755317f5fa9a1ccf7db346aa77fd287d80..0d9a8743fda49994fd0e162848a6dde1ab7dd30a 100644 +--- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java ++++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java +@@ -46,8 +46,7 @@ public class PacketUtils { + try { // Paper - detailed watchdog information + if (MinecraftServer.getServer().hasStopped() || (listener instanceof ServerGamePacketListenerImpl && ((ServerGamePacketListenerImpl) listener).processedDisconnect)) return; // CraftBukkit, MC-142590 + if (listener.isAcceptingMessages()) { +- co.aikar.timings.Timing timing = co.aikar.timings.MinecraftTimings.getPacketTiming(packet); // Paper - timings +- try (co.aikar.timings.Timing ignored = timing.startTiming()) { // Paper - timings ++ try { + packet.handle(listener); + } catch (Exception exception) { + if (listener.shouldPropagateHandlingExceptions()) { +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 3328eb0715dab1786a677029bf6356d9118059b9..d6f41a95d1fe6891cbfdb6e3c7fc7872e2effbbb 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -183,8 +183,6 @@ import org.bukkit.event.player.AsyncPlayerChatPreviewEvent; + import org.bukkit.event.server.ServerLoadEvent; + // CraftBukkit end + +-import co.aikar.timings.MinecraftTimings; // Paper +- + public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements CommandSource, AutoCloseable { + + public static final int SERVER_THREAD_PRIORITY = Integer.getInteger("gale.thread.priority.server", -1); // Gale - server thread priority environment variable +@@ -928,7 +926,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { + return !this.canSleepForTickNoOversleep(); // Paper - move oversleep into full server tick +@@ -1390,15 +1387,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { + return !this.canOversleep(); + }); +- isOversleep = false;MinecraftTimings.serverOversleep.stopTiming(); ++ isOversleep = false; + // Paper end + new com.destroystokyo.paper.event.server.ServerTickStartEvent(this.tickCount+1).callEvent(); // Paper + +@@ -1430,11 +1426,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { +@@ -1502,20 +1490,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Purpur +@@ -1554,14 +1536,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop waitable = new Waitable<>() { +- @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 + ConsoleInput serverCommand = new ConsoleInput(event.getCommand(), wrapper); + server.dispatchServerCommand(event.getSender(), serverCommand); +- } // Paper + }); + // Paper start + if (waitableArray[0] != null) { +diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java +index f192057ee342b9f09cc4ead1e605e1677b944ecd..fd26d043747a9937078a25307248b7e8be017809 100644 +--- a/src/main/java/net/minecraft/server/level/ChunkMap.java ++++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +@@ -1,6 +1,5 @@ + package net.minecraft.server.level; + +-import co.aikar.timings.Timing; // Paper + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableList.Builder; + import com.google.common.collect.Iterables; +@@ -637,13 +636,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + + protected void tick(BooleanSupplier shouldKeepTicking) { +- try (Timing ignored = this.level.timings.poiUnload.startTiming()) { // Paper + this.poiManager.tick(shouldKeepTicking); +- } // Paper + if (!this.level.noSave()) { +- try (Timing ignored = this.level.timings.chunkUnload.startTiming()) { // Paper + this.processUnloads(shouldKeepTicking); +- } // Paper + } + } + +@@ -1263,25 +1258,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + + // Paper start - optimised tracker + private final void processTrackQueue() { +- this.level.timings.tracker1.startTiming(); +- try { + for (TrackedEntity tracker : this.entityMap.values()) { + // update tracker entry + tracker.updatePlayers(tracker.entity.getPlayersInTrackRange()); + } +- } finally { +- this.level.timings.tracker1.stopTiming(); +- } +- + +- this.level.timings.tracker2.startTiming(); +- try { + for (TrackedEntity tracker : this.entityMap.values()) { + tracker.serverEntity.sendChanges(); + } +- } finally { +- this.level.timings.tracker2.stopTiming(); +- } + } + // Paper end - optimised tracker + +@@ -1295,7 +1279,6 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + List list = Lists.newArrayList(); + List list1 = this.level.players(); + ObjectIterator objectiterator = this.entityMap.values().iterator(); +- level.timings.tracker1.startTiming(); // Paper + + ChunkMap.TrackedEntity playerchunkmap_entitytracker; + +@@ -1320,17 +1303,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + playerchunkmap_entitytracker.serverEntity.sendChanges(); + } + } +- 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 +index cb7f88e37b6bd3a0a78f80ef6062e65818ab180c..30b243ca777a5b362b50dd4ad1ea22545c038162 100644 +--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java ++++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +@@ -294,10 +294,8 @@ public class ServerChunkCache extends ChunkSource { + io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.pushChunkWait(this.level, x1, z1); // Paper - rewrite chunk system + // Paper end + com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x1, z1); // Paper - sync load info +- this.level.timings.syncChunkLoad.startTiming(); // Paper + chunkproviderserver_b.managedBlock(completablefuture::isDone); + io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - async chunk debug // Paper - rewrite chunk system +- this.level.timings.syncChunkLoad.stopTiming(); // Paper + } // Paper + ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { + return ichunkaccess1; +@@ -446,17 +444,13 @@ public class ServerChunkCache extends ChunkSource { + + 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 + } + + // Paper start - duplicate save, but call incremental + public void saveIncrementally() { + this.runDistanceManagerUpdates(); +- try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings + this.chunkMap.saveIncrementally(); +- } // Paper - Timings + } + // Paper end + +@@ -482,20 +476,14 @@ public class ServerChunkCache extends ChunkSource { + + @Override + public void tick(BooleanSupplier shouldKeepTicking, boolean tickChunks) { +- this.level.timings.doChunkMap.startTiming(); // Spigot + this.distanceManager.purgeStaleTickets(); + this.runDistanceManagerUpdates(); +- this.level.timings.doChunkMap.stopTiming(); // Spigot + if (tickChunks) { +- this.level.timings.chunks.startTiming(); // Paper - timings + this.chunkMap.level.playerChunkLoader.tick(); // Paper - replace player chunk loader - this is mostly required to account for view distance changes + this.tickChunks(); +- this.level.timings.chunks.stopTiming(); // Paper - timings + } + +- this.level.timings.doChunkUnload.startTiming(); // Spigot + this.chunkMap.tick(shouldKeepTicking); +- this.level.timings.doChunkUnload.stopTiming(); // Spigot + this.clearCache(); + } + +@@ -552,7 +540,6 @@ public class ServerChunkCache extends ChunkSource { + boolean flag2AndHasNaturalSpawn = flag2 && this.anySpawnCategoryIsSpawnedThisTick(); + if (flag2AndHasNaturalSpawn) { + // Gale end - MultiPaper - skip unnecessary mob spawning computations +- this.level.timings.countNaturalMobs.startTiming(); // Paper - timings + int l = this.distanceManager.getNaturalSpawnChunkCount(); + // Paper start - per player mob spawning + if ((this.spawnFriendlies || this.spawnEnemies) && this.chunkMap.playerMobDistanceMap != null) { // don't count mobs when animals and monsters are disabled +@@ -582,7 +569,6 @@ public class ServerChunkCache extends ChunkSource { + // Pufferfish end + } + // Paper end +- this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings + + //this.lastSpawnState = spawnercreature_d; // Pufferfish - this is managed asynchronously + // Gale start - MultiPaper - skip unnecessary mob spawning computations +@@ -590,9 +576,6 @@ public class ServerChunkCache extends ChunkSource { + spawnercreature_d = null; + } + // Gale end - MultiPaper - skip unnecessary mob spawning computations +- // Paper - moved down +- this.level.timings.chunkTicks.startTiming(); // Paper +- + // Paper - moved down + + // Paper - only shuffle if per-player mob spawning is disabled +@@ -643,14 +626,10 @@ public class ServerChunkCache extends ChunkSource { + } + } + // Paper end - optimise chunk tick iteration +- this.level.timings.chunkTicks.stopTiming(); // Paper + if (flag2) { +- try (co.aikar.timings.Timing ignored = this.level.timings.miscMobSpawning.startTiming()) { // Paper - timings + this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies); +- } // Paper - timings + } + // Paper start - use set of chunks requiring updates, rather than iterating every single one loaded +- this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing + if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) { + ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone(); + this.chunkMap.needsChangeBroadcasting.clear(); +@@ -662,7 +641,6 @@ public class ServerChunkCache extends ChunkSource { + } + } + } +- this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing + // Paper end - use set of chunks requiring updates, rather than iterating every single one loaded + // Paper start - controlled flush for entity tracker packets + List disabledFlushes = new java.util.ArrayList<>(this.level.players.size()); +diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java +index b77a84a5ab85839e37aee24da0f4356be3f478e2..be7c1ecd78a169d2dc9f642fcddbf47ce6905439 100644 +--- a/src/main/java/net/minecraft/server/level/ServerLevel.java ++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +@@ -1,7 +1,6 @@ + package net.minecraft.server.level; + + import com.google.common.annotations.VisibleForTesting; +-import co.aikar.timings.TimingHistory; // Paper + import com.google.common.collect.Lists; + import com.mojang.datafixers.DataFixer; + import com.mojang.datafixers.util.Pair; +@@ -824,23 +823,15 @@ public class ServerLevel extends Level implements WorldGenLevel { + + this.updateSkyBrightness(); + this.tickTime(); +- timings.scheduledBlocks.startTiming(); // Paper + if (!this.isDebug()) { + j = this.getGameTime(); + this.blockTicks.tick(j, 65536, this::tickBlock); + this.fluidTicks.tick(j, 65536, this::tickFluid); + } +- timings.scheduledBlocks.stopTiming(); // Paper + +- this.timings.raids.startTiming(); // Paper - timings + this.raids.tick(); +- this.timings.raids.stopTiming(); // Paper - timings +- this.timings.chunkProviderTick.startTiming(); // Paper - timings + this.getChunkSource().tick(shouldKeepTicking, true); +- this.timings.chunkProviderTick.stopTiming(); // Paper - timings +- timings.doSounds.startTiming(); // Spigot + this.runBlockEvents(); +- timings.doSounds.stopTiming(); // Spigot + this.handlingTick = false; + boolean flag = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players + +@@ -849,13 +840,11 @@ public class ServerLevel extends Level implements WorldGenLevel { + } + + if (flag || this.emptyTime++ < 300) { +- timings.tickEntities.startTiming(); // Spigot + if (this.dragonFight != null) { + this.dragonFight.tick(); + } + + org.spigotmc.ActivationRange.activateEntities(this); // Spigot +- timings.entityTick.startTiming(); // Spigot + this.entityTickList.forEach((entity) -> { + entity.activatedPriorityReset = false; // Pufferfish - DAB + if (!entity.isRemoved()) { +@@ -892,8 +881,6 @@ public class ServerLevel extends Level implements WorldGenLevel { + } + } + }); +- timings.entityTick.stopTiming(); // Spigot +- timings.tickEntities.stopTiming(); // Spigot + this.tickBlockEntities(); + } + +@@ -1067,7 +1054,6 @@ public class ServerLevel extends Level implements WorldGenLevel { + } + + // Paper start - optimise random block ticking +- timings.chunkTicksBlocks.startTiming(); // Paper + if (randomTickSpeed > 0) { + LevelChunkSection[] sections = chunk.getSections(); + int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this); +@@ -1101,7 +1087,6 @@ public class ServerLevel extends Level implements WorldGenLevel { + } + } + // Paper end - optimise random block ticking +- timings.chunkTicksBlocks.stopTiming(); // Paper + } + + public Optional findLightningRod(BlockPos pos) { +@@ -1380,31 +1365,21 @@ public class ServerLevel extends Level implements WorldGenLevel { + currentlyTickingEntity.lazySet(entity); + } + // Paper end - log detailed entity tick information +- ++TimingHistory.entityTicks; // Paper - timings + // Spigot start +- co.aikar.timings.Timing timer; // Paper + /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out - EAR 2, reimplement below + entity.tickCount++; +- timer = entity.getType().inactiveTickTimer.startTiming(); try { // Paper - timings + entity.inactiveTick(); +- } finally { timer.stopTiming(); } // Paper + return; + }*/ // Paper - comment out EAR 2 + // Spigot end +- // Paper start- timings + final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); +- timer = isActive ? entity.getType().tickTimer.startTiming() : entity.getType().inactiveTickTimer.startTiming(); // Paper +- try { +- // Paper end - timings + entity.setOldPosAndRot(); + + ++entity.tickCount; + if (isActive) { // Paper - EAR 2 +- TimingHistory.activatedEntityTicks++; + entity.tick(); + entity.postTick(); // CraftBukkit + } else { entity.inactiveTick(); } // Paper - EAR 2 +- } finally { timer.stopTiming(); } // Paper - timings + Iterator iterator = entity.getPassengers().iterator(); + + while (iterator.hasNext()) { +@@ -1412,7 +1387,6 @@ public class ServerLevel extends Level implements WorldGenLevel { + + this.tickPassenger(entity, entity1); + } +- // } finally { timer.stopTiming(); } // Paper - timings - move up + // Paper start - log detailed entity tick information + } finally { + if (currentlyTickingEntity.get() == entity) { +@@ -1427,9 +1401,6 @@ public class ServerLevel extends Level implements WorldGenLevel { + if (passenger instanceof Player || this.entityTickList.contains(passenger)) { + // Paper - EAR 2 + final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger); +- co.aikar.timings.Timing timer = isActive ? passenger.getType().passengerTickTimer.startTiming() : passenger.getType().passengerInactiveTickTimer.startTiming(); // Paper +- try { +- // Paper end + passenger.setOldPosAndRot(); + ++passenger.tickCount; + // Paper start - EAR 2 +@@ -1450,8 +1421,6 @@ public class ServerLevel extends Level implements WorldGenLevel { + + this.tickPassenger(passenger, entity2); + } +- +- } finally { timer.stopTiming(); }// Paper - EAR2 timings + } + } else { + passenger.stopRiding(); +@@ -1471,14 +1440,11 @@ public class ServerLevel extends Level implements WorldGenLevel { + org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); + } + +- try (co.aikar.timings.Timing ignored = this.timings.worldSave.startTiming()) { + if (doFull) { + this.saveLevelData(); + } + +- this.timings.worldSaveChunks.startTiming(); // Paper + if (!this.noSave()) chunkproviderserver.saveIncrementally(); +- this.timings.worldSaveChunks.stopTiming(); // Paper + + // Copied from save() + // CraftBukkit start - moved from MinecraftServer.saveChunks +@@ -1490,7 +1456,6 @@ public class ServerLevel extends Level implements WorldGenLevel { + this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); + } + // CraftBukkit end +- } + } + // Paper end + +@@ -1504,7 +1469,6 @@ public class ServerLevel extends Level implements WorldGenLevel { + + if (!savingDisabled) { + 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) { + progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); + } +@@ -1514,11 +1478,8 @@ public class ServerLevel extends Level implements WorldGenLevel { + progressListener.progressStage(Component.translatable("menu.savingChunks")); + } + +- timings.worldSaveChunks.startTiming(); // Paper + if (!close) chunkproviderserver.save(flush); // Paper - rewrite chunk system + if (close) chunkproviderserver.close(true); // Paper - rewrite chunk system +- timings.worldSaveChunks.stopTiming(); // Paper +- }// Paper + // Paper - rewrite chunk system - entity saving moved into ChunkHolder + + } else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system +diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index b959abd801fa2d0646375a388f1d9053fff88f29..40f32af1976323fd5ffe9aef0725025284daffb3 100644 +--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -2673,7 +2673,6 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic + } + } + // Paper End +- co.aikar.timings.MinecraftTimings.playerCommandTimer.startTiming(); // Paper + if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot + this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); + +@@ -2683,7 +2682,6 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic + this.cserver.getPluginManager().callEvent(event); + + if (event.isCancelled()) { +- co.aikar.timings.MinecraftTimings.playerCommandTimer.stopTiming(); // Paper + return; + } + +@@ -2695,8 +2693,6 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic + player.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command"); + java.util.logging.Logger.getLogger(ServerGamePacketListenerImpl.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + return; +- } finally { +- co.aikar.timings.MinecraftTimings.playerCommandTimer.stopTiming(); // Paper + } + } + // CraftBukkit end +diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java +index 3f60073c5ced65abf67f6fe175f9032c7bf49cfa..e3d1e030063a8746dbdaea14c6de7d900bc1ad0f 100644 +--- a/src/main/java/net/minecraft/server/players/PlayerList.java ++++ b/src/main/java/net/minecraft/server/players/PlayerList.java +@@ -1,6 +1,5 @@ + 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; +@@ -1321,7 +1320,6 @@ public abstract class PlayerList { + + public void saveAll(int interval) { + io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main +- MinecraftTimings.savePlayers.startTiming(); // Paper + int numSaved = 0; + long now = MinecraftServer.currentTick; + for (int i = 0; i < this.players.size(); ++i) { +@@ -1332,7 +1330,6 @@ public abstract class PlayerList { + } + // Paper end + } +- MinecraftTimings.savePlayers.stopTiming(); // Paper + return null; }); // Paper - ensure main + } + +diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java +index a8ffa403ac48041e17aa4ce057be0539e5468fd4..f4640a8a6c3ac5055c6017d61b037d43f205e6fa 100644 +--- a/src/main/java/net/minecraft/world/entity/EntityType.java ++++ b/src/main/java/net/minecraft/world/entity/EntityType.java +@@ -335,15 +335,6 @@ public class EntityType implements FeatureElement, EntityTypeT + } + + public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, int maxTrackDistance, int trackTickInterval, FeatureFlagSet requiredFeatures) { +- // Paper start +- this(factory, spawnGroup, saveable, summonable, fireImmune, spawnableFarFromPlayer, canSpawnInside, dimensions, maxTrackDistance, trackTickInterval, requiredFeatures, "custom"); +- } +- public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, int maxTrackDistance, int trackTickInterval, FeatureFlagSet requiredFeatures, String id) { +- this.tickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "tick"); +- this.inactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "inactiveTick"); +- this.passengerTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerTick"); +- this.passengerInactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerInactiveTick"); +- // Paper end + this.builtInRegistryHolder = BuiltInRegistries.ENTITY_TYPE.createIntrusiveHolder(this); + this.factory = factory; + this.category = spawnGroup; +@@ -713,12 +704,6 @@ public class EntityType implements FeatureElement, EntityTypeT + 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() { + 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; + } +@@ -824,7 +809,7 @@ public class EntityType implements FeatureElement, EntityTypeT + 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, id); // Paper - add 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); + } + } + +diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java +index 57ef7fbba3028c28231abf7b7ae78aa019323536..b518a94a5be42bf015221cfabaedff0b77d720ab 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java ++++ b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java +@@ -13,9 +13,8 @@ public abstract class Behavior implements BehaviorContro + private long endTimestamp; + private final int minDuration; + private final int maxDuration; +- // Paper start - configurable behavior tick rate and timings ++ // Paper start - configurable behavior tick rate + private final String configKey; +- private final co.aikar.timings.Timing timing; + // Paper end + + public Behavior(Map, MemoryStatus> requiredMemoryState) { +@@ -30,14 +29,13 @@ public abstract class Behavior implements BehaviorContro + this.minDuration = minRunTime; + this.maxDuration = maxRunTime; + this.entryCondition = requiredMemoryState; +- // Paper start - configurable behavior tick rate and timings ++ // Paper start - configurable behavior tick rate + String key = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()); + int lastSeparator = key.lastIndexOf('.'); + if (lastSeparator != -1) { + key = key.substring(lastSeparator + 1); + } + this.configKey = key.toLowerCase(java.util.Locale.ROOT); +- this.timing = co.aikar.timings.MinecraftTimings.getBehaviorTimings(configKey); + // Paper end + } + +@@ -58,9 +56,7 @@ public abstract class Behavior implements BehaviorContro + this.status = Behavior.Status.RUNNING; + int i = this.minDuration + world.getRandom().nextInt(this.maxDuration + 1 - this.minDuration); + this.endTimestamp = time + (long)i; +- this.timing.startTiming(); // Paper - behavior timings + this.start(world, entity, time); +- this.timing.stopTiming(); // Paper - behavior timings + return true; + } else { + return false; +@@ -72,14 +68,11 @@ public abstract class Behavior implements BehaviorContro + + @Override + public final void tickOrStop(ServerLevel world, E entity, long time) { +- this.timing.startTiming(); // Paper - behavior timings + if (!this.timedOut(time) && this.canStillUse(world, entity, time)) { + this.tick(world, entity, time); + } else { + this.doStop(world, entity, time); + } +- this.timing.stopTiming(); // Paper - behavior timings +- + } + + protected void tick(ServerLevel world, E entity, long time) { +diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java +index fcdb9bde8e1605e30dde3e580491522d4b62cdc0..4de18d00cc464313b777874430da3f5595f9c202 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java ++++ b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java +@@ -19,20 +19,18 @@ public abstract class Sensor { + private static final TargetingConditions ATTACK_TARGET_CONDITIONS_IGNORE_INVISIBILITY_AND_LINE_OF_SIGHT = TargetingConditions.forCombat().range(16.0D).ignoreLineOfSight().ignoreInvisibilityTesting(); + private final int scanRate; + private long timeToTick; +- // Paper start - configurable sensor tick rate and timings ++ // Paper start - configurable sensor tick rate + private final String configKey; +- private final co.aikar.timings.Timing timing; + // Paper end + + public Sensor(int senseInterval) { +- // Paper start - configurable sensor tick rate and timings ++ // Paper start - configurable sensor tick rate + String key = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()); + int lastSeparator = key.lastIndexOf('.'); + if (lastSeparator != -1) { + key = key.substring(lastSeparator + 1); + } + this.configKey = key.toLowerCase(java.util.Locale.ROOT); +- this.timing = co.aikar.timings.MinecraftTimings.getSensorTimings(configKey, senseInterval); + // Paper end + this.scanRate = senseInterval; + this.timeToTick = (long)RANDOM.nextInt(senseInterval); +@@ -44,12 +42,10 @@ public abstract class Sensor { + + public final void tick(ServerLevel world, E entity) { + if (--this.timeToTick <= 0L) { +- // Paper start - configurable sensor tick rate and timings ++ // Paper start - configurable sensor tick rate + this.timeToTick = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.sensor.get(entity.getType(), this.configKey), this.scanRate); +- this.timing.startTiming(); + // Paper end + this.doTick(world, entity); +- this.timing.stopTiming(); // Paper - sensor timings + } + + } +diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java +index a3ce11801710a1f87afeab5eafcced8ca98d2b31..7f7d5b9ac42bd510e29834d1df7f49d5659fbfa2 100644 +--- a/src/main/java/net/minecraft/world/level/Level.java ++++ b/src/main/java/net/minecraft/world/level/Level.java +@@ -176,7 +176,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + + public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray + public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur +- public final co.aikar.timings.WorldTimingsHandler timings; // Paper + public static BlockPos lastPhysicsProblem; // Spigot + private org.spigotmc.TickLimiter entityLimiter; + private org.spigotmc.TickLimiter tileLimiter; +@@ -418,7 +417,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + public void onBorderSetDamageSafeZOne(WorldBorder border, double safeZoneRadius) {} + }); + // CraftBukkit end +- timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings + this.keepSpawnInMemory = this.paperConfig().spawn.keepSpawnLoaded; // Paper + this.entityLimiter = new org.spigotmc.TickLimiter(spigotConfig.entityMaxTickTime); + this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime); +@@ -1011,15 +1009,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + } + + protected void tickBlockEntities() { +- timings.tileEntityPending.startTiming(); // Spigot + this.tickingBlockEntities = true; + if (!this.pendingBlockEntityTickers.isEmpty()) { + this.blockEntityTickers.addAll(this.pendingBlockEntityTickers); + this.pendingBlockEntityTickers.clear(); + } +- timings.tileEntityPending.stopTiming(); // Spigot + +- timings.tileEntityTick.startTiming(); // Spigot + // Spigot start + // Iterator iterator = this.blockEntityTickers.iterator(); + int tilesThisCycle = 0; +@@ -1052,9 +1047,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + } + this.blockEntityTickers.removeAll(toRemove); + +- timings.tileEntityTick.stopTiming(); // Spigot + this.tickingBlockEntities = false; +- co.aikar.timings.TimingHistory.tileEntityTicks += this.blockEntityTickers.size(); // Paper + spigotConfig.currentPrimedTnt = 0; // Spigot + } + +diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java +index cc41a921d3d3b07267317ac75f7aba33c39562a4..8126bd60d5075e344df77add0a38f73c53b3bdd1 100644 +--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java ++++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java +@@ -132,7 +132,6 @@ public final class NaturalSpawner { + } + + public static void spawnForChunk(ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnState info, boolean spawnAnimals, boolean spawnMonsters, boolean rareSpawn) { +- world.timings.mobSpawn.startTiming(); // Spigot + MobCategory[] aenumcreaturetype = NaturalSpawner.SPAWNING_CATEGORIES; + int i = aenumcreaturetype.length; + +@@ -186,8 +185,6 @@ public final class NaturalSpawner { + // Paper end + } + } +- +- world.timings.mobSpawn.stopTiming(); // Spigot + } + + // Paper start +diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java +index 15868cef6d7037a9c914244bc975fef238c6ff30..8e85c86685fba43d318c7ec6efa92564dd1e55c7 100644 +--- a/src/main/java/net/minecraft/world/level/block/Block.java ++++ b/src/main/java/net/minecraft/world/level/block/Block.java +@@ -115,13 +115,6 @@ public class Block extends BlockBehaviour implements ItemLike { + this != Blocks.STRUCTURE_BLOCK && + this != Blocks.JIGSAW; + } +- 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; +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 +index 3431f1a00ae2918b91a6b7a449e613e6e12ff6d4..cad0931ebd4b0ee8fab4fbbf111bb3cfb2608fbb 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +@@ -23,14 +23,9 @@ import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; + import org.bukkit.inventory.InventoryHolder; + // CraftBukkit end + +-import org.spigotmc.CustomTimingsHandler; // Spigot +-import co.aikar.timings.MinecraftTimings; // Paper +-import co.aikar.timings.Timing; // Paper +- + public abstract class BlockEntity { + static boolean ignoreTileUpdates; // Paper + +- 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 +index 6530e172527ad4c42a65f03ce8d4847facf43b38..b0016f7ccc6225257f2bc893ffb1565c6c2da2f1 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java ++++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +@@ -888,7 +888,6 @@ public class LevelChunk extends ChunkAccess { + this.chunkHolder.getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system + + if (this.needsDecoration) { +- try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper + this.needsDecoration = false; + java.util.Random random = new java.util.Random(); + random.setSeed(this.level.getSeed()); +@@ -908,7 +907,6 @@ public class LevelChunk extends ChunkAccess { + } + } + server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk)); +- } // Paper + } + } + } +@@ -1263,7 +1261,6 @@ public class LevelChunk extends ChunkAccess { + + if (LevelChunk.this.isTicking(blockposition)) { + try { +- this.blockEntity.tickTimer.startTiming(); // Spigot + BlockState iblockdata = LevelChunk.this.getBlockState(blockposition); + + if (this.blockEntity.getType().isValid(iblockdata)) { +@@ -1281,10 +1278,6 @@ public class LevelChunk extends ChunkAccess { + net.minecraft.world.level.chunk.LevelChunk.this.level.getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new ServerInternalException(msg, throwable))); + LevelChunk.this.removeBlockEntity(this.getPos()); + // Paper end +- // Spigot start +- } finally { +- this.blockEntity.tickTimer.stopTiming(); +- // Spigot end + } + } + } +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 40ce72ac4ca4f262ad77cf5ba47b8f2c8d9055d2..b656114a0c2594c553e60b8a923a8a99c3b682c2 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -471,7 +471,6 @@ public final class CraftServer implements Server { + 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")); // 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")); +diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java +index 89107a4aaecbb38fb061bc45d8a6d689a69c87fc..034b0ee29fc325c162e79b3d88570001a973e999 100644 +--- a/src/main/java/org/bukkit/craftbukkit/Main.java ++++ b/src/main/java/org/bukkit/craftbukkit/Main.java +@@ -369,8 +369,6 @@ public class Main { + tryPreloadClass("org.jline.terminal.impl.MouseSupport"); + tryPreloadClass("org.jline.terminal.impl.MouseSupport$1"); + tryPreloadClass("org.jline.terminal.Terminal$MouseTracking"); +- tryPreloadClass("co.aikar.timings.TimingHistory"); +- tryPreloadClass("co.aikar.timings.TimingHistory$MinuteReport"); + tryPreloadClass("io.netty.channel.AbstractChannelHandlerContext"); + tryPreloadClass("io.netty.channel.AbstractChannelHandlerContext$11"); + tryPreloadClass("io.netty.channel.AbstractChannelHandlerContext$12"); +diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +index 65566adec52a51df05c5ce9c1e673f3c4885ac5e..0756ab78eaae2943e1f6594c0095421affeccfcd 100644 +--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java ++++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +@@ -1,6 +1,5 @@ + package org.bukkit.craftbukkit.scheduler; + +-import co.aikar.timings.MinecraftTimings; // Paper + import com.google.common.base.Preconditions; + import com.google.common.util.concurrent.ThreadFactoryBuilder; + import java.util.ArrayList; +@@ -302,7 +301,7 @@ public class CraftScheduler implements BukkitScheduler { + } + return false; + } +- }){{this.timings=co.aikar.timings.MinecraftTimings.getCancelTasksTimer();}}; // Paper ++ }); + this.handle(task, 0L); + for (CraftTask taskPending = this.head.getNext(); taskPending != null; taskPending = taskPending.getNext()) { + if (taskPending == task) { +@@ -342,7 +341,7 @@ public class CraftScheduler implements BukkitScheduler { + } + } + } +- }){{this.timings=co.aikar.timings.MinecraftTimings.getCancelTasksTimer(plugin);}}; // Paper ++ }); + this.handle(task, 0L); + for (CraftTask taskPending = this.head.getNext(); taskPending != null; taskPending = taskPending.getNext()) { + if (taskPending == task) { +@@ -513,10 +512,8 @@ public class CraftScheduler implements BukkitScheduler { + this.runners.remove(task.getTaskId()); + } + } +- MinecraftTimings.bukkitSchedulerFinishTimer.startTiming(); // Paper + this.pending.addAll(temp); + temp.clear(); +- MinecraftTimings.bukkitSchedulerFinishTimer.stopTiming(); // Paper + //this.debugHead = this.debugHead.getNextHead(currentTick); // Paper + } + +@@ -559,7 +556,6 @@ public class CraftScheduler implements BukkitScheduler { + } + + void parsePending() { // Paper +- if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.startTiming(); // Paper + CraftTask head = this.head; + CraftTask task = head.getNext(); + CraftTask lastTask = head; +@@ -578,7 +574,6 @@ public class CraftScheduler implements BukkitScheduler { + task.setNext(null); + } + this.head = lastTask; +- if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.stopTiming(); // Paper + } + + private boolean isReady(final int currentTick) { +diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java +index 3f45bab0e9f7b3697e6d9d1092a1e6e579f7066f..dc785cb249e0d6c556e404bc77fb8c5ee9cd3eb5 100644 +--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java ++++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java +@@ -2,15 +2,10 @@ 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.spigotmc.CustomTimingsHandler; // Spigot +-import co.aikar.timings.MinecraftTimings; // Paper +-import co.aikar.timings.Timing; // Paper +- + public class CraftTask implements BukkitTask, Runnable { // Spigot + + private volatile CraftTask next = null; +@@ -31,7 +26,6 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot + private long nextRun; + public final Runnable rTask; // Paper + public final Consumer cTask; // Paper +- public Timing timings; // Paper + private final Plugin plugin; + private final int id; + private final long createdAt = System.nanoTime(); +@@ -50,12 +44,10 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot + this.rTask = (Runnable) task; + this.cTask = null; + this.plugin = CraftScheduler.MINECRAFT; +- this.taskName = taskName; + this.internal = true; + this.id = id; + this.period = CraftTask.NO_REPEATING; + this.taskName = taskName; +- this.timings = MinecraftTimings.getInternalTaskName(taskName); + } + // Paper end + +@@ -76,7 +68,6 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot + } + this.id = id; + this.period = period; +- timings = task != null ? MinecraftTimings.getPluginTaskTimings(this, period) : NullTimingHandler.NULL; // Paper + } + + @Override +@@ -96,13 +87,11 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot + + @Override + public void run() { +- try (Timing ignored = timings.startTiming()) { // Paper + if (this.rTask != null) { + this.rTask.run(); + } else { + this.cTask.accept(this); + } +- } // Paper + } + + long getCreatedAt() { +diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java +index 500f2eb0df5a07637cd278c263e95592b0037eb6..2309645342a527f6b3cd28ad15c7409a7fc5e232 100644 +--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java ++++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java +@@ -113,18 +113,10 @@ public final class CraftScoreboardManager implements ScoreboardManager { + + // CraftBukkit method + public void getScoreboardScores(ObjectiveCriteria criteria, String name, Consumer consumer) { +- // Paper start - add timings for scoreboard search + // plugins leaking scoreboards will make this very expensive, let server owners debug it easily +- co.aikar.timings.MinecraftTimings.scoreboardScoreSearch.startTimingIfSync(); +- try { +- // Paper end - add timings for scoreboard search + for (CraftScoreboard scoreboard : this.scoreboards) { + Scoreboard board = scoreboard.board; + board.forAllObjectives(criteria, name, (score) -> consumer.accept(score)); + } +- } finally { // Paper start - add timings for scoreboard search +- co.aikar.timings.MinecraftTimings.scoreboardScoreSearch.stopTimingIfSync(); +- } +- // Paper end - add timings for scoreboard search + } + } +diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +index 4cb83b8ae5f1e1769d620d92b700986014456963..25f95d97e71fd534df0343ecf7f28abf30447c1b 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +@@ -224,12 +224,6 @@ public final class CraftMagicNumbers implements UnsafeValues { + } + // Paper end + // ======================================================================== +- // Paper start +- @Override +- public void reportTimings() { +- co.aikar.timings.TimingsExport.reportTimings(); +- } +- // Paper end + + public static byte toLegacyData(BlockState data) { + return CraftLegacy.toLegacyData(data); +@@ -463,10 +457,6 @@ public final class CraftMagicNumbers implements UnsafeValues { + } + + // Paper start +- @Override +- public String getTimingsServerName() { +- return io.papermc.paper.configuration.GlobalConfiguration.get().timings.serverName; +- } + + @Override + public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { +diff --git a/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java b/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java +index 5b7e2afd8ecc5b8bbe524d4ba6e1d0ac0282878b..3f12cf7608f8966b8a4279c17f86c5d7e1002714 100644 +--- a/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java ++++ b/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java +@@ -79,41 +79,6 @@ public class GaleGlobalConfiguration extends ConfigurationPart { + public int premiumAccountSlowLoginTimeout = -1; // Gale - make slow login timeout configurable + public boolean ignoreNullLegacyStructureData = false; // Gale - MultiPaper - ignore null legacy structure data + +- public IncludeInTimingsReport includeInTimingsReport; +- +- public class IncludeInTimingsReport extends ConfigurationPart { +- +- // Gale start - include server.properties in timings +- public ServerProperties serverProperties; +- public class ServerProperties extends ConfigurationPart { +- public boolean dataPacks = true; +- public boolean enableRcon = false; +- public boolean generatorSettings = true; +- public boolean levelName = false; +- public boolean motd = false; +- public boolean queryPort = false; +- public boolean rconPort = false; +- public boolean resourcePackPrompt = false; +- @Setting("resource-pack-and-resource-pack-sha1") +- public boolean resourcePackAndResourcePackSha1 = false; +- public boolean serverIp = false; +- public boolean serverPort = false; +- public boolean textFilteringConfig = false; +- } +- // Gale end - include server.properties in timings +- +- // Gale start - include hardware specs in timings +- public HardwareSpecs hardwareSpecs; +- public class HardwareSpecs extends ConfigurationPart { +- public boolean cpu = true; +- public boolean disks = true; +- public boolean gpus = true; +- public boolean memory = true; +- } +- // Gale end - include hardware specs in timings +- +- } +- + public Keepalive keepalive; + public class Keepalive extends ConfigurationPart { + public boolean sendMultiple = true; // Gale - Purpur - send multiple keep-alive packets +diff --git a/src/main/java/org/galemc/gale/configuration/timingsexport/GaleConfigurationTimingsExport.java b/src/main/java/org/galemc/gale/configuration/timingsexport/GaleConfigurationTimingsExport.java +deleted file mode 100644 +index 579c2e69d8f6ce8398eb1297d1d1ead98c9068a5..0000000000000000000000000000000000000000 +--- a/src/main/java/org/galemc/gale/configuration/timingsexport/GaleConfigurationTimingsExport.java ++++ /dev/null +@@ -1,19 +0,0 @@ +-// Gale - Gale configuration +- +-package org.galemc.gale.configuration.timingsexport; +- +-import co.aikar.timings.TimingsExport; +-import org.bukkit.Bukkit; +-import org.jetbrains.annotations.NotNull; +-import org.json.simple.JSONObject; +- +-public final class GaleConfigurationTimingsExport { +- +- private GaleConfigurationTimingsExport() {} +- +- public static @NotNull JSONObject get() { +- var json = TimingsExport.mapAsJSON(Bukkit.spigot().getGaleConfig(), null); +- return json; +- } +- +-} +diff --git a/src/main/java/org/galemc/gale/configuration/timingsexport/VanillaServerPropertiesTimingsExport.java b/src/main/java/org/galemc/gale/configuration/timingsexport/VanillaServerPropertiesTimingsExport.java +deleted file mode 100644 +index 9d9ee3f38f04cfc4fcab00b8ff5558e75674da11..0000000000000000000000000000000000000000 +--- a/src/main/java/org/galemc/gale/configuration/timingsexport/VanillaServerPropertiesTimingsExport.java ++++ /dev/null +@@ -1,128 +0,0 @@ +-// Gale - include server.properties in timings +- +-package org.galemc.gale.configuration.timingsexport; +- +-import co.aikar.timings.TimingsExport; +-import net.minecraft.server.MinecraftServer; +-import net.minecraft.server.dedicated.DedicatedServer; +-import org.galemc.gale.configuration.GaleGlobalConfiguration; +-import org.jetbrains.annotations.NotNull; +-import org.json.simple.JSONObject; +- +-import java.util.Optional; +- +-/** +- * Exports the vanilla server.properties to a JSON object, to be included in a timings report. +- * +- * @see TimingsExport +- * +- * @author Martijn Muijsers under GPL-3.0 +- */ +-public final class VanillaServerPropertiesTimingsExport { +- +- private VanillaServerPropertiesTimingsExport() {} +- +- @SuppressWarnings("unchecked") +- public static @NotNull JSONObject get() { +- +- var json = new JSONObject(); +- var properties = ((DedicatedServer) MinecraftServer.getServer()).getProperties(); +- var includeConfig = GaleGlobalConfiguration.get().misc.includeInTimingsReport.serverProperties; +- +- json.put("allow-flight", String.valueOf(properties.allowFlight)); +- json.put("allow-nether", String.valueOf(properties.allowNether)); +- json.put("broadcast-console-to-ops", String.valueOf(properties.broadcastConsoleToOps)); +- json.put("broadcast-rcon-to-ops", String.valueOf(properties.broadcastRconToOps)); +- json.put("debug", String.valueOf(properties.debug)); +- json.put("difficulty", String.valueOf(properties.difficulty)); +- json.put("enable-command-block", String.valueOf(properties.enableCommandBlock)); +- json.put("enable-jmx-monitoring", String.valueOf(properties.enableJmxMonitoring)); +- json.put("enable-query", String.valueOf(properties.enableQuery)); +- if (includeConfig.enableRcon) { +- json.put("enable-rcon", String.valueOf(properties.enableRcon)); +- } +- json.put("enable-status", String.valueOf(properties.enableStatus)); +- json.put("enforce-secure-profile", String.valueOf(properties.enforceSecureProfile)); +- json.put("enforce-whitelist", String.valueOf(properties.enforceWhitelist)); +- json.put("entity-broadcast-range-percentage", String.valueOf(properties.entityBroadcastRangePercentage)); +- json.put("force-gamemode", String.valueOf(properties.forceGameMode)); +- json.put("function-permission-level", String.valueOf(properties.functionPermissionLevel)); +- json.put("gamemode", String.valueOf(properties.gamemode)); +- Optional.ofNullable(properties.worldOptions).ifPresent(worldOptions -> json.put("generate-structures", String.valueOf(worldOptions.generateStructures()))); +- if (includeConfig.generatorSettings) { +- Optional.ofNullable(properties.worldDimensionData).ifPresent(worldDimensionData -> json.put("generator-settings", String.valueOf(worldDimensionData.generatorSettings()))); +- } +- json.put("hardcore", String.valueOf(properties.hardcore)); +- json.put("hide-online-players", String.valueOf(properties.hideOnlinePlayers)); +- if (includeConfig.dataPacks) { +- Optional.ofNullable(properties.initialDataPackConfiguration).ifPresent(initialDataPackConfiguration -> { +- json.put("initial-enabled-packs", String.valueOf(initialDataPackConfiguration.getEnabled())); +- json.put("initial-disabled-packs", String.valueOf(initialDataPackConfiguration.getDisabled())); +- }); +- } +- if (includeConfig.levelName) { +- json.put("level-name", String.valueOf(properties.levelName)); +- } +- // Note: level-seed is never included to prevent it being leaked +-// if (includeConfig.levelSeed) { +-// json.put("level-seed", String.valueOf(properties.levelSeed)); +-// } +- Optional.ofNullable(properties.worldDimensionData).ifPresent(worldDimensionData -> json.put("level-type", String.valueOf(worldDimensionData.levelType()))); +- json.put("max-chained-neighbor-updates", String.valueOf(properties.maxChainedNeighborUpdates)); +- json.put("max-players", String.valueOf(properties.maxPlayers)); +- json.put("max-tick-time", String.valueOf(properties.maxTickTime)); +- json.put("max-world-size", String.valueOf(properties.maxWorldSize)); +- if (includeConfig.motd) { +- json.put("motd", String.valueOf(properties.motd)); +- } +- json.put("network-compression-threshold", String.valueOf(properties.networkCompressionThreshold)); +- json.put("online-mode", String.valueOf(properties.onlineMode)); +- json.put("op-permission-level", String.valueOf(properties.opPermissionLevel)); +- Optional.ofNullable(properties.playerIdleTimeout).ifPresent(playerIdleTimeout -> json.put("player-idle-timeout", String.valueOf(playerIdleTimeout.get()))); +- json.put("prevent-proxy-connections", String.valueOf(properties.preventProxyConnections)); +- json.put("pvp", String.valueOf(properties.pvp)); +- if (includeConfig.queryPort) { +- json.put("query-port", String.valueOf(properties.queryPort)); +- } +- json.put("rate-limit", String.valueOf(properties.rateLimitPacketsPerSecond)); +- // Note: rcon-password is never included to prevent it being leaked +-// if (includeConfig.rconPassword) { +-// json.put("rcon-password", String.valueOf(properties.rconPassword)); +-// } +- if (includeConfig.rconPort) { +- json.put("rcon-port", String.valueOf(properties.queryPort)); +- } +- properties.serverResourcePackInfo.ifPresent(serverResourcePackInfo -> { +- json.put("require-resource-pack", String.valueOf(serverResourcePackInfo.isRequired())); +- if (includeConfig.resourcePackAndResourcePackSha1) { +- json.put("resource-pack", String.valueOf(serverResourcePackInfo.url())); +- json.put("resource-pack-sha1", String.valueOf(serverResourcePackInfo.hash())); +- } +- }); +- if (includeConfig.resourcePackPrompt) { +- json.put("resource-pack-prompt", String.valueOf(properties.resourcePackPrompt)); +- } +- if (includeConfig.serverIp) { +- json.put("server-ip", String.valueOf(properties.serverIp)); +- } +- if (includeConfig.serverPort) { +- json.put("server-port", String.valueOf(properties.serverPort)); +- } +- json.put("simulation-distance", String.valueOf(properties.simulationDistance)); +- json.put("spawn-animals", String.valueOf(properties.spawnAnimals)); +- json.put("spawn-monsters", String.valueOf(properties.spawnMonsters)); +- json.put("spawn-npcs", String.valueOf(properties.spawnNpcs)); +- json.put("spawn-protection", String.valueOf(properties.spawnProtection)); +- json.put("sync-chunk-writes", String.valueOf(properties.syncChunkWrites)); +- if (includeConfig.textFilteringConfig) { +- json.put("text-filtering-config", String.valueOf(properties.textFilteringConfig)); +- } +- json.put("use-native-transport", String.valueOf(properties.useNativeTransport)); +- json.put("view-distance", String.valueOf(properties.viewDistance)); +- Optional.ofNullable(properties.whiteList).ifPresent(whiteList -> json.put("white-list", String.valueOf(whiteList.get()))); +- +- return json; +- +- } +- +-} +diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java +index c89a95801439bb0ab570bc33ded3f270451de9f2..9f1d131f1fc9e827beb050f115c4a9b6cc14f876 100644 +--- a/src/main/java/org/spigotmc/ActivationRange.java ++++ b/src/main/java/org/spigotmc/ActivationRange.java +@@ -35,7 +35,6 @@ import net.minecraft.world.entity.projectile.FireworkRocketEntity; + import net.minecraft.world.entity.projectile.ThrowableProjectile; + import net.minecraft.world.entity.projectile.ThrownTrident; + import net.minecraft.world.entity.raid.Raider; +-import co.aikar.timings.MinecraftTimings; + import net.minecraft.world.entity.schedule.Activity; + import net.minecraft.world.level.Level; + import net.minecraft.world.phys.AABB; +@@ -184,7 +183,6 @@ public class ActivationRange + */ + public static void activateEntities(Level world) + { +- MinecraftTimings.entityActivationCheckTimer.startTiming(); + final int miscActivationRange = world.spigotConfig.miscActivationRange; + final int raiderActivationRange = world.spigotConfig.raiderActivationRange; + final int animalActivationRange = world.spigotConfig.animalActivationRange; +@@ -259,7 +257,6 @@ public class ActivationRange + } + // Paper end + } +- MinecraftTimings.entityActivationCheckTimer.stopTiming(); + } + + /** diff --git a/patches/server/0010-Purpur-Configurable-server-mod-name.patch b/patches/server/0011-Purpur-Configurable-server-mod-name.patch similarity index 94% rename from patches/server/0010-Purpur-Configurable-server-mod-name.patch rename to patches/server/0011-Purpur-Configurable-server-mod-name.patch index c04792de..b8274b79 100644 --- a/patches/server/0010-Purpur-Configurable-server-mod-name.patch +++ b/patches/server/0011-Purpur-Configurable-server-mod-name.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Purpur: Configurable server mod name diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 3328eb0715dab1786a677029bf6356d9118059b9..d9d92e74b101b2a4276b419ad9dcbdc361cb6860 100644 +index d6f41a95d1fe6891cbfdb6e3c7fc7872e2effbbb..bae93e3bbe3067250f08b4c8fad160f9bdf6f6d3 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1683,7 +1683,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 1.18.x update by Mojang. By removing this check, it enable hackers to use some modules of hack clients. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index b959abd801fa2d0646375a388f1d9053fff88f29..823ad91c82d96477655d9f895483a3dd07f30e84 100644 +index 40f32af1976323fd5ffe9aef0725025284daffb3..97958536a31f4a5f3b1935f5afeb9c81ecfa458b 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2101,7 +2101,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic diff --git a/patches/server/0015-KTP-Optimize-spigot-event-bus.patch b/patches/server/0016-KTP-Optimize-spigot-event-bus.patch similarity index 93% rename from patches/server/0015-KTP-Optimize-spigot-event-bus.patch rename to patches/server/0016-KTP-Optimize-spigot-event-bus.patch index d0299650..bbab50d7 100644 --- a/patches/server/0015-KTP-Optimize-spigot-event-bus.patch +++ b/patches/server/0016-KTP-Optimize-spigot-event-bus.patch @@ -12,10 +12,10 @@ events to be published by the server without impacting the overall performance too much. diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -index 7ce9ebba8ce304d1f3f21d4f15ee5f3560d7700b..760535e1d6335cf07b6222525610a11318d2596f 100644 +index a1c9726d25479b5326fe2fa2b0f5a98d6b2da4c5..06dfd0b27ac0006a2be07f54a0702519a691c6ec 100644 --- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -@@ -36,11 +36,17 @@ class PaperEventManager { +@@ -35,11 +35,17 @@ class PaperEventManager { // SimplePluginManager public void callEvent(@NotNull Event event) { diff --git a/patches/server/0016-KeYi-Player-Skull-API.patch b/patches/server/0017-KeYi-Player-Skull-API.patch similarity index 100% rename from patches/server/0016-KeYi-Player-Skull-API.patch rename to patches/server/0017-KeYi-Player-Skull-API.patch diff --git a/patches/server/0017-KeYi-Disable-arrow-despawn-counter-by-default.patch b/patches/server/0018-KeYi-Disable-arrow-despawn-counter-by-default.patch similarity index 100% rename from patches/server/0017-KeYi-Disable-arrow-despawn-counter-by-default.patch rename to patches/server/0018-KeYi-Disable-arrow-despawn-counter-by-default.patch diff --git a/patches/server/0018-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch b/patches/server/0019-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch similarity index 96% rename from patches/server/0018-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch rename to patches/server/0019-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch index 21b2327c..ef13595c 100644 --- a/patches/server/0018-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch +++ b/patches/server/0019-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch @@ -7,7 +7,7 @@ Original license: MIT Original project: https://github.com/KeYiMC/KeYi diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index 30295f15b7f7f95058878231529102f91203ba58..e038813da06c3e22266f3607bb107fda6e220499 100644 +index 3ff5c2a4a2cca5c9a89ceafd9fddeb1012344433..90ab4610026b23ac84e6c941c6581d13fe3565a2 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -331,7 +331,7 @@ public class ItemEntity extends Entity implements TraceableEntity { diff --git a/patches/server/0019-Carpet-Fixes-Optimized-getBiome-method.patch b/patches/server/0020-Carpet-Fixes-Optimized-getBiome-method.patch similarity index 100% rename from patches/server/0019-Carpet-Fixes-Optimized-getBiome-method.patch rename to patches/server/0020-Carpet-Fixes-Optimized-getBiome-method.patch diff --git a/patches/server/0020-Carpet-Fixes-Use-optimized-RecipeManager.patch b/patches/server/0021-Carpet-Fixes-Use-optimized-RecipeManager.patch similarity index 100% rename from patches/server/0020-Carpet-Fixes-Use-optimized-RecipeManager.patch rename to patches/server/0021-Carpet-Fixes-Use-optimized-RecipeManager.patch diff --git a/patches/server/0021-Akarin-Save-Json-list-asynchronously.patch b/patches/server/0022-Akarin-Save-Json-list-asynchronously.patch similarity index 100% rename from patches/server/0021-Akarin-Save-Json-list-asynchronously.patch rename to patches/server/0022-Akarin-Save-Json-list-asynchronously.patch diff --git a/patches/server/0022-Slice-Smooth-Teleports.patch b/patches/server/0023-Slice-Smooth-Teleports.patch similarity index 96% rename from patches/server/0022-Slice-Smooth-Teleports.patch rename to patches/server/0023-Slice-Smooth-Teleports.patch index 0ea3dffb..2b97acd4 100644 --- a/patches/server/0022-Slice-Smooth-Teleports.patch +++ b/patches/server/0023-Slice-Smooth-Teleports.patch @@ -19,10 +19,10 @@ index 54807be5d539fd768f9cb7a8ce912983ae328b46..26f904d5c63bd25d7aac3ab667ec4590 private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 3f60073c5ced65abf67f6fe175f9032c7bf49cfa..ba45ab1a76c9f98b134d0bd9798fa9a9830dbdac 100644 +index e3d1e030063a8746dbdaea14c6de7d900bc1ad0f..ec1dd7c0046ac9091d5b6b2cd703237883b3841f 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -953,12 +953,12 @@ public abstract class PlayerList { +@@ -952,12 +952,12 @@ public abstract class PlayerList { int i = flag ? 1 : 0; // CraftBukkit start LevelData worlddata = worldserver1.getLevelData(); diff --git a/patches/server/0023-Parchment-Make-FixLight-use-action-bar.patch b/patches/server/0024-Parchment-Make-FixLight-use-action-bar.patch similarity index 100% rename from patches/server/0023-Parchment-Make-FixLight-use-action-bar.patch rename to patches/server/0024-Parchment-Make-FixLight-use-action-bar.patch diff --git a/patches/server/0024-Leaves-Server-Utils.patch b/patches/server/0025-Leaves-Server-Utils.patch similarity index 100% rename from patches/server/0024-Leaves-Server-Utils.patch rename to patches/server/0025-Leaves-Server-Utils.patch diff --git a/patches/server/0025-Leaves-Jade-Protocol.patch b/patches/server/0026-Leaves-Jade-Protocol.patch similarity index 98% rename from patches/server/0025-Leaves-Jade-Protocol.patch rename to patches/server/0026-Leaves-Jade-Protocol.patch index 0afd1982..a9a66dea 100644 --- a/patches/server/0025-Leaves-Jade-Protocol.patch +++ b/patches/server/0026-Leaves-Jade-Protocol.patch @@ -9,7 +9,7 @@ Original project: https://github.com/LeavesMC/Leaves This patch is Powered by Jade(https://github.com/Snownee/Jade) diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 823ad91c82d96477655d9f895483a3dd07f30e84..577bcfdb715c116146c6e182073864b71b693385 100644 +index 97958536a31f4a5f3b1935f5afeb9c81ecfa458b..223bb1f3e48cc073ef239a154966cab4e0b71059 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -250,6 +250,7 @@ import org.bukkit.inventory.CraftingInventory; @@ -20,7 +20,7 @@ index 823ad91c82d96477655d9f895483a3dd07f30e84..577bcfdb715c116146c6e182073864b7 // CraftBukkit end public class ServerGamePacketListenerImpl implements ServerPlayerConnection, TickablePacketListener, ServerGamePacketListener { -@@ -3775,6 +3776,9 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -3771,6 +3772,9 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic } // Paper end this.cserver.getMessenger().dispatchIncomingMessage(this.player.getBukkitEntity(), packet.identifier.toString(), data); @@ -31,10 +31,10 @@ index 823ad91c82d96477655d9f895483a3dd07f30e84..577bcfdb715c116146c6e182073864b7 ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex); this.disconnect("Invalid custom payload!", org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index ba45ab1a76c9f98b134d0bd9798fa9a9830dbdac..848baa457daaf3ffbbcad46b1a7fe69eae347fea 100644 +index ec1dd7c0046ac9091d5b6b2cd703237883b3841f..ffc24a510d5557a31e9bea7bd51ee9ccb58ba633 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -358,6 +358,8 @@ public abstract class PlayerList { +@@ -357,6 +357,8 @@ public abstract class PlayerList { player.didPlayerJoinEvent = true; // Gale - EMC - do not process chat/commands before player has joined @@ -57,10 +57,10 @@ index e91b4d63d42276f8a498cab7c439c785730f3f6f..a2d7c5008c6d6716d9530e00de0db027 } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 40ce72ac4ca4f262ad77cf5ba47b8f2c8d9055d2..de1d2c270dc454b959694af03bb85b6e6616e336 100644 +index b656114a0c2594c553e60b8a923a8a99c3b682c2..9de1ba2ae71c65ad3262d445a89c1620d84d860c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -484,6 +484,7 @@ public final class CraftServer implements Server { +@@ -483,6 +483,7 @@ public final class CraftServer implements Server { MapPalette.setMapColorCache(new CraftMapColorCache(this.logger)); } datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper @@ -68,7 +68,7 @@ index 40ce72ac4ca4f262ad77cf5ba47b8f2c8d9055d2..de1d2c270dc454b959694af03bb85b6e } public boolean getCommandBlockOverride(String command) { -@@ -1077,6 +1078,11 @@ public final class CraftServer implements Server { +@@ -1076,6 +1077,11 @@ public final class CraftServer implements Server { this.console.paperConfigurations.reloadConfigs(this.console); this.console.galeConfigurations.reloadConfigs(this.console); // Gale - Gale configuration org.purpurmc.purpur.PurpurConfig.init((File) console.options.valueOf("purpur-settings")); // Purpur diff --git a/patches/server/0026-Leaves-Appleskin-Protocol.patch b/patches/server/0027-Leaves-Appleskin-Protocol.patch similarity index 93% rename from patches/server/0026-Leaves-Appleskin-Protocol.patch rename to patches/server/0027-Leaves-Appleskin-Protocol.patch index 6987c039..ddfb5f85 100644 --- a/patches/server/0026-Leaves-Appleskin-Protocol.patch +++ b/patches/server/0027-Leaves-Appleskin-Protocol.patch @@ -7,23 +7,22 @@ Original license: GPLv3 Original project: https://github.com/LeavesMC/Leaves diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index d9d92e74b101b2a4276b419ad9dcbdc361cb6860..312ba9705533f5790a95ed484d32ca46e9377887 100644 +index bae93e3bbe3067250f08b4c8fad160f9bdf6f6d3..b007d9fb7beb350424c14d5b1ac05050e9d92cef 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1591,6 +1591,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop unloadQueue; int viewDistance; public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobDistanceMap; // Paper @@ -26,7 +26,7 @@ index f192057ee342b9f09cc4ead1e605e1677b944ecd..1beec3d5b9c00c025cb65d8c79f5d028 // Paper - rewrite chunk system // Paper start - optimise checkDespawn -@@ -1444,7 +1442,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1424,7 +1422,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider final Entity entity; private final int range; SectionPos lastSectionPos; @@ -36,7 +36,7 @@ index f192057ee342b9f09cc4ead1e605e1677b944ecd..1beec3d5b9c00c025cb65d8c79f5d028 public TrackedEntity(Entity entity, int i, int j, boolean flag) { this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index cb7f88e37b6bd3a0a78f80ef6062e65818ab180c..fd047a0d3eabf9c57583d5780194fe57b2ab7394 100644 +index 30b243ca777a5b362b50dd4ad1ea22545c038162..10a1c2ccf7cf74dc052eb9a8abf41225a69d5bc0 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -10,6 +10,7 @@ import java.util.Arrays; @@ -55,9 +55,9 @@ index cb7f88e37b6bd3a0a78f80ef6062e65818ab180c..fd047a0d3eabf9c57583d5780194fe57 public class ServerChunkCache extends ChunkSource { -@@ -652,7 +652,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -631,7 +631,7 @@ public class ServerChunkCache extends ChunkSource { + } // Paper start - use set of chunks requiring updates, rather than iterating every single one loaded - this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) { - ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone(); + List copy = new ArrayList<>(this.chunkMap.needsChangeBroadcasting); // Leaf diff --git a/patches/server/0034-Cache-minecart-vehicle-collide-results.patch b/patches/server/0035-Cache-minecart-vehicle-collide-results.patch similarity index 100% rename from patches/server/0034-Cache-minecart-vehicle-collide-results.patch rename to patches/server/0035-Cache-minecart-vehicle-collide-results.patch diff --git a/patches/server/0035-Reduce-canSee-work.patch b/patches/server/0036-Reduce-canSee-work.patch similarity index 93% rename from patches/server/0035-Reduce-canSee-work.patch rename to patches/server/0036-Reduce-canSee-work.patch index 44294c79..3f6b21c1 100644 --- a/patches/server/0035-Reduce-canSee-work.patch +++ b/patches/server/0036-Reduce-canSee-work.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Reduce canSee work Credit by: Martijn Muijsers , MachineBreaker diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index a3ce11801710a1f87afeab5eafcced8ca98d2b31..98db0ab64f4d3ce89462c0038d52c781cf70cfad 100644 +index 7f7d5b9ac42bd510e29834d1df7f49d5659fbfa2..97c7e9c8dc2dc3860de4e697ecd2c1179ef6fd56 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -444,11 +444,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -442,11 +442,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { for (int i = 0, len = entities.size(); i < len; ++i) { Entity entity = entities.get(i); @@ -22,7 +22,7 @@ index a3ce11801710a1f87afeab5eafcced8ca98d2b31..98db0ab64f4d3ce89462c0038d52c781 // !entity1.dead && entity1.i && (entity == null || !entity1.x(entity)); // elide the last check since vanilla calls with entity = null // only we care about the source for the canSee check -@@ -456,6 +452,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -454,6 +450,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { continue; } diff --git a/patches/server/0036-Faster-Natural-Spawning.patch b/patches/server/0037-Faster-Natural-Spawning.patch similarity index 95% rename from patches/server/0036-Faster-Natural-Spawning.patch rename to patches/server/0037-Faster-Natural-Spawning.patch index 8c1afb0a..afc39fb1 100644 --- a/patches/server/0036-Faster-Natural-Spawning.patch +++ b/patches/server/0037-Faster-Natural-Spawning.patch @@ -22,7 +22,7 @@ index ff1ad1024419182f7f3de578442c1c033d4c9ebb..5e51a1c79811291a740ad4d5e79a7d67 @Deprecated static RandomSource createThreadSafe() { diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 98db0ab64f4d3ce89462c0038d52c781cf70cfad..f3224f9393cb644ed6504fe9d8854979597368f8 100644 +index 97c7e9c8dc2dc3860de4e697ecd2c1179ef6fd56..4a6528cbc2810032cce96bf7228e9075def0c18d 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -125,6 +125,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -34,10 +34,10 @@ index 98db0ab64f4d3ce89462c0038d52c781cf70cfad..f3224f9393cb644ed6504fe9d8854979 @Deprecated private final RandomSource threadSafeRandom = RandomSource.createThreadSafe(); diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index cc41a921d3d3b07267317ac75f7aba33c39562a4..b61a36b478aea2de53e1fb1f00f34662511a87a1 100644 +index 8126bd60d5075e344df77add0a38f73c53b3bdd1..6fb5da6f8def49c80a56b4ad583bf54801cd378d 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -432,11 +432,13 @@ public final class NaturalSpawner { +@@ -429,11 +429,13 @@ public final class NaturalSpawner { private static BlockPos getRandomPosWithin(ServerLevel world, LevelChunk chunk) { // Gale - Airplane - Use ThreadUnsafeRandom for mob spawning - accept ServerLevel ChunkPos chunkcoordintpair = chunk.getPos(); // Gale start - Airplane - Use ThreadUnsafeRandom for mob spawning - use ThreadUnsafeRandom