diff --git a/Core/src/main/java/com/plotsquared/core/command/Info.java b/Core/src/main/java/com/plotsquared/core/command/Info.java index 3efabe114d..bdae3b8289 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Info.java +++ b/Core/src/main/java/com/plotsquared/core/command/Info.java @@ -23,6 +23,8 @@ import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.database.DBFunc; import com.plotsquared.core.permissions.Permission; +import com.plotsquared.core.player.MetaDataAccess; +import com.plotsquared.core.player.PlayerMetaDataKeys; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.flag.implementations.HideInfoFlag; @@ -39,7 +41,7 @@ @CommandDeclaration(command = "info", aliases = "i", - usage = "/plot info [-f to force info]", + usage = "/plot info [-f to force info] [-r to show raw flag values]", category = CommandCategory.INFO) public class Info extends SubCommand { @@ -83,6 +85,25 @@ public boolean onCommand(final PlotPlayer player, String[] args) { } } + // Check for raw flag display preference + boolean showRawFlags = false; + for (final String argument : args) { + if (argument.equalsIgnoreCase("-r")) { + if (!player.hasPermission("plots.admin.info.raw")) { + player.sendMessage( + TranslatableCaption.of("permission.no_permission"), + TagResolver.resolver( + "node", + Tag.inserting(Component.text("plots.admin.info.raw")) + ) + ); + return true; + } + showRawFlags = true; + break; + } + } + // hide-info flag if (plot.getFlag(HideInfoFlag.class)) { boolean allowed = false; @@ -140,7 +161,23 @@ public boolean onCommand(final PlotPlayer player, String[] args) { } else { full = false; } - plot.format(info, player, full).thenAcceptAsync(player::sendMessage); + + // Store raw flag preference in player metadata + try (final MetaDataAccess metaDataAccess = player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_RAW_FLAGS)) { + if (showRawFlags) { + metaDataAccess.set(true); + } else { + metaDataAccess.remove(); + } + } + + plot.format(info, player, full).thenAcceptAsync(formatted -> { + player.sendMessage(formatted); + // Clean up metadata after use + try (final MetaDataAccess metaDataAccess = player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_RAW_FLAGS)) { + metaDataAccess.remove(); + } + }); return true; } @@ -150,6 +187,9 @@ public Collection tab(PlotPlayer player, String[] args, boolean spac if (player.hasPermission(Permission.PERMISSION_AREA_INFO_FORCE)) { completions.add("-f"); } + if (player.hasPermission("plots.admin.info.raw")) { + completions.add("-r"); + } final List commands = completions.stream().filter(completion -> completion .toLowerCase() diff --git a/Core/src/main/java/com/plotsquared/core/configuration/caption/CaptionUtility.java b/Core/src/main/java/com/plotsquared/core/configuration/caption/CaptionUtility.java index 160e3277ab..39ef82bcc1 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/caption/CaptionUtility.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/caption/CaptionUtility.java @@ -116,6 +116,17 @@ public static String stripClickEvents(final @NonNull String miniMessageString) { return MiniMessage.miniMessage().serialize(component); } + /** + * Checks if a flag should be parsed as MiniMessage. + * + * @param flag the flag to check + * @return true if the flag value should be parsed as MiniMessage + * @since 7.3.9 + */ + public static boolean isMiniMessageFlag(PlotFlag flag) { + return MINI_MESSAGE_FLAGS.contains(flag.getClass()); + } + /** * Strips configured MiniMessage click events from a plot flag value. * This is used before letting the string be parsed by the plot flag. diff --git a/Core/src/main/java/com/plotsquared/core/player/PlayerMetaDataKeys.java b/Core/src/main/java/com/plotsquared/core/player/PlayerMetaDataKeys.java index 07fb482cc8..b9557470fc 100644 --- a/Core/src/main/java/com/plotsquared/core/player/PlayerMetaDataKeys.java +++ b/Core/src/main/java/com/plotsquared/core/player/PlayerMetaDataKeys.java @@ -64,6 +64,8 @@ public final class PlayerMetaDataKeys { }); public static final MetaDataKey TEMPORARY_CONFIRM = MetaDataKey.of("cmdConfirm", new TypeLiteral<>() { }); + public static final MetaDataKey TEMPORARY_RAW_FLAGS = MetaDataKey.of("rawFlags", new TypeLiteral<>() { + }); //@formatter:on private PlayerMetaDataKeys() { diff --git a/Core/src/main/java/com/plotsquared/core/plot/Plot.java b/Core/src/main/java/com/plotsquared/core/plot/Plot.java index 655dc6d3f5..a00442a954 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/Plot.java +++ b/Core/src/main/java/com/plotsquared/core/plot/Plot.java @@ -39,6 +39,8 @@ import com.plotsquared.core.location.Location; import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.player.ConsolePlayer; +import com.plotsquared.core.player.MetaDataAccess; +import com.plotsquared.core.player.PlayerMetaDataKeys; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.expiration.PlotAnalysis; @@ -2897,6 +2899,27 @@ public CompletableFuture format(final Caption iInfo, PlotPlayer play } else { value = flag.toString(); } + // Create value component - check if raw display is requested + Component valueComponent; + String formattedValue = CaptionUtility.formatRaw(player, value.toString()); + + // Check if player requested raw flag display + boolean showRaw = false; + try (final MetaDataAccess metaDataAccess = player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_RAW_FLAGS)) { + showRaw = metaDataAccess.get().orElse(false); + } + + if (!showRaw && CaptionUtility.isMiniMessageFlag(flag)) { + try { + valueComponent = MINI_MESSAGE.deserialize(formattedValue); + } catch (Exception e) { + // Fallback to plain text if parsing fails + valueComponent = Component.text(formattedValue); + } + } else { + valueComponent = Component.text(formattedValue); + } + Component snip = MINI_MESSAGE.deserialize( prefix + CaptionUtility.format( player, @@ -2904,10 +2927,7 @@ public CompletableFuture format(final Caption iInfo, PlotPlayer play ), TagResolver.builder() .tag("flag", Tag.inserting(Component.text(flag.getName()))) - .tag("value", Tag.inserting(Component.text(CaptionUtility.formatRaw( - player, - value.toString() - )))) + .tag("value", Tag.inserting(valueComponent)) .build() ); flagBuilder.append(snip);