Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Туториал [урок] чтение настроек. формат yaml

DmitriyMX

Старожил
Пользователь
Баллы
153
В прошлом уроке мы научились делать плагин, который меняет цвет ника в чате. Это, конечно, хорошо, но что если мы захотим выделить привилегированных пользователей(випы, опы, админы…)? Можно было бы прописать ники прямо в плагине и жить припеваючи, но что если випы у нас меняются каждый день? Постоянно перекомпилировать плагин, заливать на сервер, перезапускать его… Нет, это идиотизм. Мы умные люди и будем поступать по умному. Пусть у нашего плагина будет файл, где будут указаны не только ники особых персон, но и формат вывода их сообщений. Итак, в этом уроке мы будем учится читать данные из yml-файла.

Спецификация YAML формата

Думаю, многие из вас держали свои серверы и, когда настраивали плагины, встречали файлы вида config.yml. По сути, это обычный текстовый файл, но с древовидным синтаксисом: каждая новая ветка – это новая строка с некоторым количеством пробелов в начале. Не понятно? Хорошо, поясню на примере.
Код:
Пункт 1:
  Подпункт 1: “обычная строка/текст”
  Подпункт 2(массив):
    - пункт 1
    - пункт 2
Пункт 2:
  Подпункт 1: 5978
    Под-подпункт 1: false
Пункт 3: “тоже текст”
  Подпункт 1: true
  Подпункт 2: |
    Много
    строчный
    текст
  Подпункт 3(массив): [1, 2, 3]
#Комментарий, который игнорируется
Если всё это древо представить в виде системы каталогов (папок), то будет намного понятнее: есть папка “Пункт 1”, которая содержит папки “Подпункт 1” и “Подпункт 2”, и далее по аналогии. Обращаю ваше внимание, что вложенность определяется числом пробелов перед названием пункта. К примеру:
Код:
Пункт1
  Пункт2
    Пункт3
    Пункт4
Пункт5
    Пункт6
Они имеют следующую иерархию:
  • Пункт1 содержит Пункт2
  • Пункт2 содержит Пункт3 и Пункт4
  • Пункт5 содержит Пункт6
И не важно, что у Пунктов 3, 4 и 6 одинаковое количество пробелов в начале. Вложенность Пункта2 ограничилось Пунктом4, т.к. Пункт5 уже имел меньшее количество пробелов, чем Пункт4.

Как видно из первого примера, yaml умеет хранить:
  • однострочный текст
  • многострочный текст
  • цифры
  • массивы (2 вида записи)
  • логические значения true и false
Так же в примере видно, как эти данные хранятся в файле, поэтому я не вижу смысла пояснять здесь что-либо. Разве что заострю внимание на многострочном тексте: он записывается строкой ниже и оформляется как подпункты одной ветки.

Еще один важный момент. Для построения иерархии используются только пробелы, никаких табуляций! Это ошибка 90% новичков, которые редактируют настройки, а потом не могут понять, почему ничего не работает. Вообще, лучше совсем не использовать табуляцию в yml-файлах – все равно в майнкрафте она не отображается.

Дорабатываем плагин

Со спецификацией закончили. Теперь перейдем непосредственно к коду. Пусть наш файл настроек будет такого вида:
Код:
dmitriymx: “#0[#aadmin#0]#f<#b+name#f>: ”
alex: “<#4+name#f>: ”
Вернемся к нашему предыдущему плагину. В секцию объявления общих переменных(там, где мы объявляли mclog) добавим новую переменную:
Код:
public YamlConfiguration config;
В onEnable() напишем код загрузки файла:
Код:
config = LoadConfig(getDataFolder()+File.separator+"config.yml");
Файл “config.yml” будет загружен из папки “plugins/Chat/”.

Затем, измените строку, где мы объявляли переменную-обработчик chatListener:
Код:
private DMXChatListener chatListener = new DMXChatListener(this);
Переходим в класс DMXChatListener. Объявим 2 переменные:
Код:
private DMXChat plugin;
private Set<String> userList;
Первая служит ссылкой на сам плагин, а вторая является списком пользователей, для которых должно применяться особое форматирование чата.

