This is generated by calude As it's only change the display, no tests and review are required
368 lines
22 KiB
Diff
368 lines
22 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: SakuraiMochi0721 <sakuraimochi0721@163.com>
|
|
Date: Sun, 12 Jul 2026 10:15:29 +0800
|
|
Subject: [PATCH] Improved server health command
|
|
|
|
This is generated by calude
|
|
As it's only change the display, no tests and review are required
|
|
|
|
diff --git a/io/papermc/paper/threadedregions/commands/CommandServerHealth.java b/io/papermc/paper/threadedregions/commands/CommandServerHealth.java
|
|
index aa860cfe9de616f185163fe74e0f4f49bd13a805..3545258acc0f516045594674c6f39f749d4d073a 100644
|
|
--- a/io/papermc/paper/threadedregions/commands/CommandServerHealth.java
|
|
+++ b/io/papermc/paper/threadedregions/commands/CommandServerHealth.java
|
|
@@ -42,46 +42,88 @@ public final class CommandServerHealth extends Command {
|
|
return new DecimalFormat("#,##0");
|
|
});
|
|
|
|
- private static final TextColor HEADER = TextColor.color(79, 164, 240);
|
|
- private static final TextColor PRIMARY = TextColor.color(48, 145, 237);
|
|
- private static final TextColor SECONDARY = TextColor.color(104, 177, 240);
|
|
- private static final TextColor INFORMATION = TextColor.color(145, 198, 243);
|
|
- private static final TextColor LIST = TextColor.color(33, 97, 188);
|
|
+ private static final TextColor HEADER = TextColor.color(0xcb, 0xa6, 0xf7); // Camellia - Catppuccin Mocha: Mauve
|
|
+ private static final TextColor PRIMARY = TextColor.color(0xa6, 0xad, 0xc8); // Camellia - Catppuccin Mocha: Subtext0
|
|
+ private static final TextColor SECONDARY = TextColor.color(0xb4, 0xbe, 0xfe); // Camellia - Catppuccin Mocha: Lavender
|
|
+ private static final TextColor INFORMATION = TextColor.color(0xcd, 0xd6, 0xf4); // Camellia - Catppuccin Mocha: Text
|
|
+ private static final TextColor LIST = TextColor.color(0x74, 0xc7, 0xec); // Camellia - Catppuccin Mocha: Sapphire
|
|
+ // Camellia start - prettier /tps output
|
|
+ private static final TextColor MUTED = TextColor.color(0x6c, 0x70, 0x86); // Catppuccin Mocha: Overlay0
|
|
+ private static final int DIVIDER_WIDTH = 44;
|
|
+ private static final int BAR_SEGMENTS = 20;
|
|
+ private static final String[] RANK_ICONS = {"①", "②", "③", "④", "⑤", "⑥", "⑦", "⑧", "⑨", "⑩"};
|
|
+ // Camellia end
|
|
|
|
public CommandServerHealth() {
|
|
super("tps");
|
|
- this.setUsage("/<command> [server/region] [lowest regions to display]");
|
|
+ this.setUsage("/<command> [server/region] [lowest regions to display|all]"); // Camellia - document "all" option
|
|
this.setDescription("Reports information about server health.");
|
|
this.setPermission("bukkit.command.tps");
|
|
}
|
|
|
|
+ // Camellia start - prettier /tps output helpers
|
|
+ private static Component divider() {
|
|
+ // strikethrough spaces render as a solid flat line on every client/font, unlike box-drawing glyphs
|
|
+ return Component.text(" ".repeat(DIVIDER_WIDTH), MUTED, TextDecoration.STRIKETHROUGH);
|
|
+ }
|
|
+
|
|
+ private static Component sectionHeader(final String title) {
|
|
+ return Component.text()
|
|
+ .append(Component.text("» ", HEADER, TextDecoration.BOLD))
|
|
+ .append(Component.text(title + "\n", HEADER, TextDecoration.BOLD))
|
|
+ .build();
|
|
+ }
|
|
+
|
|
+ private static String rankLabel(final int index) {
|
|
+ return index < RANK_ICONS.length ? RANK_ICONS[index] : ("#" + (index + 1));
|
|
+ }
|
|
+
|
|
+ private static Component progressBar(final double fraction) {
|
|
+ // same strikethrough-space trick as divider() so the bar is a smooth flat two-tone line, not a
|
|
+ // row of block glyphs that may render as tiny/misaligned dots depending on the client's font
|
|
+ final double clamped = Math.max(0.0, Math.min(1.0, fraction));
|
|
+ final int filled = (int) Math.round(clamped * BAR_SEGMENTS);
|
|
+ final TextColor barColour = CommandUtil.getUtilisationColourRegion(clamped);
|
|
+ return Component.text()
|
|
+ .append(Component.text(" ".repeat(filled), barColour, TextDecoration.STRIKETHROUGH))
|
|
+ .append(Component.text(" ".repeat(BAR_SEGMENTS - filled), MUTED, TextDecoration.STRIKETHROUGH))
|
|
+ .build();
|
|
+ }
|
|
+ // Camellia end
|
|
+
|
|
private static Component formatRegionInfo(final String prefix, final double util, final double mspt, final double tps,
|
|
final boolean newline) {
|
|
+ // Camellia start - use progress bar + dot separators instead of plain "util at ... MSPT at ..." text
|
|
return Component.text()
|
|
- .append(Component.text(prefix, PRIMARY, TextDecoration.BOLD))
|
|
- .append(Component.text(ONE_DECIMAL_PLACES.get().format(util * 100.0), CommandUtil.getUtilisationColourRegion(util)))
|
|
- .append(Component.text("% util at ", PRIMARY))
|
|
- .append(Component.text(TWO_DECIMAL_PLACES.get().format(mspt), CommandUtil.getColourForMSPT(mspt)))
|
|
- .append(Component.text(" MSPT at ", PRIMARY))
|
|
- .append(Component.text(TWO_DECIMAL_PLACES.get().format(tps), CommandUtil.getColourForTPS(tps)))
|
|
- .append(Component.text(" TPS" + (newline ? "\n" : ""), PRIMARY))
|
|
- .build();
|
|
+ .append(Component.text(prefix, PRIMARY, TextDecoration.BOLD))
|
|
+ .append(progressBar(util))
|
|
+ .append(Component.text(" "))
|
|
+ .append(Component.text(ONE_DECIMAL_PLACES.get().format(util * 100.0) + "%", CommandUtil.getUtilisationColourRegion(util)))
|
|
+ .append(Component.text(" · ", MUTED))
|
|
+ .append(Component.text(TWO_DECIMAL_PLACES.get().format(mspt) + " ms", CommandUtil.getColourForMSPT(mspt)))
|
|
+ .append(Component.text(" · ", MUTED))
|
|
+ .append(Component.text(TWO_DECIMAL_PLACES.get().format(tps) + " tps", CommandUtil.getColourForTPS(tps)))
|
|
+ .append(Component.text(newline ? "\n" : "", PRIMARY))
|
|
+ .build();
|
|
+ // Camellia end
|
|
}
|
|
|
|
private static Component formatRegionStats(final TickRegions.RegionStats stats, final boolean newline) {
|
|
+ // Camellia start - add "·" separators for readability
|
|
return Component.text()
|
|
- .append(Component.text("Chunks: ", PRIMARY))
|
|
- .append(Component.text(NO_DECIMAL_PLACES.get().format((long)stats.getChunkCount()), INFORMATION))
|
|
- .append(Component.text(" Players: ", PRIMARY))
|
|
- .append(Component.text(NO_DECIMAL_PLACES.get().format((long)stats.getPlayerCount()), INFORMATION))
|
|
- .append(Component.text(" Entities: ", PRIMARY))
|
|
- .append(Component.text(NO_DECIMAL_PLACES.get().format((long)stats.getEntityCount()) + (newline ? "\n" : ""), INFORMATION))
|
|
- .build();
|
|
+ .append(Component.text("Chunks: ", PRIMARY))
|
|
+ .append(Component.text(NO_DECIMAL_PLACES.get().format((long)stats.getChunkCount()), INFORMATION))
|
|
+ .append(Component.text(" · Players: ", PRIMARY))
|
|
+ .append(Component.text(NO_DECIMAL_PLACES.get().format((long)stats.getPlayerCount()), INFORMATION))
|
|
+ .append(Component.text(" · Entities: ", PRIMARY))
|
|
+ .append(Component.text(NO_DECIMAL_PLACES.get().format((long)stats.getEntityCount()) + (newline ? "\n" : ""), INFORMATION))
|
|
+ .build();
|
|
+ // Camellia end
|
|
}
|
|
|
|
private static boolean executeRegion(final CommandSender sender, final String commandLabel, final String[] args) {
|
|
final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> region =
|
|
- TickRegionScheduler.getCurrentRegion();
|
|
+ TickRegionScheduler.getCurrentRegion();
|
|
if (region == null) {
|
|
sender.sendMessage(Component.text("You are not in a region currently", NamedTextColor.RED));
|
|
return true;
|
|
@@ -108,22 +150,24 @@ public final class CommandServerHealth extends Command {
|
|
final int yLoc = 80;
|
|
final String location = "[w:'" + world.getWorld().getName() + "'," + centerBlockX + "," + yLoc + "," + centerBlockZ + "]";
|
|
|
|
+ // Camellia start - prettier /tps region output
|
|
final Component line = Component.text()
|
|
- .append(Component.text("Region around block ", PRIMARY))
|
|
- .append(Component.text(location, INFORMATION))
|
|
- .append(Component.text(":\n", PRIMARY))
|
|
-
|
|
- .append(
|
|
- formatRegionInfo("15s: ", util15s, mspt15s, tps15s, true)
|
|
- )
|
|
- .append(
|
|
- formatRegionInfo("1m: ", util1m, mspt1m, tps1m, true)
|
|
- )
|
|
- .append(
|
|
- formatRegionStats(region.getData().getRegionStats(), false)
|
|
- )
|
|
-
|
|
- .build();
|
|
+ .append(sectionHeader("Region around " + location))
|
|
+ .append(divider())
|
|
+ .append(Component.text("\n"))
|
|
+
|
|
+ .append(
|
|
+ formatRegionInfo("15s: ", util15s, mspt15s, tps15s, true)
|
|
+ )
|
|
+ .append(
|
|
+ formatRegionInfo("1m: ", util1m, mspt1m, tps1m, true)
|
|
+ )
|
|
+ .append(
|
|
+ formatRegionStats(region.getData().getRegionStats(), false)
|
|
+ )
|
|
+
|
|
+ .build();
|
|
+ // Camellia end
|
|
|
|
sender.sendMessage(line);
|
|
|
|
@@ -131,9 +175,13 @@ public final class CommandServerHealth extends Command {
|
|
}
|
|
|
|
private static boolean executeServer(final CommandSender sender, final String commandLabel, final String[] args) {
|
|
+ // Camellia start - "all" lists every tick region instead of just the top N by utilisation
|
|
+ final boolean showAllRegions = args.length >= 2 && args[1].equalsIgnoreCase("all");
|
|
final int lowestRegionsCount;
|
|
- if (args.length < 2) {
|
|
- lowestRegionsCount = 3;
|
|
+ if (showAllRegions) {
|
|
+ lowestRegionsCount = Integer.MAX_VALUE; // unused when showAllRegions is true, kept for definite assignment
|
|
+ } else if (args.length < 2) {
|
|
+ lowestRegionsCount = 5; // default to top 5 regions
|
|
} else {
|
|
try {
|
|
lowestRegionsCount = Integer.parseInt(args[1]);
|
|
@@ -142,9 +190,10 @@ public final class CommandServerHealth extends Command {
|
|
return true;
|
|
}
|
|
}
|
|
+ // Camellia end
|
|
|
|
final List<ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData>> regions =
|
|
- new ArrayList<>();
|
|
+ new ArrayList<>();
|
|
|
|
for (final World bukkitWorld : Bukkit.getWorlds()) {
|
|
final ServerLevel world = ((CraftWorld)bukkitWorld).getHandle();
|
|
@@ -174,6 +223,7 @@ public final class CommandServerHealth extends Command {
|
|
final double loadRate = ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkFullTask.loadRate(currTime);
|
|
|
|
totalUtil += globalTickReport.utilisation();
|
|
+ final double overallFraction = maxThreadCount > 0 ? (totalUtil / maxThreadCount) : 0.0; // Camellia - overall load fraction for progress bar
|
|
|
|
tpsByRegion.sort(null);
|
|
if (!tpsByRegion.isEmpty()) {
|
|
@@ -194,7 +244,7 @@ public final class CommandServerHealth extends Command {
|
|
}
|
|
|
|
final List<ObjectObjectImmutablePair<ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData>, TickData.TickReportData>>
|
|
- regionsBelowThreshold = new ArrayList<>();
|
|
+ regionsBelowThreshold = new ArrayList<>();
|
|
|
|
for (int i = 0, len = regions.size(); i < len; ++i) {
|
|
final TickData.TickReportData report = reportsByRegion.get(i);
|
|
@@ -215,15 +265,15 @@ public final class CommandServerHealth extends Command {
|
|
final TextComponent.Builder lowestRegionsBuilder = Component.text();
|
|
|
|
if (sender instanceof Player) {
|
|
- lowestRegionsBuilder.append(Component.text(" Click to teleport\n", SECONDARY));
|
|
+ lowestRegionsBuilder.append(Component.text(" Click to teleport\n", SECONDARY, TextDecoration.ITALIC)); // Camellia - restyle hint text
|
|
}
|
|
- for (int i = 0, len = Math.min(lowestRegionsCount, regionsBelowThreshold.size()); i < len; ++i) {
|
|
+ for (int i = 0, len = showAllRegions ? regionsBelowThreshold.size() : Math.min(lowestRegionsCount, regionsBelowThreshold.size()); i < len; ++i) { // Camellia - support "all"
|
|
final ObjectObjectImmutablePair<ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData>, TickData.TickReportData>
|
|
- pair = regionsBelowThreshold.get(i);
|
|
+ pair = regionsBelowThreshold.get(i);
|
|
|
|
final TickData.TickReportData report = pair.right();
|
|
final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> region =
|
|
- pair.left();
|
|
+ pair.left();
|
|
|
|
if (report == null) {
|
|
// skip regions with no data
|
|
@@ -244,74 +294,76 @@ public final class CommandServerHealth extends Command {
|
|
|
|
final int yLoc = 80;
|
|
final String location = "[w:'" + world.getWorld().getName() + "'," + centerBlockX + "," + yLoc + "," + centerBlockZ + "]";
|
|
+ // Camellia start - prettier /tps region list entries
|
|
final Component line = Component.text()
|
|
- .append(Component.text(" - ", LIST, TextDecoration.BOLD))
|
|
- .append(Component.text("Region around block ", PRIMARY))
|
|
- .append(Component.text(location, INFORMATION))
|
|
- .append(Component.text(":\n", PRIMARY))
|
|
-
|
|
- .append(Component.text(" ", PRIMARY))
|
|
- .append(Component.text(ONE_DECIMAL_PLACES.get().format(util * 100.0), CommandUtil.getUtilisationColourRegion(util)))
|
|
- .append(Component.text("% util at ", PRIMARY))
|
|
- .append(Component.text(TWO_DECIMAL_PLACES.get().format(mspt), CommandUtil.getColourForMSPT(mspt)))
|
|
- .append(Component.text(" MSPT at ", PRIMARY))
|
|
- .append(Component.text(TWO_DECIMAL_PLACES.get().format(tps), CommandUtil.getColourForTPS(tps)))
|
|
- .append(Component.text(" TPS\n", PRIMARY))
|
|
-
|
|
- .append(Component.text(" ", PRIMARY))
|
|
- .append(formatRegionStats(region.getData().getRegionStats(), (i + 1) != len))
|
|
- .build()
|
|
-
|
|
- .clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, Payload.string("/minecraft:execute as @s in " + world.getWorld().getKey().toString() + " run tp " + centerBlockX + ".5 " + yLoc + " " + centerBlockZ + ".5")))
|
|
- .hoverEvent(HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT, Component.text("Click to teleport to " + location, SECONDARY)));
|
|
+ .append(Component.text(" " + rankLabel(i) + " ", LIST, TextDecoration.BOLD)) // Camellia - Catppuccin Mocha: Sapphire rank marker
|
|
+ .append(Component.text(location + "\n", INFORMATION))
|
|
+
|
|
+ .append(Component.text(" "))
|
|
+ .append(progressBar(util))
|
|
+ .append(Component.text(" "))
|
|
+ .append(Component.text(ONE_DECIMAL_PLACES.get().format(util * 100.0) + "%", CommandUtil.getUtilisationColourRegion(util)))
|
|
+ .append(Component.text(" · ", MUTED))
|
|
+ .append(Component.text(TWO_DECIMAL_PLACES.get().format(mspt) + " ms", CommandUtil.getColourForMSPT(mspt)))
|
|
+ .append(Component.text(" · ", MUTED))
|
|
+ .append(Component.text(TWO_DECIMAL_PLACES.get().format(tps) + " tps\n", CommandUtil.getColourForTPS(tps)))
|
|
+
|
|
+ .append(Component.text(" "))
|
|
+ .append(formatRegionStats(region.getData().getRegionStats(), (i + 1) != len))
|
|
+ .build()
|
|
+
|
|
+ .clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, Payload.string("/minecraft:execute as @s in " + world.getWorld().getKey().toString() + " run tp " + centerBlockX + ".5 " + yLoc + " " + centerBlockZ + ".5")))
|
|
+ .hoverEvent(HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT, Component.text("Click to teleport to " + location, SECONDARY)));
|
|
+ // Camellia end
|
|
|
|
lowestRegionsBuilder.append(line);
|
|
}
|
|
|
|
sender.sendMessage(
|
|
- Component.text()
|
|
- .append(Component.text("Server Health Report\n", HEADER, TextDecoration.BOLD))
|
|
-
|
|
- .append(Component.text(" - ", LIST, TextDecoration.BOLD))
|
|
- .append(Component.text("Online Players: ", PRIMARY))
|
|
- .append(Component.text(Bukkit.getOnlinePlayers().size() + "\n", INFORMATION))
|
|
-
|
|
- .append(Component.text(" - ", LIST, TextDecoration.BOLD))
|
|
- .append(Component.text("Total regions: ", PRIMARY))
|
|
- .append(Component.text(regions.size() + "\n", INFORMATION))
|
|
-
|
|
- .append(Component.text(" - ", LIST, TextDecoration.BOLD))
|
|
- .append(Component.text("Utilisation: ", PRIMARY))
|
|
- .append(Component.text(ONE_DECIMAL_PLACES.get().format(totalUtil * 100.0), CommandUtil.getUtilisationColourRegion(totalUtil / (double)maxThreadCount)))
|
|
- .append(Component.text("% / ", PRIMARY))
|
|
- .append(Component.text(ONE_DECIMAL_PLACES.get().format(maxThreadCount * 100.0), INFORMATION))
|
|
- .append(Component.text("%\n", PRIMARY))
|
|
-
|
|
- .append(Component.text(" - ", LIST, TextDecoration.BOLD))
|
|
- .append(Component.text("Load rate: ", PRIMARY))
|
|
- .append(Component.text(TWO_DECIMAL_PLACES.get().format(loadRate) + ", ", INFORMATION))
|
|
- .append(Component.text("Gen rate: ", PRIMARY))
|
|
- .append(Component.text(TWO_DECIMAL_PLACES.get().format(genRate) + "\n", INFORMATION))
|
|
-
|
|
- .append(Component.text(" - ", LIST, TextDecoration.BOLD))
|
|
- .append(Component.text("Lowest Region TPS: ", PRIMARY))
|
|
- .append(Component.text(TWO_DECIMAL_PLACES.get().format(minTps) + "\n", CommandUtil.getColourForTPS(minTps)))
|
|
-
|
|
-
|
|
- .append(Component.text(" - ", LIST, TextDecoration.BOLD))
|
|
- .append(Component.text("Median Region TPS: ", PRIMARY))
|
|
- .append(Component.text(TWO_DECIMAL_PLACES.get().format(medianTps) + "\n", CommandUtil.getColourForTPS(medianTps)))
|
|
-
|
|
- .append(Component.text(" - ", LIST, TextDecoration.BOLD))
|
|
- .append(Component.text("Highest Region TPS: ", PRIMARY))
|
|
- .append(Component.text(TWO_DECIMAL_PLACES.get().format(maxTps) + "\n", CommandUtil.getColourForTPS(maxTps)))
|
|
-
|
|
- .append(Component.text("Highest ", HEADER, TextDecoration.BOLD))
|
|
- .append(Component.text(Integer.toString(lowestRegionsCount), INFORMATION, TextDecoration.BOLD))
|
|
- .append(Component.text(" utilisation regions\n", HEADER, TextDecoration.BOLD))
|
|
-
|
|
- .append(lowestRegionsBuilder.build())
|
|
- .build()
|
|
+ // Camellia start - prettier /tps server output
|
|
+ Component.text()
|
|
+ .append(sectionHeader("Server Health Report"))
|
|
+ .append(divider())
|
|
+ .append(Component.text("\n"))
|
|
+
|
|
+ .append(Component.text(" Summary\n", HEADER, TextDecoration.BOLD))
|
|
+ .append(Component.text(" Players ", PRIMARY))
|
|
+ .append(Component.text(Bukkit.getOnlinePlayers().size() + " ", INFORMATION))
|
|
+ .append(Component.text("Regions ", PRIMARY))
|
|
+ .append(Component.text(regions.size() + "\n", INFORMATION))
|
|
+
|
|
+ .append(Component.text(" Chunk system load\n", HEADER, TextDecoration.BOLD))
|
|
+ .append(Component.text(" Load rate ", PRIMARY))
|
|
+ .append(Component.text(TWO_DECIMAL_PLACES.get().format(loadRate) + " ", INFORMATION))
|
|
+ .append(Component.text("Gen rate ", PRIMARY))
|
|
+ .append(Component.text(TWO_DECIMAL_PLACES.get().format(genRate) + "\n", INFORMATION))
|
|
+
|
|
+ .append(Component.text(" Overall load\n", HEADER, TextDecoration.BOLD))
|
|
+ .append(Component.text(" "))
|
|
+ .append(progressBar(overallFraction))
|
|
+ .append(Component.text(" "))
|
|
+ .append(Component.text(ONE_DECIMAL_PLACES.get().format(overallFraction * 100.0) + "%", CommandUtil.getUtilisationColourRegion(overallFraction)))
|
|
+ .append(Component.text(" (", MUTED))
|
|
+ .append(Component.text(ONE_DECIMAL_PLACES.get().format(totalUtil * 100.0) + "%", INFORMATION))
|
|
+ .append(Component.text(" / ", MUTED))
|
|
+ .append(Component.text(maxThreadCount + " threads", INFORMATION))
|
|
+ .append(Component.text(")\n", MUTED))
|
|
+
|
|
+ .append(Component.text(" TPS\n", HEADER, TextDecoration.BOLD))
|
|
+ .append(Component.text(" min ", PRIMARY))
|
|
+ .append(Component.text(TWO_DECIMAL_PLACES.get().format(minTps) + " ", CommandUtil.getColourForTPS(minTps)))
|
|
+ .append(Component.text("med ", PRIMARY))
|
|
+ .append(Component.text(TWO_DECIMAL_PLACES.get().format(medianTps) + " ", CommandUtil.getColourForTPS(medianTps)))
|
|
+ .append(Component.text("max ", PRIMARY))
|
|
+ .append(Component.text(TWO_DECIMAL_PLACES.get().format(maxTps) + "\n", CommandUtil.getColourForTPS(maxTps)))
|
|
+
|
|
+ .append(divider())
|
|
+ .append(Component.text("\n"))
|
|
+ .append(sectionHeader(showAllRegions ? "All " + regions.size() + " regions by utilisation" : "Top " + lowestRegionsCount + " regions by utilisation")) // Camellia - "all" heading
|
|
+
|
|
+ .append(lowestRegionsBuilder.build())
|
|
+ .build()
|
|
+ // Camellia end
|
|
);
|
|
|
|
return true;
|