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 d8dfaf5041ccf3f360e0bd94bf03580a8b3d9a38..0000000000000000000000000000000000000000 --- a/src/main/java/co/aikar/timings/FullServerTickHandler.java +++ /dev/null @@ -1,87 +0,0 @@ -package co.aikar.timings; - -import static co.aikar.timings.TimingsManager.*; - -import org.bukkit.Bukkit; -import org.jetbrains.annotations.NotNull; - -/** - * @deprecated Timings will be removed in the future - */ -@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 42e7e712403676171d34d5f2be27e48e7a071ebd..0000000000000000000000000000000000000000 --- a/src/main/java/co/aikar/timings/NullTimingHandler.java +++ /dev/null @@ -1,72 +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 Timings will be removed in the future - */ -@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 157617933a772451f6c073d97afaf305769b4d40..0000000000000000000000000000000000000000 --- a/src/main/java/co/aikar/timings/TimedEventExecutor.java +++ /dev/null @@ -1,93 +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 Timings will be removed in the future - */ -@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 4195efcfe044618052bb03dea34a4fb2ca7c44f0..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 be removed 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 c8287776ad585d04fb4fa3290cd73d7097035ea0..0000000000000000000000000000000000000000 --- a/src/main/java/co/aikar/timings/TimingHistory.java +++ /dev/null @@ -1,357 +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.*; - -/** - * Internal. - * - * @deprecated Timings will be removed in the future - */ -@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(), - 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 index 95b7cdf0677ef71e6885fa78aa5c75bb500f5f53..908b610bfdfe911675748211b74b809d9e0af3e5 100644 --- a/src/main/java/co/aikar/timings/Timings.java +++ b/src/main/java/co/aikar/timings/Timings.java @@ -23,303 +23,48 @@ */ 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; +// Leaf start - Remove Timings /** * @deprecated Timings will be removed in the future + * Keep this class for plugin compatibility (detect usage) */ @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; + return false; } - - /** - *

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) { - if (enabled && !warnedAboutDeprecationOnEnable) { - Bukkit.getLogger().severe(PlainTextComponentSerializer.plainText().serialize(deprecationMessage())); - warnedAboutDeprecationOnEnable = true; - } } - public static Component deprecationMessage() { - return Component.text() - .color(TextColor.color(0xffc93a)) - .append(Component.text("[!] The timings profiler is in no-op mode and will be fully removed in a later update.")) - .append(Component.newline()) - .append(Component.text(" We recommend migrating to the spark profiler.")) - .append(Component.newline()) - .append( - Component.text(" For more information please visit: ") - .append( - Component.text() - .content("https://github.com/PaperMC/Paper/discussions/10565") - .clickEvent(ClickEvent.openUrl("https://github.com/PaperMC/Paper/discussions/10565"))) - ) - .build(); + return Component.empty(); } - - /** - *

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; + return false; } - - /** - *

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; + return 0; } - - /** - *

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; + return 0; } - - /** - * 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); } + // Leaf end - Remove Timings } 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 b83e5ff7ada8771fdf27ba9807c77ba6a4ce12da..0000000000000000000000000000000000000000 --- a/src/main/java/co/aikar/timings/TimingsCommand.java +++ /dev/null @@ -1,127 +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 Timings will be removed in the future - */ -@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 (true) { - sender.sendMessage(Timings.deprecationMessage()); - return true; - } - 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 83a70358e9b7d3d9ae76cf130915b3c33d09a793..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 be removed 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 df066d6f8d55afbc0c1897c486d638657a5f8df9..0000000000000000000000000000000000000000 --- a/src/main/java/co/aikar/timings/TimingsReportListener.java +++ /dev/null @@ -1,90 +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 Timings will be removed in the future - */ -@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 232bf09e1a7bc176bfd34b1acb5326a06a92fe79..0000000000000000000000000000000000000000 --- a/src/main/java/co/aikar/util/JSONUtil.java +++ /dev/null @@ -1,138 +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 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/command/Command.java b/src/main/java/org/bukkit/command/Command.java index 27a7c69f23084e821d945d5e97e51a94ddd94e58..d645ee8470a2dd9f7b8eff2b7ff2211aba9c342f 100644 --- a/src/main/java/org/bukkit/command/Command.java +++ b/src/main/java/org/bukkit/command/Command.java @@ -32,16 +32,6 @@ public abstract class Command { protected String usageMessage; private String permission; private net.kyori.adventure.text.Component permissionMessage; // Paper - /** - * @deprecated Timings will be removed in the future - */ - @Deprecated(forRemoval = true) - public co.aikar.timings.Timing timings; // Paper - /** - * @deprecated Timings will be removed in the future - */ - @Deprecated(forRemoval = true) - @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 59fada9b1eb78238d280c6bbb711f52facba52c6..eb4d78c6111a530d015a0b91d14c40ad0eec9ca7 100644 --- a/src/main/java/org/bukkit/command/FormattedCommandAlias.java +++ b/src/main/java/org/bukkit/command/FormattedCommandAlias.java @@ -14,7 +14,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; } @@ -122,10 +121,6 @@ public class FormattedCommandAlias extends Command { return formatString.trim(); // Paper - Causes an extra space at the end, breaks with brig commands } - @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/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java index 613a0bad5c07cf14098218652eba1f4deaf77c6d..25a0414cc9482925ad0426dde57e65012d62e637 100644 --- a/src/main/java/org/bukkit/command/SimpleCommandMap.java +++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java @@ -32,7 +32,6 @@ public class SimpleCommandMap implements CommandMap { private void setDefaultCommands() { register("bukkit", new ReloadCommand("reload")); - register("bukkit", new co.aikar.timings.TimingsCommand("timings")); } public void setFallbackCommands() { @@ -64,7 +63,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(Locale.ROOT).trim(); fallbackPrefix = fallbackPrefix.toLowerCase(Locale.ROOT).trim(); boolean registered = register(label, command, false, fallbackPrefix); @@ -159,23 +157,13 @@ public class SimpleCommandMap implements CommandMap { parsedArgs = event.getArgs(); // Purpur end - ExecuteCommandEvent - // 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, parsedArgs); // Purpur - ExecuteCommandEvent - } // 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 2e6d62c4f3687e299c34e876c503b400e13be05a..e7f1a35610d53891d346a3284cca1bca8e53761d 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -61,7 +61,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; @@ -724,12 +723,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)); - } + getEventListeners(event).register(new RegisteredListener(listener, executor, priority, plugin, ignoreCancelled)); // Leaf - Remove Timings } @NotNull @@ -959,8 +953,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 + return this.paperPluginManager.useTimings(); // Paper // Leaf - Remove Timings } /** @@ -970,7 +963,6 @@ public final class SimplePluginManager implements PluginManager { */ @Deprecated(forRemoval = true) public void useTimings(boolean use) { - co.aikar.timings.Timings.setTimingsEnabled(use); // Paper } // Paper start diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java index ce45dbc7b02c405f1b3460563cf87e7888702ba9..c43ce5b7bed3297cd655a7f2ed4b4717e139bbfd 100644 --- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java @@ -297,7 +297,7 @@ public final class JavaPluginLoader implements PluginLoader { } } - EventExecutor executor = new co.aikar.timings.TimedEventExecutor(new EventExecutor() { // Paper + EventExecutor executor = new EventExecutor() { // Paper // Leaf - Remove Timings @Override public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException { // Paper try { @@ -311,7 +311,7 @@ public final class JavaPluginLoader implements PluginLoader { throw new EventException(t); } } - }, plugin, method, eventClass); // Paper + }; // Paper // Leaf - Remove Timings 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 index 5fbacfcf108432c5187aa9a4092d00d7d5b0fd53..68e2a332e512a4aea45b8fb33a6e34431548d3be 100644 --- a/src/main/java/org/spigotmc/CustomTimingsHandler.java +++ b/src/main/java/org/spigotmc/CustomTimingsHandler.java @@ -23,45 +23,20 @@ */ 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; +// Leaf start - Remove Timings /** - * 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 Timings will be removed in the future + * Keep this class for plugin compatibility (detect usage) */ @Deprecated(forRemoval = true) public final class CustomTimingsHandler { - private final Timing handler; public CustomTimingsHandler(@NotNull String name) { - Timing timing; - - new AuthorNagException("Deprecated use of CustomTimingsHandler. Timings has been removed.").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(); } - + public void startTiming() {} + public void stopTiming() {} + // Leaf end - Remove Timings } diff --git a/src/test/java/org/bukkit/AnnotationTest.java b/src/test/java/org/bukkit/AnnotationTest.java index 37feafd626aaa17aba888d7ff13728b3c6f26d4d..e42619418c1a3e3dac22e7310bb9d64b42b9f6a7 100644 --- a/src/test/java/org/bukkit/AnnotationTest.java +++ b/src/test/java/org/bukkit/AnnotationTest.java @@ -50,15 +50,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