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

Плагин [DEV] XConfiguration v1.2 - универсальная библиотека для работы с конфигурациями

Тема в разделе "Неподтвержденные плагины", создана пользователем CoolBoy, 21 авг 2019.

Метки:
  1. Автор темы
    CoolBoy

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

    Баллы:
    96
    Имя в Minecraft:
    Xezard
    Версия плагина: 1.1
    Протестирован на версиях: [1.14.4]
    (Должен работать и на более старых версиях)
    SpigotMC: [Ссылка]
    GitHub: [Ссылка]

    XConfiguration - это универсальная библиотека на основе аннотаций для взаимодействия с конфигурациями Bukkit / Spigot. С её помощью можно автоматически создавать / перезагружать конфигурации, оставлять в них комментарии, а главное, автоматически сохранять и получать объекты Java из конфигурации.

    Сначала указываем репозиторий jitpack:
    • Gradle:
    Код:
    repositories {
       maven { url 'https://jitpack.io' }
    }
    • Maven:
    Код:
    <repository>
       <id>jitpack.io</id>
       <url>https://jitpack.io</url>
    </repository>
    Затем добавляем XConfiguration в зависимость:
    • Gradle:
    Код:
    dependencies {
       implementation 'com.github.Xezard:XConfiguration:1.0-RELEASE'
    }
    • Maven:
    Код:
    <dependency>
       <groupId>com.github.Xezard</groupId>
       <artifactId>XConfiguration</artifactId>
       <version>1.0-RELEASE</version>
    </dependency>
    Начнём с простейшего примера:
    Код:
    public class MessagesConfiguration
    extends Configuration
    {
       public MessagesConfiguration(Plugin plugin)
       {
           super(plugin, "messages.yml");
       }
    
       @Setter
       @Getter
       @ConfigurationField("Hello-world")
       public String helloWorld = "Hello, world!";
    }
    
    Прежде всего, нужно создать класс конфигурации. Этот класс должен быть унаследован от класса Configuration. В конструкторе суперкласса передаём ссылку на основной класс плагина (это который extends JavaPlugin) и имя файла для конфигурации. Внутри класса все объявленные поля, помеченные @ConfigurationField - считаются полями конфигурации. Значение аннотации @ConfigurationField - это путь к значению поля в конфигурации.

    В основном классе плагина:
    Код:
    public class Main
    extends JavaPlugin
    {
        /*
         * Создаём новый обьект класса нашей конфигурации и сразу же инициализируем его.
         */
        private MessagesConfiguration messagesConfiguration = new MessagesConfiguration(this);
    
        @Override
        public void onEnable()
        {
            /*
             * Этот метод автоматически создаёт файл конфигурации,
             * если тот ещё не был создан. Кроме того, он автоматически
             * заполняет класс конфигурации значениями из конфига
             * и наоборот, заполняет конфигурацию значениями из класса,
             * если в файле конфигурации ещё нет соответствующих полей.
             *
             * Этот же метод также можно вызывать когда
             * нужно перезагрузить конфигурацию плагина.
             */
            this.messagesConfiguration.load();
    
            /*
             * После загрузки нашего конфига мы можем использовать
             * любые значения из него.
             */
            this.getLogger().info(this.messagesConfiguration.getHelloWorld());
        }
        @Override
        public void onDisable()
        {
            this.messagesConfiguration = null;
        }
    }
    
    При определении полей конфигурации можно также указать к ним комментарии:
    Код:
    public class MessagesConfiguration
    extends Configuration
    {
        public MessagesConfiguration(Plugin plugin)
        {
            super(plugin, "messages.yml");
        }
    
        @Setter
        @Getter
        @ConfigurationField
        (
            value = "Hello-world.With-comment-above",
            comments =
            {
                @Comment
                (
                    path = "Hello-world",
                    comments = {"# Single-line comment"}
                ),
     
                @Comment
                (
                    path = "With-comment-above",
                    comments =
                    {
                        "",
                        "  # Indented comment"
                    }
                )
           }
       )
       public String helloWorld = "Hello, world!";
    }
    
    Примечания:
    После вызова метода load() можно будет увидеть следующую конфигурацию:
    Код:
    # Single-line comment
    Hello-world:
    
      # Indented comment
      With-comment-above: Hello, world!
    А как насчет полей с вашими собственными типами? Легко.
    Создадим наш класс:
    Код:
    @Data
    @AllArgsConstructor
    @SerializableAs("Pojo")
    public class POJO
    implements ConfigurationSerializable
    {
        private String name;
    
        private int id;
    
        @Override
        public Map<String, Object> serialize()
        {
            return Map.of("Name", this.name, "Id", this.id);
        }
    
        public static POJO deserialize(Map<String, Object> serialized)
        {
            return new POJO((String) serialized.get("Name"), (int) serialized.get("Id"));
        }
    }
    Чтобы использовать наш класс в конфигурации, мы должны реализовать интерфейс ConfigurationSerializable и 2 метода: 'Map <String, Object> serialize()' и 'POJO deserialize (Map <String, Object> serialized)'. Они будут использоваться для сериализации и десериализации нашего объекта.

    После этого в классе конфигурации:
    Код:
    public class MessagesConfiguration
    extends Configuration
    {
        public MessagesConfiguration(Plugin plugin)
        {
            super(plugin, "messages.yml");
        }
    
        @Setter
        @Getter
        @ConfigurationField("POJO")
        public POJO pojo = new POJO("pojo", 1);
    }
    Теперь после загрузки конфигурации можно автоматически получить уже сериализованный объект :D
    Допустим, наш обьект может сериализоваться самостоятельно в строку, но, при этом
    мы не можем редактировать класс этого обьекта (класс чужой библиотеки, например):
    Код:
    @Data
    @AllArgsConstructor
    public class POJO
    {
       private String name;
     
       private int id;
     
       public String serialize()
       {
           return this.name + ":" + this.id;
       }
    
       public static POJO deserialize(String string)
       {
           String[] parts = string.split(":");
         
            return new POJO(parts[0], Integer.parseInt(parts[1]));
       }
    }
    
    В этом случае мы можем создать класс сериализации, специально под этот обьект:
    Код:
    @EqualsAndHashCode(callSuper = true)
    public class ConfigurationDataPOJO
    extends AbstractConfigurationData<POJO>
    {
        public ConfigurationDataPOJO()
        {
            super(POJO.class);
        }
     
        @Override
        public void set(FileConfiguration configuration, String path, POJO value, Class<?>... type)
        {
            configuration.set(path, value.serialize());
        }
    
        @Override
        public POJO get(FileConfiguration configuration, String path, Class<?>... type)
        {
            return POJO.deserialize(configuration.getString(path));
        }
    
        @Override
        public POJO get(FileConfiguration configuration, String path, POJO def, Class<?>... type)
        {
            POJO pojo = this.get(configuration, path, type);
         
            return pojo == null ? def : pojo;
        }
    
        @Override
        public boolean isValid(FileConfiguration configuration, String path)
        {
            return configuration.isString(path);
        }
    
        @Override
        public POJO getDefault()
        {
            return new POJO("null", 0);
        }
    }
    
    И зарегестрировать его в ConfigurationManager:
    Код:
    public class Main
    extends JavaPlugin
    {
        private MessagesConfiguration messagesConfiguration = new MessagesConfiguration(this);
     
        private ConfigurationDataPOJO configurationDataPOJO = new ConfigurationDataPOJO();
    
        @Override
        public void onEnable()
        {
            ConfigurationManager.register(configurationDataPOJO);
         
            this.messagesConfiguration.load();
    
            this.getLogger().info(this.messagesConfiguration.getPojo());
        }
     
        @Override
        public void onDisable()
        {
            ConfigurationManager.unregister(configurationDataPOJO);
          
            this.messagesConfiguration = null;
        }
    }
    
    [​IMG]
    [​IMG]

    Скачать: [Ссылка]

    Лог изменений:
    Версия 1.2:
    • Исправлены дубликаты комментариев при вызове метода .load().
    • Исправлена перезапись значений конфигурации значениями из класса конфигурации.
    Версия 1.1:
    • Добавлена поддержка Java 8 и выше.
    • Теперь все поля в конфигурации генерируются в том порядке, в котором указаны в классе конфигурации.
    Версия 1.0:
    • Релиз.
     
    Последнее редактирование: 5 сен 2019
  2. Типа админ:D

    Типа админ:D Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    Qamulex
    Всё, конечно же, почти идеально, но слишком жирная изначальная запись всего этого (4 строки грубо говоря)
     
  3. Автор темы
    CoolBoy

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

    Баллы:
    96
    Имя в Minecraft:
    Xezard
    Держи в курсе
     
  4. Автор темы
    CoolBoy

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

    Баллы:
    96
    Имя в Minecraft:
    Xezard
    Updated v.1.2:
    • Исправлены дубликаты комментариев при вызове метода .load().
    • Исправлена перезапись значений конфигурации значениями из класса конфигурации.
     
  5. slavik123123123

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

    Баллы:
    143
    Имя в Minecraft:
    Leymooo
    конечно прикольно, но разве не удобнее будет так:

    Код:
    public class MessagesConfiguration
        extends Configuration {
      public MessagesConfiguration(Plugin plugin) {
        super(plugin, "messages.yml");
      }
    
      @ConfigurationSection("Hello-world") //Если не указано имя, то можно использовать имя класса. '_' заменять на '-'
      @Getter
      @Setter
      private HelloWorld helloWorldSection = new HelloWorld();
    
      //Это можно будет вынести в отдельный класс
      @Comment({"Коментарий для секции"})
      public static class HelloWorld {
        @ConfigurationFiled("With-comment-above") //Если не указано имя, то можно использовать имя поля. '_' заменять на '-'
        @Comment({"Коментарий для поля"})
        @Getter
        @Setter
        private String helloWorld = "Hello World";
      }
      @ConfigurationFiled()
      @Getter
      @Setter
      private String joinMessage = "Hello, %Player%";
    }
    Как по мне, это более читаемо, и практичнее. Например вместо целого конфига, можно будет передавать только необходимые секции, которые необходимы для реализации нужной функции.

    И почему бы не вынести бакитовский конфиг в отельную либу, чтобы можно было использовать это не только в баккит плагинах? Если вдруг тебе лень, то вот - https://mega.nz/#!2VwnHIhT!n8onesZNGyrcVIRqhCEHtgL8LiJDlYUWR0ZMQVKqleI . Я это делал на версии 1.13, не знаю менялось ли что либо в новых версиях.
     
  6. alexandrage

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

    Баллы:
    173
    Какой ужас! Лучше HOCON юзать.
     
  7. Автор темы
    CoolBoy

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

    Баллы:
    96
    Имя в Minecraft:
    Xezard
    Толковое предложение, глянем, может быть прикручу всё это в будущих версиях. Спасибо :coffee:
    99% паблик плагинов юзают yaml для конфигураций. Этот плагин - для паблика. Естественно на собственном проекте можно использовать самый передовой код и последние модные библиотеки для всего - но нужно ли ими делиться с другими?)
     
  8. alexandrage

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

    Баллы:
    173
    Уж лучше ими, чем каким то высером. Да тот же yamlbeans будет куда удобнее.
    Создаешь простой pojo класс и он сериализуется, без говна и палок.
     
    Последнее редактирование: 7 сен 2019
  9. Автор темы
    CoolBoy

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

    Баллы:
    96
    Имя в Minecraft:
    Xezard
    Круто. Теперь иди на spigotmc и объясни всем какой yamlbeans и HOCON крутой. А пока что все юзают yaml баккита и особо не парятся)
     

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