fromgate
Administrator
Некоторое время назад, я представил плагин Yamler (порт одноименного плагина с платформы Spigot/Bukkit, который позволяет организовать удобную работу с файлами конфигурации.
Предлагаемый им способ гораздо удобнее стандартных методов как в bukkit (класс YamlConfiguration) так и в nukkit (класс Config).
Однако у него есть огромный недостаток: для работы с конфигом приходится устанавливать сторонний плагин. А это сами понимаете, не самая интересная идея.
Поэтому меня "глодала мысль" создать нечто подобное на основе станадртных классов: опробовав удобство Yamler, меня уже неустраивала громоздскость обычных конфигураторов и написание плагинов на их основе просто стало мукой
В итоге, в процессе написания плагина Regions (я надеюсь, скоро он будет готов), я написал небольшой класс который позволяет работать с конфигурацией способом подобным способам
Итак вот сам класс - его надо будет просто создать в любом пакете Вашего плагина:
Использовать это класс очень просто. Создаем класс, в котором будет храниться конфигурация плагина:
Полученный класс-конфигуратор, тоже просто в использовании.
Переменные — это обычные переменные, к которым ожно обращаться или напрямую или (если хочется сделать их private) посредством геттеров/сеттеров.
Т.е. фактически нужно создать объект класс-конфигуратора. Выполнить метод load() для загрузки настроек, после чего нужно просто обращаться к полям файла.
Если же нужно сохранить изменения в конфиге, то надо просто изменить поля в конфигураторе и вызвать метод save.
Использование этого подхода имеет ряд преимуществ:
Предлагаемый им способ гораздо удобнее стандартных методов как в bukkit (класс YamlConfiguration) так и в nukkit (класс Config).
Однако у него есть огромный недостаток: для работы с конфигом приходится устанавливать сторонний плагин. А это сами понимаете, не самая интересная идея.
Поэтому меня "глодала мысль" создать нечто подобное на основе станадртных классов: опробовав удобство Yamler, меня уже неустраивала громоздскость обычных конфигураторов и написание плагинов на их основе просто стало мукой
В итоге, в процессе написания плагина Regions (я надеюсь, скоро он будет готов), я написал небольшой класс который позволяет работать с конфигурацией способом подобным способам
Итак вот сам класс - его надо будет просто создать в любом пакете Вашего плагина:
Java:
import cn.nukkit.utils.Config;
import java.io.File;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public abstract class YamlConfig {
public boolean save(File f){
f.getParentFile().mkdirs();
try {
if (f.exists()) f.delete();
f.createNewFile();
} catch (Exception e) {
e.printStackTrace();
return false;
}
Config cfg = new Config(f, Config.YAML);
for (Field field : this.getClass().getDeclaredFields()) {
String path = getPath(field);
try {
cfg.set(path,field.get(this));
} catch (IllegalAccessException e) {
e.printStackTrace();
return false;
}
}
cfg.save();
return true;
}
public boolean load(File f){
f.getParentFile().mkdirs();
try {
if (!f.exists()) f.createNewFile();
} catch (Exception e) {
e.printStackTrace();
return false;
}
Config cfg = new Config(f, Config.YAML);
for (Field field : this.getClass().getDeclaredFields()) {
String path = getPath(field);
try {
if (field.getType()==int.class||field.getType()==Integer.class)
field.set(this, cfg.getInt(path, field.getInt(this)));
else if (field.getType()==boolean.class||field.getType()==Boolean.class)
field.set(this,cfg.getBoolean(path,field.getBoolean(this)));
else if (field.getType() == String.class)
field.set(this,cfg.getString(path, (String) field.get(this)));
else throw new UnsupportedClassVersionError("YamlConfig did not supports this class: "+field.getType().getName());
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
return false;
}
private String getPath (Field field){
String path = null;
if (field.isAnnotationPresent(Path.class)) {
Path pathDefine = field.getAnnotation(Path.class);
path = pathDefine.value();
}
if (path == null||path.isEmpty()) field.getName().replaceAll("_", ".");
if (Modifier.isPrivate(field.getModifiers())) {
field.setAccessible(true);
}
return path;
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Path {
String value() default "";
}
}
Java:
package ru.nukkit.regions.config;
public class RegionsConfig extends YamlConfig {
@Path (value = "claim.max-regions-per-player")
public int maxRegionPerPlayer=5;
@Path (value = "claim.max-claim-volume")
public int maxClaimVolume=10000;
@Path (value = "claim.claim-only-existing-regions")
public boolean claimOnlyExisting;
}
Переменные — это обычные переменные, к которым ожно обращаться или напрямую или (если хочется сделать их private) посредством геттеров/сеттеров.
Java:
cfg.load(new File(this.getDataFolder(),"config.yml"));
cfg.claimOnlyExisting=true;
cfg.maxClaimVolume=5000;
cfg.save(new File(this.getDataFolder(),"config.yml"));
Если же нужно сохранить изменения в конфиге, то надо просто изменить поля в конфигураторе и вызвать метод save.
Использование этого подхода имеет ряд преимуществ:
- Параметры конфигурации хранятся непосредственно в переменных, а не в полях коллекции LinkedHashMap. Т.е. если мерить наносекундами, то обращение к такой переменной будет выполняться быстрее.
- Доступ к переменной, изменение его значения означает обычное обращение к полям объекта. Название полей конфига указывается лишь в виде аннотации (@Path (value="xxx.xxx)
- Описать класс наследующий YamlConfig гораздо проще и быстрее чем традиционная работа со стандартным конфигуратором.
Last edited: