Изменения конфига не сохраняются

Версия Minecraft
1.7.10
1,159
38
544
Хелоу народ. Решил запилить конфиг из этого тутора. Только он всегда сбрасывает значения до дефолтных ри повторном открытии. ЧХЗ происходит? Я уже который день ковыряюсь в нем отладчиком, но пока не могу докопаться до причины
Config.java:
package rsstats.common;

import cpw.mods.fml.client.IModGuiFactory;
import cpw.mods.fml.client.config.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.common.config.Configuration;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import static net.minecraftforge.common.config.Configuration.CATEGORY_GENERAL;

// TODO: Дочитай туториал в MinecraftByExample

/**
* Синглтон-класс, управляющий конфигурацией мода.
*/
public class Config {
    /** Числовой код цвета позитивных модификаторов по умолчанию. Представлен строкой. */
    public static final String DEFAULT_MODIFIER_COLOR_POSITIVE = "green";
    /** Числовой код цвета негативных модификаторов по умолчанию. Представлен строкой. */
    public static final String DEFAULT_MODIFIER_COLOR_NEGATIVE = "red";
    public static final boolean DEFAULT_IGNORE_DOWNTIME_IN_COOLDOWN = false;

    private static final String CATEGORY_CHAT = "client chat";

    private static final String TEXT_COLOR_NORMAL_KEY = "textColorNormal";
    private static final String MODIFIER_COLOR_POSITIVE_KEY = "modifierColorPositive";
    private static final String MODIFIER_COLOR_NEGATIVE_KEY = "modifierColorNegative";
    private static final String IGNORE_DOWNTIME_IN_COOLDOWN_KEY = "ignoreDowntimeInCooldown";

    /** Инферфейс управления конфигурацией */
    private Configuration configuration;

    public String textColorNormal;
    public EnumChatFormatting modifierColorPositive;
    public EnumChatFormatting modifierColorNegative;

    public boolean ignoreDowntimeInCooldown;

    private static Config config;

    private Config(File configFile) {
        configuration = new Configuration(configFile);
        load();
        save();
    }

    public static Config getConfig(File configFile) {
        if (config == null) {
            config = new Config(configFile);
        }

        return config;
    }

    public void save() {
        // CATEGORY_GENERAL
        configuration.getBoolean(IGNORE_DOWNTIME_IN_COOLDOWN_KEY, CATEGORY_GENERAL, DEFAULT_IGNORE_DOWNTIME_IN_COOLDOWN, "Стоит ли кулдаунам игнорировать время, которое сервер провел в выключенном состоянии");

        // CHAT_CLIENT
        configuration.getString(TEXT_COLOR_NORMAL_KEY, CATEGORY_CHAT, "f", "test comment");
        configuration.getString(MODIFIER_COLOR_POSITIVE_KEY, CATEGORY_CHAT, DEFAULT_MODIFIER_COLOR_POSITIVE, "Цвет положительных модификаторов броска");//new Property(MODIFIER_COLOR_POSITIVE_KEY, 2, Type.CHAR_TYPE);
        configuration.getString(MODIFIER_COLOR_NEGATIVE_KEY, CATEGORY_CHAT, DEFAULT_MODIFIER_COLOR_NEGATIVE, "Цвет отрицательных модификаторов броска");

        configuration.save();
    }

    public void load() {
        configuration.load();
        ignoreDowntimeInCooldown = configuration.get(CATEGORY_GENERAL, IGNORE_DOWNTIME_IN_COOLDOWN_KEY, DEFAULT_IGNORE_DOWNTIME_IN_COOLDOWN, "test comment").getBoolean();

        textColorNormal = configuration.get(CATEGORY_CHAT, TEXT_COLOR_NORMAL_KEY, "f").getString();
        modifierColorPositive = EnumChatFormatting.getValueByName(configuration.get(CATEGORY_CHAT, MODIFIER_COLOR_POSITIVE_KEY, DEFAULT_MODIFIER_COLOR_POSITIVE).getString());//new Property(MODIFIER_COLOR_POSITIVE_KEY, 2, Type.CHAR_TYPE);
        modifierColorNegative = EnumChatFormatting.getValueByName(configuration.get(CATEGORY_CHAT, MODIFIER_COLOR_NEGATIVE_KEY, DEFAULT_MODIFIER_COLOR_NEGATIVE).getString());


    }

