ConfigManagerImpl.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * This file is licensed under the MIT License, part of Roughly Enough Items.
  3. * Copyright (c) 2018, 2019, 2020 shedaniel
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in all
  13. * copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. * SOFTWARE.
  22. */
  23. package me.shedaniel.rei.impl;
  24. import com.google.gson.Gson;
  25. import com.google.gson.GsonBuilder;
  26. import com.google.gson.JsonElement;
  27. import me.sargunvohra.mcmods.autoconfig1u.AutoConfig;
  28. import me.sargunvohra.mcmods.autoconfig1u.annotation.ConfigEntry;
  29. import me.sargunvohra.mcmods.autoconfig1u.gui.ConfigScreenProvider;
  30. import me.sargunvohra.mcmods.autoconfig1u.gui.registry.GuiRegistry;
  31. import me.sargunvohra.mcmods.autoconfig1u.serializer.JanksonConfigSerializer;
  32. import me.sargunvohra.mcmods.autoconfig1u.shadowed.blue.endless.jankson.Jankson;
  33. import me.sargunvohra.mcmods.autoconfig1u.shadowed.blue.endless.jankson.JsonObject;
  34. import me.sargunvohra.mcmods.autoconfig1u.shadowed.blue.endless.jankson.JsonPrimitive;
  35. import me.sargunvohra.mcmods.autoconfig1u.util.Utils;
  36. import me.shedaniel.cloth.api.client.events.v0.ScreenHooks;
  37. import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
  38. import me.shedaniel.clothconfig2.api.Modifier;
  39. import me.shedaniel.clothconfig2.api.ModifierKeyCode;
  40. import me.shedaniel.clothconfig2.gui.entries.KeyCodeEntry;
  41. import me.shedaniel.rei.RoughlyEnoughItemsCore;
  42. import me.shedaniel.rei.api.*;
  43. import me.shedaniel.rei.gui.ContainerScreenOverlay;
  44. import me.shedaniel.rei.gui.config.RecipeScreenType;
  45. import me.shedaniel.rei.gui.config.entry.FilteringEntry;
  46. import me.shedaniel.rei.gui.config.entry.NoFilteringEntry;
  47. import me.shedaniel.rei.gui.config.entry.RecipeScreenTypeEntry;
  48. import me.shedaniel.rei.gui.config.entry.ReloadPluginsEntry;
  49. import me.shedaniel.rei.gui.credits.CreditsScreen;
  50. import net.minecraft.client.MinecraftClient;
  51. import net.minecraft.client.gui.screen.Screen;
  52. import net.minecraft.client.gui.widget.ButtonWidget;
  53. import net.minecraft.client.util.InputUtil;
  54. import net.minecraft.text.LiteralText;
  55. import net.minecraft.text.TranslatableText;
  56. import net.minecraft.util.math.MathHelper;
  57. import org.jetbrains.annotations.ApiStatus;
  58. import java.util.ArrayList;
  59. import java.util.Collections;
  60. import java.util.List;
  61. import static me.sargunvohra.mcmods.autoconfig1u.util.Utils.getUnsafely;
  62. import static me.sargunvohra.mcmods.autoconfig1u.util.Utils.setUnsafely;
  63. @ApiStatus.Internal
  64. public class ConfigManagerImpl implements ConfigManager {
  65. private boolean craftableOnly;
  66. private final Gson gson = new GsonBuilder().create();
  67. public ConfigManagerImpl() {
  68. this.craftableOnly = false;
  69. AutoConfig.register(ConfigObjectImpl.class, (definition, configClass) -> new JanksonConfigSerializer<>(definition, configClass, Jankson.builder().registerPrimitiveTypeAdapter(InputUtil.KeyCode.class, it -> {
  70. return it instanceof String ? InputUtil.fromName((String) it) : null;
  71. }).registerSerializer(InputUtil.KeyCode.class, (it, marshaller) -> new JsonPrimitive(it.getName())).registerTypeAdapter(ModifierKeyCode.class, o -> {
  72. String code = ((JsonPrimitive) o.get("keyCode")).asString();
  73. if (code.endsWith(".unknown")) return ModifierKeyCode.unknown();
  74. InputUtil.KeyCode keyCode = InputUtil.fromName(code);
  75. Modifier modifier = Modifier.of(((Number) ((JsonPrimitive) o.get("modifier")).getValue()).shortValue());
  76. return ModifierKeyCode.of(keyCode, modifier);
  77. }).registerSerializer(ModifierKeyCode.class, (keyCode, marshaller) -> {
  78. JsonObject object = new JsonObject();
  79. object.put("keyCode", new JsonPrimitive(keyCode.getKeyCode().getName()));
  80. object.put("modifier", new JsonPrimitive(keyCode.getModifier().getValue()));
  81. return object;
  82. }).registerSerializer(EntryStack.class, (stack, marshaller) -> {
  83. return new JsonPrimitive(gson.toJson(stack.toJson()));
  84. }).registerPrimitiveTypeAdapter(EntryStack.class, it -> {
  85. return it instanceof String ? EntryStack.readFromJson(gson.fromJson((String) it, JsonElement.class)) : null;
  86. }).build()));
  87. GuiRegistry guiRegistry = AutoConfig.getGuiRegistry(ConfigObjectImpl.class);
  88. guiRegistry.registerPredicateProvider((i13n, field, config, defaults, guiProvider) -> {
  89. if (field.isAnnotationPresent(ConfigEntry.Gui.Excluded.class))
  90. return Collections.emptyList();
  91. KeyCodeEntry entry = ConfigEntryBuilder.create().startModifierKeyCodeField(new TranslatableText(i13n), getUnsafely(field, config, ModifierKeyCode.unknown())).setModifierDefaultValue(() -> getUnsafely(field, defaults)).setModifierSaveConsumer(newValue -> setUnsafely(field, config, newValue)).build();
  92. entry.setAllowMouse(false);
  93. return Collections.singletonList(entry);
  94. }, field -> field.getType() == ModifierKeyCode.class);
  95. guiRegistry.registerAnnotationProvider((i13n, field, config, defaults, guiProvider) -> {
  96. ConfigObjectImpl.UsePercentage bounds = field.getAnnotation(ConfigObjectImpl.UsePercentage.class);
  97. return Collections.singletonList(ConfigEntryBuilder.create().startIntSlider(new TranslatableText(i13n), MathHelper.ceil(Utils.getUnsafely(field, config, 0.0) * 100), MathHelper.ceil(bounds.min() * 100), MathHelper.ceil(bounds.max() * 100)).setDefaultValue(() -> MathHelper.ceil((double) Utils.getUnsafely(field, defaults) * 100)).setSaveConsumer((newValue) -> {
  98. Utils.setUnsafely(field, config, newValue / 100d);
  99. }).setTextGetter(integer -> new LiteralText(String.format("Size: %d%%", integer))).build());
  100. }, (field) -> field.getType() == Double.TYPE || field.getType() == Double.class, ConfigObjectImpl.UsePercentage.class);
  101. guiRegistry.registerAnnotationProvider((i13n, field, config, defaults, guiProvider) ->
  102. Collections.singletonList(new RecipeScreenTypeEntry(220, new TranslatableText(i13n), getUnsafely(field, config, RecipeScreenType.UNSET), getUnsafely(field, defaults), type -> setUnsafely(field, config, type)))
  103. , (field) -> field.getType() == RecipeScreenType.class, ConfigObjectImpl.UseSpecialRecipeTypeScreen.class);
  104. guiRegistry.registerAnnotationProvider((i13n, field, config, defaults, guiProvider) ->
  105. REIHelper.getInstance().getPreviousContainerScreen() == null || MinecraftClient.getInstance().getNetworkHandler() == null || MinecraftClient.getInstance().getNetworkHandler().getRecipeManager() == null ?
  106. Collections.singletonList(new NoFilteringEntry(220, getUnsafely(field, config, new ArrayList<>()), getUnsafely(field, defaults), list -> setUnsafely(field, config, list)))
  107. :
  108. Collections.singletonList(new FilteringEntry(220, getUnsafely(field, config, new ArrayList<>()), getUnsafely(field, defaults), list -> setUnsafely(field, config, list)))
  109. , (field) -> field.getType() == List.class, ConfigObjectImpl.UseFilteringScreen.class);
  110. saveConfig();
  111. RoughlyEnoughItemsCore.LOGGER.info("Config loaded.");
  112. }
  113. @Override
  114. public void saveConfig() {
  115. if (getConfig().getFavorites() != null)
  116. getConfig().getFavorites().removeIf(EntryStack::isEmpty);
  117. if (getConfig().getFilteredStacks() != null) {
  118. getConfig().getFilteredStacks().removeIf(EntryStack::isEmpty);
  119. for (EntryStack stack : getConfig().getFilteredStacks()) {
  120. stack.setting(EntryStack.Settings.CHECK_AMOUNT, EntryStack.Settings.FALSE).setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.CHECK_TAGS, EntryStack.Settings.TRUE);
  121. }
  122. }
  123. ((me.sargunvohra.mcmods.autoconfig1u.ConfigManager<ConfigObjectImpl>) AutoConfig.getConfigHolder(ConfigObjectImpl.class)).save();
  124. }
  125. public ConfigObject getConfig() {
  126. return AutoConfig.getConfigHolder(ConfigObjectImpl.class).getConfig();
  127. }
  128. @Override
  129. public boolean isCraftableOnlyEnabled() {
  130. return craftableOnly;
  131. }
  132. @Override
  133. public void toggleCraftableOnly() {
  134. craftableOnly = !craftableOnly;
  135. }
  136. @SuppressWarnings("deprecation")
  137. @Override
  138. public Screen getConfigScreen(Screen parent) {
  139. try {
  140. ConfigScreenProvider<ConfigObjectImpl> provider = (ConfigScreenProvider<ConfigObjectImpl>) AutoConfig.getConfigScreen(ConfigObjectImpl.class, parent);
  141. provider.setI13nFunction(manager -> "config.roughlyenoughitems");
  142. provider.setOptionFunction((baseI13n, field) -> field.isAnnotationPresent(ConfigObjectImpl.DontApplyFieldName.class) ? baseI13n : String.format("%s.%s", baseI13n, field.getName()));
  143. provider.setCategoryFunction((baseI13n, categoryName) -> String.format("%s.%s", baseI13n, categoryName));
  144. provider.setBuildFunction(builder -> {
  145. builder.setGlobalized(true);
  146. builder.setGlobalizedExpanded(true);
  147. if (MinecraftClient.getInstance().getNetworkHandler() != null && MinecraftClient.getInstance().getNetworkHandler().getRecipeManager() != null) {
  148. builder.getOrCreateCategory(new TranslatableText("config.roughlyenoughitems.advanced")).getEntries().add(0, new ReloadPluginsEntry(220));
  149. }
  150. return builder.setAfterInitConsumer(screen -> {
  151. ((ScreenHooks) screen).cloth$addButtonWidget(new ButtonWidget(screen.width - 104, 4, 100, 20, new TranslatableText("text.rei.credits"), button -> {
  152. MinecraftClient.getInstance().openScreen(new CreditsScreen(screen));
  153. }));
  154. }).setSavingRunnable(() -> {
  155. saveConfig();
  156. ((EntryRegistryImpl) EntryRegistry.getInstance()).refilter();
  157. if (ScreenHelper.getSearchField() != null)
  158. ContainerScreenOverlay.getEntryListWidget().updateSearch(ScreenHelper.getSearchField().getText(), true);
  159. }).build();
  160. });
  161. return provider.get();
  162. } catch (Exception e) {
  163. e.printStackTrace();
  164. }
  165. return null;
  166. }
  167. }