1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите Поддержка текста с градиентом

Тема в разделе "Разработка плагинов для новичков", создана пользователем Aviloo, 12 окт 2023.

  1. Автор темы
    Aviloo

    Aviloo Активный участник Пользователь

    Баллы:
    61
    Имя в Minecraft:
    Aviloo
    Всем привет. У меня есть небольшой плагин на скорборд. Проблема собственно состоит в том, что если ,например, у меня на сервере есть префиксы с использованием градиента , то в скорборде текст отображается, как каша из символов. Хотел узнать, как можно реализовать отображение текста с градиентом.
     
  2. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    В чём конкретно проблема? Цветовые коды отображаются текстом? Хоть бы скрин показал.

    И какое ядро и версия?

    На Paper и его форках начиная с 1.16 (возможно 1.16.5) есть поддержка Adventure API, для получения градиента можно парсить строку в формате MiniMessage. Тут всё просто:
    PHP:
    @Nonnull
    public static Component createRgbGradient(@Nonnull String text, @Nonnull TextColor start, @Nonnull TextColor end) {
        return 
    MiniMessage.miniMessage().deserialize(
            
    "<gradient:" start.asHexString() + ":" end.asHexString() + ">"
                
    text
                
    "</gradient>"
        
    );
    }

    @
    Nonnull
    public static String create16ColorsGradient(@Nonnull String text, @Nonnull TextColor start, @Nonnull TextColor end) {
        return 
    LegacyComponentSerializer.legacySection().serialize(createRgbGradient(textstartend));
    }
    Возможно когда-нибудь появится нормальный метод в апи для создания RGB-градиентов, но пока только через MiniMessage.

    На Spigot или на старых версиях Paper (до 1.15 включительно) нет возможности задавать параметры Objective, Team и Entry компонентами из Bungee или Adventure, поэтому придётся обычной строкой:
    PHP:
    @Nonnull
    public static String createRgbGradient(@Nonnull String text, @Nonnull ChatColor start, @Nonnull ChatColor end) {
        return 
    createGradient(textstartendtrue);
    }

    @
    Nonnull
    public static String create16ColorsGradient(@Nonnull String text, @Nonnull ChatColor start, @Nonnull ChatColor end) {
        return 
    createGradient(textstartendfalse);
    }

    @
    Nonnull
    private static String createGradient(@Nonnull String text, @Nonnull ChatColor start, @Nonnull ChatColor endboolean useRGB) {
        
    char[] chars text.toCharArray();
        
    int length chars.length;

        
    StringBuilder result = new StringBuilder();
        for (
    int i 0lengthi++) {
            
    ChatColor color getGradientColor(startend, ((double) i) / length);
            if (!
    useRGB) {
                
    color nearestNamedTo(color);
            }
            
    result.append(color).append(chars[i]);
        }

        return 
    result.toString();
    }

    @
    Nonnull
    private static ChatColor getGradientColor(@Nonnull ChatColor start, @Nonnull ChatColor enddouble percent) {
        
    Color s start.getColor();
        
    Color e end.getColor();
        return 
    ChatColor.of(new Color(
            (int) (
    s.getRed() + ((e.getRed() - s.getRed()) * percent)),
            (int) (
    s.getGreen() + ((e.getGreen() - s.getGreen()) * percent)),
            (int) (
    s.getBlue() + ((e.getBlue() - s.getBlue()) * percent))
        ));
    }

    private static final 
    ChatColor[] NAMED_COLORS = new ChatColor[]{
        
    ChatColor.BLACKChatColor.DARK_BLUEChatColor.DARK_GREENChatColor.DARK_AQUA,
        
    ChatColor.DARK_REDChatColor.DARK_PURPLEChatColor.GOLDChatColor.GRAY,
        
    ChatColor.DARK_GRAYChatColor.BLUEChatColor.GREENChatColor.AQUA,
        
    ChatColor.REDChatColor.LIGHT_PURPLEChatColor.YELLOWChatColor.WHITE
    };

    @
    Nonnull
    private static ChatColor nearestNamedTo(@Nonnull ChatColor any) {
        
    float matchedDistance Float.MAX_VALUE;
        
    ChatColor match NAMED_COLORS[0];
        
    int i 0;

        for (
    int length NAMED_COLORS.lengthlength; ++i) {
            
    ChatColor potential NAMED_COLORS[i];

            
    float distance distance(any.getColor(), potential.getColor());
            if (
    distance matchedDistance) {
                
    match potential;
                
    matchedDistance distance;
            }

            if (
    distance == 0.0F) {
                break;
            }
        }

        return 
    match;
    }

    private static 
    float distance(@Nonnull Color first, @Nonnull Color second) {
        
    float[] selfHVS Color.RGBtoHSB(first.getRed(), first.getGreen(), first.getBlue(), null);
        
    float[] otherHVS Color.RGBtoHSB(second.getRed(), second.getGreen(), second.getBlue(), null);
        
    float hueDistance 3.0F Math.min(Math.abs(selfHVS[0] - otherHVS[0]), 1.0F Math.abs(selfHVS[0] - otherHVS[0]));
        
    float saturationDiff selfHVS[1] - otherHVS[1];
        
    float valueDiff selfHVS[2] - otherHVS[2];
        return (
    hueDistance hueDistance) + (saturationDiff saturationDiff) + (valueDiff valueDiff);
    }
    Важно: Убедись, что в импортах net.md_5.bungee.api.ChatColor, а не org.bukkit.ChatColor. Баккитовский вообще не поддерживает RGB.


    Данный код отлично подходит для большинства задач: для отправки сообщений в чат, создания названий предметов и задания названий скорбордам, а также создания префиксов/суффиксов команд.

    Однако независимо от версии игры и ядра score (entry команд) не поддерживают RGB.
    Результат:
    upload_2023-10-14_23-48-48.png
    PHP:
    public static void test(@Nonnull Player player) {
        
    ScoreboardManager manager player.getServer().getScoreboardManager();
        
    Scoreboard board manager.getNewScoreboard();

        
    Objective objective board.registerNewObjective(randomString(), Criteria.DUMMYgradient("OBJ_NAME"));
        
    objective.setDisplaySlot(DisplaySlot.SIDEBAR);

        
    Team team board.registerNewTeam(randomString());
        
    team.prefix(gradient("PREFIX"));
        
    team.displayName(Component.text(randomString()));
        
    team.suffix(gradient("SUFFIX"));

        
    String score LegacyComponentSerializer.legacySection().serialize(gradient("SCORE"));
        
    team.addEntry(score);
        
    objective.getScore(score).setScore(0);

        
    player.setScoreboard(board);
    }

    @
    Nonnull
    private static Component gradient(@Nonnull String text) {
        return 
    createRgbGradient(textNamedTextColor.WHITENamedTextColor.BLACK);
    }

    @
    Nonnull
    private static String randomString() {
        return 
    UUID.randomUUID().toString();
    }
    Результат:
    upload_2023-10-12_12-24-54.png
    PHP:
    public static void test(@Nonnull Player player) {
        
    ScoreboardManager manager player.getServer().getScoreboardManager();
        
    Scoreboard board manager.getNewScoreboard();

        
    Objective objective board.registerNewObjective(randomString(), "dummy");
        
    objective.setDisplaySlot(DisplaySlot.SIDEBAR);
        
    objective.setDisplayName(gradient("OBJ_NAME"));

        
    Team team board.registerNewTeam(randomString());
        
    team.setPrefix(gradient("PREFIX"));
        
    team.setDisplayName(randomString());
        
    team.setSuffix(gradient("SUFFIX"));

        
    String score gradient("SCORE");
        
    team.addEntry(score);
        
    objective.getScore(score).setScore(0);

        
    player.setScoreboard(board);
    }

    @
    Nonnull
    private static String gradient(@Nonnull String text) {
        return 
    createRgbGradient(textChatColor.WHITEChatColor.BLACK);
    }

    @
    Nonnull
    private static String randomString() {
        return 
    UUID.randomUUID().toString();
    }

    Решать эту проблему можно двумя путями:

    1) Отказаться от RGB и использовать лишь 16 цветов при помощи цветовых кодов (параграфов).
    Для этого и нужен метод create16ColorsGradient(), который в коде выше.

    2) Скрыть эти entry вовсе и использовать исключительно префиксы и суффиксы команд.
    В качестве названия entry в этом случае можно применять уникальную комбинацию цветовых кодов примерно таким образом:
    PHP:
    private int lastEntryNumber 0;

    @
    Nonnull
    private String randomEntry() {
        
    StringBuilder entry = new StringBuilder();
        for (
    char ch String.format("%04X"this.lastEntryNumber++).toLowerCase().toCharArray()) {
            
    entry.append('§').append(ch);
        }
        return 
    entry.toString();
    }
    Entry при этом будут разные, но в игре отображаться не будут.

    P.S. По логике ты можешь использовать AdventureAPI и на спиготе 1.16+, но в этом случае не забудь добавить зависимость в джарник плагина или указать в libraries в plugin.yml. В целом с Adventure работать удобней, чем со строками или компонентами Bungee
     
    Последнее редактирование: 14 окт 2023
  3. Автор темы
    Aviloo

    Aviloo Активный участник Пользователь

    Баллы:
    61
    Имя в Minecraft:
    Aviloo
    Привет. Спасибо за ответ. Скрин : upload_2023-10-12_22-49-26.png

    Версия: 1.19+
     
  4. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Ну, если Paper или форки - используй компоненты Adventure. Если Spigot, то строки обычные.
    Единственное, что score (entry команд) даже на 1.19 являются обычной строкой, которая не поддерживает RGB, поэтому я бы в любом случае рекомендовал скрывать их и использовать для отображения текста только префиксы и суффиксы команд.
    Чуть подправил своё предыдущее сообщение и расписал там подробнее, как это сделать
     
    Последнее редактирование: 14 окт 2023
  5. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Не неверно выводишь hex цвета, вот и не работает.
     

Поделиться этой страницей