Вопрос Проверка наличия значения в конфиге и добавление при отсутствии

Версия Minecraft
1.18.X

MrDrag0nXYT

Модератор
Пользователь
Сообщения
2 341
Решения
69
Веб-сайт
drakoshaslv.ru
Всем привет
Представим такую ситуацию: в обновлении плагина появились новые значения для конфига, а у пользователя он старый. Можно просто попросить пользователя добавить значения вручную или пересоздать конфиг, но это создаёт лишние неудобства и так делать как-то не хочется. Поэтому появилась идея: сделать проверку на наличие параметра в конфиге, и если его нет, то добавлять для него дефолтное значение.

Есть вот такой код:
Java:
protected YamlConfiguration config = // ...

protected <T> T checkValue(String path, T defaultValue) {
    if (!config.contains(path)) {
        config.set(path, defaultValue);
        return defaultValue;

    } else {
        return (T) config.get(path);
    }
}

И он практически идеально выполняет свою задачу, но я заметил вот такую ошибку: если переменная в long, то параметр в конфиг записывается как обычное число. И при получении его такой строкой:
Java:
private long minimalPlayedTime = 3600L;
minimalPlayedTime = checkValue("minimalPlayedTime", minimalPlayedTime);

Получается такая ошибка:
Код:
java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Long (java.lang.Integer and java.lang.Long are in module java.base of loader 'bootstrap')

Как можно сделать лучше?
 
Я обычно делаю такой класс и запускаю метод актуализации при включении плагина. Этот метод вернет тебе актуальную версию конфига на момент вызова
Java:
public class ConfigActualizer {
    private final Plugin plugin;

    public ConfigActualizer(Plugin plugin) {
        this.plugin = plugin;
    }

    public YamlConfiguration actualize(String resourcePath) throws IOException {
        Configuration resource = YamlConfiguration.loadConfiguration(
                new InputStreamReader(plugin.getResource(resourcePath))
        );
        YamlConfiguration original = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder(), resourcePath));
        Map<String, Object> missing = new HashMap<>();
        resource.getValues(true).forEach((key, value) -> {
            if (!original.contains(key)) missing.put(key, value);
        });
        missing.forEach(original::set);
        original.save(new File(plugin.getDataFolder(), resourcePath));

        return original;
    }
}
 
Последнее редактирование:
Всем привет
Представим такую ситуацию: в обновлении плагина появились новые значения для конфига, а у пользователя он старый. Можно просто попросить пользователя добавить значения вручную или пересоздать конфиг, но это создаёт лишние неудобства и так делать как-то не хочется. Поэтому появилась идея: сделать проверку на наличие параметра в конфиге, и если его нет, то добавлять для него дефолтное значение.

Есть вот такой код:
private long minimalPlayedTime = 3600L; minimalPlayedTime = checkValue("minimalPlayedTime", minimalPlayedTime);
offtop
minimalPlayedTime = checkValue("minimalPlayedTime", (int)minimalPlayedTime)

А вообще, можешь попробовать мои Tson-конфиги, проблемы с типами данных нет вообще
Дает огромную гибкость в конфигах и позволяет творить что-то такое

Java:
public static ItemStack stackFromTson(TsonObj obj){
    if(obj.isCustom())return (ItemStack) obj.getField();
    if(obj.isString()){
        return new ItemStack(materialFromTson(obj));
    }
    if(obj.isMap()){
        TsonMap map = obj.getMap();
        ItemStack stack = new ItemStack(
                materialFromTson(map.get("material")),
                clamp(calc(map, "amount", 1), 1, 64),
                (short)calc(map, "damage", 0)
        );

        map.ifContainsList("lore", raw -> {
            ArrayList<String> lore = new ArrayList<>(raw.size());
            for (TsonObj tsonObj : raw)
                lore.add(tsonObj.getStr());
            stack.setLore(lore);
        });

        map.ifContains("display", display -> {
            if(display.isString())
                stack.getItemMeta().setDisplayName(display.getStr());
            else
                stack.getItemMeta().setDisplayNameComponent(
                        new BaseComponent[]{compFromTson(display)}
                );
        });
        ...
    }
    throw new IllegalArgumentException("Invalid itemstack");
}

Сам конфиг
C-like:
{
    item1 = "stone",
    item2 = {material = "stone", amount = *5, damage = 10},
    //рыбят, мы разгоняемся, врмврмрмврмрмрм
    item3 = {
        material = plus.mymod.Material.SUPER_AXE,
        amount = new Random().nextInt(32),
        damage = plus.mymod.Functions.calcDamage(this, 10),
        lore = [
            "lore1",
            "lore2",
            10.256,
            plus.mymod.Constants.LORE
        ],
        onclick = {
            right = plus.mymod.Functions::doSomething
        }
    }
}

 
Последнее редактирование:
Назад
Сверху Снизу