    public static class GuiFactory implements IModGuiFactory {

        @Override
        public void initialize(Minecraft minecraftInstance) {

        }

        @Override
        public Class<? extends GuiScreen> mainConfigGuiClass() {
            return TestModConfigGUI.class;
        }

        @Override
        public Set<RuntimeOptionCategoryElement> runtimeGuiCategories() {
            return null;
        }

        @Override
        public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement element) {
            return null;
        }
    }

    public static class TestModConfigGUI extends GuiConfig {


        public TestModConfigGUI(GuiScreen parent) {
            super(parent, getConfigElements(),
//                    new ConfigElement(RSStats.config.configuration.getCategory(CATEGORY_CHAT)).getChildElements(),
                    RSStats.MODID, false, false, GuiConfig.getAbridgedConfigPath(RSStats.config.configuration.toString()));

            // TODO: Сменить пример текста на свой в ChatColorEntry
        }

        private static List<IConfigElement> getConfigElements()
        {
            List<IConfigElement> stringsList = new ArrayList<IConfigElement>();

            stringsList.add(new DummyConfigElement<String>("modifierColorPositiveColorPicker", String.valueOf(EnumChatFormatting.getValueByName(DEFAULT_MODIFIER_COLOR_POSITIVE).getFormattingCode()), ConfigGuiType.COLOR, "config.modifierColorPositiveColorPicker", new String[] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}));
            stringsList.add(new DummyConfigElement<String>("modifierColorNegativeColorPicker", String.valueOf(EnumChatFormatting.getValueByName(DEFAULT_MODIFIER_COLOR_NEGATIVE).getFormattingCode()), ConfigGuiType.COLOR, "config.modifierColorNegativeColorPicker", new String[] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}));
            return stringsList;
        }
    }
}

EventHandler.java:
@SubscribeEvent
public void onConfigChanged(ConfigChangedEvent.OnConfigChangedEvent event){
    if(event.modID.equals(RSStats.MODID)) RSStats.config.save();
}

Ну шо не так с этой заразой?
 
Последнее редактирование:
1,159
38
544
Класс "EventHandler" есть , но я не вижу её регистрацию. Её желательно на клиентской стороне регистрировать и под FML шиной.
Это настолько банальная х**ета что я даже не стал ее включать. ConfigChangedEvent.OnConfigChangedEvent успешно выбрасывается.

К примеру как делаю у себя (может тебе поможет):
И что это значит? Кусок вырван из контекста
 
Последнее редактирование:

timaxa007

Модератор
5,831
409
672
@RareScrap, не нужно нервничать. Я не могу точно знать, что у тебя не так, я тоже делал по этому уроку, но делал я по своему. Может быть твой конфиг не считает, что в него какие-то изменения сделаны или же он пытаеться загрузить дефлотные значения и их-же сразу-же сохраняет, нету-же проверки: if (configuration.hasChanged()) для configuration.save();
 
1,159
38
544
@RareScrap, не нужно нервничать.
Что-то у меня действительно сдали нервы, сорян))

И добавляешь .set(значение)
А откуда брать значение? Как получить досту к измененному через UI значению? Я пытался разобраться как это делает конфиг форджа в ForgeModContainer: там измененное значение поучается из Property. Когда я пытаюсь вытащить его из своего Property - возращается дефолтное. Я не знаю почему, но изменения в UI конфига не изменяют мои Property.
 
Последнее редактирование:

Icosider

Kotliner
Администратор
3,603
99
664
А ничего, что ты в начале загружаешь конфиг как положено, а после зачем-то перезаписываешь значения на дефолтные и сохраняешь их? :m_faceplam: У тебя ошибка в save методе.

