13
0
geforkt von Mirrors/Paper

Remove ChatColor usages (#7543)

Dieser Commit ist enthalten in:
Jake Potrebic 2022-06-02 21:26:56 -07:00
Ursprung b63b1a42cf
Commit f65eead418
15 geänderte Dateien mit 472 neuen und 362 gelöschten Zeilen

Datei anzeigen

@ -58,17 +58,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (args.length == 1) { + if (args.length == 1) {
+ if (args[0].equalsIgnoreCase("permissions")) { + if (args[0].equalsIgnoreCase("permissions")) {
+ Bukkit.getServer().reloadPermissions(); + Bukkit.getServer().reloadPermissions();
+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Permissions successfully reloaded."); + Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("Permissions successfully reloaded.", net.kyori.adventure.text.format.NamedTextColor.GREEN));
+ return true; + return true;
+ } else if ("confirm".equalsIgnoreCase(args[0])) { + } else if ("confirm".equalsIgnoreCase(args[0])) {
+ confirmed = true; + confirmed = true;
+ } else { + } else {
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "Usage: " + usageMessage); + Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("Usage: " + usageMessage, net.kyori.adventure.text.format.NamedTextColor.RED));
+ return true; + return true;
+ } + }
+ } + }
+ if (!confirmed) { + if (!confirmed) {
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "Are you sure you wish to reload your server? Doing so may cause bugs and memory leaks. It is recommended to restart instead of using /reload. To confirm, please type " + ChatColor.YELLOW + "/reload confirm"); + Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("Are you sure you wish to reload your server? Doing so may cause bugs and memory leaks. It is recommended to restart instead of using /reload. To confirm, please type ", net.kyori.adventure.text.format.NamedTextColor.RED).append(net.kyori.adventure.text.Component.text("/reload confirm", net.kyori.adventure.text.format.NamedTextColor.YELLOW)));
+ return true; + return true;
+ } + }
+ // Paper end + // Paper end

Datei anzeigen

@ -1366,6 +1366,43 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public static void broadcastCommandMessage(@NotNull CommandSender source, @NotNull String message) { public static void broadcastCommandMessage(@NotNull CommandSender source, @NotNull String message) {
broadcastCommandMessage(source, message, true); broadcastCommandMessage(source, message, true);
}
public static void broadcastCommandMessage(@NotNull CommandSender source, @NotNull String message, boolean sendToSource) {
- String result = source.getName() + ": " + message;
+ // Paper start
+ broadcastCommandMessage(source, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message), sendToSource);
+ }
+
+ public static void broadcastCommandMessage(@NotNull CommandSender source, @NotNull net.kyori.adventure.text.Component message) {
+ broadcastCommandMessage(source, message, true);
+ }
+
+ public static void broadcastCommandMessage(@NotNull CommandSender source, @NotNull net.kyori.adventure.text.Component message, boolean sendToSource) {
+ net.kyori.adventure.text.TextComponent.Builder result = net.kyori.adventure.text.Component.text()
+ .color(net.kyori.adventure.text.format.NamedTextColor.WHITE)
+ .decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false)
+ .append(source.name())
+ .append(net.kyori.adventure.text.Component.text(": "))
+ .append(message);
+ // Paper end
if (source instanceof BlockCommandSender) {
BlockCommandSender blockCommandSender = (BlockCommandSender) source;
@@ -0,0 +0,0 @@ public abstract class Command {
}
Set<Permissible> users = Bukkit.getPluginManager().getPermissionSubscriptions(Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
- String colored = ChatColor.GRAY + "" + ChatColor.ITALIC + "[" + result + ChatColor.GRAY + ChatColor.ITALIC + "]";
+ // Paper start
+ net.kyori.adventure.text.TextComponent.Builder colored = net.kyori.adventure.text.Component.text()
+ .color(net.kyori.adventure.text.format.NamedTextColor.GRAY)
+ .decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC)
+ .append(net.kyori.adventure.text.Component.text("["), result, net.kyori.adventure.text.Component.text("]"));
+ // Paper end
if (sendToSource && !(source instanceof ConsoleCommandSender)) {
source.sendMessage(message);
diff --git a/src/main/java/org/bukkit/command/CommandSender.java b/src/main/java/org/bukkit/command/CommandSender.java diff --git a/src/main/java/org/bukkit/command/CommandSender.java b/src/main/java/org/bukkit/command/CommandSender.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/command/CommandSender.java --- a/src/main/java/org/bukkit/command/CommandSender.java

Datei anzeigen

@ -86,13 +86,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
@@ -0,0 +0,0 @@ public class ReloadCommand extends BukkitCommand { @@ -0,0 +0,0 @@ public class ReloadCommand extends BukkitCommand {
Bukkit.getServer().reloadPermissions(); Bukkit.getServer().reloadPermissions();
Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Permissions successfully reloaded."); Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("Permissions successfully reloaded.", net.kyori.adventure.text.format.NamedTextColor.GREEN));
return true; return true;
+ } else if ("commands".equalsIgnoreCase(args[0])) { + } else if ("commands".equalsIgnoreCase(args[0])) {
+ if (Bukkit.getServer().reloadCommandAliases()) { + if (Bukkit.getServer().reloadCommandAliases()) {
+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Command aliases successfully reloaded."); + Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("Command aliases successfully reloaded.", net.kyori.adventure.text.format.NamedTextColor.GREEN));
+ } else { + } else {
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "An error occurred while trying to reload command aliases."); + Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("An error occurred while trying to reload command aliases.", net.kyori.adventure.text.format.NamedTextColor.RED));
+ } + }
+ return true; + return true;
} else if ("confirm".equalsIgnoreCase(args[0])) { } else if ("confirm".equalsIgnoreCase(args[0])) {

Datei anzeigen

@ -1589,8 +1589,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package co.aikar.timings; +package co.aikar.timings;
+ +
+import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.apache.commons.lang.Validate; +import org.apache.commons.lang.Validate;
+import org.bukkit.ChatColor;
+import org.bukkit.command.CommandSender; +import org.bukkit.command.CommandSender;
+import org.bukkit.command.defaults.BukkitCommand; +import org.bukkit.command.defaults.BukkitCommand;
+import org.bukkit.util.StringUtil; +import org.bukkit.util.StringUtil;
@ -1598,7 +1598,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.ArrayList; +import java.util.ArrayList;
+import java.util.List; +import java.util.List;
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable; +
+import static net.kyori.adventure.text.Component.text;
+ +
+ +
+public class TimingsCommand extends BukkitCommand { +public class TimingsCommand extends BukkitCommand {
@ -1618,41 +1619,41 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return true; + return true;
+ } + }
+ if (args.length < 1) { + if (args.length < 1) {
+ sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + sender.sendMessage(text("Usage: " + this.usageMessage, NamedTextColor.RED));
+ return true; + return true;
+ } + }
+ final String arg = args[0]; + final String arg = args[0];
+ if ("on".equalsIgnoreCase(arg)) { + if ("on".equalsIgnoreCase(arg)) {
+ Timings.setTimingsEnabled(true); + Timings.setTimingsEnabled(true);
+ sender.sendMessage("Enabled Timings & Reset"); + sender.sendMessage(text("Enabled Timings & Reset"));
+ return true; + return true;
+ } else if ("off".equalsIgnoreCase(arg)) { + } else if ("off".equalsIgnoreCase(arg)) {
+ Timings.setTimingsEnabled(false); + Timings.setTimingsEnabled(false);
+ sender.sendMessage("Disabled Timings"); + sender.sendMessage(text("Disabled Timings"));
+ return true; + return true;
+ } + }
+ +
+ if (!Timings.isTimingsEnabled()) { + if (!Timings.isTimingsEnabled()) {
+ sender.sendMessage("Please enable timings by typing /timings on"); + sender.sendMessage(text("Please enable timings by typing /timings on"));
+ return true; + return true;
+ } + }
+ +
+ long now = System.currentTimeMillis(); + long now = System.currentTimeMillis();
+ if ("verbon".equalsIgnoreCase(arg)) { + if ("verbon".equalsIgnoreCase(arg)) {
+ Timings.setVerboseTimingsEnabled(true); + Timings.setVerboseTimingsEnabled(true);
+ sender.sendMessage("Enabled Verbose Timings"); + sender.sendMessage(text("Enabled Verbose Timings"));
+ return true; + return true;
+ } else if ("verboff".equalsIgnoreCase(arg)) { + } else if ("verboff".equalsIgnoreCase(arg)) {
+ Timings.setVerboseTimingsEnabled(false); + Timings.setVerboseTimingsEnabled(false);
+ sender.sendMessage("Disabled Verbose Timings"); + sender.sendMessage(text("Disabled Verbose Timings"));
+ return true; + return true;
+ } else if ("reset".equalsIgnoreCase(arg)) { + } else if ("reset".equalsIgnoreCase(arg)) {
+ if (now - lastResetAttempt < 30000) { + if (now - lastResetAttempt < 30000) {
+ TimingsManager.reset(); + TimingsManager.reset();
+ sender.sendMessage(ChatColor.RED + "Timings reset. Please wait 5-10 minutes before using /timings report."); + sender.sendMessage(text("Timings reset. Please wait 5-10 minutes before using /timings report.", NamedTextColor.RED));
+ } else { + } else {
+ lastResetAttempt = now; + lastResetAttempt = now;
+ sender.sendMessage(ChatColor.RED + "WARNING: Timings v2 should not be reset. If you are encountering lag, please wait 3 minutes and then issue a report. The best timings will include 10+ minutes, with data before and after your lag period. If you really want to reset, run this command again within 30 seconds."); + sender.sendMessage(text("WARNING: Timings v2 should not be reset. If you are experiencing lag, please wait 3 minutes and then issue a report. The best timings will include 10+ minutes, with data before and after your lag period. If you really want to reset, run this command again within 30 seconds.", NamedTextColor.RED));
+ } + }
+ } else if ( + } else if (
+ "paste".equalsIgnoreCase(arg) || + "paste".equalsIgnoreCase(arg) ||
@ -1663,7 +1664,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ ) { + ) {
+ Timings.generateReport(sender); + Timings.generateReport(sender);
+ } else { + } else {
+ sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + sender.sendMessage(text("Usage: " + this.usageMessage, NamedTextColor.RED));
+ } + }
+ return true; + return true;
+ } + }

