From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Samsuik Date: Sun, 19 Sep 2021 01:10:02 +0100 Subject: [PATCH] Track Tick Information Keeps track of useful information every tick such as the tick rate, entities, chunks and displays them with the tps command. diff --git a/src/main/java/me/samsuik/sakura/command/SakuraCommands.java b/src/main/java/me/samsuik/sakura/command/SakuraCommands.java index cbb2e57f9ab3b48a6e5f792711c4c6fd2d34d445..8e93fc5d7e1bc200f79b0e54edb62dc4d0bf5e74 100644 --- a/src/main/java/me/samsuik/sakura/command/SakuraCommands.java +++ b/src/main/java/me/samsuik/sakura/command/SakuraCommands.java @@ -4,6 +4,7 @@ import me.samsuik.sakura.command.subcommands.ConfigCommand; import me.samsuik.sakura.command.subcommands.FPSCommand; import me.samsuik.sakura.command.subcommands.VisualCommand; import me.samsuik.sakura.player.visibility.VisibilityTypes; +import me.samsuik.sakura.command.subcommands.TPSCommand; import net.minecraft.server.MinecraftServer; import org.bukkit.command.Command; @@ -18,6 +19,7 @@ public final class SakuraCommands { COMMANDS.put("fps", new FPSCommand("fps")); COMMANDS.put("tntvisibility", new VisualCommand(VisibilityTypes.TNT, "tnttoggle")); COMMANDS.put("sandvisibility", new VisualCommand(VisibilityTypes.SAND, "sandtoggle")); + COMMANDS.put("tps", new TPSCommand("tps")); } public static void registerCommands(MinecraftServer server) { diff --git a/src/main/java/me/samsuik/sakura/command/subcommands/TPSCommand.java b/src/main/java/me/samsuik/sakura/command/subcommands/TPSCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..db6d03c1ed1c1d0390826dd3f96e774e2bea8a1a --- /dev/null +++ b/src/main/java/me/samsuik/sakura/command/subcommands/TPSCommand.java @@ -0,0 +1,92 @@ +package me.samsuik.sakura.command.subcommands; + +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableList; +import me.samsuik.sakura.command.BaseSubCommand; +import me.samsuik.sakura.tps.ServerTickInformation; +import me.samsuik.sakura.tps.graph.BuiltComponentCanvas; +import me.samsuik.sakura.tps.graph.DetailedTPSGraph; +import me.samsuik.sakura.tps.graph.GraphComponents; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextDecoration; +import net.minecraft.server.MinecraftServer; +import org.bukkit.command.CommandSender; +import org.jspecify.annotations.NullMarked; + +@NullMarked +public final class TPSCommand extends BaseSubCommand { + private static final int GRAPH_WIDTH = 71; + private static final int GRAPH_HEIGHT = 10; + private static final Style GRAY_WITH_STRIKETHROUGH = Style.style(NamedTextColor.GRAY, TextDecoration.STRIKETHROUGH); + + public TPSCommand(String name) { + super(name); + this.description = "Displays the current ticks per second"; + } + + @Override + public void execute(CommandSender sender, String[] args) { + ServerTickInformation tickInformation = MinecraftServer.getServer().latestTickInformation(); + long identifier = this.parseLong(args, 1).orElse(tickInformation.identifier()); + double scale = this.parseDouble(args, 0).orElse(-1.0); + if (scale < 0.0) { + scale = this.dynamicScale(identifier); + } + + ImmutableList tickHistory = MinecraftServer.getServer().tickHistory(identifier - GRAPH_WIDTH, identifier); + DetailedTPSGraph graph = new DetailedTPSGraph(GRAPH_WIDTH, GRAPH_HEIGHT, scale, tickHistory); + BuiltComponentCanvas canvas = graph.plot(); + canvas.appendLeft(Component.text(":", NamedTextColor.BLACK)); + canvas.appendRight(Component.text(":", NamedTextColor.BLACK)); + canvas.header(this.createHeaderComponent(tickInformation, identifier)); + canvas.footer(Component.text("*", NamedTextColor.DARK_GRAY) + .append(Component.text(Strings.repeat(" ", GRAPH_WIDTH - 1), GRAY_WITH_STRIKETHROUGH)) + .append(Component.text("*"))); + + for (Component component : canvas.components()) { + sender.sendMessage(component); + } + } + + private double dynamicScale(long identifier) { + ImmutableList tickHistory = MinecraftServer.getServer().tickHistory(identifier - 5, identifier); + double averageTps = tickHistory.stream() + .mapToDouble(ServerTickInformation::tps) + .average() + .orElse(0.0); + return 20 / averageTps; + } + + private Component createHeaderComponent(ServerTickInformation tickInformation, long identifier) { + int scrollAmount = GRAPH_WIDTH / 3 * 2; + double memoryUsage = memoryUsage(); + TextComponent.Builder builder = Component.text(); + builder.color(NamedTextColor.DARK_GRAY); + builder.append(Component.text("< ") + .clickEvent(ClickEvent.runCommand("/tps -1 " + (identifier + scrollAmount)))); + builder.append(Component.text(Strings.repeat(" ", 19), GRAY_WITH_STRIKETHROUGH)); + builder.append(Component.text(" ( ")); + builder.append(Component.text("Now: ", NamedTextColor.WHITE) + .append(Component.text("%.1f".formatted(tickInformation.tps()), tickInformation.colour()))); + builder.appendSpace(); + builder.append(Component.text("Mem: ", NamedTextColor.WHITE) + .append(Component.text("%.1f".formatted(memoryUsage * 100), GraphComponents.colour(1 - (float) memoryUsage)))); + builder.append(Component.text("% ) ")); + builder.append(Component.text(Strings.repeat(" ", 18), GRAY_WITH_STRIKETHROUGH)); + builder.append(Component.text(" >") + .clickEvent(ClickEvent.runCommand("/tps -1 " + (identifier - scrollAmount)))); + return builder.build(); + } + + private static double memoryUsage() { + Runtime runtime = Runtime.getRuntime(); + double free = runtime.freeMemory(); + double max = runtime.maxMemory(); + double alloc = runtime.totalMemory(); + return (alloc - free) / max; + } +} diff --git a/src/main/java/me/samsuik/sakura/tps/ServerTickInformation.java b/src/main/java/me/samsuik/sakura/tps/ServerTickInformation.java new file mode 100644 index 0000000000000000000000000000000000000000..9a65a3dac75834a2fe10d2c6d6ae594ceb208fef --- /dev/null +++ b/src/main/java/me/samsuik/sakura/tps/ServerTickInformation.java @@ -0,0 +1,37 @@ +package me.samsuik.sakura.tps; + +import me.samsuik.sakura.configuration.GlobalConfiguration; +import me.samsuik.sakura.tps.graph.GraphComponents; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.format.TextColor; +import net.minecraft.server.MinecraftServer; +import org.jspecify.annotations.NullMarked; + +@NullMarked +public record ServerTickInformation(long identifier, double tps, double averageTick, long longestTick, float targetTickRate, int chunks, int entities) { + public static final ServerTickInformation FILLER = new ServerTickInformation(0, 0.0, 0.0, 0, 0.0f, 0, 0); + + public TextColor colour() { + float lag = (float) this.tps / this.targetTickRate; + return GraphComponents.colour(lag); + } + + public Component hoverComponent(TextColor colour) { + TextComponent.Builder builder = Component.text(); + builder.append(Component.text("TPS: ") + .append(Component.text("%.1f".formatted(this.tps), colour))); + builder.appendNewline(); + builder.append(Component.text("MSPT: ") + .append(Component.text("%.1f".formatted(this.averageTick), colour)) + .append(Component.text("/")) + .append(Component.text(this.longestTick, colour))); + if (GlobalConfiguration.get().messages.tpsShowEntityAndChunkCount) { + builder.appendNewline(); + builder.append(Component.text("Entities: " + this.entities)); + builder.appendNewline(); + builder.append(Component.text("Chunks: " + this.chunks)); + } + return builder.build(); + } +} diff --git a/src/main/java/me/samsuik/sakura/tps/TickInformationCollector.java b/src/main/java/me/samsuik/sakura/tps/TickInformationCollector.java new file mode 100644 index 0000000000000000000000000000000000000000..5f88e17db0cf8eca161d98cc8cdac8383903e694 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/tps/TickInformationCollector.java @@ -0,0 +1,71 @@ +package me.samsuik.sakura.tps; + +import com.google.common.collect.ImmutableList; +import it.unimi.dsi.fastutil.longs.LongArrayList; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import org.jspecify.annotations.NullMarked; + +import java.util.Collection; +import java.util.List; + +@NullMarked +public final class TickInformationCollector { + private static final int TEN_MINUTES = 10 * 60; + private final ObjectArrayList collectedInformation = new ObjectArrayList<>(); + private final LongArrayList tickSamples = new LongArrayList(); + private long identifier = 0; + + public ServerTickInformation latestTickInformation() { + return this.collectedInformation.getLast(); + } + + public void levelData(Collection levels, double tps) { + int chunks = 0; + int entities = 0; + for (ServerLevel level : levels) { + chunks += level.chunkSource.getFullChunksCount(); + entities += level.entityTickList.entities.size(); + } + + double averageTick = this.tickSamples.longStream() + .average() + .orElse(0.0); + long longestTick = this.tickSamples.longStream() + .max() + .orElse(0); + float targetTickRate = MinecraftServer.getServer().tickRateManager().tickrate(); + + ServerTickInformation tickInformation = new ServerTickInformation( + this.identifier++, tps, averageTick, longestTick, targetTickRate, chunks, entities + ); + + this.collectedInformation.add(tickInformation); + this.tickSamples.clear(); + + if (this.collectedInformation.size() > TEN_MINUTES) { + this.collectedInformation.subList(0, 60).clear(); + } + } + + public void tickDuration(long timeTaken) { + this.tickSamples.add(timeTaken); + } + + public ImmutableList collect(long from, long to) { + List collected = new ObjectArrayList<>(); + for (ServerTickInformation tickInformation : this.collectedInformation.reversed()) { + if (tickInformation.identifier() >= from && tickInformation.identifier() < to) { + collected.add(tickInformation); + } + } + long ahead = to - this.identifier; + long missing = to - from - collected.size(); + for (int i = 0; i < missing; ++i) { + int ind = (i < ahead) ? 0 : collected.size(); + collected.add(ind, ServerTickInformation.FILLER); + } + return ImmutableList.copyOf(collected); + } +} diff --git a/src/main/java/me/samsuik/sakura/tps/graph/BuiltComponentCanvas.java b/src/main/java/me/samsuik/sakura/tps/graph/BuiltComponentCanvas.java new file mode 100644 index 0000000000000000000000000000000000000000..bf3e953c99825274b800d19c74019c904620ec74 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/tps/graph/BuiltComponentCanvas.java @@ -0,0 +1,36 @@ +package me.samsuik.sakura.tps.graph; + +import com.google.common.collect.ImmutableList; +import net.kyori.adventure.text.Component; +import org.jspecify.annotations.NullMarked; + +import java.util.List; + +@NullMarked +public final class BuiltComponentCanvas { + private final List components; + + BuiltComponentCanvas(List components) { + this.components = components; + } + + public void appendLeft(Component component) { + this.components.replaceAll(component::append); + } + + public void appendRight(Component component) { + this.components.replaceAll(row -> row.append(component)); + } + + public void header(Component component) { + this.components.addFirst(component); + } + + public void footer(Component component) { + this.components.add(component); + } + + public ImmutableList components() { + return ImmutableList.copyOf(this.components); + } +} diff --git a/src/main/java/me/samsuik/sakura/tps/graph/ComponentCanvas.java b/src/main/java/me/samsuik/sakura/tps/graph/ComponentCanvas.java new file mode 100644 index 0000000000000000000000000000000000000000..42024655f1b1cad12ba1db66086bb978c5ee8f02 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/tps/graph/ComponentCanvas.java @@ -0,0 +1,63 @@ +package me.samsuik.sakura.tps.graph; + +import com.google.common.base.Preconditions; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.JoinConfiguration; +import org.jspecify.annotations.NullMarked; + +import java.util.List; + +@NullMarked +public final class ComponentCanvas { + private final int width; + private final int height; + private final Component[][] components; + + public ComponentCanvas(int width, int height) { + this.width = width; + this.height = height; + // [x, y] is flipped as it makes converting the components into a list easier + this.components = new Component[height][width]; + } + + public void flip() { + for (int y = 0; y < this.height; ++y) { + if (y >= this.height / 2) { + Component[] row = this.components[y]; + int relocatingRow = this.height - 1 - y; + this.components[y] = this.components[relocatingRow]; + this.components[relocatingRow] = row; + } + } + } + + public void fill(Component component) { + for (int x = 0; x < this.width; ++x) { + for (int y = 0; y < this.height; ++y) { + this.set(x, y, component); + } + } + } + + public Component get(int x, int y) { + Component component = this.components[y][x]; + return Preconditions.checkNotNull(component, "missing component at x:{} y:{}", x, y); + } + + public void set(int x, int y, Component component) { + this.components[y][x] = component; + } + + public BuiltComponentCanvas build() { + return new BuiltComponentCanvas(this.joinComponents()); + } + + private List joinComponents() { + List componentList = new ObjectArrayList<>(this.height); + for (Component[] row : this.components) { + componentList.add(Component.join(JoinConfiguration.noSeparators(), row)); + } + return componentList; + } +} diff --git a/src/main/java/me/samsuik/sakura/tps/graph/DetailedTPSGraph.java b/src/main/java/me/samsuik/sakura/tps/graph/DetailedTPSGraph.java new file mode 100644 index 0000000000000000000000000000000000000000..bebc61d33a5cbb6a46c7f5ac0a9b453e0ab48655 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/tps/graph/DetailedTPSGraph.java @@ -0,0 +1,102 @@ +package me.samsuik.sakura.tps.graph; + +import me.samsuik.sakura.tps.ServerTickInformation; +import org.jspecify.annotations.NullMarked; + +import java.util.List; + +@NullMarked +public final class DetailedTPSGraph extends TPSGraph { + public DetailedTPSGraph(int width, int height, double scale, List tickInformation) { + super(width, height, scale, tickInformation); + } + + @Override + public BuiltComponentCanvas plot() { + ComponentCanvas canvas = new ComponentCanvas(this.width, this.height); + canvas.fill(GraphComponents.BACKGROUND); + + this.basicOutline(canvas); + this.prettifyOutline(canvas); + this.addColourAndHoverInformation(canvas); + + canvas.flip(); + return canvas.build(); + } + + private void basicOutline(ComponentCanvas canvas) { + for (int x = 0; x < this.width; ++x) { + int row = this.rowFromColumn(x); + int nextRow = this.rowFromColumn(x + 1); + int minRow = Math.min(row, nextRow); + int maxRow = Math.max(row, nextRow); + + if (maxRow - minRow >= 2) { + canvas.set(x, minRow, GraphComponents.TOP_DOTTED_LINE); + canvas.set(x, maxRow, GraphComponents.BOTTOM_DOTTED_LINE); + + for (int y = minRow + 1; y < maxRow; ++y) { + canvas.set(x, y, GraphComponents.VERTICAL_LINE); + } + } else { + canvas.set(x, row, GraphComponents.HORIZONTAL_LINE); + } + } + } + + private void prettifyOutline(ComponentCanvas canvas) { + for (int x = 0; x < this.width; ++x) { + int row = this.rowFromColumn(x); + int nextRow = this.rowFromColumn(x + 1); + int prevRow = this.rowFromColumn(x - 1); + int minRow = Math.min(row, nextRow); + int maxRow = Math.max(row, nextRow); + + if (maxRow - minRow >= 2) { + this.prettifyVerticalOutline(canvas, x, row, nextRow, prevRow, minRow, maxRow); + } else { + this.prettifySlopes(canvas, x, row, nextRow, prevRow); + } + } + } + + private void prettifyVerticalOutline(ComponentCanvas canvas, int x, int row, int nextRow, int prevRow, int minRow, int maxRow) { + if (minRow == nextRow) { + canvas.set(x, minRow, GraphComponents.CONE_BOTTOM_LEFT); + } else if (prevRow <= minRow) { + canvas.set(x, minRow, GraphComponents.CONE_BOTTOM_RIGHT); + } + if (prevRow == row + 1 && nextRow < row) { + canvas.set(x, maxRow, GraphComponents.CONE_TOP_RIGHT); + } + if (maxRow == row && Math.abs(nextRow - maxRow) > 1 && Math.abs(prevRow - maxRow) > 1 && prevRow < maxRow) { + canvas.set(x - 1, maxRow, GraphComponents.CONE_TOP_LEFT); + canvas.set(x, maxRow, GraphComponents.CONE_TOP_RIGHT); + } + if (minRow == row && Math.abs(nextRow - minRow) > 1 && Math.abs(prevRow - minRow) > 1 && prevRow > minRow) { + canvas.set(x - 1, minRow, GraphComponents.CONE_BOTTOM_LEFT); + canvas.set(x, minRow, GraphComponents.CONE_BOTTOM_RIGHT); + } + } + + private void prettifySlopes(ComponentCanvas canvas, int x, int row, int nextRow, int prevRow) { + int slopeDirection = nextRow - prevRow; + int slopeChange = Math.abs(slopeDirection); + + if (slopeChange >= 2 && Math.max(nextRow, prevRow) == row + 1) { + canvas.set(x, row, slopeDirection < 0 ? GraphComponents.TL_TO_BR : GraphComponents.BL_TO_TR); + } else if (Math.abs(row - nextRow) == 1 || slopeDirection == 0) { + if (row < nextRow) { + canvas.set(x, row, GraphComponents.TOP_DOTTED_LINE); + } else if (row > nextRow) { + canvas.set(x, row, GraphComponents.BOTTOM_DOTTED_LINE); + } + } else if (Math.abs(row - prevRow) == 1) { + if (prevRow > row) { + canvas.set(x, row, GraphComponents.TOP_DOTTED_LINE); + } else if (prevRow < row) { + canvas.set(x, row, GraphComponents.BOTTOM_DOTTED_LINE); + } + } + } +} diff --git a/src/main/java/me/samsuik/sakura/tps/graph/GraphComponents.java b/src/main/java/me/samsuik/sakura/tps/graph/GraphComponents.java new file mode 100644 index 0000000000000000000000000000000000000000..95d3c8031e4708d2d0a0a12213060acd9ab65522 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/tps/graph/GraphComponents.java @@ -0,0 +1,42 @@ +package me.samsuik.sakura.tps.graph; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; + +import java.util.List; + +public final class GraphComponents { + private static final Style STRIKE_THROUGH_STYLE = Style.style(TextDecoration.STRIKETHROUGH); + private static final Style REMOVE_STRIKE_THROUGH_STYLE = Style.style(TextDecoration.STRIKETHROUGH.withState(false)); + + public static final Component BACKGROUND = Component.text("::"); + public static final Component HORIZONTAL_LINE = Component.text(" ", STRIKE_THROUGH_STYLE); + public static final Component VERTICAL_LINE = Component.text("||"); + public static final Component TOP_DOTTED_LINE = Component.text("''"); + public static final Component BOTTOM_DOTTED_LINE = Component.text(".."); + public static final Component BL_TO_TR = Component.text(".", STRIKE_THROUGH_STYLE).append(Component.text("'", REMOVE_STRIKE_THROUGH_STYLE)); + public static final Component TL_TO_BR = Component.text("'").append(Component.text(".", STRIKE_THROUGH_STYLE)); + public static final Component CONE_TOP_LEFT = Component.text(".!"); + public static final Component CONE_TOP_RIGHT = Component.text("!."); + public static final Component CONE_BOTTOM_LEFT = Component.text("'!"); + public static final Component CONE_BOTTOM_RIGHT = Component.text("!'"); + + private static final List COLOURS = List.of( + NamedTextColor.GREEN, NamedTextColor.YELLOW, NamedTextColor.GOLD, + NamedTextColor.RED, NamedTextColor.DARK_GRAY, TextColor.color(40, 40, 40) + ); + + public static TextColor colour(float num) { + float segment = 1.0f / COLOURS.size(); + float a = (1.0f - num) / segment; + float t = a % 1.0f; + int startIndex = Math.clamp((int) a, 0, COLOURS.size() - 2); + int endIndex = startIndex + 1; + TextColor startColour = COLOURS.get(startIndex); + TextColor endColour = COLOURS.get(endIndex); + return TextColor.lerp(t, startColour, endColour); + } +} diff --git a/src/main/java/me/samsuik/sakura/tps/graph/TPSGraph.java b/src/main/java/me/samsuik/sakura/tps/graph/TPSGraph.java new file mode 100644 index 0000000000000000000000000000000000000000..27b6b071ad38589d37e35ea7fdf1d45924079f49 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/tps/graph/TPSGraph.java @@ -0,0 +1,60 @@ +package me.samsuik.sakura.tps.graph; + +import com.google.common.base.Preconditions; +import me.samsuik.sakura.tps.ServerTickInformation; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; +import net.minecraft.util.Mth; +import org.jspecify.annotations.NullMarked; + +import java.util.List; + +@NullMarked +public abstract class TPSGraph { + protected final List tickInformation; + protected final int width; + protected final int height; + protected final double scale; + + public TPSGraph(int width, int height, double scale, List tickInformation) { + Preconditions.checkArgument(tickInformation.size() == width); + this.width = width; + this.height = height; + this.scale = scale; + this.tickInformation = tickInformation; + } + + public abstract BuiltComponentCanvas plot(); + + protected final int rowFromColumn(int x) { + int clamped = Math.clamp(x, 0, this.width - 1); + ServerTickInformation tickInformation = this.tickInformation.get(clamped); + return this.rowFromTPS(tickInformation.tps()); + } + + protected final int rowFromTPS(double tps) { + int row = Mth.floor((tps / 3) * this.scale); + return Mth.clamp(row, 0, this.height - 1); + } + + protected final void addColourAndHoverInformation(ComponentCanvas canvas) { + for (int x = 0; x < this.width; ++x) { + ServerTickInformation tickInformation = this.tickInformation.get(x); + TextColor colourFromTPS = tickInformation.colour(); + Component hoverComponent = tickInformation.hoverComponent(colourFromTPS); + HoverEvent hoverEvent = HoverEvent.showText(hoverComponent); + + for (int y = 0; y < this.height; ++y) { + Component component = canvas.get(x, y); + if (component == GraphComponents.BACKGROUND) { + component = component.color(NamedTextColor.BLACK); + } else { + component = component.color(colourFromTPS); + } + canvas.set(x, y, component.hoverEvent(hoverEvent)); + } + } + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 1d0462b970304f543ff949f7aa32c67a1860ba4f..733541e91b0064d50de6c5c0985e9c472685c20c 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -427,6 +427,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop tickHistory(long from, long to) { + return this.tickInformationCollector.collect(from, to); + } + // Sakura end - track tick information public MinecraftServer(OptionSet options, WorldLoader.DataLoadContext worldLoader, Thread thread, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PackRepository resourcepackrepository, WorldStem worldstem, Proxy proxy, DataFixer datafixer, Services services, ChunkProgressListenerFactory worldloadlistenerfactory) { super("Server"); @@ -1301,6 +1312,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop public // Paper - rewrite chunk system private final GameEventDispatcher gameEventDispatcher; public boolean noSave; diff --git a/src/main/java/net/minecraft/world/level/entity/EntityTickList.java b/src/main/java/net/minecraft/world/level/entity/EntityTickList.java index d8b4196adf955f8d414688dc451caac2d9c609d9..0859aecb141261638b8547fb8854768fb6b6f5c7 100644 --- a/src/main/java/net/minecraft/world/level/entity/EntityTickList.java +++ b/src/main/java/net/minecraft/world/level/entity/EntityTickList.java @@ -9,7 +9,7 @@ import javax.annotation.Nullable; import net.minecraft.world.entity.Entity; public class EntityTickList { - private final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet entities = new ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<>(); // Paper - rewrite chunk system + public final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet entities = new ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<>(); // Sakura - track tick information; expose entity list // Paper - rewrite chunk system private void ensureActiveIsNotIterated() { // Paper - rewrite chunk system diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java index 4dbb109d0526afee99b9190fc256585121aac9b5..019ae7104a644f23495e42510a80573a7ac06a37 100644 --- a/src/main/java/org/spigotmc/SpigotConfig.java +++ b/src/main/java/org/spigotmc/SpigotConfig.java @@ -279,7 +279,7 @@ public class SpigotConfig private static void tpsCommand() { - SpigotConfig.commands.put( "tps", new TicksPerSecondCommand( "tps" ) ); + // SpigotConfig.commands.put( "tps", new TicksPerSecondCommand( "tps" ) ); // Sakura - TPS Graph } public static int playerSample;