Java:
public void save() {
        // CATEGORY_GENERAL
        configuration.getBoolean(IGNORE_DOWNTIME_IN_COOLDOWN_KEY, CATEGORY_GENERAL, ignoreDowntimeInCooldown, "Стоит ли кулдаунам игнорировать время, которое сервер провел в выключенном состоянии");

        // CHAT_CLIENT
        configuration.getString(TEXT_COLOR_NORMAL_KEY, CATEGORY_CHAT, textColorNormal, "test comment");
        configuration.getString(MODIFIER_COLOR_POSITIVE_KEY, CATEGORY_CHAT, modifierColorPositive, "Цвет положительных модификаторов броска");//new Property(MODIFIER_COLOR_POSITIVE_KEY, 2, Type.CHAR_TYPE);
        configuration.getString(MODIFIER_COLOR_NEGATIVE_KEY, CATEGORY_CHAT, modifierColorNegative, "Цвет отрицательных модификаторов броска");

        configuration.save();
    }

    public void load() {
        configuration.load();
        ignoreDowntimeInCooldown = configuration.get(CATEGORY_GENERAL, IGNORE_DOWNTIME_IN_COOLDOWN_KEY, DEFAULT_IGNORE_DOWNTIME_IN_COOLDOWN, "test comment").getBoolean();

        textColorNormal = configuration.get(CATEGORY_CHAT, TEXT_COLOR_NORMAL_KEY, "f").getString();
        modifierColorPositive = EnumChatFormatting.getValueByName(configuration.get(CATEGORY_CHAT, MODIFIER_COLOR_POSITIVE_KEY, DEFAULT_MODIFIER_COLOR_POSITIVE).getString());//new Property(MODIFIER_COLOR_POSITIVE_KEY, 2, Type.CHAR_TYPE);
        modifierColorNegative = EnumChatFormatting.getValueByName(configuration.get(CATEGORY_CHAT, MODIFIER_COLOR_NEGATIVE_KEY, DEFAULT_MODIFIER_COLOR_NEGATIVE).getString());
    }
После этих правок заработает(Upd: пересмотрел твой load метод, нет, с первого раза не сработает, если load не поправишь)

Свои дефолтные значения пропиши сразу в переменные
 
1,159
38
544
Товарищи, я умудрился запутаться в трех соснах. @Ivasik сори, твой ответ мне вообще не помог - просто не понял где у меня ошибка.

@Eifel сетить окаалось ничего не надо. Можно гораздо проще.

Покопавшись отладчиком я выяснил что фордж формирует UI конфига на основании типа свойства: числовой, строковый и т.д. Форжд выбирает подходящий (если тот не указан явно) IConfigEntry, который как раз и отвечает за рендер поля данного property. Моя ошибка была в том, что я не только не позволял форджу самостоятельно формировать UI отображаемых элементов настроек, но и использовал UI элементы, который вообще не умели быть связанными с property'ями конфига. Первое решилось юзанием new ConfigElement(RSStats.config.configuration.getCategory(CATEGORY_CHAT)).getChildElements() в конструкторе MyGuiConfig. Дело в том, что именно при вызове этой конструкции фордж не только анализирует тип пропертей и выбирает IConfigEntry для их рендера, но и СВЯЗЫВАЕТ проперти конфига с этими самыми IConfigEntry. Все что мне нужно было сделать - явно определить тип проперти в syncConfig() (которого у меня кстати не было, т.к. я решил обойтись без него).
Config.java:
public void syncConfig(boolean load)
{
    // ...
   
    // От себя добавлю, что мне нужно было сделать кнопку для настройки цвета.
    // Фордж уже имеет UI элемент для рисоваия такой кнопки, правда сетится он коряво.
    // Чтобы все заработало - заюзайте следуюие две строки
    prop = config.get("chat client", "color", "5", "test comment", Property.Type.COLOR);
    prop.setValidValues(new String[] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"});
   
    // ...
}

И второе! Если вы зайдете в конфиг UI Forge Mod Loader'а, то найдете там примеры виджетов для конфигов. Так вот, НЕ ЮЗАЙТЕ ИХ! Они сделаны через DummyConfigElement, которые вообще не умеют коннектиться с пропертями, оттого их изменения НЕ СОХАНЯЮТСЯ! Чтобы фордж выбрал подходящий виджет, достаточно лишь установить тип и допустимые значения пропертям в syncConfig(). Но точно не строить отдельный список видетов как это делает FML в FMLConfigGuiScreen#getConfigElements()! Вообще я считаю что пример виджетов элементов конфигов в FML реализован отвратительно. Полный идиотизм делать тестовый пример настолько не похожим на рабочий только в угоду отсуствия сохранения изменений конфига.

Вот и все. Теперь у меня есть кнопка выбора цвета, реализованная средствами форджа без необходимости писать свой велосипед, которая к тому же сохраняет измененное значение в конфиге. Всем спасибо за помощь и участие! В полном коде нет нужды, кому надо - разберется сам.
 
Сверху