Теперь объявляем свою реализацию конструктора:
Код:
public DMXChatListener(DMXChat plg){
    this.plugin = plg;
    userList = plg.config.getKeys(false);
}
И приведем onPlayerChat() к следующему виду:
Код:
public void onPlayerChat(PlayerChatEvent event){
    String playerName = event.getPlayer().getName().toLowerCase();
    String thisFormat = “<#b+name#f>: +message”;
    if(userList.containts(playerName)){
        thisFormat = plugin.config.getString(playerName) + “+message”;
    }
    ConvertFormat(thisFormat);
    event.setFormat(thisFormat);
}
В первой строке мы берем имя игрока и приводим его к нижнему регистру. Это нужно для того, чтобы несмотря на то, как написан ник (DmitriyMX, Dmitriymx. dmitriyMX) форматирование применялось к нужному человеку. Второй строкой мы задаем формат чата по умолчанию. Далее, в конструкции if(…), мы ищем совпадения в списке с избранными пользователями и, если есть совпадение, записываем новый формат чата. Затем, функцией ConvertFormat() приводим переменную в нужный вид и устанавливаем новоиспеченный формат в системе.

Функция ConvertFormat() должна быть написана в DMXChatListener и выглядеть следующим образом:
Код:
private void ConvertFormat(String format){
    //заменяем псевдо-переменные на те, что воспринимает bukkit
    format = format.replace(“+name”, “%1$s”).replace(“+message”, “%2$s”)
    //заменим цветовые коды на коды, понятные bukkit’у
    format = format.replace("#0", ""+ChatColor.BLACK).replace("#1", ""+ChatColor.DARK_BLUE).replace("#2", ""+ChatColor.DARK_GREEN).replace("#3", ""+ChatColor.DARK_AQUA).replace("#4", ""+ChatColor.DARK_RED).replace("#5", ""+ChatColor.DARK_PURPLE).replace("#6", ""+ChatColor.GOLD).replace("#7", ""+ChatColor.GRAY).replace("#8", ""+ChatColor.DARK_GRAY).replace("#9", ""+ChatColor.BLUE).replace("#a", ""+ChatColor.GREEN).replace("#b", ""+ChatColor.AQUA).replace("#c", ""+ChatColor.RED).replace("#d", ""+ChatColor.LIGHT_PURPLE).replace("#e", ""+ChatColor.YELLOW).replace("#f", ""+ChatColor.WHITE);
 
    //Уважаемые программисты на Java. Если вы знаете как можно упростить или оптимизировать эту кошмарную функцию, напишите в комментариях. Очень вас прошу.
 
    return;
}
В следующем уроке, мы еще доработаем наш плагин, добавив в него реакцию на команды.

_____________________________​
 
Удобно, жаль что уже сделал XML - парсер
 
Код:
config = LoadConfig(getDataFolder()+File.separator+"config.yml");
здесь ругаеться на File если прописываю строчку import java.io.File; то ругаеться на LoadConfig подскажите что прописать?
 
Сорян за некропостинг, но ты сам попросил улучшить твой код. Ответа от других я не увидел, так что вот:

Код:
private void ConvertFormat(String format){
    // Заменяем псевдо-переменные на те, что воспринимает bukkit
    format = format.replace("+name", "%1$s").replace("+message", "%2$s");
    // Заменим цветовые коды которые используем мы, на коды понятные bukkit’у
    format = ChatColor.translateAlternateColorCodes('#', format);
}
%1$s нулевой аргумент после команды
%2$s первый аргумент после команды
Наглядный пример: /command one two
%1$s - one, %2$s - two

Подсказки:

Переменные могут быть любыми, главное использоваться в тексте именно как переменные.

Наглядный пример:
Игрок %player% использовал команду {command}

В коде мы должны находить совпадения целых слов

Возьмём text как текст который игрок получит
text.replaceAll("%player", player.getName());
text.replaceAll("{command}", cmd.getName());

Итог:
Игрок V0rHaM использовал команду testing

Для того чтобы использовать свои цветовые коды достаточно взять за основу любой символ, к примеру:

#, @, !,^, &, *

После в тексте где мы хотим чтобы текст автоматически перевело в понимаемый для Bukkit код, пишем следующее:

переменная с текстом - text
символ цвета - #

ChatColor.translateAlternateColorCodes('#', text);
Готово!
 
Назад
Верх