From bfbbcb3e68e019da4657ef0da22b889de656ae3f Mon Sep 17 00:00:00 2001 From: Luck Date: Tue, 28 Dec 2021 18:12:33 +0000 Subject: Include platform and system statistics in profiler viewer payload --- .../src/main/java/me/lucko/spark/bukkit/BukkitPlatformInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'spark-bukkit') diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitPlatformInfo.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitPlatformInfo.java index 3f0c155..2bf17ac 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitPlatformInfo.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitPlatformInfo.java @@ -20,14 +20,14 @@ package me.lucko.spark.bukkit; -import me.lucko.spark.common.platform.AbstractPlatformInfo; +import me.lucko.spark.common.platform.PlatformInfo; import org.bukkit.Server; import java.lang.reflect.Field; import java.lang.reflect.Method; -public class BukkitPlatformInfo extends AbstractPlatformInfo { +public class BukkitPlatformInfo implements PlatformInfo { private final Server server; public BukkitPlatformInfo(Server server) { -- cgit From d2716da1dc7f61aa45c0058e9a8fd65aa858f3c8 Mon Sep 17 00:00:00 2001 From: Luck Date: Thu, 20 Jan 2022 20:22:02 +0000 Subject: Add ping statistics and command --- .../spark/bukkit/BukkitPlayerPingProvider.java | 57 +++++ .../me/lucko/spark/bukkit/BukkitSparkPlugin.java | 10 + .../placeholder/SparkPlaceholderProvider.java | 54 ++--- .../bungeecord/BungeeCordPlayerPingProvider.java | 47 ++++ .../spark/bungeecord/BungeeCordSparkPlugin.java | 6 + .../java/me/lucko/spark/common/SparkPlatform.java | 17 ++ .../java/me/lucko/spark/common/SparkPlugin.java | 12 ++ .../spark/common/command/modules/HealthModule.java | 239 ++++++++------------- .../spark/common/monitor/MonitoringExecutor.java | 16 ++ .../lucko/spark/common/monitor/cpu/CpuMonitor.java | 12 +- .../spark/common/monitor/ping/PingStatistics.java | 148 +++++++++++++ .../spark/common/monitor/ping/PingSummary.java | 81 +++++++ .../common/monitor/ping/PlayerPingProvider.java | 40 ++++ .../platform/PlatformStatisticsProvider.java | 17 +- .../me/lucko/spark/common/util/RollingAverage.java | 6 + .../spark/common/util/StatisticFormatter.java | 187 ++++++++++++++++ spark-common/src/main/proto/spark/spark.proto | 25 ++- .../spark/fabric/FabricPlayerPingProvider.java | 47 ++++ .../placeholder/SparkFabricPlaceholderApi.java | 36 ++-- .../fabric/plugin/FabricServerSparkPlugin.java | 7 + .../lucko/spark/forge/ForgePlayerPingProvider.java | 47 ++++ .../spark/forge/plugin/ForgeServerSparkPlugin.java | 7 + .../spark/nukkit/NukkitPlayerPingProvider.java | 47 ++++ .../me/lucko/spark/nukkit/NukkitSparkPlugin.java | 6 + .../spark/sponge/Sponge7PlayerPingProvider.java | 47 ++++ .../me/lucko/spark/sponge/Sponge7SparkPlugin.java | 10 + .../spark/sponge/Sponge8PlayerPingProvider.java | 47 ++++ .../me/lucko/spark/sponge/Sponge8SparkPlugin.java | 10 + .../spark/velocity/VelocityPlayerPingProvider.java | 46 ++++ .../lucko/spark/velocity/VelocitySparkPlugin.java | 6 + .../velocity/Velocity4PlayerPingProvider.java | 46 ++++ .../lucko/spark/velocity/Velocity4SparkPlugin.java | 6 + .../spark/waterdog/WaterdogPlayerPingProvider.java | 47 ++++ .../lucko/spark/waterdog/WaterdogSparkPlugin.java | 6 + 34 files changed, 1220 insertions(+), 222 deletions(-) create mode 100644 spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitPlayerPingProvider.java create mode 100644 spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/BungeeCordPlayerPingProvider.java create mode 100644 spark-common/src/main/java/me/lucko/spark/common/monitor/MonitoringExecutor.java create mode 100644 spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PingStatistics.java create mode 100644 spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PingSummary.java create mode 100644 spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PlayerPingProvider.java create mode 100644 spark-common/src/main/java/me/lucko/spark/common/util/StatisticFormatter.java create mode 100644 spark-fabric/src/main/java/me/lucko/spark/fabric/FabricPlayerPingProvider.java create mode 100644 spark-forge/src/main/java/me/lucko/spark/forge/ForgePlayerPingProvider.java create mode 100644 spark-nukkit/src/main/java/me/lucko/spark/nukkit/NukkitPlayerPingProvider.java create mode 100644 spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7PlayerPingProvider.java create mode 100644 spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8PlayerPingProvider.java create mode 100644 spark-velocity/src/main/java/me/lucko/spark/velocity/VelocityPlayerPingProvider.java create mode 100644 spark-velocity4/src/main/java/me/lucko/spark/velocity/Velocity4PlayerPingProvider.java create mode 100644 spark-waterdog/src/main/java/me/lucko/spark/waterdog/WaterdogPlayerPingProvider.java (limited to 'spark-bukkit') diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitPlayerPingProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitPlayerPingProvider.java new file mode 100644 index 0000000..2cf58cf --- /dev/null +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitPlayerPingProvider.java @@ -0,0 +1,57 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.bukkit; + +import com.google.common.collect.ImmutableMap; + +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; + +import org.bukkit.Server; +import org.bukkit.entity.Player; + +import java.util.Map; + +public class BukkitPlayerPingProvider implements PlayerPingProvider { + + public static boolean isSupported() { + try { + Player.Spigot.class.getMethod("getPing"); + return true; + } catch (Exception e) { + return false; + } + } + + private final Server server; + + public BukkitPlayerPingProvider(Server server) { + this.server = server; + } + + @Override + public Map poll() { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (Player player : this.server.getOnlinePlayers()) { + builder.put(player.getName(), player.spigot().getPing()); + } + return builder.build(); + } +} diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitSparkPlugin.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitSparkPlugin.java index f81a176..6929a4d 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitSparkPlugin.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitSparkPlugin.java @@ -25,6 +25,7 @@ import me.lucko.spark.bukkit.placeholder.SparkMVdWPlaceholders; import me.lucko.spark.bukkit.placeholder.SparkPlaceholderApi; import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.SparkPlugin; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.sampler.ThreadDumper; import me.lucko.spark.common.tick.TickHook; @@ -171,6 +172,15 @@ public class BukkitSparkPlugin extends JavaPlugin implements SparkPlugin { return new BukkitClassSourceLookup(); } + @Override + public PlayerPingProvider createPlayerPingProvider() { + if (BukkitPlayerPingProvider.isSupported()) { + return new BukkitPlayerPingProvider(getServer()); + } else { + return null; + } + } + @Override public PlatformInfo getPlatformInfo() { return new BukkitPlatformInfo(getServer()); diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderProvider.java index 6e14bdb..96c9e93 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderProvider.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderProvider.java @@ -21,9 +21,9 @@ package me.lucko.spark.bukkit.placeholder; import me.lucko.spark.common.SparkPlatform; -import me.lucko.spark.common.command.modules.HealthModule; import me.lucko.spark.common.monitor.cpu.CpuMonitor; import me.lucko.spark.common.monitor.tick.TickStatistics; +import me.lucko.spark.common.util.StatisticFormatter; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; @@ -42,22 +42,22 @@ enum SparkPlaceholderProvider { switch (placeholder) { case "tps": return Component.text() - .append(HealthModule.formatTps(tickStatistics.tps5Sec())).append(Component.text(", ")) - .append(HealthModule.formatTps(tickStatistics.tps10Sec())).append(Component.text(", ")) - .append(HealthModule.formatTps(tickStatistics.tps1Min())).append(Component.text(", ")) - .append(HealthModule.formatTps(tickStatistics.tps5Min())).append(Component.text(", ")) - .append(HealthModule.formatTps(tickStatistics.tps15Min())) + .append(StatisticFormatter.formatTps(tickStatistics.tps5Sec())).append(Component.text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps10Sec())).append(Component.text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps1Min())).append(Component.text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps5Min())).append(Component.text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps15Min())) .build(); case "tps_5s": - return HealthModule.formatTps(tickStatistics.tps5Sec()); + return StatisticFormatter.formatTps(tickStatistics.tps5Sec()); case "tps_10s": - return HealthModule.formatTps(tickStatistics.tps10Sec()); + return StatisticFormatter.formatTps(tickStatistics.tps10Sec()); case "tps_1m": - return HealthModule.formatTps(tickStatistics.tps1Min()); + return StatisticFormatter.formatTps(tickStatistics.tps1Min()); case "tps_5m": - return HealthModule.formatTps(tickStatistics.tps5Min()); + return StatisticFormatter.formatTps(tickStatistics.tps5Min()); case "tps_15m": - return HealthModule.formatTps(tickStatistics.tps15Min()); + return StatisticFormatter.formatTps(tickStatistics.tps15Min()); } } @@ -70,13 +70,13 @@ enum SparkPlaceholderProvider { switch (placeholder) { case "tickduration": return Component.text() - .append(HealthModule.formatTickDurations(tickStatistics.duration10Sec())).append(Component.text("; ")) - .append(HealthModule.formatTickDurations(tickStatistics.duration1Min())) + .append(StatisticFormatter.formatTickDurations(tickStatistics.duration10Sec())).append(Component.text("; ")) + .append(StatisticFormatter.formatTickDurations(tickStatistics.duration1Min())) .build(); case "tickduration_10s": - return HealthModule.formatTickDurations(tickStatistics.duration10Sec()); + return StatisticFormatter.formatTickDurations(tickStatistics.duration10Sec()); case "tickduration_1m": - return HealthModule.formatTickDurations(tickStatistics.duration1Min()); + return StatisticFormatter.formatTickDurations(tickStatistics.duration1Min()); } } @@ -84,28 +84,28 @@ enum SparkPlaceholderProvider { switch (placeholder) { case "cpu_system": return Component.text() - .append(HealthModule.formatCpuUsage(CpuMonitor.systemLoad10SecAvg())).append(Component.text(", ")) - .append(HealthModule.formatCpuUsage(CpuMonitor.systemLoad1MinAvg())).append(Component.text(", ")) - .append(HealthModule.formatCpuUsage(CpuMonitor.systemLoad15MinAvg())) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad10SecAvg())).append(Component.text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad1MinAvg())).append(Component.text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad15MinAvg())) .build(); case "cpu_system_10s": - return HealthModule.formatCpuUsage(CpuMonitor.systemLoad10SecAvg()); + return StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad10SecAvg()); case "cpu_system_1m": - return HealthModule.formatCpuUsage(CpuMonitor.systemLoad1MinAvg()); + return StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad1MinAvg()); case "cpu_system_15m": - return HealthModule.formatCpuUsage(CpuMonitor.systemLoad15MinAvg()); + return StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad15MinAvg()); case "cpu_process": return Component.text() - .append(HealthModule.formatCpuUsage(CpuMonitor.processLoad10SecAvg())).append(Component.text(", ")) - .append(HealthModule.formatCpuUsage(CpuMonitor.processLoad1MinAvg())).append(Component.text(", ")) - .append(HealthModule.formatCpuUsage(CpuMonitor.processLoad15MinAvg())) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad10SecAvg())).append(Component.text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad1MinAvg())).append(Component.text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad15MinAvg())) .build(); case "cpu_process_10s": - return HealthModule.formatCpuUsage(CpuMonitor.processLoad10SecAvg()); + return StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad10SecAvg()); case "cpu_process_1m": - return HealthModule.formatCpuUsage(CpuMonitor.processLoad1MinAvg()); + return StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad1MinAvg()); case "cpu_process_15m": - return HealthModule.formatCpuUsage(CpuMonitor.processLoad15MinAvg()); + return StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad15MinAvg()); } } diff --git a/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/BungeeCordPlayerPingProvider.java b/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/BungeeCordPlayerPingProvider.java new file mode 100644 index 0000000..37955a3 --- /dev/null +++ b/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/BungeeCordPlayerPingProvider.java @@ -0,0 +1,47 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.bungeecord; + +import com.google.common.collect.ImmutableMap; + +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; + +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.util.Map; + +public class BungeeCordPlayerPingProvider implements PlayerPingProvider { + private final ProxyServer proxy; + + public BungeeCordPlayerPingProvider(ProxyServer proxy) { + this.proxy = proxy; + } + + @Override + public Map poll() { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (ProxiedPlayer player : this.proxy.getPlayers()) { + builder.put(player.getName(), player.getPing()); + } + return builder.build(); + } +} diff --git a/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/BungeeCordSparkPlugin.java b/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/BungeeCordSparkPlugin.java index ebdfe18..e259adc 100644 --- a/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/BungeeCordSparkPlugin.java +++ b/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/BungeeCordSparkPlugin.java @@ -22,6 +22,7 @@ package me.lucko.spark.bungeecord; import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.SparkPlugin; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.util.ClassSourceLookup; @@ -90,6 +91,11 @@ public class BungeeCordSparkPlugin extends Plugin implements SparkPlugin { return new BungeeCordClassSourceLookup(); } + @Override + public PlayerPingProvider createPlayerPingProvider() { + return new BungeeCordPlayerPingProvider(getProxy()); + } + @Override public PlatformInfo getPlatformInfo() { return new BungeeCordPlatformInfo(getProxy()); diff --git a/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java b/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java index 53454aa..c93b876 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java +++ b/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java @@ -40,6 +40,8 @@ import me.lucko.spark.common.command.tabcomplete.CompletionSupplier; import me.lucko.spark.common.command.tabcomplete.TabCompleter; import me.lucko.spark.common.monitor.cpu.CpuMonitor; import me.lucko.spark.common.monitor.memory.GarbageCollectorStatistics; +import me.lucko.spark.common.monitor.ping.PingStatistics; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.monitor.tick.TickStatistics; import me.lucko.spark.common.platform.PlatformStatisticsProvider; import me.lucko.spark.common.tick.TickHook; @@ -99,6 +101,7 @@ public class SparkPlatform { private final TickHook tickHook; private final TickReporter tickReporter; private final TickStatistics tickStatistics; + private final PingStatistics pingStatistics; private final PlatformStatisticsProvider statisticsProvider; private Map startupGcStatistics = ImmutableMap.of(); private long serverNormalOperationStartTime; @@ -136,6 +139,10 @@ public class SparkPlatform { this.tickHook = plugin.createTickHook(); this.tickReporter = plugin.createTickReporter(); this.tickStatistics = this.tickHook != null ? new TickStatistics() : null; + + PlayerPingProvider pingProvider = plugin.createPlayerPingProvider(); + this.pingStatistics = pingProvider != null ? new PingStatistics(pingProvider) : null; + this.statisticsProvider = new PlatformStatisticsProvider(this); } @@ -152,6 +159,9 @@ public class SparkPlatform { this.tickReporter.addCallback(this.tickStatistics); this.tickReporter.start(); } + if (this.pingStatistics != null) { + this.pingStatistics.start(); + } CpuMonitor.ensureMonitoring(); // poll startup GC statistics after plugins & the world have loaded @@ -172,6 +182,9 @@ public class SparkPlatform { if (this.tickReporter != null) { this.tickReporter.close(); } + if (this.pingStatistics != null) { + this.pingStatistics.close(); + } for (CommandModule module : this.commandModules) { module.close(); @@ -231,6 +244,10 @@ public class SparkPlatform { return this.tickStatistics; } + public PingStatistics getPingStatistics() { + return this.pingStatistics; + } + public Map getStartupGcStatistics() { return this.startupGcStatistics; } diff --git a/spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java b/spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java index f312916..5feb172 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java +++ b/spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java @@ -22,6 +22,7 @@ package me.lucko.spark.common; import me.lucko.spark.api.Spark; import me.lucko.spark.common.command.sender.CommandSender; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.sampler.ThreadDumper; import me.lucko.spark.common.tick.TickHook; @@ -120,6 +121,17 @@ public interface SparkPlugin { return ClassSourceLookup.NO_OP; } + /** + * Creates a player ping provider function. + * + *

Returns {@code null} if the platform does not support querying player pings

+ * + * @return the player ping provider function + */ + default PlayerPingProvider createPlayerPingProvider() { + return null; + } + /** * Gets information for the platform. * diff --git a/spark-common/src/main/java/me/lucko/spark/common/command/modules/HealthModule.java b/spark-common/src/main/java/me/lucko/spark/common/command/modules/HealthModule.java index b036d21..ea4f140 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/command/modules/HealthModule.java +++ b/spark-common/src/main/java/me/lucko/spark/common/command/modules/HealthModule.java @@ -20,8 +20,6 @@ package me.lucko.spark.common.command.modules; -import com.google.common.base.Strings; - import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.command.Arguments; import me.lucko.spark.common.command.Command; @@ -31,13 +29,14 @@ import me.lucko.spark.common.command.sender.CommandSender; import me.lucko.spark.common.command.tabcomplete.TabCompleter; import me.lucko.spark.common.monitor.cpu.CpuMonitor; import me.lucko.spark.common.monitor.disk.DiskUsage; +import me.lucko.spark.common.monitor.ping.PingStatistics; +import me.lucko.spark.common.monitor.ping.PingSummary; import me.lucko.spark.common.monitor.tick.TickStatistics; import me.lucko.spark.common.util.FormatUtil; import me.lucko.spark.common.util.RollingAverage; +import me.lucko.spark.common.util.StatisticFormatter; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextComponent; -import net.kyori.adventure.text.format.TextColor; import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; @@ -46,6 +45,7 @@ import java.lang.management.MemoryType; import java.lang.management.MemoryUsage; import java.util.LinkedList; import java.util.List; +import java.util.Set; import java.util.function.Consumer; import static net.kyori.adventure.text.Component.empty; @@ -57,7 +57,6 @@ import static net.kyori.adventure.text.format.NamedTextColor.GRAY; import static net.kyori.adventure.text.format.NamedTextColor.GREEN; import static net.kyori.adventure.text.format.NamedTextColor.RED; import static net.kyori.adventure.text.format.NamedTextColor.WHITE; -import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; import static net.kyori.adventure.text.format.TextDecoration.BOLD; public class HealthModule implements CommandModule { @@ -71,6 +70,14 @@ public class HealthModule implements CommandModule { .build() ); + consumer.accept(Command.builder() + .aliases("ping") + .argumentUsage("player", "username") + .executor(HealthModule::ping) + .tabCompleter((platform, sender, arguments) -> TabCompleter.completeForOpts(arguments, "--player")) + .build() + ); + consumer.accept(Command.builder() .aliases("healthreport", "health", "ht") .argumentUsage("memory", null) @@ -86,11 +93,11 @@ public class HealthModule implements CommandModule { resp.replyPrefixed(text("TPS from last 5s, 10s, 1m, 5m, 15m:")); resp.replyPrefixed(text() .content(" ") - .append(formatTps(tickStatistics.tps5Sec())).append(text(", ")) - .append(formatTps(tickStatistics.tps10Sec())).append(text(", ")) - .append(formatTps(tickStatistics.tps1Min())).append(text(", ")) - .append(formatTps(tickStatistics.tps5Min())).append(text(", ")) - .append(formatTps(tickStatistics.tps15Min())) + .append(StatisticFormatter.formatTps(tickStatistics.tps5Sec())).append(text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps10Sec())).append(text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps1Min())).append(text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps5Min())).append(text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps15Min())) .build() ); resp.replyPrefixed(empty()); @@ -99,8 +106,8 @@ public class HealthModule implements CommandModule { resp.replyPrefixed(text("Tick durations (min/med/95%ile/max ms) from last 10s, 1m:")); resp.replyPrefixed(text() .content(" ") - .append(formatTickDurations(tickStatistics.duration10Sec())).append(text("; ")) - .append(formatTickDurations(tickStatistics.duration1Min())) + .append(StatisticFormatter.formatTickDurations(tickStatistics.duration10Sec())).append(text("; ")) + .append(StatisticFormatter.formatTickDurations(tickStatistics.duration1Min())) .build() ); resp.replyPrefixed(empty()); @@ -110,22 +117,67 @@ public class HealthModule implements CommandModule { resp.replyPrefixed(text("CPU usage from last 10s, 1m, 15m:")); resp.replyPrefixed(text() .content(" ") - .append(formatCpuUsage(CpuMonitor.systemLoad10SecAvg())).append(text(", ")) - .append(formatCpuUsage(CpuMonitor.systemLoad1MinAvg())).append(text(", ")) - .append(formatCpuUsage(CpuMonitor.systemLoad15MinAvg())) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad10SecAvg())).append(text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad1MinAvg())).append(text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad15MinAvg())) .append(text(" (system)", DARK_GRAY)) .build() ); resp.replyPrefixed(text() .content(" ") - .append(formatCpuUsage(CpuMonitor.processLoad10SecAvg())).append(text(", ")) - .append(formatCpuUsage(CpuMonitor.processLoad1MinAvg())).append(text(", ")) - .append(formatCpuUsage(CpuMonitor.processLoad15MinAvg())) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad10SecAvg())).append(text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad1MinAvg())).append(text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad15MinAvg())) .append(text(" (process)", DARK_GRAY)) .build() ); } + private static void ping(SparkPlatform platform, CommandSender sender, CommandResponseHandler resp, Arguments arguments) { + PingStatistics pingStatistics = platform.getPingStatistics(); + if (pingStatistics == null) { + resp.replyPrefixed(text("Ping data is not available on this platform.")); + return; + } + + // lookup for specific player + Set players = arguments.stringFlag("player"); + if (!players.isEmpty()) { + for (String player : players) { + PingStatistics.PlayerPing playerPing = pingStatistics.query(player); + if (playerPing == null) { + resp.replyPrefixed(text("Ping data is not available for '" + player + "'.")); + } else { + resp.replyPrefixed(text() + .content("Player ") + .append(text(playerPing.name(), WHITE)) + .append(text(" has ")) + .append(StatisticFormatter.formatPingRtt(playerPing.ping())) + .append(text(" ms ping.")) + .build() + ); + } + } + return; + } + + PingSummary summary = pingStatistics.currentSummary(); + RollingAverage average = pingStatistics.getPingAverage(); + + if (summary.total() == 0 && average.getSamples() == 0) { + resp.replyPrefixed(text("There is not enough data to show ping averages yet. Please try again later.")); + return; + } + + resp.replyPrefixed(text("Average Pings (min/med/95%ile/max ms) from now, last 15m:")); + resp.replyPrefixed(text() + .content(" ") + .append(StatisticFormatter.formatPingRtts(summary.min(), summary.median(), summary.percentile95th(), summary.max())).append(text("; ")) + .append(StatisticFormatter.formatPingRtts(average.min(), average.median(), average.percentile95th(), average.max())) + .build() + ); + } + private static void healthReport(SparkPlatform platform, CommandSender sender, CommandResponseHandler resp, Arguments arguments) { resp.replyPrefixed(text("Generating server health report...")); List report = new LinkedList<>(); @@ -159,11 +211,11 @@ public class HealthModule implements CommandModule { ); report.add(text() .content(" ") - .append(formatTps(tickStatistics.tps5Sec())).append(text(", ")) - .append(formatTps(tickStatistics.tps10Sec())).append(text(", ")) - .append(formatTps(tickStatistics.tps1Min())).append(text(", ")) - .append(formatTps(tickStatistics.tps5Min())).append(text(", ")) - .append(formatTps(tickStatistics.tps15Min())) + .append(StatisticFormatter.formatTps(tickStatistics.tps5Sec())).append(text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps10Sec())).append(text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps1Min())).append(text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps5Min())).append(text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps15Min())) .build() ); report.add(empty()); @@ -177,8 +229,8 @@ public class HealthModule implements CommandModule { ); report.add(text() .content(" ") - .append(formatTickDurations(tickStatistics.duration10Sec())).append(text("; ")) - .append(formatTickDurations(tickStatistics.duration1Min())) + .append(StatisticFormatter.formatTickDurations(tickStatistics.duration10Sec())).append(text("; ")) + .append(StatisticFormatter.formatTickDurations(tickStatistics.duration1Min())) .build() ); report.add(empty()); @@ -194,17 +246,17 @@ public class HealthModule implements CommandModule { ); report.add(text() .content(" ") - .append(formatCpuUsage(CpuMonitor.systemLoad10SecAvg())).append(text(", ")) - .append(formatCpuUsage(CpuMonitor.systemLoad1MinAvg())).append(text(", ")) - .append(formatCpuUsage(CpuMonitor.systemLoad15MinAvg())) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad10SecAvg())).append(text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad1MinAvg())).append(text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad15MinAvg())) .append(text(" (system)", DARK_GRAY)) .build() ); report.add(text() .content(" ") - .append(formatCpuUsage(CpuMonitor.processLoad10SecAvg())).append(text(", ")) - .append(formatCpuUsage(CpuMonitor.processLoad1MinAvg())).append(text(", ")) - .append(formatCpuUsage(CpuMonitor.processLoad15MinAvg())) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad10SecAvg())).append(text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad1MinAvg())).append(text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad15MinAvg())) .append(text(" (process)", DARK_GRAY)) .build() ); @@ -232,7 +284,7 @@ public class HealthModule implements CommandModule { .append(text(")", GRAY)) .build() ); - report.add(text().content(" ").append(generateMemoryUsageDiagram(heapUsage, 40)).build()); + report.add(text().content(" ").append(StatisticFormatter.generateMemoryUsageDiagram(heapUsage, 60)).build()); report.add(empty()); } @@ -283,7 +335,7 @@ public class HealthModule implements CommandModule { .append(text(")", GRAY)) .build() ); - report.add(text().content(" ").append(generateMemoryPoolDiagram(usage, collectionUsage, 40)).build()); + report.add(text().content(" ").append(StatisticFormatter.generateMemoryPoolDiagram(usage, collectionUsage, 60)).build()); if (collectionUsage != null) { report.add(text() @@ -327,127 +379,8 @@ public class HealthModule implements CommandModule { .append(text(")", GRAY)) .build() ); - report.add(text().content(" ").append(generateDiskUsageDiagram(used, total, 40)).build()); + report.add(text().content(" ").append(StatisticFormatter.generateDiskUsageDiagram(used, total, 60)).build()); report.add(empty()); } - public static TextComponent formatTps(double tps) { - TextColor color; - if (tps > 18.0) { - color = GREEN; - } else if (tps > 16.0) { - color = YELLOW; - } else { - color = RED; - } - - return text((tps > 20.0 ? "*" : "") + Math.min(Math.round(tps * 100.0) / 100.0, 20.0), color); - } - - public static TextComponent formatTickDurations(RollingAverage average) { - return text() - .append(formatTickDuration(average.min())) - .append(text('/', GRAY)) - .append(formatTickDuration(average.median())) - .append(text('/', GRAY)) - .append(formatTickDuration(average.percentile95th())) - .append(text('/', GRAY)) - .append(formatTickDuration(average.max())) - .build(); - } - - public static TextComponent formatTickDuration(double duration) { - TextColor color; - if (duration >= 50d) { - color = RED; - } else if (duration >= 40d) { - color = YELLOW; - } else { - color = GREEN; - } - - return text(String.format("%.1f", duration), color); - } - - public static TextComponent formatCpuUsage(double usage) { - TextColor color; - if (usage > 0.9) { - color = RED; - } else if (usage > 0.65) { - color = YELLOW; - } else { - color = GREEN; - } - - return text(FormatUtil.percent(usage, 1d), color); - } - - private static TextComponent generateMemoryUsageDiagram(MemoryUsage usage, int length) { - double used = usage.getUsed(); - double committed = usage.getCommitted(); - double max = usage.getMax(); - - int usedChars = (int) ((used * length) / max); - int committedChars = (int) ((committed * length) / max); - - TextComponent.Builder line = text().content(Strings.repeat("/", usedChars)).color(GRAY); - if (committedChars > usedChars) { - line.append(text(Strings.repeat(" ", (committedChars - usedChars) - 1))); - line.append(text("|", YELLOW)); - } - if (length > committedChars) { - line.append(text(Strings.repeat(" ", (length - committedChars)))); - } - - return text() - .append(text("[", DARK_GRAY)) - .append(line.build()) - .append(text("]", DARK_GRAY)) - .build(); - } - - private static TextComponent generateMemoryPoolDiagram(MemoryUsage usage, MemoryUsage collectionUsage, int length) { - double used = usage.getUsed(); - double collectionUsed = used; - if (collectionUsage != null) { - collectionUsed = collectionUsage.getUsed(); - } - double committed = usage.getCommitted(); - double max = usage.getMax(); - - int usedChars = (int) ((used * length) / max); - int collectionUsedChars = (int) ((collectionUsed * length) / max); - int committedChars = (int) ((committed * length) / max); - - TextComponent.Builder line = text().content(Strings.repeat("/", collectionUsedChars)).color(GRAY); - - if (usedChars > collectionUsedChars) { - line.append(text("|", RED)); - line.append(text(Strings.repeat("/", (usedChars - collectionUsedChars) - 1), GRAY)); - } - if (committedChars > usedChars) { - line.append(text(Strings.repeat(" ", (committedChars - usedChars) - 1))); - line.append(text("|", YELLOW)); - } - if (length > committedChars) { - line.append(text(Strings.repeat(" ", (length - committedChars)))); - } - - return text() - .append(text("[", DARK_GRAY)) - .append(line.build()) - .append(text("]", DARK_GRAY)) - .build(); - } - - private static TextComponent generateDiskUsageDiagram(double used, double max, int length) { - int usedChars = (int) ((used * length) / max); - String line = Strings.repeat("/", usedChars) + Strings.repeat(" ", length - usedChars); - return text() - .append(text("[", DARK_GRAY)) - .append(text(line, GRAY)) - .append(text("]", DARK_GRAY)) - .build(); - } - } diff --git a/spark-common/src/main/java/me/lucko/spark/common/monitor/MonitoringExecutor.java b/spark-common/src/main/java/me/lucko/spark/common/monitor/MonitoringExecutor.java new file mode 100644 index 0000000..779dbbf --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/monitor/MonitoringExecutor.java @@ -0,0 +1,16 @@ +package me.lucko.spark.common.monitor; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + +public enum MonitoringExecutor { + ; + + /** The executor used to monitor & calculate rolling averages. */ + public static final ScheduledExecutorService INSTANCE = Executors.newSingleThreadScheduledExecutor(r -> { + Thread thread = Executors.defaultThreadFactory().newThread(r); + thread.setName("spark-monitor"); + thread.setDaemon(true); + return thread; + }); +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/monitor/cpu/CpuMonitor.java b/spark-common/src/main/java/me/lucko/spark/common/monitor/cpu/CpuMonitor.java index 43e1f90..b4ab831 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/monitor/cpu/CpuMonitor.java +++ b/spark-common/src/main/java/me/lucko/spark/common/monitor/cpu/CpuMonitor.java @@ -20,12 +20,11 @@ package me.lucko.spark.common.monitor.cpu; +import me.lucko.spark.common.monitor.MonitoringExecutor; import me.lucko.spark.common.util.RollingAverage; import java.lang.management.ManagementFactory; import java.math.BigDecimal; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.management.JMX; @@ -42,13 +41,6 @@ public enum CpuMonitor { private static final String OPERATING_SYSTEM_BEAN = "java.lang:type=OperatingSystem"; /** The OperatingSystemMXBean instance */ private static final OperatingSystemMXBean BEAN; - /** The executor used to monitor & calculate rolling averages. */ - private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor(r -> { - Thread thread = Executors.defaultThreadFactory().newThread(r); - thread.setName("spark-cpu-monitor"); - thread.setDaemon(true); - return thread; - }); // Rolling averages for system/process data private static final RollingAverage SYSTEM_AVERAGE_10_SEC = new RollingAverage(10); @@ -68,7 +60,7 @@ public enum CpuMonitor { } // schedule rolling average calculations. - EXECUTOR.scheduleAtFixedRate(new RollingAverageCollectionTask(), 1, 1, TimeUnit.SECONDS); + MonitoringExecutor.INSTANCE.scheduleAtFixedRate(new RollingAverageCollectionTask(), 1, 1, TimeUnit.SECONDS); } /** diff --git a/spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PingStatistics.java b/spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PingStatistics.java new file mode 100644 index 0000000..8b5b5b3 --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PingStatistics.java @@ -0,0 +1,148 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.common.monitor.ping; + +import me.lucko.spark.common.monitor.MonitoringExecutor; +import me.lucko.spark.common.util.RollingAverage; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.math.BigDecimal; +import java.util.Map; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +/** + * Provides statistics for player ping RTT to the server. + */ +public final class PingStatistics implements Runnable, AutoCloseable { + private static final int WINDOW_SIZE_SECONDS = (int) TimeUnit.MINUTES.toSeconds(15); + private static final int QUERY_RATE_SECONDS = 10; + + /** The platform function that provides player ping times */ + private final PlayerPingProvider provider; + /** Rolling average of the median ping across all players */ + private final RollingAverage rollingAverage = new RollingAverage(WINDOW_SIZE_SECONDS / QUERY_RATE_SECONDS); + + /** The scheduler task that polls pings and calculates the rolling average */ + private ScheduledFuture future; + + public PingStatistics(PlayerPingProvider provider) { + this.provider = provider; + } + + /** + * Starts the statistics monitor + */ + public void start() { + if (this.future != null) { + throw new IllegalStateException(); + } + this.future = MonitoringExecutor.INSTANCE.scheduleAtFixedRate(this, QUERY_RATE_SECONDS, QUERY_RATE_SECONDS, TimeUnit.SECONDS); + } + + @Override + public void close() { + if (this.future != null) { + this.future.cancel(false); + this.future = null; + } + } + + @Override + public void run() { + PingSummary summary = currentSummary(); + if (summary.total() == 0) { + return; + } + + this.rollingAverage.add(BigDecimal.valueOf(summary.median())); + } + + /** + * Gets the ping rolling average. + * + * @return the rolling average + */ + public RollingAverage getPingAverage() { + return this.rollingAverage; + } + + /** + * Queries a summary of current player pings. + * + * @return a summary of current pings + */ + public PingSummary currentSummary() { + Map results = this.provider.poll(); + int[] values = results.values().stream().filter(ping -> ping > 0).mapToInt(i -> i).toArray(); + return values.length == 0 + ? new PingSummary(new int[]{0}) + : new PingSummary(values); + } + + /** + * Queries the ping of a given player. + * + * @param playerName the name of the player + * @return the ping, if available + */ + public @Nullable PlayerPing query(String playerName) { + Map results = this.provider.poll(); + + // try exact match + Integer result = results.get(playerName); + if (result != null) { + return new PlayerPing(playerName, result); + } + + // try case-insensitive match + for (Map.Entry entry : results.entrySet()) { + if (entry.getKey().equalsIgnoreCase(playerName)) { + return new PlayerPing( + entry.getKey(), + entry.getValue() + ); + } + } + + return null; + } + + public static final class PlayerPing { + private final String name; + private final int ping; + + PlayerPing(String name, int ping) { + this.name = name; + this.ping = ping; + } + + public String name() { + return this.name; + } + + public int ping() { + return this.ping; + } + } + +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PingSummary.java b/spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PingSummary.java new file mode 100644 index 0000000..024d27d --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PingSummary.java @@ -0,0 +1,81 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.common.monitor.ping; + +import java.util.Arrays; + +public final class PingSummary { + + private final int[] values; + private final int total; + private final int max; + private final int min; + private final double mean; + + public PingSummary(int[] values) { + Arrays.sort(values); + this.values = values; + + int total = 0; + for (int value : values) { + total += value; + } + this.total = total; + + this.mean = (double) total / values.length; + this.max = values[values.length - 1]; + this.min = values[0]; + } + + public int total() { + return this.total; + } + + public double mean() { + return this.mean; + } + + public int max() { + return this.max; + } + + public int min() { + return this.min; + } + + public int percentile(double percentile) { + if (percentile < 0 || percentile > 1) { + throw new IllegalArgumentException("Invalid percentile " + percentile); + } + + int rank = (int) Math.ceil(percentile * (this.values.length - 1)); + return this.values[rank]; + } + + public double median() { + return percentile(0.50d); + } + + public double percentile95th() { + return percentile(0.95d); + } + +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PlayerPingProvider.java b/spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PlayerPingProvider.java new file mode 100644 index 0000000..7576573 --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/monitor/ping/PlayerPingProvider.java @@ -0,0 +1,40 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.common.monitor.ping; + +import java.util.Map; + +/** + * Provides information about player ping RTT. + */ +@FunctionalInterface +public interface PlayerPingProvider { + + /** + * Poll current player pings in milliseconds. + * + *

The map keys are player names and the values are the ping values.

+ * + * @return a map of player pings + */ + Map poll(); + +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/platform/PlatformStatisticsProvider.java b/spark-common/src/main/java/me/lucko/spark/common/platform/PlatformStatisticsProvider.java index fce45ec..5b8d1d4 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/platform/PlatformStatisticsProvider.java +++ b/spark-common/src/main/java/me/lucko/spark/common/platform/PlatformStatisticsProvider.java @@ -26,6 +26,7 @@ import me.lucko.spark.common.monitor.cpu.CpuMonitor; import me.lucko.spark.common.monitor.disk.DiskUsage; import me.lucko.spark.common.monitor.memory.GarbageCollectorStatistics; import me.lucko.spark.common.monitor.memory.MemoryInfo; +import me.lucko.spark.common.monitor.ping.PingStatistics; import me.lucko.spark.common.monitor.tick.TickStatistics; import me.lucko.spark.common.util.RollingAverage; import me.lucko.spark.proto.SparkProtos.PlatformStatistics; @@ -148,18 +149,26 @@ public class PlatformStatisticsProvider { ); if (tickStatistics.isDurationSupported()) { builder.setMspt(PlatformStatistics.Mspt.newBuilder() - .setLast1M(msptValues(tickStatistics.duration1Min())) - .setLast5M(msptValues(tickStatistics.duration5Min())) + .setLast1M(rollingAverageValues(tickStatistics.duration1Min())) + .setLast5M(rollingAverageValues(tickStatistics.duration5Min())) .build() ); } } + PingStatistics pingStatistics = this.platform.getPingStatistics(); + if (pingStatistics != null && pingStatistics.getPingAverage().getSamples() != 0) { + builder.setPing(PlatformStatistics.Ping.newBuilder() + .setLast15M(rollingAverageValues(pingStatistics.getPingAverage())) + .build() + ); + } + return builder.build(); } - private static PlatformStatistics.Mspt.Values msptValues(RollingAverage rollingAverage) { - return PlatformStatistics.Mspt.Values.newBuilder() + private static PlatformStatistics.RollingAverageValues rollingAverageValues(RollingAverage rollingAverage) { + return PlatformStatistics.RollingAverageValues.newBuilder() .setMean(rollingAverage.mean()) .setMax(rollingAverage.max()) .setMin(rollingAverage.min()) diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/RollingAverage.java b/spark-common/src/main/java/me/lucko/spark/common/util/RollingAverage.java index 87c41a4..57dfdff 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/util/RollingAverage.java +++ b/spark-common/src/main/java/me/lucko/spark/common/util/RollingAverage.java @@ -39,6 +39,12 @@ public class RollingAverage implements DoubleAverageInfo { this.samples = new ArrayDeque<>(this.windowSize + 1); } + public int getSamples() { + synchronized (this) { + return this.samples.size(); + } + } + public void add(BigDecimal num) { synchronized (this) { this.total = this.total.add(num); diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/StatisticFormatter.java b/spark-common/src/main/java/me/lucko/spark/common/util/StatisticFormatter.java new file mode 100644 index 0000000..9a2850e --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/util/StatisticFormatter.java @@ -0,0 +1,187 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.common.util; + +import com.google.common.base.Strings; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.format.TextColor; + +import java.lang.management.MemoryUsage; + +import static net.kyori.adventure.text.Component.text; +import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY; +import static net.kyori.adventure.text.format.NamedTextColor.GRAY; +import static net.kyori.adventure.text.format.NamedTextColor.GREEN; +import static net.kyori.adventure.text.format.NamedTextColor.RED; +import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; + +public enum StatisticFormatter { + ; + + private static final String BAR_CHARACTER = "|"; + + public static TextComponent formatTps(double tps) { + TextColor color; + if (tps > 18.0) { + color = GREEN; + } else if (tps > 16.0) { + color = YELLOW; + } else { + color = RED; + } + + return text((tps > 20.0 ? "*" : "") + Math.min(Math.round(tps * 100.0) / 100.0, 20.0), color); + } + + public static TextComponent formatTickDurations(RollingAverage average) { + return text() + .append(formatTickDuration(average.min())) + .append(text('/', GRAY)) + .append(formatTickDuration(average.median())) + .append(text('/', GRAY)) + .append(formatTickDuration(average.percentile95th())) + .append(text('/', GRAY)) + .append(formatTickDuration(average.max())) + .build(); + } + + public static TextComponent formatTickDuration(double duration) { + TextColor color; + if (duration >= 50d) { + color = RED; + } else if (duration >= 40d) { + color = YELLOW; + } else { + color = GREEN; + } + + return text(String.format("%.1f", duration), color); + } + + public static TextComponent formatCpuUsage(double usage) { + TextColor color; + if (usage > 0.9) { + color = RED; + } else if (usage > 0.65) { + color = YELLOW; + } else { + color = GREEN; + } + + return text(FormatUtil.percent(usage, 1d), color); + } + + public static TextComponent formatPingRtts(double min, double median, double percentile95th, double max) { + return text() + .append(formatPingRtt(min)) + .append(text('/', GRAY)) + .append(formatPingRtt(median)) + .append(text('/', GRAY)) + .append(formatPingRtt(percentile95th)) + .append(text('/', GRAY)) + .append(formatPingRtt(max)) + .build(); + } + + public static TextComponent formatPingRtt(double ping) { + TextColor color; + if (ping >= 200) { + color = RED; + } else if (ping >= 100) { + color = YELLOW; + } else { + color = GREEN; + } + + return text((int) Math.ceil(ping), color); + } + + public static TextComponent generateMemoryUsageDiagram(MemoryUsage usage, int length) { + double used = usage.getUsed(); + double committed = usage.getCommitted(); + double max = usage.getMax(); + + int usedChars = (int) ((used * length) / max); + int committedChars = (int) ((committed * length) / max); + + TextComponent.Builder line = text().content(Strings.repeat(BAR_CHARACTER, usedChars)).color(YELLOW); + if (committedChars > usedChars) { + line.append(text(Strings.repeat(BAR_CHARACTER, (committedChars - usedChars) - 1), GRAY)); + line.append(Component.text(BAR_CHARACTER, RED)); + } + if (length > committedChars) { + line.append(text(Strings.repeat(BAR_CHARACTER, (length - committedChars)), GRAY)); + } + + return text() + .append(text("[", DARK_GRAY)) + .append(line.build()) + .append(text("]", DARK_GRAY)) + .build(); + } + + public static TextComponent generateMemoryPoolDiagram(MemoryUsage usage, MemoryUsage collectionUsage, int length) { + double used = usage.getUsed(); + double collectionUsed = used; + if (collectionUsage != null) { + collectionUsed = collectionUsage.getUsed(); + } + double committed = usage.getCommitted(); + double max = usage.getMax(); + + int usedChars = (int) ((used * length) / max); + int collectionUsedChars = (int) ((collectionUsed * length) / max); + int committedChars = (int) ((committed * length) / max); + + TextComponent.Builder line = text().content(Strings.repeat(BAR_CHARACTER, collectionUsedChars)).color(YELLOW); + + if (usedChars > collectionUsedChars) { + line.append(Component.text(BAR_CHARACTER, RED)); + line.append(text(Strings.repeat(BAR_CHARACTER, (usedChars - collectionUsedChars) - 1), YELLOW)); + } + if (committedChars > usedChars) { + line.append(text(Strings.repeat(BAR_CHARACTER, (committedChars - usedChars) - 1), GRAY)); + line.append(Component.text(BAR_CHARACTER, YELLOW)); + } + if (length > committedChars) { + line.append(text(Strings.repeat(BAR_CHARACTER, (length - committedChars)), GRAY)); + } + + return text() + .append(text("[", DARK_GRAY)) + .append(line.build()) + .append(text("]", DARK_GRAY)) + .build(); + } + + public static TextComponent generateDiskUsageDiagram(double used, double max, int length) { + int usedChars = (int) ((used * length) / max); + int freeChars = length - usedChars; + return text() + .append(text("[", DARK_GRAY)) + .append(text(Strings.repeat(BAR_CHARACTER, usedChars), YELLOW)) + .append(text(Strings.repeat(BAR_CHARACTER, freeChars), GRAY)) + .append(text("]", DARK_GRAY)) + .build(); + } +} diff --git a/spark-common/src/main/proto/spark/spark.proto b/spark-common/src/main/proto/spark/spark.proto index ae04cd7..d800762 100644 --- a/spark-common/src/main/proto/spark/spark.proto +++ b/spark-common/src/main/proto/spark/spark.proto @@ -85,6 +85,7 @@ message PlatformStatistics { int64 uptime = 3; Tps tps = 4; // optional Mspt mspt = 5; // optional + Ping ping = 6; // optional message Memory { MemoryPool heap = 1; @@ -108,16 +109,20 @@ message PlatformStatistics { } message Mspt { - Values last1m = 1; - Values last5m = 2; - - message Values { - double mean = 1; - double max = 2; - double min = 3; - double median = 4; - double percentile95 = 5; - } + RollingAverageValues last1m = 1; + RollingAverageValues last5m = 2; + } + + message Ping { + RollingAverageValues last15m = 1; + } + + message RollingAverageValues { + double mean = 1; + double max = 2; + double min = 3; + double median = 4; + double percentile95 = 5; } } diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricPlayerPingProvider.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricPlayerPingProvider.java new file mode 100644 index 0000000..bae6c41 --- /dev/null +++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricPlayerPingProvider.java @@ -0,0 +1,47 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.fabric; + +import com.google.common.collect.ImmutableMap; + +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerPlayerEntity; + +import java.util.Map; + +public class FabricPlayerPingProvider implements PlayerPingProvider { + private final MinecraftServer server; + + public FabricPlayerPingProvider(MinecraftServer server) { + this.server = server; + } + + @Override + public Map poll() { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (ServerPlayerEntity player : this.server.getPlayerManager().getPlayerList()) { + builder.put(player.getGameProfile().getName(), player.pingMilliseconds); + } + return builder.build(); + } +} diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java index 9171cbb..b9cff691 100644 --- a/spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java +++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java @@ -4,10 +4,10 @@ import eu.pb4.placeholders.PlaceholderAPI; import eu.pb4.placeholders.PlaceholderResult; import me.lucko.spark.common.SparkPlatform; -import me.lucko.spark.common.command.modules.HealthModule; import me.lucko.spark.common.monitor.cpu.CpuMonitor; import me.lucko.spark.common.monitor.tick.TickStatistics; import me.lucko.spark.common.util.RollingAverage; +import me.lucko.spark.common.util.StatisticFormatter; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; @@ -47,16 +47,16 @@ public class SparkFabricPlaceholderApi { if (tps == null) { return PlaceholderResult.invalid("Invalid argument"); } else { - return PlaceholderResult.value(toText(HealthModule.formatTps(tps))); + return PlaceholderResult.value(toText(StatisticFormatter.formatTps(tps))); } } else { return PlaceholderResult.value(toText( Component.text() - .append(HealthModule.formatTps(tickStatistics.tps5Sec())).append(Component.text(", ")) - .append(HealthModule.formatTps(tickStatistics.tps10Sec())).append(Component.text(", ")) - .append(HealthModule.formatTps(tickStatistics.tps1Min())).append(Component.text(", ")) - .append(HealthModule.formatTps(tickStatistics.tps5Min())).append(Component.text(", ")) - .append(HealthModule.formatTps(tickStatistics.tps15Min())) + .append(StatisticFormatter.formatTps(tickStatistics.tps5Sec())).append(Component.text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps10Sec())).append(Component.text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps1Min())).append(Component.text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps5Min())).append(Component.text(", ")) + .append(StatisticFormatter.formatTps(tickStatistics.tps15Min())) .build() )); } @@ -84,13 +84,13 @@ public class SparkFabricPlaceholderApi { if (duration == null) { return PlaceholderResult.invalid("Invalid argument"); } else { - return PlaceholderResult.value(toText(HealthModule.formatTickDurations(duration))); + return PlaceholderResult.value(toText(StatisticFormatter.formatTickDurations(duration))); } } else { return PlaceholderResult.value(toText( Component.text() - .append(HealthModule.formatTickDurations(tickStatistics.duration10Sec())).append(Component.text("; ")) - .append(HealthModule.formatTickDurations(tickStatistics.duration1Min())) + .append(StatisticFormatter.formatTickDurations(tickStatistics.duration10Sec())).append(Component.text("; ")) + .append(StatisticFormatter.formatTickDurations(tickStatistics.duration1Min())) .build() )); } @@ -115,14 +115,14 @@ public class SparkFabricPlaceholderApi { if (usage == null) { return PlaceholderResult.invalid("Invalid argument"); } else { - return PlaceholderResult.value(toText(HealthModule.formatCpuUsage(usage))); + return PlaceholderResult.value(toText(StatisticFormatter.formatCpuUsage(usage))); } } else { return PlaceholderResult.value(toText( Component.text() - .append(HealthModule.formatCpuUsage(CpuMonitor.systemLoad10SecAvg())).append(Component.text(", ")) - .append(HealthModule.formatCpuUsage(CpuMonitor.systemLoad1MinAvg())).append(Component.text(", ")) - .append(HealthModule.formatCpuUsage(CpuMonitor.systemLoad15MinAvg())) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad10SecAvg())).append(Component.text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad1MinAvg())).append(Component.text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad15MinAvg())) .build() )); } @@ -147,14 +147,14 @@ public class SparkFabricPlaceholderApi { if (usage == null) { return PlaceholderResult.invalid("Invalid argument"); } else { - return PlaceholderResult.value(toText(HealthModule.formatCpuUsage(usage))); + return PlaceholderResult.value(toText(StatisticFormatter.formatCpuUsage(usage))); } } else { return PlaceholderResult.value(toText( Component.text() - .append(HealthModule.formatCpuUsage(CpuMonitor.processLoad10SecAvg())).append(Component.text(", ")) - .append(HealthModule.formatCpuUsage(CpuMonitor.processLoad1MinAvg())).append(Component.text(", ")) - .append(HealthModule.formatCpuUsage(CpuMonitor.processLoad15MinAvg())) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad10SecAvg())).append(Component.text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad1MinAvg())).append(Component.text(", ")) + .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad15MinAvg())) .build() )); } diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java index 617564a..6dc5483 100644 --- a/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java +++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java @@ -29,11 +29,13 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import me.lucko.fabric.api.permissions.v0.Permissions; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.tick.TickHook; import me.lucko.spark.common.tick.TickReporter; import me.lucko.spark.fabric.FabricCommandSender; import me.lucko.spark.fabric.FabricPlatformInfo; +import me.lucko.spark.fabric.FabricPlayerPingProvider; import me.lucko.spark.fabric.FabricSparkMod; import me.lucko.spark.fabric.FabricTickHook; import me.lucko.spark.fabric.FabricTickReporter; @@ -140,6 +142,11 @@ public class FabricServerSparkPlugin extends FabricSparkPlugin implements Comman return new FabricTickReporter.Server(); } + @Override + public PlayerPingProvider createPlayerPingProvider() { + return new FabricPlayerPingProvider(this.server); + } + @Override public PlatformInfo getPlatformInfo() { return new FabricPlatformInfo(PlatformInfo.Type.SERVER); diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgePlayerPingProvider.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgePlayerPingProvider.java new file mode 100644 index 0000000..f31cc5b --- /dev/null +++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgePlayerPingProvider.java @@ -0,0 +1,47 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.forge; + +import com.google.common.collect.ImmutableMap; + +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; + +import java.util.Map; + +public class ForgePlayerPingProvider implements PlayerPingProvider { + private final MinecraftServer server; + + public ForgePlayerPingProvider(MinecraftServer server) { + this.server = server; + } + + @Override + public Map poll() { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (ServerPlayer player : this.server.getPlayerList().getPlayers()) { + builder.put(player.getGameProfile().getName(), player.latency); + } + return builder.build(); + } +} diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeServerSparkPlugin.java b/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeServerSparkPlugin.java index c03bb05..bbfb8a5 100644 --- a/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeServerSparkPlugin.java +++ b/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeServerSparkPlugin.java @@ -29,11 +29,13 @@ import com.mojang.brigadier.suggestion.SuggestionProvider; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.tick.TickHook; import me.lucko.spark.common.tick.TickReporter; import me.lucko.spark.forge.ForgeCommandSender; import me.lucko.spark.forge.ForgePlatformInfo; +import me.lucko.spark.forge.ForgePlayerPingProvider; import me.lucko.spark.forge.ForgeSparkMod; import me.lucko.spark.forge.ForgeTickHook; import me.lucko.spark.forge.ForgeTickReporter; @@ -200,6 +202,11 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< return new ForgeTickReporter(TickEvent.Type.SERVER); } + @Override + public PlayerPingProvider createPlayerPingProvider() { + return new ForgePlayerPingProvider(this.server); + } + @Override public PlatformInfo getPlatformInfo() { return new ForgePlatformInfo(PlatformInfo.Type.SERVER); diff --git a/spark-nukkit/src/main/java/me/lucko/spark/nukkit/NukkitPlayerPingProvider.java b/spark-nukkit/src/main/java/me/lucko/spark/nukkit/NukkitPlayerPingProvider.java new file mode 100644 index 0000000..fc25d7c --- /dev/null +++ b/spark-nukkit/src/main/java/me/lucko/spark/nukkit/NukkitPlayerPingProvider.java @@ -0,0 +1,47 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.nukkit; + +import com.google.common.collect.ImmutableMap; + +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; + +import cn.nukkit.Player; +import cn.nukkit.Server; + +import java.util.Map; + +public class NukkitPlayerPingProvider implements PlayerPingProvider { + private final Server server; + + public NukkitPlayerPingProvider(Server server) { + this.server = server; + } + + @Override + public Map poll() { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (Player player : this.server.getOnlinePlayers().values()) { + builder.put(player.getName(), player.getPing()); + } + return builder.build(); + } +} diff --git a/spark-nukkit/src/main/java/me/lucko/spark/nukkit/NukkitSparkPlugin.java b/spark-nukkit/src/main/java/me/lucko/spark/nukkit/NukkitSparkPlugin.java index c9e099d..18132c3 100644 --- a/spark-nukkit/src/main/java/me/lucko/spark/nukkit/NukkitSparkPlugin.java +++ b/spark-nukkit/src/main/java/me/lucko/spark/nukkit/NukkitSparkPlugin.java @@ -23,6 +23,7 @@ package me.lucko.spark.nukkit; import me.lucko.spark.api.Spark; import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.SparkPlugin; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.util.ClassSourceLookup; @@ -107,6 +108,11 @@ public class NukkitSparkPlugin extends PluginBase implements SparkPlugin { return new NukkitClassSourceLookup(); } + @Override + public PlayerPingProvider createPlayerPingProvider() { + return new NukkitPlayerPingProvider(getServer()); + } + @Override public PlatformInfo getPlatformInfo() { return new NukkitPlatformInfo(getServer()); diff --git a/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7PlayerPingProvider.java b/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7PlayerPingProvider.java new file mode 100644 index 0000000..8f4c15f --- /dev/null +++ b/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7PlayerPingProvider.java @@ -0,0 +1,47 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.sponge; + +import com.google.common.collect.ImmutableMap; + +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; + +import org.spongepowered.api.Server; +import org.spongepowered.api.entity.living.player.Player; + +import java.util.Map; + +public class Sponge7PlayerPingProvider implements PlayerPingProvider { + private final Server server; + + public Sponge7PlayerPingProvider(Server server) { + this.server = server; + } + + @Override + public Map poll() { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (Player player : this.server.getOnlinePlayers()) { + builder.put(player.getName(), player.getConnection().getLatency()); + } + return builder.build(); + } +} diff --git a/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7SparkPlugin.java b/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7SparkPlugin.java index 7ac317b..1aed04a 100644 --- a/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7SparkPlugin.java +++ b/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7SparkPlugin.java @@ -25,6 +25,7 @@ import com.google.inject.Inject; import me.lucko.spark.api.Spark; import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.SparkPlugin; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.sampler.ThreadDumper; import me.lucko.spark.common.tick.TickHook; @@ -144,6 +145,15 @@ public class Sponge7SparkPlugin implements SparkPlugin { return new Sponge7TickHook(this); } + @Override + public PlayerPingProvider createPlayerPingProvider() { + if (this.game.isServerAvailable()) { + return new Sponge7PlayerPingProvider(this.game.getServer()); + } else { + return null; + } + } + @Override public PlatformInfo getPlatformInfo() { return new Sponge7PlatformInfo(this.game); diff --git a/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8PlayerPingProvider.java b/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8PlayerPingProvider.java new file mode 100644 index 0000000..2bcaf6a --- /dev/null +++ b/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8PlayerPingProvider.java @@ -0,0 +1,47 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.sponge; + +import com.google.common.collect.ImmutableMap; + +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; + +import org.spongepowered.api.Server; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; + +import java.util.Map; + +public class Sponge8PlayerPingProvider implements PlayerPingProvider { + private final Server server; + + public Sponge8PlayerPingProvider(Server server) { + this.server = server; + } + + @Override + public Map poll() { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (ServerPlayer player : this.server.onlinePlayers()) { + builder.put(player.name(), player.connection().latency()); + } + return builder.build(); + } +} diff --git a/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8SparkPlugin.java b/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8SparkPlugin.java index 0195b24..6eb2674 100644 --- a/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8SparkPlugin.java +++ b/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8SparkPlugin.java @@ -25,6 +25,7 @@ import com.google.inject.Inject; import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.SparkPlugin; import me.lucko.spark.common.command.sender.CommandSender; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.sampler.ThreadDumper; import me.lucko.spark.common.tick.TickHook; @@ -146,6 +147,15 @@ public class Sponge8SparkPlugin implements SparkPlugin { return new Sponge8TickHook(this.pluginContainer, this.game); } + @Override + public PlayerPingProvider createPlayerPingProvider() { + if (this.game.isServerAvailable()) { + return new Sponge8PlayerPingProvider(this.game.server()); + } else { + return null; + } + } + @Override public PlatformInfo getPlatformInfo() { return new Sponge8PlatformInfo(this.game); diff --git a/spark-velocity/src/main/java/me/lucko/spark/velocity/VelocityPlayerPingProvider.java b/spark-velocity/src/main/java/me/lucko/spark/velocity/VelocityPlayerPingProvider.java new file mode 100644 index 0000000..382ea22 --- /dev/null +++ b/spark-velocity/src/main/java/me/lucko/spark/velocity/VelocityPlayerPingProvider.java @@ -0,0 +1,46 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.velocity; + +import com.google.common.collect.ImmutableMap; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; + +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; + +import java.util.Map; + +public class VelocityPlayerPingProvider implements PlayerPingProvider { + private final ProxyServer proxy; + + public VelocityPlayerPingProvider(ProxyServer proxy) { + this.proxy = proxy; + } + + @Override + public Map poll() { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (Player player : this.proxy.getAllPlayers()) { + builder.put(player.getUsername(), (int) player.getPing()); + } + return builder.build(); + } +} diff --git a/spark-velocity/src/main/java/me/lucko/spark/velocity/VelocitySparkPlugin.java b/spark-velocity/src/main/java/me/lucko/spark/velocity/VelocitySparkPlugin.java index 698aab0..7d9ced8 100644 --- a/spark-velocity/src/main/java/me/lucko/spark/velocity/VelocitySparkPlugin.java +++ b/spark-velocity/src/main/java/me/lucko/spark/velocity/VelocitySparkPlugin.java @@ -32,6 +32,7 @@ import com.velocitypowered.api.proxy.ProxyServer; import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.SparkPlugin; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.util.ClassSourceLookup; @@ -132,6 +133,11 @@ public class VelocitySparkPlugin implements SparkPlugin, SimpleCommand { return new VelocityClassSourceLookup(this.proxy.getPluginManager()); } + @Override + public PlayerPingProvider createPlayerPingProvider() { + return new VelocityPlayerPingProvider(this.proxy); + } + @Override public PlatformInfo getPlatformInfo() { return new VelocityPlatformInfo(this.proxy); diff --git a/spark-velocity4/src/main/java/me/lucko/spark/velocity/Velocity4PlayerPingProvider.java b/spark-velocity4/src/main/java/me/lucko/spark/velocity/Velocity4PlayerPingProvider.java new file mode 100644 index 0000000..18f36a7 --- /dev/null +++ b/spark-velocity4/src/main/java/me/lucko/spark/velocity/Velocity4PlayerPingProvider.java @@ -0,0 +1,46 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.velocity; + +import com.google.common.collect.ImmutableMap; +import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.api.proxy.connection.Player; + +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; + +import java.util.Map; + +public class Velocity4PlayerPingProvider implements PlayerPingProvider { + private final ProxyServer proxy; + + public Velocity4PlayerPingProvider(ProxyServer proxy) { + this.proxy = proxy; + } + + @Override + public Map poll() { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (Player player : this.proxy.connectedPlayers()) { + builder.put(player.username(), (int) player.ping()); + } + return builder.build(); + } +} diff --git a/spark-velocity4/src/main/java/me/lucko/spark/velocity/Velocity4SparkPlugin.java b/spark-velocity4/src/main/java/me/lucko/spark/velocity/Velocity4SparkPlugin.java index e1acd57..0c57689 100644 --- a/spark-velocity4/src/main/java/me/lucko/spark/velocity/Velocity4SparkPlugin.java +++ b/spark-velocity4/src/main/java/me/lucko/spark/velocity/Velocity4SparkPlugin.java @@ -32,6 +32,7 @@ import com.velocitypowered.api.proxy.ProxyServer; import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.SparkPlugin; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.util.ClassSourceLookup; @@ -132,6 +133,11 @@ public class Velocity4SparkPlugin implements SparkPlugin, SimpleCommand { return new Velocity4ClassSourceLookup(this.proxy.pluginManager()); } + @Override + public PlayerPingProvider createPlayerPingProvider() { + return new Velocity4PlayerPingProvider(this.proxy); + } + @Override public PlatformInfo getPlatformInfo() { return new Velocity4PlatformInfo(this.proxy); diff --git a/spark-waterdog/src/main/java/me/lucko/spark/waterdog/WaterdogPlayerPingProvider.java b/spark-waterdog/src/main/java/me/lucko/spark/waterdog/WaterdogPlayerPingProvider.java new file mode 100644 index 0000000..b22325c --- /dev/null +++ b/spark-waterdog/src/main/java/me/lucko/spark/waterdog/WaterdogPlayerPingProvider.java @@ -0,0 +1,47 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.waterdog; + +import com.google.common.collect.ImmutableMap; + +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; + +import dev.waterdog.waterdogpe.ProxyServer; +import dev.waterdog.waterdogpe.player.ProxiedPlayer; + +import java.util.Map; + +public class WaterdogPlayerPingProvider implements PlayerPingProvider { + private final ProxyServer proxy; + + public WaterdogPlayerPingProvider(ProxyServer proxy) { + this.proxy = proxy; + } + + @Override + public Map poll() { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (ProxiedPlayer player : this.proxy.getPlayers().values()) { + builder.put(player.getName(), (int) player.getPing()); + } + return builder.build(); + } +} diff --git a/spark-waterdog/src/main/java/me/lucko/spark/waterdog/WaterdogSparkPlugin.java b/spark-waterdog/src/main/java/me/lucko/spark/waterdog/WaterdogSparkPlugin.java index fd2f031..07b153a 100644 --- a/spark-waterdog/src/main/java/me/lucko/spark/waterdog/WaterdogSparkPlugin.java +++ b/spark-waterdog/src/main/java/me/lucko/spark/waterdog/WaterdogSparkPlugin.java @@ -22,6 +22,7 @@ package me.lucko.spark.waterdog; import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.SparkPlugin; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.util.ClassSourceLookup; @@ -99,6 +100,11 @@ public class WaterdogSparkPlugin extends Plugin implements SparkPlugin { return new WaterdogClassSourceLookup(getProxy()); } + @Override + public PlayerPingProvider createPlayerPingProvider() { + return new WaterdogPlayerPingProvider(getProxy()); + } + @Override public PlatformInfo getPlatformInfo() { return new WaterdogPlatformInfo(); -- cgit From bd0827f199e12a6b31e92e12fb33c549e2788ef8 Mon Sep 17 00:00:00 2001 From: Luck Date: Thu, 20 Jan 2022 22:49:34 +0000 Subject: Expose some server configuration values in the viewer --- .../spark/bukkit/BukkitServerConfigProvider.java | 78 ++++++++++++++ .../me/lucko/spark/bukkit/BukkitSparkPlugin.java | 6 ++ .../java/me/lucko/spark/common/SparkPlugin.java | 10 ++ .../serverconfig/AbstractServerConfigProvider.java | 113 +++++++++++++++++++++ .../serverconfig/ServerConfigProvider.java | 59 +++++++++++ .../spark/common/sampler/AbstractSampler.java | 8 ++ .../src/main/proto/spark/spark_sampler.proto | 1 + 7 files changed, 275 insertions(+) create mode 100644 spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java create mode 100644 spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java create mode 100644 spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/ServerConfigProvider.java (limited to 'spark-bukkit') diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java new file mode 100644 index 0000000..b1d2a60 --- /dev/null +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java @@ -0,0 +1,78 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.bukkit; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonSerializer; + +import me.lucko.spark.common.platform.serverconfig.AbstractServerConfigProvider; + +import org.bukkit.configuration.MemorySection; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; + +public class BukkitServerConfigProvider extends AbstractServerConfigProvider { + private static final Gson GSON = new GsonBuilder() + .registerTypeAdapter(MemorySection.class, (JsonSerializer) (obj, type, ctx) -> ctx.serialize(obj.getValues(false))) + .create(); + + private static final Map FILES = ImmutableMap.of( + "bukkit.yml", FileType.YAML, + "spigot.yml", FileType.YAML, + "paper.yml", FileType.YAML + ); + + // todo: make configurable? + private static final List HIDDEN_PATHS = ImmutableList.of( + "database", + "settings.bungeecord-addresses", + "settings.velocity-support.secret" + ); + + public BukkitServerConfigProvider() { + super(FILES, HIDDEN_PATHS); + } + + @Override + protected JsonElement load(String path, FileType type) throws IOException { + try (BufferedReader reader = Files.newBufferedReader(Paths.get(path), StandardCharsets.UTF_8)) { + YamlConfiguration config = YamlConfiguration.loadConfiguration(reader); + Map values = config.getValues(false); + return GSON.toJsonTree(values); + } + } + + enum FileType { + YAML + } + +} diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitSparkPlugin.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitSparkPlugin.java index 6929a4d..9727277 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitSparkPlugin.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitSparkPlugin.java @@ -27,6 +27,7 @@ import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.SparkPlugin; import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; +import me.lucko.spark.common.platform.serverconfig.ServerConfigProvider; import me.lucko.spark.common.sampler.ThreadDumper; import me.lucko.spark.common.tick.TickHook; import me.lucko.spark.common.tick.TickReporter; @@ -181,6 +182,11 @@ public class BukkitSparkPlugin extends JavaPlugin implements SparkPlugin { } } + @Override + public ServerConfigProvider createServerConfigProvider() { + return new BukkitServerConfigProvider(); + } + @Override public PlatformInfo getPlatformInfo() { return new BukkitPlatformInfo(getServer()); diff --git a/spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java b/spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java index 5feb172..b817df1 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java +++ b/spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java @@ -24,6 +24,7 @@ import me.lucko.spark.api.Spark; import me.lucko.spark.common.command.sender.CommandSender; import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; +import me.lucko.spark.common.platform.serverconfig.ServerConfigProvider; import me.lucko.spark.common.sampler.ThreadDumper; import me.lucko.spark.common.tick.TickHook; import me.lucko.spark.common.tick.TickReporter; @@ -132,6 +133,15 @@ public interface SparkPlugin { return null; } + /** + * Creates a server config provider. + * + * @return the server config provider function + */ + default ServerConfigProvider createServerConfigProvider() { + return ServerConfigProvider.NO_OP; + } + /** * Gets information for the platform. * diff --git a/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java new file mode 100644 index 0000000..98db960 --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java @@ -0,0 +1,113 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.common.platform.serverconfig; + +import com.google.common.collect.ImmutableMap; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * Abstract implementation of {@link ServerConfigProvider}. + * + *

THis implementation is able to delete hidden paths from + * the configurations before they are sent to the viewer.

+ * + * @param the file type + */ +public abstract class AbstractServerConfigProvider> implements ServerConfigProvider { + private final Map files; + private final List hiddenPaths; + + protected AbstractServerConfigProvider(Map files, List hiddenPaths) { + this.files = files; + this.hiddenPaths = hiddenPaths; + } + + @Override + public final Map loadServerConfigurations() { + ImmutableMap.Builder builder = ImmutableMap.builder(); + + this.files.forEach((path, type) -> { + try { + JsonElement json = load(path, type); + delete(json, this.hiddenPaths); + builder.put(path, json); + } catch (Exception e) { + e.printStackTrace(); + } + }); + + return builder.build(); + } + + /** + * Loads a file from the system. + * + * @param path the name of the file to load + * @param type the type of the file + * @return the loaded file + * @throws IOException if an error occurs performing i/o + */ + protected abstract JsonElement load(String path, T type) throws IOException; + + /** + * Deletes the given paths from the json element. + * + * @param json the json element + * @param paths the paths to delete + */ + private static void delete(JsonElement json, List paths) { + for (String path : paths) { + Deque pathDeque = new LinkedList<>(Arrays.asList(path.split("\\."))); + delete(json, pathDeque); + } + } + + private static void delete(JsonElement json, Deque path) { + if (path.isEmpty()) { + return; + } + if (!json.isJsonObject()) { + return; + } + + JsonObject jsonObject = json.getAsJsonObject(); + String member = path.removeFirst(); + + if (!jsonObject.has(member)) { + return; + } + + if (path.isEmpty()) { + jsonObject.remove(member); + } else { + delete(jsonObject.get(member), path); + } + } + +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/ServerConfigProvider.java b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/ServerConfigProvider.java new file mode 100644 index 0000000..1fc2391 --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/ServerConfigProvider.java @@ -0,0 +1,59 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.common.platform.serverconfig; + +import com.google.gson.JsonElement; + +import java.util.Collections; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Function to export server configuration files for access within the spark viewer. + */ +@FunctionalInterface +public interface ServerConfigProvider { + + /** + * Loads a map of the server configuration files. + * + *

The key is the name of the file and the value is a + * {@link JsonElement} of the contents.

+ * + * @return the exported server configurations + */ + Map loadServerConfigurations(); + + default Map exportServerConfigurations() { + return loadServerConfigurations().entrySet() + .stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + e -> e.getValue().toString() + )); + } + + /** + * A no-op implementation + */ + ServerConfigProvider NO_OP = Collections::emptyMap; + +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java index 34abdfa..9ae82e8 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java @@ -23,6 +23,7 @@ package me.lucko.spark.common.sampler; import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.command.sender.CommandSender; import me.lucko.spark.common.monitor.memory.GarbageCollectorStatistics; +import me.lucko.spark.common.platform.serverconfig.ServerConfigProvider; import me.lucko.spark.common.sampler.aggregator.DataAggregator; import me.lucko.spark.common.sampler.node.MergeMode; import me.lucko.spark.common.sampler.node.ThreadNode; @@ -116,6 +117,13 @@ public abstract class AbstractSampler implements Sampler { e.printStackTrace(); } + try { + ServerConfigProvider serverConfigProvider = platform.getPlugin().createServerConfigProvider(); + metadata.putAllServerConfigurations(serverConfigProvider.exportServerConfigurations()); + } catch (Exception e) { + e.printStackTrace(); + } + proto.setMetadata(metadata); } diff --git a/spark-common/src/main/proto/spark/spark_sampler.proto b/spark-common/src/main/proto/spark/spark_sampler.proto index c7cecc3..48e2a87 100644 --- a/spark-common/src/main/proto/spark/spark_sampler.proto +++ b/spark-common/src/main/proto/spark/spark_sampler.proto @@ -23,6 +23,7 @@ message SamplerMetadata { PlatformMetadata platform_metadata = 7; PlatformStatistics platform_statistics = 8; SystemStatistics system_statistics = 9; + map server_configurations = 10; message ThreadDumper { Type type = 1; -- cgit From 1642af9bacc88c20614234296fd596932b14d8df Mon Sep 17 00:00:00 2001 From: Ben Kerllenevich Date: Fri, 21 Jan 2022 15:53:51 -0500 Subject: BukkitServerConfigProvider improvements (#159) --- .../spark/bukkit/BukkitServerConfigProvider.java | 103 +++++++++++++++++---- .../serverconfig/AbstractServerConfigProvider.java | 14 +-- 2 files changed, 95 insertions(+), 22 deletions(-) (limited to 'spark-bukkit') diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java index b1d2a60..5fdd178 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java @@ -20,8 +20,8 @@ package me.lucko.spark.bukkit; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; @@ -32,31 +32,31 @@ import me.lucko.spark.common.platform.serverconfig.AbstractServerConfigProvider; import org.bukkit.configuration.MemorySection; import org.bukkit.configuration.file.YamlConfiguration; +import co.aikar.timings.TimingsManager; + import java.io.BufferedReader; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Properties; public class BukkitServerConfigProvider extends AbstractServerConfigProvider { private static final Gson GSON = new GsonBuilder() .registerTypeAdapter(MemorySection.class, (JsonSerializer) (obj, type, ctx) -> ctx.serialize(obj.getValues(false))) .create(); - private static final Map FILES = ImmutableMap.of( - "bukkit.yml", FileType.YAML, - "spigot.yml", FileType.YAML, - "paper.yml", FileType.YAML - ); - - // todo: make configurable? - private static final List HIDDEN_PATHS = ImmutableList.of( - "database", - "settings.bungeecord-addresses", - "settings.velocity-support.secret" - ); + /** A map of provided files and their type */ + private static final Map FILES; + /** A collection of paths to be excluded from the files */ + private static final Collection HIDDEN_PATHS; public BukkitServerConfigProvider() { super(FILES, HIDDEN_PATHS); @@ -64,15 +64,86 @@ public class BukkitServerConfigProvider extends AbstractServerConfigProvider values = config.getValues(false); + Path filePath = Paths.get(path); + if (!Files.exists(filePath)) { + return null; + } + + try (BufferedReader reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8)) { + Map values; + + if (type == FileType.PROPERTIES) { + Properties properties = new Properties(); + properties.load(reader); + + values = new HashMap<>(); + properties.forEach((k, v) -> { + String key = k.toString(); + String value = v.toString(); + + if ("true".equals(value) || "false".equals(value)) { + values.put(key, Boolean.parseBoolean(value)); + } else if (value.matches("\\d+")) { + values.put(key, Integer.parseInt(value)); + } else { + values.put(key, value); + } + }); + } else if (type == FileType.YAML) { + YamlConfiguration config = YamlConfiguration.loadConfiguration(reader); + values = config.getValues(false); + } else { + throw new IllegalArgumentException("Unknown file type: " + type); + } + return GSON.toJsonTree(values); } } enum FileType { + PROPERTIES, YAML } + static { + ImmutableMap.Builder files = ImmutableMap.builder() + .put("server.properties", FileType.PROPERTIES) + .put("bukkit.yml", FileType.YAML) + .put("spigot.yml", FileType.YAML) + .put("paper.yml", FileType.YAML) + .put("purpur.yml", FileType.YAML); + + for (String config : getSystemPropertyList("spark.serverconfigs.extra")) { + files.put(config, FileType.YAML); + } + + ImmutableSet.Builder hiddenPaths = ImmutableSet.builder() + .add("database") + .add("settings.bungeecord-addresses") + .add("settings.velocity-support.secret") + .add("server-ip") + .add("motd") + .add("resource-pack") + .addAll(getTimingsHiddenConfigs()) + .addAll(getSystemPropertyList("spark.serverconfigs.hiddenpaths")); + + FILES = files.build(); + HIDDEN_PATHS = hiddenPaths.build(); + } + + private static List getSystemPropertyList(String property) { + String value = System.getProperty(property); + return value == null + ? Collections.emptyList() + : Arrays.asList(value.split(",")); + } + + private static List getTimingsHiddenConfigs() { + try { + return TimingsManager.hiddenConfigs; + } catch (NoClassDefFoundError e) { + return Collections.emptyList(); + } + } + } diff --git a/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java index 98db960..1e6f1b4 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java +++ b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java @@ -26,9 +26,9 @@ import com.google.gson.JsonObject; import java.io.IOException; import java.util.Arrays; +import java.util.Collection; import java.util.Deque; import java.util.LinkedList; -import java.util.List; import java.util.Map; /** @@ -41,9 +41,9 @@ import java.util.Map; */ public abstract class AbstractServerConfigProvider> implements ServerConfigProvider { private final Map files; - private final List hiddenPaths; + private final Collection hiddenPaths; - protected AbstractServerConfigProvider(Map files, List hiddenPaths) { + protected AbstractServerConfigProvider(Map files, Collection hiddenPaths) { this.files = files; this.hiddenPaths = hiddenPaths; } @@ -55,8 +55,10 @@ public abstract class AbstractServerConfigProvider> implements this.files.forEach((path, type) -> { try { JsonElement json = load(path, type); - delete(json, this.hiddenPaths); - builder.put(path, json); + if (json != null) { + delete(json, this.hiddenPaths); + builder.put(path, json); + } } catch (Exception e) { e.printStackTrace(); } @@ -81,7 +83,7 @@ public abstract class AbstractServerConfigProvider> implements * @param json the json element * @param paths the paths to delete */ - private static void delete(JsonElement json, List paths) { + private static void delete(JsonElement json, Collection paths) { for (String path : paths) { Deque pathDeque = new LinkedList<>(Arrays.asList(path.split("\\."))); delete(json, pathDeque); -- cgit From ce56c23132383bd5d865070f23dcb89e574b97cd Mon Sep 17 00:00:00 2001 From: Luck Date: Sun, 30 Jan 2022 18:59:48 +0000 Subject: Exclude rcon password from server.properties file --- .../src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java | 1 + .../common/platform/serverconfig/AbstractServerConfigProvider.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'spark-bukkit') diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java index 5fdd178..2042ee1 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java @@ -124,6 +124,7 @@ public class BukkitServerConfigProvider extends AbstractServerConfigProvider> implements } JsonObject jsonObject = json.getAsJsonObject(); - String member = path.removeFirst(); + String member = path.removeFirst().replace("\\.", "."); if (!jsonObject.has(member)) { return; -- cgit From c5494d20ce8c3c8868f0fc8e19a03d7888c6fe78 Mon Sep 17 00:00:00 2001 From: Luck Date: Thu, 3 Feb 2022 19:01:01 +0000 Subject: Fix hidden config paths containing a '.' (#169) --- .../src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java | 2 +- .../common/platform/serverconfig/AbstractServerConfigProvider.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'spark-bukkit') diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java index 2042ee1..e4750f9 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java @@ -124,7 +124,7 @@ public class BukkitServerConfigProvider extends AbstractServerConfigProviderpassword") .addAll(getTimingsHiddenConfigs()) .addAll(getSystemPropertyList("spark.serverconfigs.hiddenpaths")); diff --git a/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java index b40f07f..d9e8bf4 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java +++ b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java @@ -99,7 +99,7 @@ public abstract class AbstractServerConfigProvider> implements } JsonObject jsonObject = json.getAsJsonObject(); - String member = path.removeFirst().replace("\\.", "."); + String member = path.removeFirst().replace("", "."); if (!jsonObject.has(member)) { return; -- cgit From 25f46b649363d99f51b1b5262b5f7c0ce0c3251b Mon Sep 17 00:00:00 2001 From: Luck Date: Sun, 6 Feb 2022 20:25:07 +0000 Subject: Improve build tooling - add version to output file name - check license headers automatically --- HEADER.txt | 17 +++++++++++ build.gradle | 27 ++++++++++++++++-- settings.gradle | 4 +-- spark-api/HEADER.txt | 22 +++++++++++++++ spark-api/build.gradle | 4 +++ spark-bukkit/build.gradle | 29 ++++++++++++++++++- .../java/me/lucko/spark/bukkit/CommandMapUtil.java | 27 ++++++++---------- .../placeholder/SparkPlaceholderProvider.java | 2 +- spark-bungeecord/build.gradle | 29 ++++++++++++++++++- spark-common/build.gradle | 4 +++ .../command/tabcomplete/CompletionSupplier.java | 27 ++++++++---------- .../common/command/tabcomplete/TabCompleter.java | 27 ++++++++---------- .../spark/common/monitor/MonitoringExecutor.java | 20 +++++++++++++ .../lucko/spark/common/sampler/ThreadDumper.java | 1 - .../spark/common/sampler/java/JavaSampler.java | 1 - .../spark/common/sampler/node/AbstractNode.java | 1 - .../spark/common/sampler/node/StackTraceNode.java | 1 - .../me/lucko/spark/common/util/BytebinClient.java | 27 ++++++++---------- spark-fabric/build.gradle | 4 +-- .../placeholder/SparkFabricPlaceholderApi.java | 20 +++++++++++++ spark-forge/build.gradle | 2 +- spark-nukkit/build.gradle | 2 +- spark-sponge7/build.gradle | 2 +- spark-sponge8/build.gradle | 2 +- .../lucko/spark/sponge/Sponge8CommandSender.java | 1 + spark-universal/build.gradle | 33 ---------------------- spark-velocity/build.gradle | 2 +- spark-velocity4/build.gradle | 2 +- spark-waterdog/build.gradle | 2 +- 29 files changed, 224 insertions(+), 118 deletions(-) create mode 100644 HEADER.txt create mode 100644 spark-api/HEADER.txt delete mode 100644 spark-universal/build.gradle (limited to 'spark-bukkit') diff --git a/HEADER.txt b/HEADER.txt new file mode 100644 index 0000000..3457e84 --- /dev/null +++ b/HEADER.txt @@ -0,0 +1,17 @@ +This file is part of spark. + + Copyright (c) lucko (Luck) + Copyright (c) contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . \ No newline at end of file diff --git a/build.gradle b/build.gradle index 9e64e75..2780159 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,10 @@ +plugins { + id 'org.cadixdev.licenser' version '0.6.1' apply false +} + allprojects { group = 'me.lucko' - version = '1.6-SNAPSHOT' + version = '1.8-SNAPSHOT' configurations { compileClasspath // Fabric-loom needs this for remap jar for some reason @@ -11,9 +15,12 @@ subprojects { apply plugin: 'java' apply plugin: 'idea' apply plugin: 'java-library' + apply plugin: 'org.cadixdev.licenser' ext { - pluginVersion = '1.8.0' + baseVersion = '1.8' + patchVersion = determinePatchVersion() + pluginVersion = baseVersion + '.' + patchVersion pluginDescription = 'spark is a performance profiling plugin/mod for Minecraft clients, servers and proxies.' } @@ -26,6 +33,11 @@ subprojects { duplicatesStrategy = DuplicatesStrategy.INCLUDE } + license { + header = rootProject.file('HEADER.txt') + include '**/*.java' + } + repositories { mavenCentral() maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } @@ -34,3 +46,14 @@ subprojects { } } + +def determinePatchVersion() { + def tagInfo = new ByteArrayOutputStream() + exec { + commandLine 'git', 'describe', '--tags' + standardOutput = tagInfo + } + tagInfo = tagInfo.toString() + + return tagInfo.contains('-') ? tagInfo.split("-")[1] : 0 +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 09d0a60..8ec8a72 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,5 @@ pluginManagement { repositories { - jcenter() maven { name = 'Fabric' url = 'https://maven.fabricmc.net/' @@ -22,6 +21,5 @@ include ( 'spark-forge', 'spark-fabric', 'spark-nukkit', - 'spark-waterdog', - 'spark-universal' + 'spark-waterdog' ) diff --git a/spark-api/HEADER.txt b/spark-api/HEADER.txt new file mode 100644 index 0000000..63aafcb --- /dev/null +++ b/spark-api/HEADER.txt @@ -0,0 +1,22 @@ +This file is part of spark, licensed under the MIT License. + + Copyright (c) lucko (Luck) + Copyright (c) contributors + + 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. \ No newline at end of file diff --git a/spark-api/build.gradle b/spark-api/build.gradle index 31458af..0fbe9e1 100644 --- a/spark-api/build.gradle +++ b/spark-api/build.gradle @@ -9,6 +9,10 @@ dependencies { compileOnly 'org.jetbrains:annotations:20.1.0' } +license { + header = project.file('HEADER.txt') +} + publishing { //repositories { // maven { diff --git a/spark-bukkit/build.gradle b/spark-bukkit/build.gradle index b66134d..8e111e8 100644 --- a/spark-bukkit/build.gradle +++ b/spark-bukkit/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'com.github.johnrengelman.shadow' version '7.0.0' +} + dependencies { implementation project(':spark-common') implementation('me.lucko:adventure-platform-bukkit:4.9.4') { @@ -28,4 +32,27 @@ processResources { ) include 'plugin.yml' } -} \ No newline at end of file +} + +shadowJar { + archiveName = "spark-${project.pluginVersion}-bukkit.jar" + + relocate 'okio', 'me.lucko.spark.lib.okio' + relocate 'okhttp3', 'me.lucko.spark.lib.okhttp3' + relocate 'net.kyori.adventure', 'me.lucko.spark.lib.adventure' + relocate 'net.kyori.examination', 'me.lucko.spark.lib.adventure.examination' + relocate 'net.bytebuddy', 'me.lucko.spark.lib.bytebuddy' + relocate 'org.tukaani.xz', 'me.lucko.spark.lib.xz' + relocate 'com.google.protobuf', 'me.lucko.spark.lib.protobuf' + relocate 'org.objectweb.asm', 'me.lucko.spark.lib.asm' + relocate 'one.profiler', 'me.lucko.spark.lib.asyncprofiler' + + exclude 'module-info.class' + exclude 'META-INF/maven/**' + exclude 'META-INF/proguard/**' +} + +artifacts { + archives shadowJar + shadow shadowJar +} diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/CommandMapUtil.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/CommandMapUtil.java index 5c4d0db..e604321 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/CommandMapUtil.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/CommandMapUtil.java @@ -1,26 +1,21 @@ /* - * This file is part of helper, licensed under the MIT License. + * This file is part of spark. * * Copyright (c) lucko (Luck) * Copyright (c) contributors * - * 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: + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * 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. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package me.lucko.spark.bukkit; diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderProvider.java index 96c9e93..5b57857 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderProvider.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderProvider.java @@ -3,7 +3,7 @@ * * Copyright (c) lucko (Luck) * Copyright (c) contributors - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/spark-bungeecord/build.gradle b/spark-bungeecord/build.gradle index f1a6db5..ccea89d 100644 --- a/spark-bungeecord/build.gradle +++ b/spark-bungeecord/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'com.github.johnrengelman.shadow' version '7.0.0' +} + dependencies { implementation project(':spark-common') implementation('me.lucko:adventure-platform-bungeecord:4.9.4') { @@ -18,4 +22,27 @@ processResources { ) include 'bungee.yml' } -} \ No newline at end of file +} + +shadowJar { + archiveName = "spark-${project.pluginVersion}-bungeecord.jar" + + relocate 'okio', 'me.lucko.spark.lib.okio' + relocate 'okhttp3', 'me.lucko.spark.lib.okhttp3' + relocate 'net.kyori.adventure', 'me.lucko.spark.lib.adventure' + relocate 'net.kyori.examination', 'me.lucko.spark.lib.adventure.examination' + relocate 'net.bytebuddy', 'me.lucko.spark.lib.bytebuddy' + relocate 'org.tukaani.xz', 'me.lucko.spark.lib.xz' + relocate 'com.google.protobuf', 'me.lucko.spark.lib.protobuf' + relocate 'org.objectweb.asm', 'me.lucko.spark.lib.asm' + relocate 'one.profiler', 'me.lucko.spark.lib.asyncprofiler' + + exclude 'module-info.class' + exclude 'META-INF/maven/**' + exclude 'META-INF/proguard/**' +} + +artifacts { + archives shadowJar + shadow shadowJar +} diff --git a/spark-common/build.gradle b/spark-common/build.gradle index c1ddafb..aa0f409 100644 --- a/spark-common/build.gradle +++ b/spark-common/build.gradle @@ -2,6 +2,10 @@ plugins { id 'com.google.protobuf' version '0.8.16' } +license { + exclude '**/sampler/async/jfr/**' +} + dependencies { api project(':spark-api') implementation 'com.github.jvm-profiling-tools:async-profiler:v2.5' diff --git a/spark-common/src/main/java/me/lucko/spark/common/command/tabcomplete/CompletionSupplier.java b/spark-common/src/main/java/me/lucko/spark/common/command/tabcomplete/CompletionSupplier.java index f1a6d10..9975df5 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/command/tabcomplete/CompletionSupplier.java +++ b/spark-common/src/main/java/me/lucko/spark/common/command/tabcomplete/CompletionSupplier.java @@ -1,26 +1,21 @@ /* - * This file is part of LuckPerms, licensed under the MIT License. + * This file is part of spark. * * Copyright (c) lucko (Luck) * Copyright (c) contributors * - * 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: + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * 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. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package me.lucko.spark.common.command.tabcomplete; diff --git a/spark-common/src/main/java/me/lucko/spark/common/command/tabcomplete/TabCompleter.java b/spark-common/src/main/java/me/lucko/spark/common/command/tabcomplete/TabCompleter.java index d2b2622..9707f55 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/command/tabcomplete/TabCompleter.java +++ b/spark-common/src/main/java/me/lucko/spark/common/command/tabcomplete/TabCompleter.java @@ -1,26 +1,21 @@ /* - * This file is part of LuckPerms, licensed under the MIT License. + * This file is part of spark. * * Copyright (c) lucko (Luck) * Copyright (c) contributors * - * 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: + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * 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. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package me.lucko.spark.common.command.tabcomplete; diff --git a/spark-common/src/main/java/me/lucko/spark/common/monitor/MonitoringExecutor.java b/spark-common/src/main/java/me/lucko/spark/common/monitor/MonitoringExecutor.java index 779dbbf..635ae20 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/monitor/MonitoringExecutor.java +++ b/spark-common/src/main/java/me/lucko/spark/common/monitor/MonitoringExecutor.java @@ -1,3 +1,23 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package me.lucko.spark.common.monitor; import java.util.concurrent.Executors; diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/ThreadDumper.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/ThreadDumper.java index 5cc41b9..9d54f50 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/ThreadDumper.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/ThreadDumper.java @@ -1,7 +1,6 @@ /* * This file is part of spark. * - * Copyright (C) Albert Pham * Copyright (c) lucko (Luck) * Copyright (c) contributors * diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaSampler.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaSampler.java index d2959bd..2bedae6 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaSampler.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaSampler.java @@ -1,7 +1,6 @@ /* * This file is part of spark. * - * Copyright (C) Albert Pham * Copyright (c) lucko (Luck) * Copyright (c) contributors * diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/node/AbstractNode.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/node/AbstractNode.java index 18f67ba..fd2be8d 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/node/AbstractNode.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/node/AbstractNode.java @@ -1,7 +1,6 @@ /* * This file is part of spark. * - * Copyright (C) Albert Pham * Copyright (c) lucko (Luck) * Copyright (c) contributors * diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/node/StackTraceNode.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/node/StackTraceNode.java index 54217be..b0d9237 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/node/StackTraceNode.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/node/StackTraceNode.java @@ -1,7 +1,6 @@ /* * This file is part of spark. * - * Copyright (C) Albert Pham * Copyright (c) lucko (Luck) * Copyright (c) contributors * diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/BytebinClient.java b/spark-common/src/main/java/me/lucko/spark/common/util/BytebinClient.java index 29ee5bb..c2ca1b1 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/util/BytebinClient.java +++ b/spark-common/src/main/java/me/lucko/spark/common/util/BytebinClient.java @@ -1,26 +1,21 @@ /* - * This file is part of bytebin, licensed under the MIT License. + * This file is part of spark. * * Copyright (c) lucko (Luck) * Copyright (c) contributors * - * 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: + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * 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. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package me.lucko.spark.common.util; diff --git a/spark-fabric/build.gradle b/spark-fabric/build.gradle index d7e87cd..8cdf5fe 100644 --- a/spark-fabric/build.gradle +++ b/spark-fabric/build.gradle @@ -67,7 +67,7 @@ processResources { } shadowJar { - archiveFileName = 'spark-fabric-dev.jar' + archiveFileName = "spark-fabric-${project.pluginVersion}-dev.jar" configurations = [project.configurations.shade] relocate 'okio', 'me.lucko.spark.lib.okio' @@ -89,7 +89,7 @@ task remappedShadowJar(type: RemapJarTask) { dependsOn tasks.shadowJar input = tasks.shadowJar.archiveFile addNestedDependencies = true - archiveFileName = 'spark-fabric.jar' + archiveFileName = "spark-${project.pluginVersion}-fabric.jar" } tasks.assemble.dependsOn tasks.remappedShadowJar diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java index b9cff691..dc2e7d9 100644 --- a/spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java +++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java @@ -1,3 +1,23 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package me.lucko.spark.fabric.placeholder; import eu.pb4.placeholders.PlaceholderAPI; diff --git a/spark-forge/build.gradle b/spark-forge/build.gradle index e0fe0f8..25e51ef 100644 --- a/spark-forge/build.gradle +++ b/spark-forge/build.gradle @@ -49,7 +49,7 @@ processResources { } shadowJar { - archiveName = 'spark-forge.jar' + archiveName = "spark-${project.pluginVersion}-forge.jar" configurations = [project.configurations.shade] relocate 'okio', 'me.lucko.spark.lib.okio' diff --git a/spark-nukkit/build.gradle b/spark-nukkit/build.gradle index ff36091..2e1ad55 100644 --- a/spark-nukkit/build.gradle +++ b/spark-nukkit/build.gradle @@ -23,7 +23,7 @@ processResources { } shadowJar { - archiveName = 'spark-nukkit.jar' + archiveName = "spark-${project.pluginVersion}-nukkit.jar" relocate 'okio', 'me.lucko.spark.lib.okio' relocate 'okhttp3', 'me.lucko.spark.lib.okhttp3' diff --git a/spark-sponge7/build.gradle b/spark-sponge7/build.gradle index 5b26924..b18ffdb 100644 --- a/spark-sponge7/build.gradle +++ b/spark-sponge7/build.gradle @@ -20,7 +20,7 @@ blossom { } shadowJar { - archiveFileName = 'spark-sponge7.jar' + archiveFileName = "spark-${project.pluginVersion}-sponge7.jar" relocate 'okio', 'me.lucko.spark.lib.okio' relocate 'okhttp3', 'me.lucko.spark.lib.okhttp3' diff --git a/spark-sponge8/build.gradle b/spark-sponge8/build.gradle index 45f17b3..314ab18 100644 --- a/spark-sponge8/build.gradle +++ b/spark-sponge8/build.gradle @@ -22,7 +22,7 @@ processResources { } shadowJar { - archiveFileName = 'spark-sponge8.jar' + archiveFileName = "spark-${project.pluginVersion}-sponge8.jar" dependencies { exclude(dependency('net.kyori:^(?!adventure-text-feature-pagination).+$')) diff --git a/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8CommandSender.java b/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8CommandSender.java index 5e7a65a..e7878dc 100644 --- a/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8CommandSender.java +++ b/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8CommandSender.java @@ -17,6 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package me.lucko.spark.sponge; import me.lucko.spark.common.command.sender.AbstractCommandSender; diff --git a/spark-universal/build.gradle b/spark-universal/build.gradle deleted file mode 100644 index f784a9e..0000000 --- a/spark-universal/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'com.github.johnrengelman.shadow' version '7.0.0' -} - -dependencies { - implementation project(':spark-common') - implementation project(':spark-bukkit') - implementation project(':spark-bungeecord') -} - -shadowJar { - archiveName = 'spark.jar' - - relocate 'okio', 'me.lucko.spark.lib.okio' - relocate 'okhttp3', 'me.lucko.spark.lib.okhttp3' - relocate 'net.kyori.adventure', 'me.lucko.spark.lib.adventure' - relocate 'net.kyori.examination', 'me.lucko.spark.lib.adventure.examination' - relocate 'net.bytebuddy', 'me.lucko.spark.lib.bytebuddy' - relocate 'org.tukaani.xz', 'me.lucko.spark.lib.xz' - relocate 'com.google.protobuf', 'me.lucko.spark.lib.protobuf' - relocate 'org.objectweb.asm', 'me.lucko.spark.lib.asm' - relocate 'one.profiler', 'me.lucko.spark.lib.asyncprofiler' - - exclude 'module-info.class' - exclude 'META-INF/maven/**' - exclude 'META-INF/proguard/**' -} - -artifacts { - archives shadowJar - shadow shadowJar -} - diff --git a/spark-velocity/build.gradle b/spark-velocity/build.gradle index 8a345f9..b2e938b 100644 --- a/spark-velocity/build.gradle +++ b/spark-velocity/build.gradle @@ -20,7 +20,7 @@ blossom { } shadowJar { - archiveName = 'spark-velocity.jar' + archiveName = "spark-${project.pluginVersion}-velocity.jar" dependencies { exclude(dependency('net.kyori:^(?!adventure-text-feature-pagination).+$')) diff --git a/spark-velocity4/build.gradle b/spark-velocity4/build.gradle index e2a0559..5bef80b 100644 --- a/spark-velocity4/build.gradle +++ b/spark-velocity4/build.gradle @@ -25,7 +25,7 @@ blossom { } shadowJar { - archiveName = 'spark-velocity4.jar' + archiveName = "spark-${project.pluginVersion}-velocity4.jar" dependencies { exclude(dependency('net.kyori:^(?!adventure-text-feature-pagination).+$')) diff --git a/spark-waterdog/build.gradle b/spark-waterdog/build.gradle index 07be15c..c11e3fb 100644 --- a/spark-waterdog/build.gradle +++ b/spark-waterdog/build.gradle @@ -28,7 +28,7 @@ processResources { } shadowJar { - archiveName = 'spark-waterdog.jar' + archiveName = "spark-${project.pluginVersion}-waterdog.jar" relocate 'okio', 'me.lucko.spark.lib.okio' relocate 'okhttp3', 'me.lucko.spark.lib.okhttp3' -- cgit From 9639aefcb87770d9bf00e8caf4c10d33244e24e0 Mon Sep 17 00:00:00 2001 From: Luck Date: Sun, 6 Feb 2022 20:59:27 +0000 Subject: Fix NumberFormatException in Bukkit config provider (#173) --- .../main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'spark-bukkit') diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java index e4750f9..492e610 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java @@ -84,7 +84,11 @@ public class BukkitServerConfigProvider extends AbstractServerConfigProvider Date: Tue, 22 Feb 2022 20:46:51 +0000 Subject: Exclude level seed from server.properties config (#178) --- .../spark/bukkit/BukkitServerConfigProvider.java | 26 ++------- .../serverconfig/PropertiesFileReader.java | 64 ++++++++++++++++++++++ 2 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/PropertiesFileReader.java (limited to 'spark-bukkit') diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java index 492e610..0ef662c 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java @@ -28,6 +28,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonSerializer; import me.lucko.spark.common.platform.serverconfig.AbstractServerConfigProvider; +import me.lucko.spark.common.platform.serverconfig.PropertiesFileReader; import org.bukkit.configuration.MemorySection; import org.bukkit.configuration.file.YamlConfiguration; @@ -43,10 +44,8 @@ import java.nio.file.Paths; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Properties; public class BukkitServerConfigProvider extends AbstractServerConfigProvider { private static final Gson GSON = new GsonBuilder() @@ -73,26 +72,8 @@ public class BukkitServerConfigProvider extends AbstractServerConfigProvider values; if (type == FileType.PROPERTIES) { - Properties properties = new Properties(); - properties.load(reader); - - values = new HashMap<>(); - properties.forEach((k, v) -> { - String key = k.toString(); - String value = v.toString(); - - if ("true".equals(value) || "false".equals(value)) { - values.put(key, Boolean.parseBoolean(value)); - } else if (value.matches("\\d+")) { - try { - values.put(key, Long.parseLong(value)); - } catch (NumberFormatException e) { - values.put(key, value); - } - } else { - values.put(key, value); - } - }); + PropertiesFileReader propertiesReader = new PropertiesFileReader(reader); + values = propertiesReader.readProperties(); } else if (type == FileType.YAML) { YamlConfiguration config = YamlConfiguration.loadConfiguration(reader); values = config.getValues(false); @@ -129,6 +110,7 @@ public class BukkitServerConfigProvider extends AbstractServerConfigProviderpassword") + .add("level-seed") .addAll(getTimingsHiddenConfigs()) .addAll(getSystemPropertyList("spark.serverconfigs.hiddenpaths")); diff --git a/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/PropertiesFileReader.java b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/PropertiesFileReader.java new file mode 100644 index 0000000..8fc89d7 --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/PropertiesFileReader.java @@ -0,0 +1,64 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.common.platform.serverconfig; + +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * A {@link Reader} that can parse a .properties file. + */ +public class PropertiesFileReader extends FilterReader { + + public PropertiesFileReader(Reader in) { + super(in); + } + + public Map readProperties() throws IOException { + Properties properties = new Properties(); + properties.load(this); + + Map values = new HashMap<>(); + properties.forEach((k, v) -> { + String key = k.toString(); + String value = v.toString(); + + if ("true".equals(value) || "false".equals(value)) { + values.put(key, Boolean.parseBoolean(value)); + } else if (value.matches("\\d+")) { + try { + values.put(key, Long.parseLong(value)); + } catch (NumberFormatException e) { + values.put(key, value); + } + } else { + values.put(key, value); + } + }); + + return values; + } + +} -- cgit From c1bf08cd76f4ddee97a530f9ab4ffa613b6f27f1 Mon Sep 17 00:00:00 2001 From: Luck Date: Thu, 5 May 2022 21:04:23 +0100 Subject: Exclude feature-seeds from config (#189) --- .../me/lucko/spark/bukkit/BukkitServerConfigProvider.java | 1 + .../serverconfig/AbstractServerConfigProvider.java | 14 ++++++-------- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'spark-bukkit') diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java index 0ef662c..831150f 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java @@ -111,6 +111,7 @@ public class BukkitServerConfigProvider extends AbstractServerConfigProviderpassword") .add("level-seed") + .add("world-settings.*.feature-seeds") .addAll(getTimingsHiddenConfigs()) .addAll(getSystemPropertyList("spark.serverconfigs.hiddenpaths")); diff --git a/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java index 7e04400..d09eb7c 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java +++ b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java @@ -101,14 +101,12 @@ public abstract class AbstractServerConfigProvider> implements JsonObject jsonObject = json.getAsJsonObject(); String member = path.removeFirst().replace("", "."); - if (!jsonObject.has(member)) { - return; - } - - if (path.isEmpty()) { - jsonObject.remove(member); - } else { - delete(jsonObject.get(member), path); + if (member.equals("*") || jsonObject.has(member)) { + if (path.isEmpty()) { + jsonObject.remove(member); + } else { + delete(jsonObject.get(member), path); + } } } -- cgit From b0a22e85414e1ba7b115cf374c98f76c9f21e932 Mon Sep 17 00:00:00 2001 From: Luck Date: Sat, 4 Jun 2022 20:26:36 +0100 Subject: Filter more level seed properties from configs --- .../java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java | 1 + .../platform/serverconfig/AbstractServerConfigProvider.java | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'spark-bukkit') diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java index 831150f..953e171 100644 --- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java +++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitServerConfigProvider.java @@ -112,6 +112,7 @@ public class BukkitServerConfigProvider extends AbstractServerConfigProviderpassword") .add("level-seed") .add("world-settings.*.feature-seeds") + .add("world-settings.*.seed-*") .addAll(getTimingsHiddenConfigs()) .addAll(getSystemPropertyList("spark.serverconfigs.hiddenpaths")); diff --git a/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java index 56b3731..ead2131 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java +++ b/spark-common/src/main/java/me/lucko/spark/common/platform/serverconfig/AbstractServerConfigProvider.java @@ -108,6 +108,12 @@ public abstract class AbstractServerConfigProvider> implements keys = jsonObject.entrySet().stream() .map(Map.Entry::getKey) .collect(Collectors.toList()); + } else if (expected.endsWith("*")) { + String pattern = expected.substring(0, expected.length() - 1); + keys = jsonObject.entrySet().stream() + .map(Map.Entry::getKey) + .filter(key -> key.startsWith(pattern)) + .collect(Collectors.toList()); } else if (jsonObject.has(expected)) { keys = Collections.singletonList(expected); } else { @@ -118,7 +124,7 @@ public abstract class AbstractServerConfigProvider> implements if (path.isEmpty()) { jsonObject.remove(key); } else { - Deque pathCopy = expected.equals("*") + Deque pathCopy = keys.size() > 1 ? new LinkedList<>(path) : path; -- cgit