HelpChat / DeluxeMenus

DeluxeMenus but open source!?
https://wiki.helpch.at/clips-plugins/deluxemenus
MIT License
77 stars 36 forks source link

Add MiniMessage support for item display names, lores and menu titles #15

Open BlitzOffline opened 8 months ago

BlitzOffline commented 8 months ago

While the Spigot API does not support Adventure, we can still try to add support for it.

One way to support this would be to do a double translation: MiniMessage String -> Adventure Component -> Legacy String. The downsides of this would be that components/tags such as translatable, keybind, etc. would not be supported.

I was told that this can also be achieved using reflection and that https://github.com/TriumphTeam/triumph-gui/ does exactly this.

One thing I want to make clear is that only one option will be supported at a time. Menu creators won't be able to combine Legacy Strings with MiniMessage Strings. They will be able to toggle the option they want to use per plugin and not per menus inside "config.yml". By default Legacy Strings will be used to offer backwards support.

GG-MD commented 1 week ago

Do it already! It's been years, we've been waiting years!!! @BlitzOffline

GG-MD commented 1 week ago

package com.extendedclip.deluxemenus.utils;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import me.clip.placeholderapi.PlaceholderAPI;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;

public class StringUtils {

    private final static Pattern HEX_PATTERN = Pattern
            .compile("&(#[a-f0-9]{6})", Pattern.CASE_INSENSITIVE);

    @NotNull
    public static String color(@NotNull String input) {
        // MiniMessage processing
        MiniMessage miniMessage = MiniMessage.miniMessage();
        Component component = miniMessage.deserialize(input);
        input = LegacyComponentSerializer.legacySection().serialize(component);

        // Hex Support for 1.16.1+
        Matcher m = HEX_PATTERN.matcher(input);
        if (VersionHelper.IS_HEX_VERSION) {
            while (m.find()) {
                input = input.replace(m.group(), ChatColor.of(m.group(1)).toString());
            }
        }

        return ChatColor.translateAlternateColorCodes('&', input);
    }

    @NotNull
    public static String replacePlaceholdersAndArguments(@NotNull String input, final @Nullable Map<String, String> arguments,
                                                         final @Nullable Player player,
                                                         final boolean parsePlaceholdersInsideArguments,
                                                         final boolean parsePlaceholdersAfterArguments) {
        if (player == null) {
            return replaceArguments(input, arguments, null, parsePlaceholdersInsideArguments);
        }

        if (parsePlaceholdersAfterArguments) {
            return replacePlaceholders(replaceArguments(input, arguments, player, parsePlaceholdersInsideArguments), player);
        }

        return replaceArguments(replacePlaceholders(input, player), arguments, player, parsePlaceholdersInsideArguments);
    }

    @NotNull
    public static String replacePlaceholders(final @NotNull String input, final @NotNull Player player) {
        return PlaceholderAPI.setPlaceholders(player, input);
    }

    @NotNull
    public static String replaceArguments(@NotNull String input, final @Nullable Map<String, String> arguments,
                                          final @Nullable Player player, boolean parsePlaceholdersInsideArguments) {
        if (arguments == null || arguments.isEmpty()) {
            return input;
        }

        for (final Map.Entry<String, String> entry : arguments.entrySet()) {
            final String value = player != null && parsePlaceholdersInsideArguments
                    ? replacePlaceholders(entry.getValue(), player)
                    : entry.getValue();
            input = input.replace("{" + entry.getKey() + "}", value);
        }

        return input;
    }
}