Datei anzeigen

@ -45,6 +45,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayDeque; import java.util.ArrayDeque;
@@ -0,0 +0,0 @@ import java.util.stream.Collectors; @@ -0,0 +0,0 @@ import java.util.stream.Collectors;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.format.NamedTextColor.BLUE;
import static net.kyori.adventure.text.format.NamedTextColor.DARK_AQUA;
+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 class PaperCommand extends Command { public class PaperCommand extends Command {
private static final String BASE_PERM = "bukkit.command.paper."; private static final String BASE_PERM = "bukkit.command.paper.";
@ -81,20 +88,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ private void doSyncLoadInfo(CommandSender sender, String[] args) { + private void doSyncLoadInfo(CommandSender sender, String[] args) {
+ if (!SyncLoadFinder.ENABLED) { + if (!SyncLoadFinder.ENABLED) {
+ sender.sendMessage(ChatColor.RED + "This command requires the server startup flag '-Dpaper.debug-sync-loads=true' to be set."); + sender.sendMessage(text("This command requires the server startup flag '-Dpaper.debug-sync-loads=true' to be set.", RED));
+ return; + return;
+ } + }
+ +
+ if (args.length > 1 && args[1].equals("clear")) { + if (args.length > 1 && args[1].equals("clear")) {
+ SyncLoadFinder.clear(); + SyncLoadFinder.clear();
+ sender.sendMessage(ChatColor.GRAY + "Sync load data cleared."); + sender.sendMessage(text("Sync load data cleared.", GRAY));
+ return; + return;
+ } + }
+ +
+ File file = new File(new File(new File("."), "debug"), + File file = new File(new File(new File("."), "debug"),
+ "sync-load-info" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt"); + "sync-load-info" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt");
+ file.getParentFile().mkdirs(); + file.getParentFile().mkdirs();
+ sender.sendMessage(ChatColor.GREEN + "Writing sync load info to " + file.toString()); + sender.sendMessage(text("Writing sync load info to " + file, GREEN));
+ +
+ +
+ try { + try {
@ -113,9 +120,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ ) { + ) {
+ out.print(fileData); + out.print(fileData);
+ } + }
+ sender.sendMessage(ChatColor.GREEN + "Successfully written sync load information!"); + sender.sendMessage(text("Successfully written sync load information!", GREEN));
+ } catch (Throwable thr) { + } catch (Throwable thr) {
+ sender.sendMessage(ChatColor.RED + "Failed to write sync load information"); + sender.sendMessage(text("Failed to write sync load information!", RED));
+ thr.printStackTrace(); + thr.printStackTrace();
+ } + }
+ } + }

Datei anzeigen

@ -55,6 +55,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.function.ToIntFunction; +import java.util.function.ToIntFunction;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static net.kyori.adventure.text.Component.text;
@@ -0,0 +0,0 @@ import static net.kyori.adventure.text.format.NamedTextColor.YELLOW;
public class PaperCommand extends Command { public class PaperCommand extends Command {
private static final String BASE_PERM = "bukkit.command.paper."; private static final String BASE_PERM = "bukkit.command.paper.";
- private static final ImmutableSet<String> SUBCOMMANDS = ImmutableSet.<String>builder().add("heap", "entity", "reload", "version", "debug", "chunkinfo", "fixlight", "syncloadinfo", "dumpitem").build(); - private static final ImmutableSet<String> SUBCOMMANDS = ImmutableSet.<String>builder().add("heap", "entity", "reload", "version", "debug", "chunkinfo", "fixlight", "syncloadinfo", "dumpitem").build();

Datei anzeigen

@ -12,8 +12,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package com.destroystokyo.paper; +package com.destroystokyo.paper;
+ +
+import net.kyori.adventure.text.Component;
+import net.minecraft.server.MinecraftServer; +import net.minecraft.server.MinecraftServer;
+import org.bukkit.ChatColor;
+import org.bukkit.Location; +import org.bukkit.Location;
+import org.bukkit.command.Command; +import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender; +import org.bukkit.command.CommandSender;
@ -24,8 +24,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Collections; +import java.util.Collections;
+import java.util.List; +import java.util.List;
+ +
+import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
+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 class MSPTCommand extends Command { +public class MSPTCommand extends Command {
+ private static final DecimalFormat DF = new DecimalFormat("########0.0"); + private static final DecimalFormat DF = new DecimalFormat("########0.0");
+ private static final Component SLASH = text("/");
+ +
+ public MSPTCommand(String name) { + public MSPTCommand(String name) {
+ super(name); + super(name);
@ -45,17 +53,44 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ MinecraftServer server = MinecraftServer.getServer(); + MinecraftServer server = MinecraftServer.getServer();
+ +
+ List<String> times = new ArrayList<>(); + List<Component> times = new ArrayList<>();
+ times.addAll(eval(server.tickTimes5s.getTimes())); + times.addAll(eval(server.tickTimes5s.getTimes()));
+ times.addAll(eval(server.tickTimes10s.getTimes())); + times.addAll(eval(server.tickTimes10s.getTimes()));
+ times.addAll(eval(server.tickTimes60s.getTimes())); + times.addAll(eval(server.tickTimes60s.getTimes()));
+ +
+ sender.sendMessage("§6Server tick times §e(§7avg§e/§7min§e/§7max§e)§6 from last 5s§7,§6 10s§7,§6 1m§e:"); + sender.sendMessage(text().content("Server tick times ").color(GOLD)
+ sender.sendMessage(String.format("§6◴ %s§7/%s§7/%s§e, %s§7/%s§7/%s§e, %s§7/%s§7/%s", times.toArray())); + .append(text().color(YELLOW)
+ .append(
+ text("("),
+ text("avg", GRAY),
+ text("/"),
+ text("min", GRAY),
+ text("/"),
+ text("max", GRAY),
+ text(")")
+ )
+ ).append(
+ text(" from last 5s"),
+ text(",", GRAY),
+ text(" 10s"),
+ text(",", GRAY),
+ text(" 1m"),
+ text(":", YELLOW)
+ )
+ );
+ sender.sendMessage(text().content("◴ ").color(GOLD)
+ .append(text().color(GRAY)
+ .append(
+ times.get(0), SLASH, times.get(1), SLASH, times.get(2), text(", ", YELLOW),
+ times.get(3), SLASH, times.get(4), SLASH, times.get(5), text(", ", YELLOW),
+ times.get(6), SLASH, times.get(7), SLASH, times.get(8)
+ )
+ )
+ );
+ return true; + return true;
+ } + }
+ +
+ private static List<String> eval(long[] times) { + private static List<Component> eval(long[] times) {
+ long min = Integer.MAX_VALUE; + long min = Integer.MAX_VALUE;
+ long max = 0L; + long max = 0L;
+ long total = 0L; + long total = 0L;
@ -70,8 +105,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return Arrays.asList(getColor(avgD), getColor(minD), getColor(maxD)); + return Arrays.asList(getColor(avgD), getColor(minD), getColor(maxD));
+ } + }
+ +
+ private static String getColor(double avg) { + private static Component getColor(double avg) {
+ return ChatColor.COLOR_CHAR + (avg >= 50 ? "c" : avg >= 40 ? "e" : "a") + DF.format(avg); + return text(DF.format(avg), avg >= 50 ? RED : avg >= 40 ? YELLOW : GREEN);
+ } + }
+} +}
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java

Datei anzeigen

@ -52,7 +52,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.MutablePair;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -0,0 +0,0 @@ import java.util.stream.Collectors; @@ -0,0 +0,0 @@ import java.util.Set;
import java.util.stream.Collectors;
import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.BLUE;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_AQUA;
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 class PaperCommand extends Command { public class PaperCommand extends Command {
private static final String BASE_PERM = "bukkit.command.paper."; private static final String BASE_PERM = "bukkit.command.paper.";
@ -109,7 +117,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ for (int i = 1; i < args.length; ++i) { + for (int i = 1; i < args.length; ++i) {
+ org.bukkit.World world = Bukkit.getWorld(args[i]); + org.bukkit.World world = Bukkit.getWorld(args[i]);
+ if (world == null) { + if (world == null) {
+ sender.sendMessage(ChatColor.RED + "World '" + args[i] + "' is invalid"); + sender.sendMessage(text("World '" + args[i] + "' is invalid", RED));
+ return; + return;
+ } + }
+ worlds.add(world); + worlds.add(world);
@ -162,22 +170,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ accumulatedTicking += ticking; + accumulatedTicking += ticking;
+ accumulatedEntityTicking += entityTicking; + accumulatedEntityTicking += entityTicking;
+ +
+ sender.sendMessage(ChatColor.BLUE + "Chunks in " + ChatColor.GREEN + bukkitWorld.getName() + ChatColor.DARK_AQUA + ":"); + sender.sendMessage(text().append(text("Chunks in ", BLUE), text(bukkitWorld.getName(), GREEN), text(":")));
+ sender.sendMessage(ChatColor.BLUE + "Total: " + ChatColor.DARK_AQUA + total + ChatColor.BLUE + " Inactive: " + ChatColor.DARK_AQUA + sender.sendMessage(text().color(DARK_AQUA).append(
+ + inactive + ChatColor.BLUE + " Border: " + ChatColor.DARK_AQUA + border + ChatColor.BLUE + " Ticking: " + text("Total: ", BLUE), text(total),
+ + ChatColor.DARK_AQUA + ticking + ChatColor.BLUE + " Entity: " + ChatColor.DARK_AQUA + entityTicking); + text(" Inactive: ", BLUE), text(inactive),
+ text(" Border: ", BLUE), text(border),
+ text(" Ticking: ", BLUE), text(ticking),
+ text(" Entity: ", BLUE), text(entityTicking)
+ ));
+ } + }
+ if (worlds.size() > 1) { + if (worlds.size() > 1) {
+ sender.sendMessage(ChatColor.BLUE + "Chunks in " + ChatColor.GREEN + "all listed worlds" + ChatColor.DARK_AQUA + ":"); + sender.sendMessage(text().append(text("Chunks in ", BLUE), text("all listed worlds", GREEN), text(":", DARK_AQUA)));
+ sender.sendMessage(ChatColor.BLUE + "Total: " + ChatColor.DARK_AQUA + accumulatedTotal + ChatColor.BLUE + " Inactive: " + ChatColor.DARK_AQUA + sender.sendMessage(text().color(DARK_AQUA).append(
+ + accumulatedInactive + ChatColor.BLUE + " Border: " + ChatColor.DARK_AQUA + accumulatedBorder + ChatColor.BLUE + " Ticking: " + text("Total: ", BLUE), text(accumulatedTotal),
+ + ChatColor.DARK_AQUA + accumulatedTicking + ChatColor.BLUE + " Entity: " + ChatColor.DARK_AQUA + accumulatedEntityTicking); + text(" Inactive: ", BLUE), text(accumulatedInactive),
+ text(" Border: ", BLUE), text(accumulatedBorder),
+ text(" Ticking: ", BLUE), text(accumulatedTicking),
+ text(" Entity: ", BLUE), text(accumulatedEntityTicking)
+ ));
+ } + }
+ } + }
+ +
+ private void doDebug(CommandSender sender, String[] args) { + private void doDebug(CommandSender sender, String[] args) {
+ if (args.length < 2) { + if (args.length < 2) {
+ sender.sendMessage(ChatColor.RED + "Use /paper debug [chunks] help for more information on a specific command"); + sender.sendMessage(text("Use /paper debug [chunks] help for more information on a specific command", RED));
+ return; + return;
+ } + }
+ +
@ -185,25 +201,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ switch (debugType) { + switch (debugType) {
+ case "chunks": + case "chunks":
+ if (args.length >= 3 && args[2].toLowerCase(Locale.ENGLISH).equals("help")) { + if (args.length >= 3 && args[2].toLowerCase(Locale.ENGLISH).equals("help")) {
+ sender.sendMessage(ChatColor.RED + "Use /paper debug chunks to dump loaded chunk information to a file"); + sender.sendMessage(text("Use /paper debug chunks [world] to dump loaded chunk information to a file", RED));
+ break; + break;
+ } + }
+ File file = new File(new File(new File("."), "debug"), + File file = new File(new File(new File("."), "debug"),
+ "chunks-" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt"); + "chunks-" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt");
+ sender.sendMessage(ChatColor.GREEN + "Writing chunk information dump to " + file.toString()); + sender.sendMessage(text("Writing chunk information dump to " + file, GREEN));
+ try { + try {
+ MCUtil.dumpChunks(file); + MCUtil.dumpChunks(file);
+ sender.sendMessage(ChatColor.GREEN + "Successfully written chunk information!"); + sender.sendMessage(text("Successfully written chunk information!", GREEN));
+ } catch (Throwable thr) { + } catch (Throwable thr) {
+ MinecraftServer.LOGGER.warn("Failed to dump chunk information to file " + file.toString(), thr); + MinecraftServer.LOGGER.warn("Failed to dump chunk information to file " + file.toString(), thr);
+ sender.sendMessage(ChatColor.RED + "Failed to dump chunk information, see console"); + sender.sendMessage(text("Failed to dump chunk information, see console", RED));
+ } + }
+ +
+ break; + break;
+ case "help": + case "help":
+ // fall through to default + // fall through to default
+ default: + default:
+ sender.sendMessage(ChatColor.RED + "Use /paper debug [chunks] help for more information on a specific command"); + sender.sendMessage(text("Use /paper debug [chunks] help for more information on a specific command", RED));
+ return; + return;
+ } + }
+ } + }

Datei anzeigen

@ -39,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@@ -0,0 +0,0 @@ import java.util.stream.Collectors; @@ -0,0 +0,0 @@ import static net.kyori.adventure.text.format.NamedTextColor.YELLOW;
public class PaperCommand extends Command { public class PaperCommand extends Command {
private static final String BASE_PERM = "bukkit.command.paper."; private static final String BASE_PERM = "bukkit.command.paper.";
@ -60,7 +60,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
case "version": case "version":
@@ -0,0 +0,0 @@ public class PaperCommand extends Command { @@ -0,0 +0,0 @@ public class PaperCommand extends Command {
Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Paper config reload complete."); Command.broadcastCommandMessage(sender, text("Paper config reload complete.", GREEN));
} }
+ private void doFixLight(CommandSender sender, String[] args) { + private void doFixLight(CommandSender sender, String[] args) {
+ if (!(sender instanceof Player)) { + if (!(sender instanceof Player)) {

Datei anzeigen

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private static boolean testPermission(CommandSender commandSender, String permission) { private static boolean testPermission(CommandSender commandSender, String permission) {
if (commandSender.hasPermission(BASE_PERM + permission) || commandSender.hasPermission("bukkit.command.paper")) return true; if (commandSender.hasPermission(BASE_PERM + permission) || commandSender.hasPermission("bukkit.command.paper")) return true;
- commandSender.sendMessage(ChatColor.RED + "I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error."); // Sorry, kashike - commandSender.sendMessage(text("I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error.", RED));
+ commandSender.sendMessage(Bukkit.getPermissionMessage()); // Sorry, kashike + commandSender.sendMessage(Bukkit.getPermissionMessage()); // Sorry, kashike
return false; return false;
} }

Datei anzeigen

@ -0,0 +1,301 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
Date: Mon, 29 Feb 2016 21:02:09 -0600
Subject: [PATCH] Paper command
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -0,0 +0,0 @@
+package com.destroystokyo.paper;
+
+import com.google.common.base.Functions;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.level.ServerChunkCache;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.level.ChunkPos;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.craftbukkit.CraftWorld;
+import org.bukkit.entity.Player;
+
+import java.io.File;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static net.kyori.adventure.text.Component.text;
+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 class PaperCommand extends Command {
+ private static final String BASE_PERM = "bukkit.command.paper.";
+ private static final ImmutableSet<String> SUBCOMMANDS = ImmutableSet.<String>builder().add("heap", "entity", "reload", "version").build();
+
+ public PaperCommand(String name) {
+ super(name);
+ this.description = "Paper related commands";
+ this.usageMessage = "/paper [" + Joiner.on(" | ").join(SUBCOMMANDS) + "]";
+ this.setPermission("bukkit.command.paper;" + Joiner.on(';').join(SUBCOMMANDS.stream().map(s -> BASE_PERM + s).collect(Collectors.toSet())));
+ }
+
+ private static boolean testPermission(CommandSender commandSender, String permission) {
+ if (commandSender.hasPermission(BASE_PERM + permission) || commandSender.hasPermission("bukkit.command.paper")) return true;
+ commandSender.sendMessage(text("I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error.", RED));
+ return false;
+ }
+
+ @Override
+ public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
+ if (args.length <= 1)
+ return getListMatchingLast(sender, args, SUBCOMMANDS);
+
+ switch (args[0].toLowerCase(Locale.ENGLISH))
+ {
+ case "entity":
+ if (args.length == 2)
+ return getListMatchingLast(sender, args, "help", "list");
+ if (args.length == 3)
+ return getListMatchingLast(sender, args, EntityType.getEntityNameList().stream().map(ResourceLocation::toString).sorted().toArray(String[]::new));
+ break;
+ }
+ return Collections.emptyList();
+ }
+
+ // Code from Mojang - copyright them
+ public static List<String> getListMatchingLast(CommandSender sender, String[] args, String... matches) {
+ return getListMatchingLast(sender, args, (Collection) Arrays.asList(matches));
+ }
+
+ public static boolean matches(String s, String s1) {
+ return s1.regionMatches(true, 0, s, 0, s.length());
+ }
+
+ public static List<String> getListMatchingLast(CommandSender sender, String[] strings, Collection<?> collection) {
+ String last = strings[strings.length - 1];
+ ArrayList<String> results = Lists.newArrayList();
+
+ if (!collection.isEmpty()) {
+ Iterator iterator = Iterables.transform(collection, Functions.toStringFunction()).iterator();
+
+ while (iterator.hasNext()) {
+ String s1 = (String) iterator.next();
+
+ if (matches(last, s1) && (sender.hasPermission(BASE_PERM + s1) || sender.hasPermission("bukkit.command.paper"))) {
+ results.add(s1);
+ }
+ }
+
+ if (results.isEmpty()) {
+ iterator = collection.iterator();
+
+ while (iterator.hasNext()) {
+ Object object = iterator.next();
+
+ if (object instanceof ResourceLocation && matches(last, ((ResourceLocation) object).getPath())) {
+ results.add(String.valueOf(object));
+ }
+ }
+ }
+ }
+
+ return results;
+ }
+ // end copy stuff
+
+ @Override
+ public boolean execute(CommandSender sender, String commandLabel, String[] args) {
+ if (!testPermission(sender)) return true;
+
+ if (args.length == 0) {
+ sender.sendMessage(text("Usage: " + this.usageMessage, RED));
+ return false;
+ }
+ if (SUBCOMMANDS.contains(args[0].toLowerCase(Locale.ENGLISH))) {
+ if (!testPermission(sender, args[0].toLowerCase(Locale.ENGLISH))) return true;
+ }
+ switch (args[0].toLowerCase(Locale.ENGLISH)) {
+ case "heap":
+ dumpHeap(sender);
+ break;
+ case "entity":
+ listEntities(sender, args);
+ break;
+ case "reload":
+ doReload(sender);
+ break;
+ case "ver":
+ if (!testPermission(sender, "version")) break; // "ver" needs a special check because it's an alias. All other commands are checked up before the switch statement (because they are present in the SUBCOMMANDS set)
+ case "version":
+ Command ver = MinecraftServer.getServer().server.getCommandMap().getCommand("version");
+ if (ver != null) {
+ ver.execute(sender, commandLabel, new String[0]);
+ break;
+ }
+ // else - fall through to default
+ default:
+ sender.sendMessage(text("Usage: " + this.usageMessage, RED));
+ return false;
+ }
+
+ return true;
+ }
+
+ /*
+ * Ported from MinecraftForge - author: LexManos <LexManos@gmail.com> - License: LGPLv2.1
+ */
+ private void listEntities(CommandSender sender, String[] args) {
+ if (args.length < 2 || args[1].toLowerCase(Locale.ENGLISH).equals("help")) {
+ sender.sendMessage(text("Use /paper entity [list] help for more information on a specific command", RED));
+ return;
+ }
+
+ switch (args[1].toLowerCase(Locale.ENGLISH)) {
+ case "list":
+ String filter = "*";
+ if (args.length > 2) {
+ if (args[2].toLowerCase(Locale.ENGLISH).equals("help")) {
+ sender.sendMessage(text("Use /paper entity list [filter] [worldName] to get entity info that matches the optional filter.", RED));
+ return;
+ }
+ filter = args[2];
+ }
+ final String cleanfilter = filter.replace("?", ".?").replace("*", ".*?");
+ Set<ResourceLocation> names = EntityType.getEntityNameList().stream()
+ .filter(n -> n.toString().matches(cleanfilter))
+ .collect(Collectors.toSet());
+
+ if (names.isEmpty()) {
+ sender.sendMessage(text("Invalid filter, does not match any entities. Use /paper entity list for a proper list", RED));
+ sender.sendMessage(text("Usage: /paper entity list [filter] [worldName]", RED));
+ return;
+ }
+
+ String worldName;
+ if (args.length > 3) {
+ worldName = args[3];
+ } else if (sender instanceof Player) {
+ worldName = ((Player) sender).getWorld().getName();
+ } else {
+ sender.sendMessage(text("Please specify the name of a world", RED));
+ sender.sendMessage(text("To do so without a filter, specify '*' as the filter", RED));
+ sender.sendMessage(text("Usage: /paper entity list [filter] [worldName]", RED));
+ return;
+ }
+
+ Map<ResourceLocation, MutablePair<Integer, Map<ChunkPos, Integer>>> list = Maps.newHashMap();
+ World bukkitWorld = Bukkit.getWorld(worldName);
+ if (bukkitWorld == null) {
+ sender.sendMessage(text("Could not load world for " + worldName + ". Please select a valid world.", RED));
+ sender.sendMessage(text("Usage: /paper entity list [filter] [worldName]", RED));
+ return;
+ }
+ ServerLevel world = ((CraftWorld) Bukkit.getWorld(worldName)).getHandle();
+
+ Map<ResourceLocation, Integer> nonEntityTicking = Maps.newHashMap();
+ ServerChunkCache chunkProviderServer = world.getChunkSource();
+
+ world.getAllEntities().forEach(e -> {
+ ResourceLocation key = EntityType.getKey(e.getType());
+
+ MutablePair<Integer, Map<ChunkPos, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
+ ChunkPos chunk = e.chunkPosition();
+ info.left++;
+ info.right.put(chunk, info.right.getOrDefault(chunk, 0) + 1);
+ if (!chunkProviderServer.isPositionTicking(e)) {
+ nonEntityTicking.merge(key, Integer.valueOf(1), Integer::sum);
+ }
+ });
+
+ if (names.size() == 1) {
+ ResourceLocation name = names.iterator().next();
+ Pair<Integer, Map<ChunkPos, Integer>> info = list.get(name);
+ int nonTicking = nonEntityTicking.getOrDefault(name, Integer.valueOf(0)).intValue();
+ if (info == null) {
+ sender.sendMessage(text("No entities found.", RED));
+ return;
+ }
+ sender.sendMessage("Entity: " + name + " Total Ticking: " + (info.getLeft() - nonTicking) + ", Total Non-Ticking: " + nonTicking);
+ info.getRight().entrySet().stream()
+ .sorted((a, b) -> !a.getValue().equals(b.getValue()) ? b.getValue() - a.getValue() : a.getKey().toString().compareTo(b.getKey().toString()))
+ .limit(10).forEach(e -> sender.sendMessage(" " + e.getValue() + ": " + e.getKey().x + ", " + e.getKey().z + (chunkProviderServer.isPositionTicking(e.getKey().toLong()) ? " (Ticking)" : " (Non-Ticking)")));
+ } else {
+ List<Pair<ResourceLocation, Integer>> info = list.entrySet().stream()
+ .filter(e -> names.contains(e.getKey()))
+ .map(e -> Pair.of(e.getKey(), e.getValue().left))
+ .sorted((a, b) -> !a.getRight().equals(b.getRight()) ? b.getRight() - a.getRight() : a.getKey().toString().compareTo(b.getKey().toString()))
+ .collect(Collectors.toList());
+
+ if (info == null || info.size() == 0) {
+ sender.sendMessage(text("No entities found.", RED));
+ return;
+ }
+
+ int count = info.stream().mapToInt(Pair::getRight).sum();
+ int nonTickingCount = nonEntityTicking.values().stream().mapToInt(Integer::intValue).sum();
+ sender.sendMessage("Total Ticking: " + (count - nonTickingCount) + ", Total Non-Ticking: " + nonTickingCount);
+ info.forEach(e -> {
+ int nonTicking = nonEntityTicking.getOrDefault(e.getKey(), Integer.valueOf(0)).intValue();
+ sender.sendMessage(" " + (e.getValue() - nonTicking) + " (" + nonTicking + ") " + ": " + e.getKey());
+ });
+ sender.sendMessage("* First number is ticking entities, second number is non-ticking entities");
+ }
+ break;
+ }
+ }
+
+ private void dumpHeap(CommandSender sender) {
+ java.nio.file.Path dir = java.nio.file.Paths.get("./dumps");
+ String name = "heap-dump-" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now());
+
+ Command.broadcastCommandMessage(sender, text("Writing JVM heap data...", YELLOW));
+
+ java.nio.file.Path file = CraftServer.dumpHeap(dir, name);
+ if (file != null) {
+ Command.broadcastCommandMessage(sender, text("Heap dump saved to " + file, GREEN));
+ } else {
+ Command.broadcastCommandMessage(sender, text("Failed to write heap dump, see server log for details", RED));
+ }
+ }
+
+ private void doReload(CommandSender sender) {
+ Command.broadcastCommandMessage(sender, text("Please note that this command is not supported and may cause issues.", RED));
+ Command.broadcastCommandMessage(sender, text("If you encounter any issues please use the /stop command to restart your server.", RED));
+
+ MinecraftServer console = MinecraftServer.getServer();
+ com.destroystokyo.paper.PaperConfig.init((File) console.options.valueOf("paper-settings"));
+ for (ServerLevel world : console.getAllLevels()) {
+ world.paperConfig.init();
+ }
+ console.server.reloadCount++;
+
+ Command.broadcastCommandMessage(sender, text("Paper config reload complete.", GREEN));
+ }
+}

Datei anzeigen

@ -5,297 +5,6 @@ Subject: [PATCH] Paper config files
Loads each yml file for early init too so it can be used for early options Loads each yml file for early init too so it can be used for early options
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -0,0 +0,0 @@
+package com.destroystokyo.paper;
+
+import com.google.common.base.Functions;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.level.ServerChunkCache;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.level.ChunkPos;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.craftbukkit.CraftWorld;
+import org.bukkit.entity.Player;
+
+import java.io.File;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class PaperCommand extends Command {
+ private static final String BASE_PERM = "bukkit.command.paper.";
+ private static final ImmutableSet<String> SUBCOMMANDS = ImmutableSet.<String>builder().add("heap", "entity", "reload", "version").build();
+
+ public PaperCommand(String name) {
+ super(name);
+ this.description = "Paper related commands";
+ this.usageMessage = "/paper [" + Joiner.on(" | ").join(SUBCOMMANDS) + "]";
+ this.setPermission("bukkit.command.paper;" + Joiner.on(';').join(SUBCOMMANDS.stream().map(s -> BASE_PERM + s).collect(Collectors.toSet())));
+ }
+
+ private static boolean testPermission(CommandSender commandSender, String permission) {
+ if (commandSender.hasPermission(BASE_PERM + permission) || commandSender.hasPermission("bukkit.command.paper")) return true;
+ commandSender.sendMessage(ChatColor.RED + "I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error."); // Sorry, kashike
+ return false;
+ }
+
+ @Override
+ public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
+ if (args.length <= 1)
+ return getListMatchingLast(sender, args, SUBCOMMANDS);
+
+ switch (args[0].toLowerCase(Locale.ENGLISH))
+ {
+ case "entity":
+ if (args.length == 2)
+ return getListMatchingLast(sender, args, "help", "list");
+ if (args.length == 3)
+ return getListMatchingLast(sender, args, EntityType.getEntityNameList().stream().map(ResourceLocation::toString).sorted().toArray(String[]::new));
+ break;
+ }
+ return Collections.emptyList();
+ }
+
+ // Code from Mojang - copyright them
+ public static List<String> getListMatchingLast(CommandSender sender, String[] args, String... matches) {
+ return getListMatchingLast(sender, args, (Collection) Arrays.asList(matches));
+ }
+
+ public static boolean matches(String s, String s1) {
+ return s1.regionMatches(true, 0, s, 0, s.length());
+ }
+
+ public static List<String> getListMatchingLast(CommandSender sender, String[] strings, Collection<?> collection) {
+ String last = strings[strings.length - 1];
+ ArrayList<String> results = Lists.newArrayList();
+
+ if (!collection.isEmpty()) {
+ Iterator iterator = Iterables.transform(collection, Functions.toStringFunction()).iterator();
+
+ while (iterator.hasNext()) {
+ String s1 = (String) iterator.next();
+
+ if (matches(last, s1) && (sender.hasPermission(BASE_PERM + s1) || sender.hasPermission("bukkit.command.paper"))) {
+ results.add(s1);
+ }
+ }
+
+ if (results.isEmpty()) {
+ iterator = collection.iterator();
+
+ while (iterator.hasNext()) {
+ Object object = iterator.next();
+
+ if (object instanceof ResourceLocation && matches(last, ((ResourceLocation) object).getPath())) {
+ results.add(String.valueOf(object));
+ }
+ }
+ }
+ }
+
+ return results;
+ }
+ // end copy stuff
+
+ @Override
+ public boolean execute(CommandSender sender, String commandLabel, String[] args) {
+ if (!testPermission(sender)) return true;
+
+ if (args.length == 0) {
+ sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
+ return false;
+ }
+ if (SUBCOMMANDS.contains(args[0].toLowerCase(Locale.ENGLISH))) {
+ if (!testPermission(sender, args[0].toLowerCase(Locale.ENGLISH))) return true;
+ }
+ switch (args[0].toLowerCase(Locale.ENGLISH)) {
+ case "heap":
+ dumpHeap(sender);
+ break;
+ case "entity":
+ listEntities(sender, args);
+ break;
+ case "reload":
+ doReload(sender);
+ break;
+ case "ver":
+ if (!testPermission(sender, "version")) break; // "ver" needs a special check because it's an alias. All other commands are checked up before the switch statement (because they are present in the SUBCOMMANDS set)
+ case "version":
+ Command ver = MinecraftServer.getServer().server.getCommandMap().getCommand("version");
+ if (ver != null) {
+ ver.execute(sender, commandLabel, new String[0]);
+ break;
+ }
+ // else - fall through to default
+ default:
+ sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
+ return false;
+ }
+
+ return true;
+ }
+
+ /*
+ * Ported from MinecraftForge - author: LexManos <LexManos@gmail.com> - License: LGPLv2.1
+ */
+ private void listEntities(CommandSender sender, String[] args) {
+ if (args.length < 2 || args[1].toLowerCase(Locale.ENGLISH).equals("help")) {
+ sender.sendMessage(ChatColor.RED + "Use /paper entity [list] help for more information on a specific command.");
+ return;
+ }
+
+ switch (args[1].toLowerCase(Locale.ENGLISH)) {
+ case "list":
+ String filter = "*";
+ if (args.length > 2) {
+ if (args[2].toLowerCase(Locale.ENGLISH).equals("help")) {
+ sender.sendMessage(ChatColor.RED + "Use /paper entity list [filter] [worldName] to get entity info that matches the optional filter.");
+ return;
+ }
+ filter = args[2];
+ }
+ final String cleanfilter = filter.replace("?", ".?").replace("*", ".*?");
+ Set<ResourceLocation> names = EntityType.getEntityNameList().stream()
+ .filter(n -> n.toString().matches(cleanfilter))
+ .collect(Collectors.toSet());
+
+ if (names.isEmpty()) {
+ sender.sendMessage(ChatColor.RED + "Invalid filter, does not match any entities. Use /paper entity list for a proper list");
+ sender.sendMessage(ChatColor.RED + "Usage: /paper entity list [filter] [worldName]");
+ return;
+ }
+
+ String worldName;
+ if (args.length > 3) {
+ worldName = args[3];
+ } else if (sender instanceof Player) {
+ worldName = ((Player) sender).getWorld().getName();
+ } else {
+ sender.sendMessage(ChatColor.RED + "Please specify the name of a world");
+ sender.sendMessage(ChatColor.RED + "To do so without a filter, specify '*' as the filter");
+ sender.sendMessage(ChatColor.RED + "Usage: /paper entity list [filter] [worldName]");
+ return;
+ }
+
+ Map<ResourceLocation, MutablePair<Integer, Map<ChunkPos, Integer>>> list = Maps.newHashMap();
+ World bukkitWorld = Bukkit.getWorld(worldName);
+ if (bukkitWorld == null) {
+ sender.sendMessage(ChatColor.RED + "Could not load world for " + worldName + ". Please select a valid world.");
+ sender.sendMessage(ChatColor.RED + "Usage: /paper entity list [filter] [worldName]");
+ return;
+ }
+ ServerLevel world = ((CraftWorld) Bukkit.getWorld(worldName)).getHandle();
+
+ Map<ResourceLocation, Integer> nonEntityTicking = Maps.newHashMap();
+ ServerChunkCache chunkProviderServer = world.getChunkSource();
+
+ world.getAllEntities().forEach(e -> {
+ ResourceLocation key = EntityType.getKey(e.getType());
+
+ MutablePair<Integer, Map<ChunkPos, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
+ ChunkPos chunk = e.chunkPosition();
+ info.left++;
+ info.right.put(chunk, info.right.getOrDefault(chunk, 0) + 1);
+ if (!chunkProviderServer.isPositionTicking(e)) {
+ nonEntityTicking.merge(key, Integer.valueOf(1), Integer::sum);
+ }
+ });
+
+ if (names.size() == 1) {
+ ResourceLocation name = names.iterator().next();
+ Pair<Integer, Map<ChunkPos, Integer>> info = list.get(name);
+ int nonTicking = nonEntityTicking.getOrDefault(name, Integer.valueOf(0)).intValue();
+ if (info == null) {
+ sender.sendMessage(ChatColor.RED + "No entities found.");
+ return;
+ }
+ sender.sendMessage("Entity: " + name + " Total Ticking: " + (info.getLeft() - nonTicking) + ", Total Non-Ticking: " + nonTicking);
+ info.getRight().entrySet().stream()
+ .sorted((a, b) -> !a.getValue().equals(b.getValue()) ? b.getValue() - a.getValue() : a.getKey().toString().compareTo(b.getKey().toString()))
+ .limit(10).forEach(e -> sender.sendMessage(" " + e.getValue() + ": " + e.getKey().x + ", " + e.getKey().z + (chunkProviderServer.isPositionTicking(e.getKey().toLong()) ? " (Ticking)" : " (Non-Ticking)")));
+ } else {
+ List<Pair<ResourceLocation, Integer>> info = list.entrySet().stream()
+ .filter(e -> names.contains(e.getKey()))
+ .map(e -> Pair.of(e.getKey(), e.getValue().left))
+ .sorted((a, b) -> !a.getRight().equals(b.getRight()) ? b.getRight() - a.getRight() : a.getKey().toString().compareTo(b.getKey().toString()))
+ .collect(Collectors.toList());
+
+ if (info == null || info.size() == 0) {
+ sender.sendMessage(ChatColor.RED + "No entities found.");
+ return;
+ }
+
+ int count = info.stream().mapToInt(Pair::getRight).sum();
+ int nonTickingCount = nonEntityTicking.values().stream().mapToInt(Integer::intValue).sum();
+ sender.sendMessage("Total Ticking: " + (count - nonTickingCount) + ", Total Non-Ticking: " + nonTickingCount);
+ info.forEach(e -> {
+ int nonTicking = nonEntityTicking.getOrDefault(e.getKey(), Integer.valueOf(0)).intValue();
+ sender.sendMessage(" " + (e.getValue() - nonTicking) + " (" + nonTicking + ") " + ": " + e.getKey());
+ });
+ sender.sendMessage("* First number is ticking entities, second number is non-ticking entities");
+ }
+ break;
+ }
+ }
+
+ private void dumpHeap(CommandSender sender) {
+ java.nio.file.Path dir = java.nio.file.Paths.get("./dumps");
+ String name = "heap-dump-" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now());
+
+ Command.broadcastCommandMessage(sender, ChatColor.YELLOW + "Writing JVM heap data...");
+
+ java.nio.file.Path file = CraftServer.dumpHeap(dir, name);
+ if (file != null) {
+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Heap dump saved to " + file);
+ } else {
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "Failed to write heap dump, see sever log for details");
+ }
+ }
+
+ private void doReload(CommandSender sender) {
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues.");
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server.");
+
+ MinecraftServer console = MinecraftServer.getServer();
+ com.destroystokyo.paper.PaperConfig.init((File) console.options.valueOf("paper-settings"));
+ for (ServerLevel world : console.getAllLevels()) {
+ world.paperConfig.init();
+ }
+ console.server.reloadCount++;
+
+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Paper config reload complete.");
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000

Datei anzeigen

@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@@ -0,0 +0,0 @@ import java.util.stream.Collectors; @@ -0,0 +0,0 @@ import static net.kyori.adventure.text.format.NamedTextColor.YELLOW;
public class PaperCommand extends Command { public class PaperCommand extends Command {
private static final String BASE_PERM = "bukkit.command.paper."; private static final String BASE_PERM = "bukkit.command.paper.";
@ -48,7 +48,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
break; break;
@@ -0,0 +0,0 @@ public class PaperCommand extends Command { @@ -0,0 +0,0 @@ public class PaperCommand extends Command {
Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Paper config reload complete."); Command.broadcastCommandMessage(sender, text("Paper config reload complete.", GREEN));
} }
+ private void doDumpItem(CommandSender sender) { + private void doDumpItem(CommandSender sender) {
+ if (!(sender instanceof Player)) { + if (!(sender instanceof Player)) {

Datei anzeigen

@ -4375,20 +4375,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ lightengine.relight(chunks, + lightengine.relight(chunks,
+ (ChunkPos chunkPos) -> { + (ChunkPos chunkPos) -> {
+ ++relitChunks[0]; + ++relitChunks[0];
+ sender.getBukkitEntity().sendMessage( + sender.getBukkitEntity().sendMessage(text().color(DARK_AQUA).append(
+ ChatColor.BLUE + "Relit chunk " + ChatColor.DARK_AQUA + chunkPos + ChatColor.BLUE + + text("Relit chunk ", BLUE), text(chunkPos.toString()),
+ ", progress: " + ChatColor.DARK_AQUA + (int)(Math.round(100.0 * (double)(relitChunks[0])/(double)pending[0])) + "%" + text(", progress: ", BLUE), text((int)(Math.round(100.0 * (double)(relitChunks[0])/(double)pending[0])) + "%")
+ ); + ));
+ }, + },
+ (int totalRelit) -> { + (int totalRelit) -> {
+ final long end = System.nanoTime(); + final long end = System.nanoTime();
+ final long diff = Math.round(1.0e-6*(end - start)); + final long diff = Math.round(1.0e-6*(end - start));
+ sender.getBukkitEntity().sendMessage( + sender.getBukkitEntity().sendMessage(text().color(DARK_AQUA).append(
+ ChatColor.BLUE + "Relit " + ChatColor.DARK_AQUA + totalRelit + ChatColor.BLUE + " chunks. Took " + + text("Relit ", BLUE), text(totalRelit),
+ ChatColor.DARK_AQUA + diff + "ms" + text(" chunks. Took ", BLUE), text(diff + "ms")
+ ); + ));
+ }); + });
+ sender.getBukkitEntity().sendMessage(ChatColor.BLUE + "Relighting " + ChatColor.DARK_AQUA + pending[0] + ChatColor.BLUE + " chunks"); + sender.getBukkitEntity().sendMessage(text().color(BLUE).append(text("Relighting "), text(pending[0], DARK_AQUA), text(" chunks")));
+ } + }
+ // Paper end - rewrite light engine + // Paper end - rewrite light engine
+ +

Datei anzeigen

@ -193,14 +193,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package co.aikar.timings; +package co.aikar.timings;
+ +
+import com.google.common.collect.Sets; +import com.google.common.collect.Sets;
+import io.papermc.paper.adventure.PaperAdventure;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
+import net.minecraft.server.MinecraftServer; +import net.minecraft.server.MinecraftServer;
+import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.StringUtils;
+import org.bukkit.Bukkit; +import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material; +import org.bukkit.Material;
+import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.MemorySection; +import org.bukkit.configuration.MemorySection;
+import org.bukkit.craftbukkit.util.CraftChatMessage;
+import org.bukkit.entity.EntityType; +import org.bukkit.entity.EntityType;
+import org.json.simple.JSONObject; +import org.json.simple.JSONObject;
+import org.json.simple.JSONValue; +import org.json.simple.JSONValue;
@ -230,6 +231,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import static co.aikar.util.JSONUtil.toArray; +import static co.aikar.util.JSONUtil.toArray;
+import static co.aikar.util.JSONUtil.toArrayMapper; +import static co.aikar.util.JSONUtil.toArrayMapper;
+import static co.aikar.util.JSONUtil.toObjectMapper; +import static co.aikar.util.JSONUtil.toObjectMapper;
+import static net.kyori.adventure.text.Component.text;
+ +
+@SuppressWarnings({"rawtypes", "SuppressionAnnotation"}) +@SuppressWarnings({"rawtypes", "SuppressionAnnotation"})
+public class TimingsExport extends Thread { +public class TimingsExport extends Thread {
@ -260,17 +262,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ long now = System.currentTimeMillis(); + long now = System.currentTimeMillis();
+ final long lastReportDiff = now - lastReport; + final long lastReportDiff = now - lastReport;
+ if (lastReportDiff < 60000) { + if (lastReportDiff < 60000) {
+ listeners.sendMessage(ChatColor.RED + "Please wait at least 1 minute in between Timings reports. (" + (int)((60000 - lastReportDiff) / 1000) + " seconds)"); + listeners.sendMessage(text("Please wait at least 1 minute in between Timings reports. (" + (int)((60000 - lastReportDiff) / 1000) + " seconds)", NamedTextColor.RED));
+ listeners.done(); + listeners.done();
+ return; + return;
+ } + }
+ final long lastStartDiff = now - TimingsManager.timingStart; + final long lastStartDiff = now - TimingsManager.timingStart;
+ if (lastStartDiff < 180000) { + if (lastStartDiff < 180000) {
+ listeners.sendMessage(ChatColor.RED + "Please wait at least 3 minutes before generating a Timings report. Unlike Timings v1, v2 benefits from longer timings and is not as useful with short timings. (" + (int)((180000 - lastStartDiff) / 1000) + " seconds)"); + listeners.sendMessage(text("Please wait at least 3 minutes before generating a Timings report. Unlike Timings v1, v2 benefits from longer timings and is not as useful with short timings. (" + (int)((180000 - lastStartDiff) / 1000) + " seconds)", NamedTextColor.RED));
+ listeners.done(); + listeners.done();
+ return; + return;
+ } + }
+ listeners.sendMessage(ChatColor.GREEN + "Preparing Timings Report..."); + listeners.sendMessage(text("Preparing Timings Report...", NamedTextColor.GREEN));
+ lastReport = now; + lastReport = now;
+ Map parent = createObject( + Map parent = createObject(
+ // Get some basic system details about the server + // Get some basic system details about the server
@ -281,7 +283,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ pair("online-mode", Bukkit.getServer().getOnlineMode()), + pair("online-mode", Bukkit.getServer().getOnlineMode()),
+ pair("sampletime", (System.currentTimeMillis() - TimingsManager.timingStart) / 1000), + pair("sampletime", (System.currentTimeMillis() - TimingsManager.timingStart) / 1000),
+ pair("datapacks", toArrayMapper(MinecraftServer.getServer().getPackRepository().getSelectedPacks(), pack -> { + pair("datapacks", toArrayMapper(MinecraftServer.getServer().getPackRepository().getSelectedPacks(), pack -> {
+ return ChatColor.stripColor(CraftChatMessage.fromComponent(pack.getChatLink(true))); + return PlainTextComponentSerializer.plainText().serialize(PaperAdventure.asAdventure(pack.getChatLink(true)));
+ })) + }))
+ ); + );
+ if (!TimingsManager.privacy) { + if (!TimingsManager.privacy) {
@ -500,9 +502,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ response = getResponse(con); + response = getResponse(con);
+ +
+ if (con.getResponseCode() != 302) { + if (con.getResponseCode() != 302) {
+ listeners.sendMessage( + listeners.sendMessage(text( "Upload Error: " + con.getResponseCode() + ": " + con.getResponseMessage(), NamedTextColor.RED));
+ ChatColor.RED + "Upload Error: " + con.getResponseCode() + ": " + con.getResponseMessage()); + listeners.sendMessage(text("Check your logs for more information", NamedTextColor.RED));
+ listeners.sendMessage(ChatColor.RED + "Check your logs for more information");
+ if (response != null) { + if (response != null) {
+ Bukkit.getLogger().log(Level.SEVERE, response); + Bukkit.getLogger().log(Level.SEVERE, response);
+ } + }
@ -510,13 +511,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ timingsURL = con.getHeaderField("Location"); + timingsURL = con.getHeaderField("Location");
+ listeners.sendMessage(ChatColor.GREEN + "View Timings Report: " + timingsURL); + listeners.sendMessage(text("View Timings Report: " + timingsURL, NamedTextColor.GREEN));
+ +
+ if (response != null && !response.isEmpty()) { + if (response != null && !response.isEmpty()) {
+ Bukkit.getLogger().log(Level.INFO, "Timing Response: " + response); + Bukkit.getLogger().log(Level.INFO, "Timing Response: " + response);
+ } + }
+ } catch (IOException ex) { + } catch (IOException ex) {
+ listeners.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information"); + listeners.sendMessage(text("Error uploading timings, check your logs for more information", NamedTextColor.RED));
+ if (response != null) { + if (response != null) {
+ Bukkit.getLogger().log(Level.SEVERE, response); + Bukkit.getLogger().log(Level.SEVERE, response);
+ } + }
@ -540,7 +541,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return bos.toString(); + return bos.toString();
+ +
+ } catch (IOException ex) { + } catch (IOException ex) {
+ listeners.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information"); + listeners.sendMessage(text("Error uploading timings, check your logs for more information", NamedTextColor.RED));
+ Bukkit.getLogger().log(Level.WARNING, con.getResponseMessage(), ex); + Bukkit.getLogger().log(Level.WARNING, con.getResponseMessage(), ex);
+ return null; + return null;
+ } finally { + } finally {