diff --git a/src/main/java/com/terraformersmc/modmenu/ModMenu.java b/src/main/java/com/terraformersmc/modmenu/ModMenu.java index b126b7dc..d676725c 100644 --- a/src/main/java/com/terraformersmc/modmenu/ModMenu.java +++ b/src/main/java/com/terraformersmc/modmenu/ModMenu.java @@ -10,6 +10,7 @@ import com.terraformersmc.modmenu.config.ModMenuConfig; import com.terraformersmc.modmenu.config.ModMenuConfigManager; import com.terraformersmc.modmenu.event.ModMenuEventHandler; +import com.terraformersmc.modmenu.util.EnumToLowerCaseJsonConverter; import com.terraformersmc.modmenu.util.ModMenuScreenTexts; import com.terraformersmc.modmenu.util.UpdateCheckerUtil; import com.terraformersmc.modmenu.util.mod.Mod; @@ -34,8 +35,16 @@ public class ModMenu implements ClientModInitializer { public static final String MOD_ID = "modmenu"; public static final String GITHUB_REF = "TerraformersMC/ModMenu"; public static final Logger LOGGER = LoggerFactory.getLogger("Mod Menu"); - public static final Gson GSON = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).setPrettyPrinting().create(); - public static final Gson GSON_MINIFIED = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create(); + public static final Gson GSON; + public static final Gson GSON_MINIFIED; + + static { + GsonBuilder builder = new GsonBuilder() + .registerTypeHierarchyAdapter(Enum.class, new EnumToLowerCaseJsonConverter()) + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); + GSON = builder.setPrettyPrinting().create(); + GSON_MINIFIED = builder.create(); + } public static final Map MODS = new HashMap<>(); public static final Map ROOT_MODS = new HashMap<>(); @@ -168,12 +177,26 @@ public static boolean areModUpdatesAvailable() { public static String getDisplayedModCount() { if (cachedDisplayedModCount == -1) { + boolean includeChildren = ModMenuConfig.COUNT_CHILDREN.getValue(); + boolean includeLibraries = ModMenuConfig.COUNT_LIBRARIES.getValue(); + boolean includeHidden = ModMenuConfig.COUNT_HIDDEN_MODS.getValue(); + // listen, if you have >= 2^32 mods then that's on you - cachedDisplayedModCount = Math.toIntExact(MODS.values().stream().filter(mod -> - (ModMenuConfig.COUNT_CHILDREN.getValue() || mod.getParent() == null) && - (ModMenuConfig.COUNT_LIBRARIES.getValue() || !mod.getBadges().contains(Mod.Badge.LIBRARY)) && - (ModMenuConfig.COUNT_HIDDEN_MODS.getValue() || !mod.isHidden()) - ).count()); + cachedDisplayedModCount = Math.toIntExact(MODS.values().stream().filter(mod -> { + boolean isChild = mod.getParent() != null; + if (!includeChildren && isChild) { + return false; + } + boolean isLibrary = mod.getBadges().contains(Mod.Badge.LIBRARY); + if (!includeLibraries && isLibrary) { + return false; + } + if (!includeHidden && mod.isHidden()) { + return false; + } + + return true; + }).count()); } return NumberFormat.getInstance().format(cachedDisplayedModCount); } @@ -181,8 +204,10 @@ public static String getDisplayedModCount() { public static Text createModsButtonText(boolean title) { var titleStyle = ModMenuConfig.MODS_BUTTON_STYLE.getValue(); var gameMenuStyle = ModMenuConfig.GAME_MENU_BUTTON_STYLE.getValue(); - var isIcon = title ? titleStyle == ModMenuConfig.TitleMenuButtonStyle.ICON : gameMenuStyle == ModMenuConfig.GameMenuButtonStyle.ICON; - var isShort = title ? titleStyle == ModMenuConfig.TitleMenuButtonStyle.SHRINK : gameMenuStyle == ModMenuConfig.GameMenuButtonStyle.REPLACE_BUGS; + var isIcon = title ? titleStyle == ModMenuConfig.TitleMenuButtonStyle.ICON : gameMenuStyle == + ModMenuConfig.GameMenuButtonStyle.ICON; + var isShort = title ? titleStyle == ModMenuConfig.TitleMenuButtonStyle.SHRINK : gameMenuStyle == + ModMenuConfig.GameMenuButtonStyle.REPLACE_BUGS; MutableText modsText = ModMenuScreenTexts.TITLE.copy(); if (ModMenuConfig.MOD_COUNT_LOCATION.getValue().isOnModsButton() && !isIcon) { String count = ModMenu.getDisplayedModCount(); diff --git a/src/main/java/com/terraformersmc/modmenu/config/ModMenuConfig.java b/src/main/java/com/terraformersmc/modmenu/config/ModMenuConfig.java index 606b10ea..6766d7ec 100644 --- a/src/main/java/com/terraformersmc/modmenu/config/ModMenuConfig.java +++ b/src/main/java/com/terraformersmc/modmenu/config/ModMenuConfig.java @@ -1,6 +1,5 @@ package com.terraformersmc.modmenu.config; -import com.google.gson.annotations.SerializedName; import com.terraformersmc.modmenu.api.UpdateChannel; import com.terraformersmc.modmenu.config.option.BooleanConfigOption; import com.terraformersmc.modmenu.config.option.EnumConfigOption; @@ -21,16 +20,16 @@ public class ModMenuConfig { public static final BooleanConfigOption COUNT_LIBRARIES = new BooleanConfigOption("count_libraries", true); public static final BooleanConfigOption COMPACT_LIST = new BooleanConfigOption("compact_list", false); public static final BooleanConfigOption COUNT_CHILDREN = new BooleanConfigOption("count_children", true); - public static final EnumConfigOption MODS_BUTTON_STYLE = new EnumConfigOption<>( - "mods_button_style", - TitleMenuButtonStyle.CLASSIC); - public static final EnumConfigOption GAME_MENU_BUTTON_STYLE = new EnumConfigOption<>( - "game_menu_button_style", - GameMenuButtonStyle.REPLACE_BUGS); + public static final EnumConfigOption MODS_BUTTON_STYLE = new EnumConfigOption<>("mods_button_style", + TitleMenuButtonStyle.CLASSIC + ); + public static final EnumConfigOption GAME_MENU_BUTTON_STYLE = new EnumConfigOption<>("game_menu_button_style", + GameMenuButtonStyle.REPLACE_BUGS + ); public static final BooleanConfigOption COUNT_HIDDEN_MODS = new BooleanConfigOption("count_hidden_mods", true); - public static final EnumConfigOption MOD_COUNT_LOCATION = new EnumConfigOption<>( - "mod_count_location", - ModCountLocation.TITLE_SCREEN); + public static final EnumConfigOption MOD_COUNT_LOCATION = new EnumConfigOption<>("mod_count_location", + ModCountLocation.TITLE_SCREEN + ); public static final BooleanConfigOption HIDE_MOD_LINKS = new BooleanConfigOption("hide_mod_links", false); public static final BooleanConfigOption SHOW_LIBRARIES = new BooleanConfigOption("show_libraries", false); public static final BooleanConfigOption HIDE_MOD_LICENSE = new BooleanConfigOption("hide_mod_license", false); @@ -39,12 +38,10 @@ public class ModMenuConfig { public static final BooleanConfigOption EASTER_EGGS = new BooleanConfigOption("easter_eggs", true); public static final BooleanConfigOption RANDOM_JAVA_COLORS = new BooleanConfigOption("random_java_colors", false); public static final BooleanConfigOption TRANSLATE_NAMES = new BooleanConfigOption("translate_names", true); - public static final BooleanConfigOption TRANSLATE_DESCRIPTIONS = new BooleanConfigOption("translate_descriptions", - true); + public static final BooleanConfigOption TRANSLATE_DESCRIPTIONS = new BooleanConfigOption("translate_descriptions", true); public static final BooleanConfigOption UPDATE_CHECKER = new BooleanConfigOption("update_checker", true); public static final BooleanConfigOption BUTTON_UPDATE_BADGE = new BooleanConfigOption("button_update_badge", true); - public static final EnumConfigOption UPDATE_CHANNEL = new EnumConfigOption<>("update_channel", - UpdateChannel.RELEASE); + public static final EnumConfigOption UPDATE_CHANNEL = new EnumConfigOption<>("update_channel", UpdateChannel.RELEASE); public static final BooleanConfigOption QUICK_CONFIGURE = new BooleanConfigOption("quick_configure", true); @FileOnlyConfig @@ -56,17 +53,13 @@ public class ModMenuConfig { @FileOnlyConfig public static final BooleanConfigOption CONFIG_MODE = new BooleanConfigOption("config_mode", false); @FileOnlyConfig - public static final BooleanConfigOption DISABLE_DRAG_AND_DROP = new BooleanConfigOption("disable_drag_and_drop", - false); + public static final BooleanConfigOption DISABLE_DRAG_AND_DROP = new BooleanConfigOption("disable_drag_and_drop", false); @FileOnlyConfig public static final StringSetConfigOption HIDDEN_MODS = new StringSetConfigOption("hidden_mods", new HashSet<>()); @FileOnlyConfig - public static final StringSetConfigOption HIDDEN_CONFIGS = new StringSetConfigOption("hidden_configs", - new HashSet<>()); + public static final StringSetConfigOption HIDDEN_CONFIGS = new StringSetConfigOption("hidden_configs", new HashSet<>()); @FileOnlyConfig - public static final StringSetConfigOption DISABLE_UPDATE_CHECKER = new StringSetConfigOption( - "disable_update_checker", - new HashSet<>()); + public static final StringSetConfigOption DISABLE_UPDATE_CHECKER = new StringSetConfigOption("disable_update_checker", new HashSet<>()); public static SimpleOption[] asOptions() { ArrayList> options = new ArrayList<>(); @@ -84,11 +77,10 @@ public static SimpleOption[] asOptions() { } public enum Sorting { - @SerializedName("ascending") ASCENDING(Comparator.comparing(mod -> mod.getTranslatedName() - .toLowerCase(Locale.ROOT))), - @SerializedName("descending") DESCENDING(ASCENDING.getComparator().reversed()); + ASCENDING(Comparator.comparing(mod -> mod.getTranslatedName().toLowerCase(Locale.ROOT))), + DESCENDING(ASCENDING.getComparator().reversed()); - Comparator comparator; + private final Comparator comparator; Sorting(Comparator comparator) { this.comparator = comparator; @@ -100,10 +92,10 @@ public Comparator getComparator() { } public enum ModCountLocation { - @SerializedName("title_screen") TITLE_SCREEN(true, false), - @SerializedName("mods_button") MODS_BUTTON(false, true), - @SerializedName("title_screen_and_mods_button") TITLE_SCREEN_AND_MODS_BUTTON(true, true), - @SerializedName("none") NONE(false, false); + TITLE_SCREEN(true, false), + MODS_BUTTON(false, true), + TITLE_SCREEN_AND_MODS_BUTTON(true, true), + NONE(false, false); private final boolean titleScreen, modsButton; @@ -122,15 +114,15 @@ public boolean isOnModsButton() { } public enum TitleMenuButtonStyle { - @SerializedName("classic") CLASSIC(), - @SerializedName("replace_realms") REPLACE_REALMS(), - @SerializedName("shrink") SHRINK(), - @SerializedName("icon") ICON(); + CLASSIC(), + REPLACE_REALMS(), + SHRINK(), + ICON(); } public enum GameMenuButtonStyle { - @SerializedName("replace_bugs") REPLACE_BUGS, - @SerializedName("below_bugs") BELOW_BUGS, - @SerializedName("icon") ICON; + REPLACE_BUGS, + BELOW_BUGS, + ICON; } } diff --git a/src/main/java/com/terraformersmc/modmenu/util/EnumToLowerCaseJsonConverter.java b/src/main/java/com/terraformersmc/modmenu/util/EnumToLowerCaseJsonConverter.java new file mode 100644 index 00000000..9d470dc5 --- /dev/null +++ b/src/main/java/com/terraformersmc/modmenu/util/EnumToLowerCaseJsonConverter.java @@ -0,0 +1,45 @@ +package com.terraformersmc.modmenu.util; + +import com.google.gson.*; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +public final class EnumToLowerCaseJsonConverter implements JsonSerializer>, JsonDeserializer> { + private static final Map>> TYPE_CACHE = new HashMap<>(); + + @Override + public JsonElement serialize(final Enum src, final Type typeOfSrc, final JsonSerializationContext context) { + if (src == null) { + return JsonNull.INSTANCE; + } + return new JsonPrimitive(src.name().toLowerCase()); + } + + @Override + public Enum deserialize(final JsonElement json, + final Type type, + final JsonDeserializationContext context) throws JsonParseException { + if (json == null || json.isJsonNull()) { + return null; + } + + if (!json.isJsonPrimitive() || !json.getAsJsonPrimitive().isString()) { + throw new JsonParseException("Expecting a String JsonPrimitive, getting " + json); + } + + try { + final String enumClassName = type.getTypeName(); + Class> enumClass = TYPE_CACHE.get(enumClassName); + if (enumClass == null) { + enumClass = (Class>) Class.forName(enumClassName); + TYPE_CACHE.put(enumClassName, enumClass); + } + + return Enum.valueOf((Class) enumClass, json.getAsString().toUpperCase()); + } catch (final ClassNotFoundException e) { + throw new JsonParseException(e); + } + } +}