From 7d4f2b900254d961b847f573237e3e6f40bff8e9 Mon Sep 17 00:00:00 2001 From: Cow Date: Thu, 24 Sep 2020 17:58:17 +0200 Subject: Config (gui) rework - Completely re-done the config gui (`/moo config`) - Improved SkyBlock dungeon party finder - Improved SkyBlock dungeon performance overlay - Improved handling of invalid/missing Hypixel API key - minor text fixes --- .../de/cowtipper/cowlection/config/MooConfig.java | 614 ++++++++++++++++----- 1 file changed, 463 insertions(+), 151 deletions(-) (limited to 'src/main/java/de/cowtipper/cowlection/config/MooConfig.java') diff --git a/src/main/java/de/cowtipper/cowlection/config/MooConfig.java b/src/main/java/de/cowtipper/cowlection/config/MooConfig.java index 0a498dd..1d8b4ee 100644 --- a/src/main/java/de/cowtipper/cowlection/config/MooConfig.java +++ b/src/main/java/de/cowtipper/cowlection/config/MooConfig.java @@ -2,78 +2,122 @@ package de.cowtipper.cowlection.config; import de.cowtipper.cowlection.Cowlection; import de.cowtipper.cowlection.command.TabCompletableCommand; +import de.cowtipper.cowlection.config.gui.MooConfigGui; +import de.cowtipper.cowlection.config.gui.MooConfigPreview; +import de.cowtipper.cowlection.data.DataHelper; +import de.cowtipper.cowlection.util.MooChatComponent; import de.cowtipper.cowlection.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.command.ICommand; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagInt; +import net.minecraft.nbt.NBTTagString; +import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; import net.minecraft.util.Util; import net.minecraftforge.client.ClientCommandHandler; import net.minecraftforge.common.ForgeModContainer; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.config.ConfigCategory; import net.minecraftforge.common.config.Configuration; import net.minecraftforge.common.config.Property; -import net.minecraftforge.fml.client.FMLConfigGuiFactory; import net.minecraftforge.fml.client.event.ConfigChangedEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.lwjgl.input.Keyboard; import java.io.File; import java.time.LocalDate; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Pattern; /** - * Mod configuration via ingame gui + * Mod configuration *

* Based on TheGreyGhost's MinecraftByExample * * @see ForgeModContainer - * @see FMLConfigGuiFactory */ public class MooConfig { - static final String CATEGORY_LOGS_SEARCH = "logssearch"; - // main config + // Category: General + private static String configGuiExplanations; + public static String[] tabCompletableNamesCommands; + private static final String CATEGORY_LOGS_SEARCH = "logssearch"; + public static String[] logsDirs; + private static String defaultStartDate; + // Category: Notifications public static boolean doUpdateCheck; public static boolean showBestFriendNotifications; public static boolean showFriendNotifications; public static boolean showGuildNotifications; public static boolean doBestFriendsOnlineCheck; - public static boolean showAdvancedTooltips; - public static String[] tabCompletableNamesCommands; + // Category: SkyBlock + public static int tooltipToggleKeyBinding; + private static String tooltipAuctionHousePriceEach; + private static String tooltipItemAge; + public static boolean tooltipItemAgeShortened; + private static String tooltipItemTimestamp; private static String numeralSystem; - // SkyBlock dungeon - public static int[] dungClassRange; - public static boolean dungFilterPartiesWithDupes; - public static String dungPartyFinderArmorLookup; - public static String dungItemQualityPos; + // Category: SkyBlock Dungeons + public static int dungItemToolTipToggleKeyBinding; + private static String dungItemQualityPos; public static boolean dungOverlayEnabled; - public static int dungOverlayGuiScale; public static int dungOverlayPositionX; public static int dungOverlayPositionY; - // logs search config - public static String[] logsDirs; - private static String defaultStartDate; - // other stuff - public static String moo; + public static int dungOverlayGuiScale; + public static boolean dungOverlayTextShadow; + public static int dungClassMin; + public static boolean dungFilterPartiesWithArcherDupes; + public static boolean dungFilterPartiesWithBerserkDupes; + public static boolean dungFilterPartiesWithHealerDupes; + public static boolean dungFilterPartiesWithMageDupes; + public static boolean dungFilterPartiesWithTankDupes; + private static String dungPartyFinderArmorLookup; + private static Configuration cfg = null; + private static final List configCategories = new ArrayList<>(); private final Cowlection main; - private List propOrderGeneral; - private List propOrderLogsSearch; + private Property propTabCompletableNamesCommands; + private List logSearchProperties; public MooConfig(Cowlection main, Configuration configuration) { this.main = main; cfg = configuration; + + if (cfg.getLoadedConfigVersion() == null || !cfg.getLoadedConfigVersion().equals(cfg.getDefinedConfigVersion())) { + updateConfig(cfg.getLoadedConfigVersion()); + } + initConfig(); } - static Configuration getConfig() { - return cfg; + private void updateConfig(String oldVersion) { + if (oldVersion == null) { + // config of Cowlection v1.8.9-0.10.2 and older + + // leave log search settings as is + + if (cfg.hasCategory(Configuration.CATEGORY_CLIENT)) { + // copy old 'moo' value to new, separate config + if (cfg.hasKey(Configuration.CATEGORY_CLIENT, "moo")) { + String oldMoo = cfg.getString("moo", Configuration.CATEGORY_CLIENT, "00000000-0000-0000-0000-000000000000", "Temporary config entry, should be deleted automatically.", Utils.VALID_UUID_PATTERN); + if (StringUtils.isNotEmpty(oldMoo) && Utils.isValidUuid(oldMoo)) { + // save into new cfg: + main.getMoo().setMooIfValid(oldMoo, false); + } + } + + // delete client category (no longer used) + ConfigCategory oldClientCategory = cfg.getCategory(Configuration.CATEGORY_CLIENT); + cfg.removeCategory(oldClientCategory); + } + cfg.save(); + } } private void initConfig() { @@ -85,37 +129,28 @@ public class MooConfig { * Load the configuration values from the configuration file */ private void syncFromFile() { - syncConfig(true, true); + syncConfig(true, true, true); } /** * Save the GUI-altered values to disk */ - private void syncFromGui() { - syncConfig(false, true); + public void syncFromGui() { + syncConfig(false, true, true); } /** - * Save the Configuration variables (fields) to disk + * Save the GUI-altered values to the properties; don't save to disk - only memory */ - public void syncFromFields() { - syncConfig(false, false); + public void syncFromGuiWithoutSaving() { + syncConfig(false, true, false); } - public static LocalDate calculateStartDate() { - try { - // date format: yyyy-mm-dd - return LocalDate.parse(defaultStartDate); - } catch (DateTimeParseException e) { - // fallthrough - } - try { - int months = Integer.parseInt(defaultStartDate); - return LocalDate.now().minus(months, ChronoUnit.MONTHS); - } catch (NumberFormatException e) { - // default: 1 month - return LocalDate.now().minus(1, ChronoUnit.MONTHS); - } + /** + * Save the Configuration variables (fields) to disk + */ + public void syncFromFields() { + syncConfig(false, false, true); } /** @@ -126,127 +161,321 @@ public class MooConfig { * * @param loadConfigFromFile if true, load the config field from the configuration file on disk * @param readFieldsFromConfig if true, reload the member variables from the config field + * @param saveToFile if true, save changes to config file */ - private void syncConfig(boolean loadConfigFromFile, boolean readFieldsFromConfig) { + @SuppressWarnings("DuplicatedCode") + private void syncConfig(boolean loadConfigFromFile, boolean readFieldsFromConfig, boolean saveToFile) { if (loadConfigFromFile) { cfg.load(); } - // config section: main configuration - propOrderGeneral = new ArrayList<>(); - - Property propDoUpdateCheck = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "doUpdateCheck", true, "Check for mod updates?"), true); - Property propShowBestFriendNotifications = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "showBestFriendNotifications", true, "Set to true to receive best friends' login/logout messages, set to false hide them."), true); - Property propShowFriendNotifications = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "showFriendNotifications", true, "Set to true to receive friends' login/logout messages, set to false hide them."), true); - Property propShowGuildNotifications = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "showGuildNotifications", true, "Set to true to receive guild members' login/logout messages, set to false hide them."), true); - Property propDoBestFriendsOnlineCheck = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "doBestFriendsOnlineCheck", true, "Set to true to check best friends' online status when joining a server, set to false to disable."), true); - Property propShowAdvancedTooltips = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "showAdvancedTooltips", true, "Set to true to show advanced tooltips, set to false show default tooltips."), true); - Property propNumeralSystem = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "numeralSystem", "Arabic numerals: 1, 4, 10", "Use Roman or Arabic numeral system?", new String[]{"Arabic numerals: 1, 4, 10", "Roman numerals: I, IV, X"}), true); - Property propTabCompletableNamesCommands = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "tabCompletableNamesCommands", new String[]{"party", "p", "invite", "visit", "ah", "ignore", "msg", "tell", "w", "boop", "profile", "friend", "friends", "f"}, "List of commands with a Tab-completable username argument."), true) - .setValidationPattern(Pattern.compile("^[A-Za-z]+$")); - Property propMoo = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "moo", "", "The answer to life the universe and everything. Don't edit this entry manually!", Utils.VALID_UUID_PATTERN), false); - - // SkyBlock dungeon - Property propDungClassRange = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "dungClassRange", new int[]{-1, -1}, "Accepted level range for the dungeon party finder. Set to -1 to disable"), true) - .setMinValue(-1).setIsListLengthFixed(true); - Property propDungFilterPartiesWithDupes = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "dungFilterPartiesWithDupes", false, "Mark parties with duplicated classes?"), true); - Property propDungPartyFinderArmorLookup = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "dungPartyFinderArmorLookup", "as a tooltip", "Show armor of player joining via party finder as a tooltip or in chat?", new String[]{"as a tooltip", "in chat", "disabled"}), true); - Property propDungItemQualityPos = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "dungItemQualityPos", "top", "Position of item quality in tooltip", new String[]{"top", "bottom"}), true); - Property propDungOverlayEnabled = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "dungOverlayEnabled", true, "Enable Dungeon performance overlay?"), false); - Property propDungOverlayPositionX = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "dungGuiPositionX", 5, "Dungeon performance overlay position: x value", -1, 10000), false); - Property propDungOverlayPositionY = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "dungGuiPositionY", 5, "Dungeon performance overlay position: y value", -1, 5000), false); - Property propDungOverlayGuiScale = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, - "dungOverlayGuiScale", 100, "Dungeon performance overlay GUI scale", 50, 200), false); - cfg.setCategoryPropertyOrder(Configuration.CATEGORY_CLIENT, propOrderGeneral); - - // config section: log files search - propOrderLogsSearch = new ArrayList<>(); - - Property propLogsDirs = addConfigEntry(cfg.get(CATEGORY_LOGS_SEARCH, + // reset previous entries + configCategories.clear(); + + // Category: General + MooConfigCategory configCat = new MooConfigCategory("General", "general"); + configCategories.add(configCat); + + // Sub-Category: Cowlection config gui + MooConfigCategory.SubCategory subCat = configCat.addSubCategory("Cowlection config gui"); + subCat.addExplanations("Display of the explanations for each sub-section:", + " ‣ " + EnumChatFormatting.YELLOW + "as tooltip ①" + EnumChatFormatting.DARK_GRAY + "⬛" + EnumChatFormatting.RESET + " = tooltip when hovering over sub-category heading (with darkened background)", + " ‣ " + EnumChatFormatting.YELLOW + "as tooltip ②" + EnumChatFormatting.WHITE + "⬛" + EnumChatFormatting.RESET + " = tooltip when hovering over sub-category heading (no extra background)", + " ‣ " + EnumChatFormatting.YELLOW + "as text" + EnumChatFormatting.RESET + " = below each sub-category heading", + " ‣ " + EnumChatFormatting.YELLOW + "hidden" + EnumChatFormatting.RESET + " = "); + Property propConfigGuiExplanations = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "configGuiExplanations", "tooltip ① §0⬛", "Display config settings explanations", + new String[]{"as tooltip ①§0⬛", "as tooltip ②§f⬛", "as text", "hidden"})); + + // Sub-Category: API settings + subCat = configCat.addSubCategory("API settings"); + subCat.addExplanations("Some features use the official Hypixel API and therefore require your API key.", + "Use " + EnumChatFormatting.YELLOW + "/moo apikey " + EnumChatFormatting.RESET + "to see how to request a new API key from Hypixel", + "The API key is stored " + EnumChatFormatting.ITALIC + "locally " + EnumChatFormatting.ITALIC + "on your computer."); + subCat.addConfigEntry(main.getMoo().getPropIsMooValid()); + + // Sub-Category: Tab-completable names in commands + subCat = configCat.addSubCategory("Tab-completable usernames"); + subCat.addExplanations("For certain commands you can use " + EnumChatFormatting.YELLOW + "TAB " + EnumChatFormatting.RESET + "to autocomplete player names", + EnumChatFormatting.UNDERLINE + "Uses player names from:", + " ‣ Guild and Party chat", + " ‣ Party and game (duels) invites", + " ‣ SkyBlock Dungeon party finder: when a player joins the group", + " ‣ Online best friends (if the best friend online checker is enabled)"); + + propTabCompletableNamesCommands = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "tabCompletableNamesCommands", new String[]{"party", "p", "invite", "visit", "ah", "ignore", "msg", "tell", "w", "boop", "profile", "friend", "friends"}, "List of commands with a Tab-completable username argument.") + .setValidationPattern(Pattern.compile("^[A-Za-z]+$"))); + + // Sub-Category: Other settings + subCat = configCat.addSubCategory("Other settings"); + subCat.addExplanations("Other settings that are located in other GUIs"); + + Property propLogsDirs = subCat.addConfigEntry(cfg.get(CATEGORY_LOGS_SEARCH, "logsDirs", resolveDefaultLogsDirs(), - "Directories with Minecraft log files"), true, CATEGORY_LOGS_SEARCH); - Property propDefaultStartDate = addConfigEntry(cfg.get(CATEGORY_LOGS_SEARCH, - "defaultStartDate", "3", "Default start date (a number means X months ago, alternatively a fixed date à la yyyy-mm-dd can be used)"), true) + "Directories with Minecraft log files")); + Property propDefaultStartDate = subCat.addConfigEntry(cfg.get(CATEGORY_LOGS_SEARCH, + "defaultStartDate", "3", "Default start date (a number means X months ago, alternatively a fixed date à la yyyy-mm-dd can be used)")) .setValidationPattern(Pattern.compile("^[1-9][0-9]{0,2}|(2[0-9]{3}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))$")); + logSearchProperties = new ArrayList<>(); + logSearchProperties.add(propLogsDirs); + logSearchProperties.add(propDefaultStartDate); + + // Category: Notifications + configCat = new MooConfigCategory("Notifications", "notifications"); + configCategories.add(configCat); + + // Sub-Category: Mod update checker + subCat = configCat.addSubCategory("Mod update checker"); + Property propDoUpdateCheck = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "doUpdateCheck", true, "Check for mod updates?")); + + // Sub-Category: Login & Logout + subCat = configCat.addSubCategory("Login & Logout"); + subCat.addExplanations("Hides selected login/logout notifications ", + "while still showing notifications of best friends (if enabled).", + "Add someone to the best friends list with " + EnumChatFormatting.YELLOW + "/moo add " + EnumChatFormatting.RESET); + + Property propShowBestFriendNotifications = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "showBestFriendNotifications", true, "Set to true to receive best friends' login/logout messages, set to false hide them."), + new MooConfigPreview(new ChatComponentText("§a§lBest friend §a> §6Cow §r§ejoined."))); + Property propShowFriendNotifications = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "showFriendNotifications", true, "Set to true to receive friends' login/logout messages, set to false hide them."), + new MooConfigPreview(new ChatComponentText("§aFriend > §r§aBob §ejoined."))); + Property propShowGuildNotifications = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "showGuildNotifications", true, "Set to true to receive guild members' login/logout messages, set to false hide them."), + new MooConfigPreview(new ChatComponentText("§2Guild > §r§7Herobrian §eleft."))); + + + // Sub-Category: Best friends online status + subCat = configCat.addSubCategory("Best friend online checker"); + subCat.addExplanations("Check which best friends are online when you join the server.", + "About once a day, a check for new name changes is also performed automatically."); + + IChatComponent spacer = new MooChatComponent(", ").green(); + Property propDoBestFriendsOnlineCheck = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "doBestFriendsOnlineCheck", true, "Set to true to check best friends' online status when joining a server, set to false to disable."), + new MooConfigPreview(new MooChatComponent("§a⬤ Online best friends (§24§a/§216§a): ") + .appendSibling(MooConfigPreview.createDemoOnline("Alice", "Housing", "1 hour 13 minutes 37 seconds")).appendSibling(spacer) + .appendSibling(MooConfigPreview.createDemoOnline("Bob", "Build Battle", "2 hours 13 minutes 37 seconds")).appendSibling(spacer) + .appendSibling(MooConfigPreview.createDemoOnline("Cow", "SkyBlock", "13 minutes 37 seconds")).appendSibling(spacer) + .appendSibling(MooConfigPreview.createDemoOnline("Herobrian", "Murder Mystery", "13 hours 33 minutes 37 seconds")))); + + + // Category: SkyBlock + configCat = new MooConfigCategory("SkyBlock", "skyblock"); + configCategories.add(configCat); + + // Sub-Category: Tooltip enhancements + subCat = configCat.addSubCategory("Tooltip enhancements"); + + Property propTooltipToggleKeyBinding = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "tooltipToggleKeyBinding", Keyboard.KEY_LSHIFT, "Key to toggle tooltip")); + + Property propTooltipAuctionHousePriceEach = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "tooltipAuctionHousePriceEach", "always", "Add price per item if multiple items are bought or sold", new String[]{"always", "key press", "never"})); + + Map demoItemExtraAttributes = new HashMap<>(); + demoItemExtraAttributes.put("new_years_cake", new NBTTagInt(1)); + demoItemExtraAttributes.put("originTag", new NBTTagString("REWARD_NEW_YEARS_CAKE_NPC")); + demoItemExtraAttributes.put("id", new NBTTagString("NEW_YEAR_CAKE")); + demoItemExtraAttributes.put("uuid", new NBTTagString("64b3a60b-74f2-4ebd-818d-d019c5b7f3e0")); + demoItemExtraAttributes.put("timestamp", new NBTTagString("6/16/19 5:05 PM")); + MooConfigPreview nonStackableItemPreview = new MooConfigPreview(MooConfigPreview.createDemoItem("cake", "§dNew Year Cake", new String[]{"§7Given to every player as a", "§7celebration for the 1st SkyBlock", "§7year!", "", "§d§lSPECIAL"}, demoItemExtraAttributes)); + + Property propTooltipItemAge = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "tooltipItemAge", "always", "Show item age", new String[]{"always", "key press", "never"}), + nonStackableItemPreview); + + Property propTooltipItemAgeShortened = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "tooltipItemAgeShortened", true, "Shorten item age?")); + + Property propTooltipItemTimestamp = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "tooltipItemTimestamp", "key press", "Show item creation date", new String[]{"always", "key press", "never"})); + + Property propNumeralSystem = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "numeralSystem", "Arabic: 1, 4, 10", "Use Roman or Arabic numeral system?", new String[]{"Arabic: 1, 4, 10", "Roman: I, IV, X"})); + + + // Category: SkyBlock Dungeons + configCat = new MooConfigCategory("SkyBlock Dungeons", "skyblockdungeons"); + configCat.setMenuDisplayName("SB Dungeons"); + configCategories.add(configCat); + + // Sub-Category: Tooltip enhancements + subCat = configCat.addSubCategory("Dungeon item tooltip enhancements"); + subCat.addExplanations("Hold left " + EnumChatFormatting.YELLOW + "SHIFT " + EnumChatFormatting.RESET + "while hovering over a dungeon item.", + "Shows " + EnumChatFormatting.YELLOW + "item quality " + EnumChatFormatting.RESET + "and " + EnumChatFormatting.YELLOW + "dungeon floor" + EnumChatFormatting.RESET + ", also remove stats from reforges and essences (✪)", + "which normally makes the comparison of dungeon items difficult.", + "Instead, the tooltip shows...", + " ‣ base/default stats " + EnumChatFormatting.GRAY + "(outside dungeons; 1st value - usually red or green)", + " ‣ stats inside dungeons " + EnumChatFormatting.GRAY + "(including dungeon level stat boost, but without essences [₀ₓ✪])", + " ‣ stats inside dungeons with 5x essence upgrades " + EnumChatFormatting.GRAY + "(₅ₓ✪)"); + + Property propDungItemToolTipToggleKeyBinding = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungItemToolTipToggleKeyBinding", Keyboard.KEY_LSHIFT, "Key to toggle dungeon item tooltip")); + + Property propDungItemQualityPos = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungItemQualityPos", "top", "Position of item quality in tooltip", new String[]{"top", "bottom"}), + new MooConfigPreview( + MooConfigPreview.createDungeonItem("light", "7/17/20 7:22 PM", "§7Gear Score: §d336 §8(526)", "§7Crit Chance: §c+5% §9(Light +2%)", "§7Crit Damage: §c+30% §9(Light +4%) §8(+48.9%)", "§7Bonus Attack Speed: §c+4% §9(Light +4%)", "", "§7Health: §a+126 HP §9(Light +15 HP) §8(+205.38 HP)", "§7Defense: §a+76 §9(Light +4) §8(+123.88)", "§7Speed: §a+4 §9(Light +4) §8(+6.52)", "", "§9Growth V, §9Protection V", "§9Thorns III", "", "§7Increase the damage you deal", "§7with arrows by §c5%§7.", "", "§6Full Set Bonus: Skeleton Soldier", "§7Increase the damage you deal", "§7with arrows by an extra §c25%§7.", "", "§aPerfect 52500 / 52500", "§5§lEPIC DUNGEON LEGGINGS"), + MooConfigPreview.createDungeonItem("clean", "7/11/20 12:27 PM", "§7Gear Score: §d359 §8(561)", "§7Crit Chance: §c+11% §9(Clean +8%)", "§7Crit Damage: §c+26% §8(+42.38%)", "", "§7Health: §a+126 HP §9(Clean +15 HP) §8(+205.38 HP)", "§7Defense: §a+87 §9(Clean +15) §8(+141.81)", "", "§9Growth V, §9Protection V", "§9Thorns III", "", "§7Increase the damage you deal", "§7with arrows by §c5%§7.", "", "§6Full Set Bonus: Skeleton Soldier", "§7Increase the damage you deal", "§7with arrows by an extra §c25%§7.", "", "§aPerfect 52500 / 52500", "§5§lEPIC DUNGEON LEGGINGS"))); + + // Sub-Category: Performance Overlay + subCat = configCat.addSubCategory("Performance Overlay"); + subCat.addExplanations(EnumChatFormatting.UNDERLINE + "Keeps track of:", + " ‣ skill score " + EnumChatFormatting.GRAY + "(reduced by deaths and failed puzzles)", + " ‣ speed score " + EnumChatFormatting.GRAY + "(-2.2 points when over 20 minutes)", + " ‣ bonus score " + EnumChatFormatting.GRAY + "(+1 [max 5] for each destroyed crypt; can only be detected up to ~50 blocks away from the player)", + "Does " + EnumChatFormatting.ITALIC + "not" + EnumChatFormatting.RESET + " track explorer score " + EnumChatFormatting.GRAY + "(explored rooms, secrets, ...)"); + + Property propDungOverlayEnabled = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungOverlayEnabled", true, "Enable Dungeon performance overlay?")); + + Property propDungOverlayPositionX = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungOverlayPositionX", 1, "Dungeon performance overlay position: x value", 0, 1000), + null, "‰", // per mille + (slider) -> { + MooConfig.dungOverlayPositionX = slider.getValueInt(); + MooConfigGui.showDungeonPerformanceOverlayUntil = System.currentTimeMillis() + 500; + }); + + Property propDungOverlayPositionY = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungOverlayPositionY", 1, "Dungeon performance overlay position: y value", 0, 1000), + null, "‰", // per mille + (slider) -> { + MooConfig.dungOverlayPositionY = slider.getValueInt(); + MooConfigGui.showDungeonPerformanceOverlayUntil = System.currentTimeMillis() + 500; + }); + + Property propDungOverlayGuiScale = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungOverlayGuiScale", 100, "Dungeon performance overlay GUI scale", 50, 200), + null, "%", + (slider) -> { + MooConfig.dungOverlayGuiScale = slider.getValueInt(); + MooConfigGui.showDungeonPerformanceOverlayUntil = System.currentTimeMillis() + 500; + }); + + Property propDungOverlayTextShadow = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungOverlayTextShadow", true, "Dungeon performance overlay GUI scale")); + + // Sub-Category: Party Finder + subCat = configCat.addSubCategory("Dungeon Party Finder"); + subCat.addExplanations("Adds various indicators to the dungeon party finder", + "to make it easier to find the perfect party:", + "", + "Marks parties...", + " ‣ you cannot join: " + EnumChatFormatting.RED + "⬛" + EnumChatFormatting.RESET + " (red carpet)", + " ‣ with someone below a certain class level: " + EnumChatFormatting.RED + EnumChatFormatting.BOLD + "ᐯ" + EnumChatFormatting.RESET, + " ‣ with duplicated roles you specify below: " + EnumChatFormatting.GOLD + "²⁺", + " ‣ that match your criteria: " + EnumChatFormatting.GREEN + "⬛" + EnumChatFormatting.RESET + " (green carpet)"); + + Property propDungClassMin = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungClassMin", 0, "Marks parties with members with lower class level than this value") + .setMinValue(0).setMaxValue(50), + new MooConfigPreview(new MooChatComponent("Marked with: " + EnumChatFormatting.RED + EnumChatFormatting.BOLD + "ᐯ").gray())); + + Property propDungFilterPartiesWithArcherDupes = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungFilterPartiesWithArcherDupes", true, "Mark parties with duplicated Archer class?"), + new MooConfigPreview(new MooChatComponent("Marked with: " + EnumChatFormatting.GOLD + "²⁺A").gray())); + + Property propDungFilterPartiesWithBerserkDupes = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungFilterPartiesWithBerserkDupes", false, "Mark parties with duplicated Berserk class?"), + new MooConfigPreview(new MooChatComponent("Marked with: " + EnumChatFormatting.GOLD + "²⁺B").gray())); + + Property propDungFilterPartiesWithHealerDupes = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungFilterPartiesWithHealerDupes", false, "Mark parties with duplicated Healer class?"), + new MooConfigPreview(new MooChatComponent("Marked with: " + EnumChatFormatting.GOLD + "²⁺H").gray())); + + Property propDungFilterPartiesWithMageDupes = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungFilterPartiesWithMageDupes", false, "Mark parties with duplicated Mage class?"), + new MooConfigPreview(new MooChatComponent("Marked with: " + EnumChatFormatting.GOLD + "²⁺M").gray())); + + Property propDungFilterPartiesWithTankDupes = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungFilterPartiesWithTankDupes", false, "Mark parties with duplicated Tank class?"), + new MooConfigPreview(new MooChatComponent("Marked with: " + EnumChatFormatting.GOLD + "²⁺T").gray())); + + Property propDungPartyFinderArmorLookup = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungPartyFinderArmorLookup", "as a tooltip", "Show armor of player joining via party finder as a tooltip or in chat?", new String[]{"as a tooltip", "in chat", "disabled"})); - cfg.setCategoryPropertyOrder(CATEGORY_LOGS_SEARCH, propOrderLogsSearch); - - // 'manual' replacement for propTabCompletableNamesCommands.hasChanged() boolean modifiedTabCompletableCommandsList = false; String[] tabCompletableCommandsPreChange = tabCompletableNamesCommands != null ? tabCompletableNamesCommands.clone() : null; if (readFieldsFromConfig) { - // main config + // Category: General + configGuiExplanations = propConfigGuiExplanations.getString(); + tabCompletableNamesCommands = propTabCompletableNamesCommands.getStringList(); + logsDirs = propLogsDirs.getStringList(); + defaultStartDate = propDefaultStartDate.getString().trim(); + // Category: Notifications doUpdateCheck = propDoUpdateCheck.getBoolean(); showBestFriendNotifications = propShowBestFriendNotifications.getBoolean(); showFriendNotifications = propShowFriendNotifications.getBoolean(); showGuildNotifications = propShowGuildNotifications.getBoolean(); doBestFriendsOnlineCheck = propDoBestFriendsOnlineCheck.getBoolean(); - showAdvancedTooltips = propShowAdvancedTooltips.getBoolean(); + // Category: SkyBlock + tooltipToggleKeyBinding = propTooltipToggleKeyBinding.getInt(); + tooltipAuctionHousePriceEach = propTooltipAuctionHousePriceEach.getString(); + tooltipItemAge = propTooltipItemAge.getString(); + tooltipItemAgeShortened = propTooltipItemAgeShortened.getBoolean(); + tooltipItemTimestamp = propTooltipItemTimestamp.getString(); numeralSystem = propNumeralSystem.getString(); - tabCompletableNamesCommands = propTabCompletableNamesCommands.getStringList(); - moo = propMoo.getString(); - - // SkyBlock dungeon - dungClassRange = propDungClassRange.getIntList(); - dungFilterPartiesWithDupes = propDungFilterPartiesWithDupes.getBoolean(); - dungPartyFinderArmorLookup = propDungPartyFinderArmorLookup.getString(); + // Category: SkyBlock Dungeons + dungItemToolTipToggleKeyBinding = propDungItemToolTipToggleKeyBinding.getInt(); dungItemQualityPos = propDungItemQualityPos.getString(); dungOverlayEnabled = propDungOverlayEnabled.getBoolean(); dungOverlayPositionX = propDungOverlayPositionX.getInt(); dungOverlayPositionY = propDungOverlayPositionY.getInt(); dungOverlayGuiScale = propDungOverlayGuiScale.getInt(); + dungOverlayTextShadow = propDungOverlayTextShadow.getBoolean(); + dungClassMin = propDungClassMin.getInt(); + dungFilterPartiesWithArcherDupes = propDungFilterPartiesWithArcherDupes.getBoolean(); + dungFilterPartiesWithBerserkDupes = propDungFilterPartiesWithBerserkDupes.getBoolean(); + dungFilterPartiesWithHealerDupes = propDungFilterPartiesWithHealerDupes.getBoolean(); + dungFilterPartiesWithMageDupes = propDungFilterPartiesWithMageDupes.getBoolean(); + dungFilterPartiesWithTankDupes = propDungFilterPartiesWithTankDupes.getBoolean(); + dungPartyFinderArmorLookup = propDungPartyFinderArmorLookup.getString(); - // logs search config - logsDirs = propLogsDirs.getStringList(); - defaultStartDate = propDefaultStartDate.getString().trim(); if (!Arrays.equals(tabCompletableCommandsPreChange, tabCompletableNamesCommands)) { modifiedTabCompletableCommandsList = true; } } - // main config + // Category: General + propConfigGuiExplanations.set(configGuiExplanations); + propTabCompletableNamesCommands.set(tabCompletableNamesCommands); + propLogsDirs.set(logsDirs); + propDefaultStartDate.set(defaultStartDate); + // Category: Notifications propDoUpdateCheck.set(doUpdateCheck); propShowBestFriendNotifications.set(showBestFriendNotifications); propShowFriendNotifications.set(showFriendNotifications); propShowGuildNotifications.set(showGuildNotifications); propDoBestFriendsOnlineCheck.set(doBestFriendsOnlineCheck); - propShowAdvancedTooltips.set(showAdvancedTooltips); + // Category: SkyBlock + propTooltipToggleKeyBinding.set(tooltipToggleKeyBinding); + propTooltipAuctionHousePriceEach.set(tooltipAuctionHousePriceEach); + propTooltipItemAge.set(tooltipItemAge); + propTooltipItemAgeShortened.set(tooltipItemAgeShortened); + propTooltipItemTimestamp.set(tooltipItemTimestamp); propNumeralSystem.set(numeralSystem); - propTabCompletableNamesCommands.set(tabCompletableNamesCommands); - propMoo.set(moo); - - // SkyBlock dungeon - propDungClassRange.set(dungClassRange); - propDungFilterPartiesWithDupes.set(dungFilterPartiesWithDupes); - propDungPartyFinderArmorLookup.set(dungPartyFinderArmorLookup); + // Category: SkyBlock Dungeons + propDungItemToolTipToggleKeyBinding.set(dungItemToolTipToggleKeyBinding); propDungItemQualityPos.set(dungItemQualityPos); propDungOverlayEnabled.set(dungOverlayEnabled); propDungOverlayPositionX.set(dungOverlayPositionX); propDungOverlayPositionY.set(dungOverlayPositionY); propDungOverlayGuiScale.set(dungOverlayGuiScale); + propDungOverlayTextShadow.set(dungOverlayTextShadow); + propDungClassMin.set(dungClassMin); + propDungFilterPartiesWithArcherDupes.set(dungFilterPartiesWithArcherDupes); + propDungFilterPartiesWithBerserkDupes.set(dungFilterPartiesWithBerserkDupes); + propDungFilterPartiesWithHealerDupes.set(dungFilterPartiesWithHealerDupes); + propDungFilterPartiesWithMageDupes.set(dungFilterPartiesWithMageDupes); + propDungFilterPartiesWithTankDupes.set(dungFilterPartiesWithTankDupes); + propDungPartyFinderArmorLookup.set(dungPartyFinderArmorLookup); - // logs search config - propLogsDirs.set(logsDirs); - propDefaultStartDate.set(defaultStartDate); - - if (cfg.hasChanged()) { + if (saveToFile && cfg.hasChanged()) { boolean isPlayerIngame = Minecraft.getMinecraft().thePlayer != null; if (modifiedTabCompletableCommandsList) { if (isPlayerIngame) { @@ -269,31 +498,9 @@ public class MooConfig { propTabCompletableNamesCommands.set(tabCompletableNamesCommands); } } - if (isPlayerIngame && dungClassRange[0] > -1 && dungClassRange[1] > -1 && dungClassRange[0] > dungClassRange[1]) { - main.getChatHelper().sendMessage(EnumChatFormatting.RED, "Dungeon class range minimum value cannot be higher than the maximum value."); - } - cfg.save(); - } - } - private Property addConfigEntry(Property property, boolean showInGui, String category) { - if (showInGui) { - property.setLanguageKey(Cowlection.MODID + ".config." + property.getName()); - } else { - property.setShowInGui(false); - } - - if (CATEGORY_LOGS_SEARCH.equals(category)) { - propOrderLogsSearch.add(property.getName()); - } else { - // == Configuration.CATEGORY_CLIENT: - propOrderGeneral.add(property.getName()); + cfg.save(); } - return property; - } - - private Property addConfigEntry(Property property, boolean showInGui) { - return addConfigEntry(property, showInGui, Configuration.CATEGORY_CLIENT); } /** @@ -329,6 +536,13 @@ public class MooConfig { return logsDirs.toArray(new String[]{}); } + // Category: General + public static Setting getConfigGuiExplanationsDisplay() { + return Setting.get(configGuiExplanations); + } + + // Category: Notifications + /** * Should login/logout notifications be modified and thus monitored? * @@ -338,18 +552,88 @@ public class MooConfig { return showBestFriendNotifications || !showFriendNotifications || !showGuildNotifications; } + // Category: SkyBlock + public static Setting getTooltipAuctionHousePriceEachDisplay() { + return Setting.get(tooltipAuctionHousePriceEach); + } + + public static Setting getTooltipItemAgeDisplay() { + return Setting.get(tooltipItemAge); + } + + public static Setting getTooltipItemTimestampDisplay() { + return Setting.get(tooltipItemTimestamp); + } + public static boolean useRomanNumerals() { return numeralSystem.startsWith("Roman"); } + public static boolean isTooltipToggleKeyBindingPressed() { + return tooltipToggleKeyBinding > 0 && Keyboard.isKeyDown(MooConfig.tooltipToggleKeyBinding); + } + + public static boolean isDungeonItemTooltipToggleKeyBindingPressed() { + return dungItemToolTipToggleKeyBinding > 0 && Keyboard.isKeyDown(MooConfig.dungItemToolTipToggleKeyBinding); + } + + // Category: SkyBlock Dungeons public static boolean isDungItemQualityAtTop() { return dungItemQualityPos.equals("top"); } - public static boolean showArmorLookupInChat() { - return "in chat".equals(dungPartyFinderArmorLookup); + public static Setting getDungPartyFinderArmorLookupDisplay() { + return Setting.get(dungPartyFinderArmorLookup); + } + + public static boolean filterDungPartiesWithDupes(DataHelper.DungeonClass dungeonClass) { + switch (dungeonClass) { + case ARCHER: + return dungFilterPartiesWithArcherDupes; + case BERSERK: + return dungFilterPartiesWithBerserkDupes; + case HEALER: + return dungFilterPartiesWithHealerDupes; + case MAGE: + return dungFilterPartiesWithMageDupes; + case TANK: + return dungFilterPartiesWithTankDupes; + default: + return false; + } } + // MC Log Search: + public static LocalDate calculateStartDate() { + try { + // date format: yyyy-mm-dd + return LocalDate.parse(defaultStartDate); + } catch (DateTimeParseException e) { + // fallthrough + } + try { + int months = Integer.parseInt(defaultStartDate); + return LocalDate.now().minus(months, ChronoUnit.MONTHS); + } catch (NumberFormatException e) { + // default: 1 month + return LocalDate.now().minus(1, ChronoUnit.MONTHS); + } + } + + // other stuff + public static List getConfigCategories() { + return configCategories; + } + + public Property getTabCompletableNamesCommandsProperty() { + return propTabCompletableNamesCommands; + } + + public List getLogSearchProperties() { + return logSearchProperties; + } + + public class ConfigEventHandler { @SubscribeEvent(priority = EventPriority.NORMAL) public void onEvent(ConfigChangedEvent.OnConfigChangedEvent e) { @@ -358,4 +642,32 @@ public class MooConfig { } } } + + public enum Setting { + UNKNOWN, DISABLED, // + ALWAYS, TOOLTIP, TEXT, // + SPECIAL; + + public static Setting get(String configValue) { + switch (configValue) { + case "always": + return ALWAYS; + case "as a tooltip": + case "as tooltip ②§f⬛": + return TOOLTIP; + case "in chat": + case "as text": + return TEXT; + case "hidden": + case "never": + case "disabled": + return DISABLED; + case "key press": + case "as tooltip ①§0⬛": + return SPECIAL; + default: + return UNKNOWN; + } + } + } } -- cgit