PerfCommand.java

net.minecraft.server.commands.PerfCommand

信息

  • 全限定名:net.minecraft.server.commands.PerfCommand
  • 类型:public class
  • 包:net.minecraft.server.commands
  • 源码路径:src/main/java/net/minecraft/server/commands/PerfCommand.java
  • 起始行号:L28
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L29
    • 说明:

      TODO

  • ERROR_NOT_RUNNING

    • 类型: SimpleCommandExceptionType
    • 修饰符: private static final
    • 源码定位: L30
    • 说明:

      TODO

  • ERROR_ALREADY_RUNNING

    • 类型: SimpleCommandExceptionType
    • 修饰符: private static final
    • 源码定位: L31
    • 说明:

      TODO

内部类/嵌套类型

构造器

方法

下面的方法块按源码顺序生成。

public static void register(CommandDispatcher<CommandSourceStack> dispatcher) @ L35

  • 方法名:register
  • 源码定位:L35
  • 返回类型:void
  • 修饰符:public static

参数:

  • dispatcher: CommandDispatcher

说明:

TODO

private static int startProfilingDedicatedServer(CommandSourceStack source) @ L44

  • 方法名:startProfilingDedicatedServer
  • 源码定位:L44
  • 返回类型:int
  • 修饰符:private static

参数:

  • source: CommandSourceStack

说明:

TODO

private static int stopProfilingDedicatedServer(CommandSourceStack source) @ L57

  • 方法名:stopProfilingDedicatedServer
  • 源码定位:L57
  • 返回类型:int
  • 修饰符:private static

参数:

  • source: CommandSourceStack

说明:

TODO

private static void saveResults(CommandSourceStack source, Path report, MinecraftServer server) @ L67

  • 方法名:saveResults
  • 源码定位:L67
  • 返回类型:void
  • 修饰符:private static

参数:

  • source: CommandSourceStack
  • report: Path
  • server: MinecraftServer

说明:

TODO

private static void whenStopped(CommandSourceStack source, ProfileResults results) @ L95

  • 方法名:whenStopped
  • 源码定位:L95
  • 返回类型:void
  • 修饰符:private static

参数:

  • source: CommandSourceStack
  • results: ProfileResults

说明:

TODO

代码

public class PerfCommand {
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final SimpleCommandExceptionType ERROR_NOT_RUNNING = new SimpleCommandExceptionType(Component.translatable("commands.perf.notRunning"));
    private static final SimpleCommandExceptionType ERROR_ALREADY_RUNNING = new SimpleCommandExceptionType(
        Component.translatable("commands.perf.alreadyRunning")
    );
 
    public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
        dispatcher.register(
            Commands.literal("perf")
                .requires(Commands.hasPermission(Commands.LEVEL_OWNERS))
                .then(Commands.literal("start").executes(c -> startProfilingDedicatedServer(c.getSource())))
                .then(Commands.literal("stop").executes(c -> stopProfilingDedicatedServer(c.getSource())))
        );
    }
 
    private static int startProfilingDedicatedServer(CommandSourceStack source) throws CommandSyntaxException {
        MinecraftServer server = source.getServer();
        if (server.isRecordingMetrics()) {
            throw ERROR_ALREADY_RUNNING.create();
        } else {
            Consumer<ProfileResults> onStopped = results -> whenStopped(source, results);
            Consumer<Path> onReportFinished = profilingLogs -> saveResults(source, profilingLogs, server);
            server.startRecordingMetrics(onStopped, onReportFinished);
            source.sendSuccess(() -> Component.translatable("commands.perf.started"), false);
            return 0;
        }
    }
 
    private static int stopProfilingDedicatedServer(CommandSourceStack source) throws CommandSyntaxException {
        MinecraftServer server = source.getServer();
        if (!server.isRecordingMetrics()) {
            throw ERROR_NOT_RUNNING.create();
        } else {
            server.finishRecordingMetrics();
            return 0;
        }
    }
 
    private static void saveResults(CommandSourceStack source, Path report, MinecraftServer server) {
        String profilingName = String.format(
            Locale.ROOT, "%s-%s-%s", Util.getFilenameFormattedDateTime(), server.getWorldData().getLevelName(), SharedConstants.getCurrentVersion().id()
        );
 
        String zipFile;
        try {
            zipFile = FileUtil.findAvailableName(MetricsPersister.PROFILING_RESULTS_DIR, profilingName, ".zip");
        } catch (IOException var11) {
            source.sendFailure(Component.translatable("commands.perf.reportFailed"));
            LOGGER.error("Failed to create report name", (Throwable)var11);
            return;
        }
 
        try (FileZipper fileZipper = new FileZipper(MetricsPersister.PROFILING_RESULTS_DIR.resolve(zipFile))) {
            fileZipper.add(Paths.get("system.txt"), server.fillSystemReport(new SystemReport()).toLineSeparatedString());
            fileZipper.add(report);
        }
 
        try {
            FileUtils.forceDelete(report.toFile());
        } catch (IOException var9) {
            LOGGER.warn("Failed to delete temporary profiling file {}", report, var9);
        }
 
        source.sendSuccess(() -> Component.translatable("commands.perf.reportSaved", zipFile), false);
    }
 
    private static void whenStopped(CommandSourceStack source, ProfileResults results) {
        if (results != EmptyProfileResults.EMPTY) {
            int ticks = results.getTickDuration();
            double durationInSeconds = (double)results.getNanoDuration() / TimeUtil.NANOSECONDS_PER_SECOND;
            source.sendSuccess(
                () -> Component.translatable(
                    "commands.perf.stopped",
                    String.format(Locale.ROOT, "%.2f", durationInSeconds),
                    ticks,
                    String.format(Locale.ROOT, "%.2f", ticks / durationInSeconds)
                ),
                false
            );
        }
    }
}

引用的其他类

  • SharedConstants

    • 引用位置: 方法调用
    • 关联成员: SharedConstants.getCurrentVersion()
  • SystemReport

    • 引用位置: 构造调用
    • 关联成员: SystemReport()
  • CommandSourceStack

    • 引用位置: 参数
  • Commands

    • 引用位置: 方法调用
    • 关联成员: Commands.hasPermission(), Commands.literal()
  • Component

    • 引用位置: 方法调用
    • 关联成员: Component.translatable()
  • MinecraftServer

    • 引用位置: 参数
  • FileUtil

    • 引用位置: 方法调用
    • 关联成员: FileUtil.findAvailableName()
  • FileZipper

    • 引用位置: 构造调用
    • 关联成员: FileZipper()
  • Util

    • 引用位置: 方法调用
    • 关联成员: Util.getFilenameFormattedDateTime()
  • ProfileResults

    • 引用位置: 参数