9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-19 14:59:32 +00:00
Files
LeavesMC/patches/server/0112-Leaves-tick-command.patch
2023-10-13 16:28:10 +08:00

258 lines
11 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: violetc <58360096+s-yh-china@users.noreply.github.com>
Date: Sun, 13 Aug 2023 17:22:08 +0800
Subject: [PATCH] Leaves tick command
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index fccb76a8dfa6a0c5d704a0a8f7392beedea320c9..781a0fc1988f950ca85c05614fec0a8ecabaeaf7 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -184,6 +184,8 @@ import org.bukkit.craftbukkit.Main;
import org.bukkit.event.server.ServerLoadEvent;
// CraftBukkit end
+import top.leavesmc.leaves.util.TickStatus; // Leaves - tick command
+
public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTask> implements ServerInfo, CommandSource, AutoCloseable {
private static MinecraftServer SERVER; // Paper
@@ -1075,6 +1077,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Spigot End
public static volatile RuntimeException chunkSystemCrash; // Paper - rewrite chunk system
+ public static TickStatus tickStatus = TickStatus.NORMAL; // Leaves - tick command
protected void runServer() {
try {
@@ -1123,21 +1126,24 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.lastOverloadWarning = this.nextTickTime;
}
- ++MinecraftServer.currentTickLong; // Paper
- if ( ++MinecraftServer.currentTick % MinecraftServer.SAMPLE_INTERVAL == 0 )
- {
- final long diff = curTime - tickSection;
- java.math.BigDecimal currentTps = TPS_BASE.divide(new java.math.BigDecimal(diff), 30, java.math.RoundingMode.HALF_UP);
- tps1.add(currentTps, diff);
- tps5.add(currentTps, diff);
- tps15.add(currentTps, diff);
- // Backwards compat with bad plugins
- this.recentTps[0] = tps1.getAverage();
- this.recentTps[1] = tps5.getAverage();
- this.recentTps[2] = tps15.getAverage();
- // Paper end
- tickSection = curTime;
+ // Leaves start - tick command
+ if (tickStatus != TickStatus.FREEZE) {
+ ++MinecraftServer.currentTickLong; // Paper
+ if (++MinecraftServer.currentTick % MinecraftServer.SAMPLE_INTERVAL == 0) {
+ final long diff = curTime - tickSection;
+ java.math.BigDecimal currentTps = TPS_BASE.divide(new java.math.BigDecimal(diff), 30, java.math.RoundingMode.HALF_UP);
+ tps1.add(currentTps, diff);
+ tps5.add(currentTps, diff);
+ tps15.add(currentTps, diff);
+ // Backwards compat with bad plugins
+ this.recentTps[0] = tps1.getAverage();
+ this.recentTps[1] = tps5.getAverage();
+ this.recentTps[2] = tps15.getAverage();
+ // Paper end
+ tickSection = curTime;
+ }
}
+ // Leaves end - tick command
// Spigot end
if (this.debugCommandProfilerDelayStart) {
@@ -1150,11 +1156,23 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.nextTickTime += 50L;
this.startMetricsRecordingTick();
this.profiler.push("tick");
- this.tickServer(this::haveTime);
+ // Leaves start - tick command
+ if (tickStatus == TickStatus.FREEZE) {
+ this.tickFreeze();
+ } else {
+ this.tickServer(this::haveTime);
+ }
+ // Leaves end - tick command
this.profiler.popPush("nextTickWait");
this.mayHaveDelayedTasks = true;
this.delayedTasksMaxNextTickTime = Math.max(Util.getMillis() + 50L, this.nextTickTime);
- this.waitUntilNextTick();
+ // Leaves start - tick command
+ if (tickStatus == TickStatus.WARP) {
+ this.nextTickTime = Util.getMillis();
+ } else {
+ this.waitUntilNextTick();
+ }
+ // Leaves end - tick command
this.profiler.pop();
this.endMetricsRecordingTick();
this.isReady = true;
@@ -1211,6 +1229,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
+ // Leaves start - tick command - freeze
+ private void tickFreeze() {
+ this.getConnection().tick();
+ this.runAllTasks();
+ while (!this.processQueue.isEmpty()) {
+ this.processQueue.remove().run();
+ }
+ org.spigotmc.WatchdogThread.tick();
+ }
+ // Leaves end - tick command - freeze
+
private static CrashReport constructOrExtractCrashReport(Throwable throwable) {
ReportedException reportedexception = null;
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 0ab5a5622b2687a6f5da2ac4d4457878a0b439fb..1e54816b487922d380941aa5f5d0e35ec91ec014 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -2734,7 +2734,7 @@ public class ServerPlayer extends Player {
}
public boolean allowOperation() {
- return (instaBreakCountPerTick == 0 || placeBlockCountPerTick == 0) && (instaBreakCountPerTick <= 1 && placeBlockCountPerTick <= 2);
+ return MinecraftServer.tickStatus == top.leavesmc.leaves.util.TickStatus.FREEZE || (instaBreakCountPerTick == 0 || placeBlockCountPerTick == 0) && (instaBreakCountPerTick <= 1 && placeBlockCountPerTick <= 2); // Leaves - tick command
}
// Leaves end - player operation limiter
// CraftBukkit end
diff --git a/src/main/java/top/leavesmc/leaves/command/LeavesCommand.java b/src/main/java/top/leavesmc/leaves/command/LeavesCommand.java
index da1f7ce2db23c509c70f673c8bb1c46af2ed7279..0259a1472bba36b5bb903e559a99f791e8a9317a 100644
--- a/src/main/java/top/leavesmc/leaves/command/LeavesCommand.java
+++ b/src/main/java/top/leavesmc/leaves/command/LeavesCommand.java
@@ -13,6 +13,7 @@ import org.bukkit.plugin.PluginManager;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jetbrains.annotations.NotNull;
import top.leavesmc.leaves.command.subcommands.PeacefulModeSwitchCommand;
+import top.leavesmc.leaves.command.subcommands.TickCommand;
import top.leavesmc.leaves.command.subcommands.UpdateCommand;
import java.util.ArrayList;
@@ -35,6 +36,7 @@ public final class LeavesCommand extends Command {
final Map<Set<String>, LeavesSubcommand> commands = new HashMap<>();
commands.put(Set.of("update"), new UpdateCommand());
commands.put(Set.of("peaceful"), new PeacefulModeSwitchCommand());
+ commands.put(Set.of("tick"), new TickCommand());
return commands.entrySet().stream()
.flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue())))
diff --git a/src/main/java/top/leavesmc/leaves/command/subcommands/TickCommand.java b/src/main/java/top/leavesmc/leaves/command/subcommands/TickCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..162c3c005130bfa07c7b924015356430b1e1ac2a
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/command/subcommands/TickCommand.java
@@ -0,0 +1,82 @@
+package top.leavesmc.leaves.command.subcommands;
+
+import io.papermc.paper.command.CommandUtil;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.JoinConfiguration;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.minecraft.server.MinecraftServer;
+import org.bukkit.command.CommandSender;
+import top.leavesmc.leaves.LeavesConfig;
+import top.leavesmc.leaves.command.LeavesSubcommand;
+import top.leavesmc.leaves.util.TickStatus;
+
+import java.util.Collections;
+import java.util.List;
+
+public class TickCommand implements LeavesSubcommand {
+
+ @Override
+ public boolean execute(CommandSender sender, String subCommand, String[] args) {
+ if (!LeavesConfig.tickCommand) {
+ return true;
+ }
+
+ if (args.length < 1) {
+ sender.sendMessage(Component.join(JoinConfiguration.noSeparators(),
+ Component.text("Tick Status: ", NamedTextColor.GRAY),
+ this.getStatus().getMessage()
+ ));
+ return true;
+ }
+
+ TickStatus oldStatus = this.getStatus();
+
+ switch (args[0]) {
+ case "warp" -> {
+ MinecraftServer.tickStatus = TickStatus.WARP;
+ sender.sendMessage(this.getStatusChangeMessage(oldStatus));
+ }
+
+ case "freeze" -> {
+ MinecraftServer.tickStatus = TickStatus.FREEZE;
+ sender.sendMessage(this.getStatusChangeMessage(oldStatus));
+ }
+
+ case "normal" -> {
+ MinecraftServer.tickStatus = TickStatus.NORMAL;
+ sender.sendMessage(this.getStatusChangeMessage(oldStatus));
+ }
+ }
+ return true;
+ }
+
+ public Component getStatusChangeMessage(TickStatus old) {
+ return Component.join(JoinConfiguration.noSeparators(),
+ Component.text("Tick Status: ", NamedTextColor.GRAY),
+ old.getMessage(),
+ Component.text(" -> ", NamedTextColor.GRAY),
+ this.getStatus().getMessage()
+ );
+ }
+
+ public TickStatus getStatus() {
+ return MinecraftServer.tickStatus;
+ }
+
+ @Override
+ public List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
+ if (!LeavesConfig.tickCommand) {
+ return Collections.emptyList();
+ }
+
+ if (args.length == 1) {
+ return CommandUtil.getListMatchingLast(sender, args, "normal", "warp", "freeze");
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean tabCompletes() {
+ return LeavesConfig.tickCommand;
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/util/TickStatus.java b/src/main/java/top/leavesmc/leaves/util/TickStatus.java
new file mode 100644
index 0000000000000000000000000000000000000000..460307c6d477704417dbfe38364afbc5efe8c767
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/util/TickStatus.java
@@ -0,0 +1,20 @@
+package top.leavesmc.leaves.util;
+
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+
+public enum TickStatus {
+ NORMAL(Component.text("normal", NamedTextColor.GRAY)),
+ WARP(Component.text("warp", NamedTextColor.GREEN)),
+ FREEZE(Component.text("freeze", NamedTextColor.AQUA));
+
+ private final Component message;
+
+ private TickStatus(Component message) {
+ this.message = message;
+ }
+
+ public Component getMessage() {
+ return message;
+ }
+}