From a48a7df386cf05bc70f4c9f7656957e355568186 Mon Sep 17 00:00:00 2001 From: gnembon Date: Sun, 6 Jun 2021 10:32:22 -0300 Subject: [PATCH] added perf command support --- gradle.properties | 4 +- src/main/java/carpet/CarpetServer.java | 11 +++- src/main/java/carpet/CarpetSettings.java | 7 +++ .../carpet/mixins/CommandManagerMixin.java | 1 + .../MinecraftServer_tickspeedMixin.java | 41 ++++++++++++-- .../mixins/PerfCommand_permissionMixin.java | 21 ++++++++ .../carpet/patches/CopyProfilerResult.java | 54 +++++++++++++++++++ .../assets/carpet/scripts/ai_tracker.sc | 3 +- src/main/resources/carpet.mixins.json | 1 + 9 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 src/main/java/carpet/mixins/PerfCommand_permissionMixin.java create mode 100644 src/main/java/carpet/patches/CopyProfilerResult.java diff --git a/gradle.properties b/gradle.properties index 91acb26c..f5a646ed 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,8 +4,8 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use # or better: https://modmuss50.me/fabric.html - minecraft_version=1.17-pre5 - yarn_mappings=1.17-pre5+build.1 + minecraft_version=1.17-rc1 + yarn_mappings=1.17-rc1+build.4 loader_version=0.11.3 fabric_version=0.34.8+1.17 diff --git a/src/main/java/carpet/CarpetServer.java b/src/main/java/carpet/CarpetServer.java index 00b7ca93..fb0afbdc 100644 --- a/src/main/java/carpet/CarpetServer.java +++ b/src/main/java/carpet/CarpetServer.java @@ -33,8 +33,10 @@ import com.mojang.brigadier.CommandDispatcher; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.DedicatedServerModInitializer; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.command.PerfCommand; import net.minecraft.server.network.ServerPlayerEntity; public class CarpetServer implements ClientModInitializer,DedicatedServerModInitializer // static for now - easier to handle all around the code, its one anyways @@ -122,7 +124,11 @@ public class CarpetServer implements ClientModInitializer,DedicatedServerModInit extensions.forEach(e -> e.onTick(server)); } - public static void registerCarpetCommands(CommandDispatcher dispatcher) + @Deprecated + public static void registerCarpetCommands(CommandDispatcher dispatcher) { + } + + public static void registerCarpetCommands(CommandDispatcher dispatcher, CommandManager.RegistrationEnvironment environment) { settingsManager.registerCommand(dispatcher); extensions.forEach(e -> { @@ -146,6 +152,9 @@ public class CarpetServer implements ClientModInitializer,DedicatedServerModInit // for all other, they will have them registered when they add themselves extensions.forEach(e -> e.registerCommands(dispatcher)); currentCommandDispatcher = dispatcher; + + if (environment != CommandManager.RegistrationEnvironment.DEDICATED) + PerfCommand.register(dispatcher); if (FabricLoader.getInstance().isDevelopmentEnvironment()) TestCommand.register(dispatcher); diff --git a/src/main/java/carpet/CarpetSettings.java b/src/main/java/carpet/CarpetSettings.java index 10b27cb2..b197524f 100644 --- a/src/main/java/carpet/CarpetSettings.java +++ b/src/main/java/carpet/CarpetSettings.java @@ -375,6 +375,13 @@ public class CarpetSettings ) public static String commandProfile = "true"; + @Rule( + desc = "Required permission level for /perf command", + options = {"2", "4"}, + category = CREATIVE + ) + public static int perfPermissionLevel = 4; + @Rule(desc = "Enables /log command to monitor events via chat and overlays", category = COMMAND) public static String commandLog = "true"; diff --git a/src/main/java/carpet/mixins/CommandManagerMixin.java b/src/main/java/carpet/mixins/CommandManagerMixin.java index 0b3ef549..05e82a37 100644 --- a/src/main/java/carpet/mixins/CommandManagerMixin.java +++ b/src/main/java/carpet/mixins/CommandManagerMixin.java @@ -27,6 +27,7 @@ public abstract class CommandManagerMixin @Inject(method = "", at = @At("RETURN")) private void onRegister(CommandManager.RegistrationEnvironment arg, CallbackInfo ci) { CarpetServer.registerCarpetCommands(this.dispatcher); + CarpetServer.registerCarpetCommands(this.dispatcher, arg); } @Inject(method = "execute", at = @At("HEAD")) diff --git a/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java b/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java index ff3b508e..29acd733 100644 --- a/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java +++ b/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java @@ -1,14 +1,17 @@ package carpet.mixins; import carpet.helpers.TickSpeed; +import carpet.patches.CopyProfilerResult; import carpet.utils.CarpetProfiler; import net.minecraft.server.MinecraftServer; import net.minecraft.server.ServerTask; -import net.minecraft.util.TickDurationMonitor; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Util; +import net.minecraft.util.profiler.EmptyProfileResult; +import net.minecraft.util.profiler.ProfileResult; import net.minecraft.util.profiler.Profiler; import net.minecraft.util.thread.ReentrantThreadExecutor; +import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.Logger; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -17,6 +20,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.function.BooleanSupplier; @@ -56,6 +60,10 @@ public abstract class MinecraftServer_tickspeedMixin extends ReentrantThreadExec @Shadow public abstract Iterable getWorlds(); + @Shadow protected abstract void endMonitor(); + + @Shadow private boolean profilerEnabled; + @Shadow private int ticks; CarpetProfiler.ProfilerToken currentSection; private float carpetMsptAccum = 0.0f; @@ -117,11 +125,15 @@ public abstract class MinecraftServer_tickspeedMixin extends ReentrantThreadExec this.lastTimeReference = this.timeReference; } + if (this.profilerEnabled) { + this.profilerEnabled = false; + this.profilerTimings = Pair.of(Util.getMeasuringTimeNano(), ticks); + //this.field_33978 = new MinecraftServer.class_6414(Util.getMeasuringTimeNano(), this.ticks); + } this.timeReference += msThisTick;//50L; //TickDurationMonitor tickDurationMonitor = TickDurationMonitor.create("Server"); //this.startMonitor(tickDurationMonitor); this.startMonitor(); - this.profiler.startTick(); this.profiler.push("tick"); this.tick(TickSpeed.time_warp_start_time != 0 ? ()->true : this::shouldKeepTicking); this.profiler.swap("nextTickWait"); @@ -134,12 +146,35 @@ public abstract class MinecraftServer_tickspeedMixin extends ReentrantThreadExec // run all tasks (this will not do a lot when warping), but that's fine since we already run them this.method_16208(); this.profiler.pop(); - this.profiler.endTick(); + this.endMonitor(); this.loading = true; } } + // just because profilerTimings class is public + Pair profilerTimings = null; + /// overworld around profiler timings + @Inject(method = "isDebugRunning", at = @At("HEAD"), cancellable = true) + public void isCMDebugRunning(CallbackInfoReturnable cir) + { + cir.setReturnValue(profilerEnabled || profilerTimings != null); + } + @Inject(method = "stopDebug", at = @At("HEAD"), cancellable = true) + public void stopCMDebug(CallbackInfoReturnable cir) + { + if (this.profilerTimings == null) { + cir.setReturnValue(EmptyProfileResult.INSTANCE); + } else { + ProfileResult profileResult = new CopyProfilerResult( + profilerTimings.getRight(), profilerTimings.getLeft(), + this.ticks, Util.getMeasuringTimeNano() + ); + this.profilerTimings = null; + cir.setReturnValue(profileResult); + } + } + private boolean runEveryTask() { if (super.runTask()) { diff --git a/src/main/java/carpet/mixins/PerfCommand_permissionMixin.java b/src/main/java/carpet/mixins/PerfCommand_permissionMixin.java new file mode 100644 index 00000000..014e1d32 --- /dev/null +++ b/src/main/java/carpet/mixins/PerfCommand_permissionMixin.java @@ -0,0 +1,21 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.server.dedicated.command.PerfCommand; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(PerfCommand.class) +public class PerfCommand_permissionMixin +{ + @SuppressWarnings("UnresolvedMixinReference") + @Inject(method = "method_37340(Lnet/minecraft/server/command/ServerCommandSource;)Z", at = @At("HEAD"), cancellable = true) + private static void canRun(ServerCommandSource source, CallbackInfoReturnable cir) + { + cir.setReturnValue(source.hasPermissionLevel(CarpetSettings.perfPermissionLevel)); + } + +} diff --git a/src/main/java/carpet/patches/CopyProfilerResult.java b/src/main/java/carpet/patches/CopyProfilerResult.java new file mode 100644 index 00000000..07a13782 --- /dev/null +++ b/src/main/java/carpet/patches/CopyProfilerResult.java @@ -0,0 +1,54 @@ +package carpet.patches; + +import net.minecraft.util.profiler.ProfileResult; +import net.minecraft.util.profiler.ProfilerTiming; + +import java.nio.file.Path; +import java.util.Collections; +import java.util.List; + +public class CopyProfilerResult implements ProfileResult { + int startI, endI; + long startL, endL; + public CopyProfilerResult(int startI, long startL, int endI, long endL) + { + this.startI = startI; + this.startL = startL; + this.endI = endI; + this.endL = endL; + } + @Override + public List getTimings(String parentPath) { + return Collections.emptyList(); + } + + @Override + public boolean save(Path path) { + return false; + } + + @Override + public long getStartTime() { + return startL; + } + + @Override + public int getStartTick() { + return startI; + } + + @Override + public long getEndTime() { + return endL; + } + + @Override + public int getEndTick() { + return endI; + } + + @Override + public String getRootTimings() { + return ""; + } +} diff --git a/src/main/resources/assets/carpet/scripts/ai_tracker.sc b/src/main/resources/assets/carpet/scripts/ai_tracker.sc index 3345edd6..636d7977 100644 --- a/src/main/resources/assets/carpet/scripts/ai_tracker.sc +++ b/src/main/resources/assets/carpet/scripts/ai_tracker.sc @@ -285,7 +285,8 @@ global_functions = { 'health' -> { '*' -> [ _(arg) -> _(e) -> ( - [[], [], [['health', 'health:', e~'health']]] + health = e~'health'; + [[], [], if (health != null, [['health', 'health:', e~'health']], [])] ), , null diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index 14e5062e..3a9766ca 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -12,6 +12,7 @@ "ServerPlayNetworkHandlerMixin", "CustomPayloadC2SPacketMixin", + "PerfCommand_permissionMixin", "FillCommandMixin", "CloneCommandMixin", "SetBlockCommandMixin",