diff options
| author | Cow <cow@volloeko.de> | 2021-07-01 21:41:59 +0200 |
|---|---|---|
| committer | Cow <cow@volloeko.de> | 2021-07-01 21:41:59 +0200 |
| commit | 581e0bc3e52d99d73cfeeffcaec64fd3da31cbc0 (patch) | |
| tree | 905f8e57a9f04b381c5cc8fa14112b62bec0d86e | |
| parent | fa965e448033d817667760f84ca73cf9bab2519b (diff) | |
| download | Cowlection-581e0bc3e52d99d73cfeeffcaec64fd3da31cbc0.tar.gz Cowlection-581e0bc3e52d99d73cfeeffcaec64fd3da31cbc0.tar.bz2 Cowlection-581e0bc3e52d99d73cfeeffcaec64fd3da31cbc0.zip | |
Added more config options to existing features
- Bazaar: order 'Sell Inventory/Sacks Now' tooltips asc/desc
- MC Log file search: maximum file size to analyze
- Toggle: dungeon performance summary at end of dungeon
- Toggle: warn when queued and entered dungeon floors are different
- Toggle: shorten item quality info for non-randomized items
13 files changed, 208 insertions, 62 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index f92cebf..912123e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,10 +16,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - *reminder:* <kbd>CTRL</kbd> + <kbd>C</kbd> (without <kbd>SHIFT</kbd>) copies the whole inventory - New config options: - Output of `/moo waila` and copied inventory data can now also be saved to files, instead of being copied to clipboard + - Bazaar: order 'Sell Inventory/Sacks Now' tooltips ascending or descending + - MC Log file search (`/moo search`): maximum log file size to analyze + - Toggle: display dungeon performance summary at the end of a dungeon + - Toggle: send warning when queued and entered dungeon floors are different + - Toggle: shorten item quality info for non-randomized items ### Changed - Disabled `M` keybinding in MC Options > Controls > Cowlection by default to avoid conflicts - `/moo config` sub-category explanations now default to "tooltip *without* darkened background", as the darkened background was more irritating than helpful +- MC Log file search now skips large files to prevent huge log files from blocking the search ### Fixed - 'Show Dungeon item base stats' feature now works with HPB'd items and master stars @@ -11,7 +11,7 @@ It is a collection of different features mainly focused on Hypixel SkyBlock. ๐ | Feature | Command/Usage | |-------------------------------------------------------------------------|-----------------------------------------| | 'Best friends' list to limit the amount of join and leave notifications (always up-to-date names even after player name changes). Also checks best friends' online status automatically | `/moo add/remove/list/online` | -| Search through your Minecraft log files (click the `?` for more info) | `/moo search` | +| Search through your Minecraft log files | `/moo search` (click the `?` for more info) | | Stalk a player (check online status, current game, ...) | `/moo stalk` | | Toggle join/leave notifications for friends, guild members or best friends separately | `/moo config` → Notifications | | Copy chat component | <kbd>ALT</kbd> + <kbd>right click</kbd><br>Hold <kbd>shift</kbd> to copy full component | diff --git a/src/main/java/de/cowtipper/cowlection/Cowlection.java b/src/main/java/de/cowtipper/cowlection/Cowlection.java index 2d7a988..3709172 100644 --- a/src/main/java/de/cowtipper/cowlection/Cowlection.java +++ b/src/main/java/de/cowtipper/cowlection/Cowlection.java @@ -14,6 +14,7 @@ import de.cowtipper.cowlection.listener.ChatListener; import de.cowtipper.cowlection.listener.PlayerListener; import de.cowtipper.cowlection.util.ChatHelper; import de.cowtipper.cowlection.util.VersionChecker; +import net.minecraft.client.Minecraft; import net.minecraft.client.settings.KeyBinding; import net.minecraftforge.client.ClientCommandHandler; import net.minecraftforge.common.MinecraftForge; @@ -39,8 +40,8 @@ public class Cowlection { public static final String GITURL = "@GITURL@"; public static KeyBinding[] keyBindings; private static Cowlection instance; - private File configDir; private File modsDir; + private File modOutDir; private MooConfig config; private CredentialStorage moo; private FriendsHandler friendsHandler; @@ -59,7 +60,7 @@ public class Cowlection { chatHelper = new ChatHelper(); - this.configDir = new File(e.getModConfigurationDirectory(), MODID + File.separatorChar); + File configDir = new File(e.getModConfigurationDirectory(), MODID + File.separatorChar); if (!configDir.exists()) { configDir.mkdirs(); } @@ -93,6 +94,7 @@ public class Cowlection { public void postInit(FMLPostInitializationEvent e) { versionChecker = new VersionChecker(this); playerCache = new PlayerCache(); + modOutDir = new File(Minecraft.getMinecraft().mcDataDir, Cowlection.MODID.toLowerCase() + "_out"); } public MooConfig getConfig() { @@ -147,14 +149,18 @@ public class Cowlection { return chestTracker; } - public File getConfigDirectory() { - return configDir; - } - public File getModsDirectory() { return modsDir; } + public File getModOutDirectory() { + if (!modOutDir.exists() && !modOutDir.mkdirs()) { + // dir didn't exist and couldn't be created + return null; + } + return modOutDir; + } + public Logger getLogger() { return logger; } diff --git a/src/main/java/de/cowtipper/cowlection/command/MooCommand.java b/src/main/java/de/cowtipper/cowlection/command/MooCommand.java index 2849666..8bab5ee 100644 --- a/src/main/java/de/cowtipper/cowlection/command/MooCommand.java +++ b/src/main/java/de/cowtipper/cowlection/command/MooCommand.java @@ -14,7 +14,6 @@ import de.cowtipper.cowlection.config.gui.MooConfigGui; import de.cowtipper.cowlection.data.*; import de.cowtipper.cowlection.data.HySkyBlockStats.Profile.Pet; import de.cowtipper.cowlection.handler.DungeonCache; -import de.cowtipper.cowlection.listener.skyblock.DungeonsListener; import de.cowtipper.cowlection.listener.skyblock.DungeonsPartyListener; import de.cowtipper.cowlection.search.GuiSearch; import de.cowtipper.cowlection.util.*; @@ -139,7 +138,7 @@ public class MooCommand extends CommandBase { main.getConfig().theyOpenedTheConfigGui(); displayGuiScreen(new MooConfigGui(buildString(args, 1))); } else if (args[0].equalsIgnoreCase("search")) { - displayGuiScreen(new GuiSearch(main.getConfigDirectory(), CommandBase.buildString(args, 1))); + displayGuiScreen(new GuiSearch(CommandBase.buildString(args, 1))); } else if (args[0].equalsIgnoreCase("guiscale")) { handleGuiScale(args); } else if (args[0].equalsIgnoreCase("rr")) { diff --git a/src/main/java/de/cowtipper/cowlection/config/MooConfig.java b/src/main/java/de/cowtipper/cowlection/config/MooConfig.java index ea980d0..f636559 100644 --- a/src/main/java/de/cowtipper/cowlection/config/MooConfig.java +++ b/src/main/java/de/cowtipper/cowlection/config/MooConfig.java @@ -60,6 +60,7 @@ public class MooConfig { private static final String CATEGORY_LOGS_SEARCH = "logssearch"; public static String[] logsDirs; private static String defaultStartDate; + private static int maxLogFileSize; // Category: Notifications public static boolean doUpdateCheck; public static boolean showBestFriendNotifications; @@ -85,6 +86,7 @@ public class MooConfig { public static String[] tooltipAuctionHousePriceEachEnchantments; private static String auctionHouseMarkEndedAuctions; public static String bazaarSellAllOrder; + public static String bazaarSellAllOrderAscDesc; private static String bazaarConnectGraphsNodes; public static int bazaarConnectGraphsLineWidth; public static String bestiaryOverviewOrder; @@ -95,9 +97,11 @@ public class MooConfig { // Category: SkyBlock Dungeons private static String showItemQualityAndFloor; private static String dungItemQualityPos; + public static boolean dungItemQualityShortenNonRandomized; public static boolean dungItemHideGearScore; public static int dungItemToolTipToggleKeyBinding; public static boolean dungSendPerformanceOnDeath; + public static boolean dungSendPerformanceOnEndScreen; public static boolean dungOverlayEnabled; public static int dungOverlayPositionX; public static int dungOverlayPositionY; @@ -117,6 +121,7 @@ public class MooConfig { private static String dungMarkPartiesWithHealer; private static String dungMarkPartiesWithMage; private static String dungMarkPartiesWithTank; + public static boolean dungSendWrongFloorWarning; private static Configuration cfg = null; private static final List<MooConfigCategory> configCategories = new ArrayList<>(); @@ -310,9 +315,12 @@ public class MooConfig { 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]))$")); + Property propMaxLogFileSize = subCat.addConfigEntry(cfg.get(CATEGORY_LOGS_SEARCH, + "maxLogFileSize", 2048, "Max log file size (in KB)?", 50, 10000)); logSearchProperties = new ArrayList<>(); logSearchProperties.add(propLogsDirs); logSearchProperties.add(propDefaultStartDate); + logSearchProperties.add(propMaxLogFileSize); // Category: Notifications configCat = new MooConfigCategory("Notifications", "notifications"); @@ -443,6 +451,9 @@ public class MooConfig { "bazaarSellAllOrder", "price (sum)", "Bazaar: sell all order", new String[]{"price (sum)", "item amount", "unordered", "price (each)"}), new MooConfigPreview(MooConfigPreview.createDemoItem("chest", "ยงaSell Inventory Now", new String[]{"ยง7Instantly sell anything in", "ยง7your inventory that can be", "ยง7sold on the Bazaar.", "", " ยงa1ยง7x ยงaEnchanted Leather ยง7for ยง65,263.1 coins", " ยงa42ยง7x ยงfLeather ยง7for ยง6436.8 coins", " ยงa2ยง7x ยงfRabbit Hide ยง7for ยง642.0 coins", " ยงa79ยง7x ยงfRaw Beef ยง7for ยง6450.3 coins", " ยงa16ยง7x ยงaEnchanted Raw Beef ยง7for ยง69,867.2 coins", "", "ยง7You earn: ยง615,698 coins", "", "ยงeClick to sell!"}, Collections.emptyMap()))); + Property propBazaarSellAllOrderAscDesc = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "bazaarSellAllOrderAscDesc", "low โ high", "Bazaar: sell all order asc/desc", new String[]{"low โ high", "high โ low"})); + MooConfigPreview bazaarGraphPreview = new MooConfigPreview(MooConfigPreview.createDemoItem("paper", "ยงaBuy Price ยง731d ยง77d ยงe24h", new String[]{ "ยง7The price at which buy orders have been filled.", "", "ยงrโ----------------------------------------------โ", "ยงrโยง66. 1kยงr+ยงbxxxxxxยง8ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยงbxxยงrโ", @@ -506,6 +517,9 @@ public class MooConfig { 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"))); + Property propDungItemQualityShortenNonRandomized = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungItemQualityShortenNonRandomized", false, "Shorten item quality for non-randomized items?")); + Property propDungItemHideGearScore = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), "dungItemHideGearScore", false, "Hide Gear Score?")); @@ -523,6 +537,9 @@ public class MooConfig { Property propDungSendPerformanceOnDeath = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), "dungSendPerformanceOnDeath", true, "Send dungeon performance after a player died?")); + Property propDungSendPerformanceOnEndScreen = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungSendPerformanceOnEndScreen", true, "Send dungeon performance on end screen?")); + Property propDungOverlayEnabled = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), "dungOverlayEnabled", true, "Enable Dungeon performance overlay?")); @@ -624,6 +641,9 @@ public class MooConfig { "dungMarkPartiesWithTank", "do not mark", "Mark parties with Tank class?", new String[]{"always", "if duplicated", "do not mark"}), new MooConfigPreview(DataHelper.DungeonClass.TANK)); + Property propDungSendWrongFloorWarning = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "dungSendWrongFloorWarning", true, "Send warning when entering wrong floor?")); + boolean modifiedMooCmdAlias = false; String mooCmdAliasPreChange = mooCmdAlias; boolean modifiedTabCompletableCommandsList = false; @@ -642,6 +662,7 @@ public class MooConfig { tabCompletableNamesCommands = propTabCompletableNamesCommands.getStringList(); logsDirs = propLogsDirs.getStringList(); defaultStartDate = propDefaultStartDate.getString().trim(); + maxLogFileSize = propMaxLogFileSize.getInt(); // Category: Notifications doUpdateCheck = propDoUpdateCheck.getBoolean(); showBestFriendNotifications = propShowBestFriendNotifications.getBoolean(); @@ -667,6 +688,7 @@ public class MooConfig { tooltipAuctionHousePriceEachEnchantments = propTooltipAuctionHousePriceEachEnchantments.getStringList(); auctionHouseMarkEndedAuctions = propAuctionHouseMarkEndedAuctions.getString(); bazaarSellAllOrder = propBazaarSellAllOrder.getString(); + bazaarSellAllOrderAscDesc = propBazaarSellAllOrderAscDesc.getString(); bazaarConnectGraphsNodes = propBazaarConnectGraphsNodes.getString(); bazaarConnectGraphsLineWidth = propBazaarConnectGraphsLineWidth.getInt(); bestiaryOverviewOrder = propBestiaryOverviewOrder.getString(); @@ -676,9 +698,11 @@ public class MooConfig { // Category: SkyBlock Dungeons showItemQualityAndFloor = propShowItemQualityAndFloor.getString(); dungItemQualityPos = propDungItemQualityPos.getString(); + dungItemQualityShortenNonRandomized = propDungItemQualityShortenNonRandomized.getBoolean(); dungItemHideGearScore = propDungItemHideGearScore.getBoolean(); dungItemToolTipToggleKeyBinding = propDungItemToolTipToggleKeyBinding.getInt(); dungSendPerformanceOnDeath = propDungSendPerformanceOnDeath.getBoolean(); + dungSendPerformanceOnEndScreen = propDungSendPerformanceOnEndScreen.getBoolean(); dungOverlayEnabled = propDungOverlayEnabled.getBoolean(); dungOverlayPositionX = propDungOverlayPositionX.getInt(); dungOverlayPositionY = propDungOverlayPositionY.getInt(); @@ -698,6 +722,7 @@ public class MooConfig { dungMarkPartiesWithHealer = propDungMarkPartiesWithHealer.getString(); dungMarkPartiesWithMage = propDungMarkPartiesWithMage.getString(); dungMarkPartiesWithTank = propDungMarkPartiesWithTank.getString(); + dungSendWrongFloorWarning = propDungSendWrongFloorWarning.getBoolean(); if (!hasOpenedConfigGui && (!propDungOverlayEnabled.isDefault() || !propDungOverlayPositionX.isDefault() || !propDungOverlayPositionY.isDefault() || !propDungOverlayGuiScale.isDefault())) { // player hasn't opened config gui yet and but already moved the dungeon overlay @@ -725,6 +750,7 @@ public class MooConfig { propTabCompletableNamesCommands.set(tabCompletableNamesCommands); propLogsDirs.set(logsDirs); propDefaultStartDate.set(defaultStartDate); + propMaxLogFileSize.set(maxLogFileSize); // Category: Notifications propDoUpdateCheck.set(doUpdateCheck); propShowBestFriendNotifications.set(showBestFriendNotifications); @@ -750,6 +776,7 @@ public class MooConfig { propTooltipAuctionHousePriceEachEnchantments.set(tooltipAuctionHousePriceEachEnchantments); propAuctionHouseMarkEndedAuctions.set(auctionHouseMarkEndedAuctions); propBazaarSellAllOrder.set(bazaarSellAllOrder); + propBazaarSellAllOrderAscDesc.set(bazaarSellAllOrderAscDesc); propBazaarConnectGraphsNodes.set(bazaarConnectGraphsNodes); propBazaarConnectGraphsLineWidth.set(bazaarConnectGraphsLineWidth); propBestiaryOverviewOrder.set(bestiaryOverviewOrder); @@ -759,9 +786,11 @@ public class MooConfig { // Category: SkyBlock Dungeons propShowItemQualityAndFloor.set(showItemQualityAndFloor); propDungItemQualityPos.set(dungItemQualityPos); + propDungItemQualityShortenNonRandomized.set(dungItemQualityShortenNonRandomized); propDungItemHideGearScore.set(dungItemHideGearScore); propDungItemToolTipToggleKeyBinding.set(dungItemToolTipToggleKeyBinding); propDungSendPerformanceOnDeath.set(dungSendPerformanceOnDeath); + propDungSendPerformanceOnEndScreen.set(dungSendPerformanceOnEndScreen); propDungOverlayEnabled.set(dungOverlayEnabled); propDungOverlayPositionX.set(dungOverlayPositionX); propDungOverlayPositionY.set(dungOverlayPositionY); @@ -781,6 +810,7 @@ public class MooConfig { propDungMarkPartiesWithHealer.set(dungMarkPartiesWithHealer); propDungMarkPartiesWithMage.set(dungMarkPartiesWithMage); propDungMarkPartiesWithTank.set(dungMarkPartiesWithTank); + propDungSendWrongFloorWarning.set(dungSendWrongFloorWarning); if (saveToFile && cfg.hasChanged()) { boolean isPlayerIngame = Minecraft.getMinecraft().thePlayer != null; @@ -870,6 +900,13 @@ public class MooConfig { return logsDirs.toArray(new String[]{}); } + /** + * @return max log file size in Bytes + */ + public static long getMaxLogFileSize() { + return maxLogFileSize * 1024L; + } + // Category: General public static Setting getConfigGuiExplanationsDisplay() { return Setting.get(configGuiExplanations); diff --git a/src/main/java/de/cowtipper/cowlection/config/gui/MooConfigCategoryScrolling.java b/src/main/java/de/cowtipper/cowlection/config/gui/MooConfigCategoryScrolling.java index dedf163..a3b28e6 100644 --- a/src/main/java/de/cowtipper/cowlection/config/gui/MooConfigCategoryScrolling.java +++ b/src/main/java/de/cowtipper/cowlection/config/gui/MooConfigCategoryScrolling.java @@ -89,7 +89,7 @@ public class MooConfigCategoryScrolling extends GuiListExtended { // add control buttons to navigate to other guis if ("Other settings".equals(subCategory.getDisplayName())) { this.listEntries.add(new GuiSwitchEntry("gotoKeyBindings", "Controls", () -> mc.displayGuiScreen(new GuiControls(MooConfigCategoryScrolling.this.parent, mc.gameSettings)))); - this.listEntries.add(new GuiSwitchEntry("gotoLogSearchConfig", "Log Search", () -> mc.displayGuiScreen(new GuiSearch(Cowlection.getInstance().getConfigDirectory(), "")))); + this.listEntries.add(new GuiSwitchEntry("gotoLogSearchConfig", "Log Search", () -> mc.displayGuiScreen(new GuiSearch("")))); continue; // don't add properties to main config gui } @@ -215,7 +215,7 @@ public class MooConfigCategoryScrolling extends GuiListExtended { if (labelWidth > this.maxListLabelWidth) { this.maxListLabelWidth = labelWidth; } - this.listEntries.add(new GuiSwitchEntry("gotoLogSearchConfig", "Log Search", () -> mc.displayGuiScreen(new GuiSearch(Cowlection.getInstance().getConfigDirectory(), "")))); + this.listEntries.add(new GuiSwitchEntry("gotoLogSearchConfig", "Log Search", () -> mc.displayGuiScreen(new GuiSearch("")))); hasLogSearchBeenAdded = true; } else if (hasLogSearchBeenAdded) { // already added the replacement-entry, thus don't increase entry counter diff --git a/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java b/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java index 9ae5d7e..009d694 100644 --- a/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java +++ b/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java @@ -31,7 +31,8 @@ import net.minecraftforge.client.event.GuiScreenEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.common.util.Constants; import net.minecraftforge.event.entity.player.ItemTooltipEvent; -import net.minecraftforge.fml.common.eventhandler.*; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraftforge.fml.relauncher.Side; import org.lwjgl.input.Mouse; @@ -160,7 +161,11 @@ public class DungeonsListener { hasCustomGearScore = true; } if (!hasCustomGearScore) { - customGearScore.append(EnumChatFormatting.LIGHT_PURPLE).append("100%").append(EnumChatFormatting.DARK_GRAY).append(" (never has randomized stats)"); + if (MooConfig.dungItemQualityShortenNonRandomized) { + customGearScore.append(EnumChatFormatting.DARK_PURPLE).append("100%"); + } else { + customGearScore.append(EnumChatFormatting.LIGHT_PURPLE).append("100%").append(EnumChatFormatting.DARK_GRAY).append(" (never has randomized stats)"); + } } if (showItemQualityAndFloor) { if (MooConfig.isDungItemQualityAtTop()) { @@ -470,23 +475,23 @@ public class DungeonsListener { if (text.startsWith("[NPC] Mort: ")) { // Mort said something, probably entered dungeons main.getDungeonCache().onDungeonEnterOrLeave(true); - return; - } - Matcher dungeonEnteredMatcher = DUNGEON_ENTERED_DUNGEON.matcher(text); - if (dungeonEnteredMatcher.matches()) { - String floor = dungeonEnteredMatcher.group(1) != null ? "Entrance" : dungeonEnteredMatcher.group(2); - if (floor == null) { - // this shouldn't ever happen: neither a floor nor the entrance was entered - return; - } - String queuedFloor = main.getDungeonCache().getQueuedFloor(); - if (queuedFloor != null && !queuedFloor.equals(floor)) { - // queued and entered dungeon floors are different! - new TickDelay(() -> { - String attentionSeeker = "" + EnumChatFormatting.LIGHT_PURPLE + EnumChatFormatting.OBFUSCATED + "#"; - main.getChatHelper().sendMessage(EnumChatFormatting.RED, attentionSeeker + EnumChatFormatting.RED + " You entered dungeon floor " + EnumChatFormatting.DARK_RED + floor + EnumChatFormatting.RED + " but originally queued for floor " + EnumChatFormatting.DARK_RED + queuedFloor + " " + attentionSeeker); - Minecraft.getMinecraft().thePlayer.playSound("mob.cow.hurt", Minecraft.getMinecraft().gameSettings.getSoundLevel(SoundCategory.MASTER), 1); - }, 100); + } else if (MooConfig.dungSendWrongFloorWarning) { + Matcher dungeonEnteredMatcher = DUNGEON_ENTERED_DUNGEON.matcher(text); + if (dungeonEnteredMatcher.matches()) { + String floor = dungeonEnteredMatcher.group(1) != null ? "Entrance" : dungeonEnteredMatcher.group(2); + if (floor == null) { + // this shouldn't ever happen: neither a floor nor the entrance was entered + return; + } + String queuedFloor = main.getDungeonCache().getQueuedFloor(); + if (queuedFloor != null && !queuedFloor.equals(floor)) { + // queued and entered dungeon floors are different! + new TickDelay(() -> { + String attentionSeeker = "" + EnumChatFormatting.LIGHT_PURPLE + EnumChatFormatting.OBFUSCATED + "#"; + main.getChatHelper().sendMessage(EnumChatFormatting.RED, attentionSeeker + EnumChatFormatting.RED + " You entered dungeon floor " + EnumChatFormatting.DARK_RED + floor + EnumChatFormatting.RED + " but originally queued for floor " + EnumChatFormatting.DARK_RED + queuedFloor + " " + attentionSeeker); + Minecraft.getMinecraft().thePlayer.playSound("mob.cow.hurt", Minecraft.getMinecraft().gameSettings.getSoundLevel(SoundCategory.MASTER), 1); + }, 100); + } } } return; @@ -504,7 +509,9 @@ public class DungeonsListener { main.getDungeonCache().revivedPlayer(dungeonRevivedMatcher.group(1)); } else if (text.trim().equals("> EXTRA STATS <")) { // dungeon "end screen" - new TickDelay(() -> main.getDungeonCache().sendDungeonPerformance(), 5); + if (MooConfig.dungSendPerformanceOnEndScreen) { + new TickDelay(() -> main.getDungeonCache().sendDungeonPerformance(), 5); + } } else if (text.startsWith("PUZZLE FAIL!")) { // Skill: failed puzzle main.getDungeonCache().addFailedPuzzle(text); diff --git a/src/main/java/de/cowtipper/cowlection/listener/skyblock/SkyBlockListener.java b/src/main/java/de/cowtipper/cowlection/listener/skyblock/SkyBlockListener.java index a28905c..432489b 100644 --- a/src/main/java/de/cowtipper/cowlection/listener/skyblock/SkyBlockListener.java +++ b/src/main/java/de/cowtipper/cowlection/listener/skyblock/SkyBlockListener.java @@ -421,7 +421,11 @@ public class SkyBlockListener { numberFormatter.setMaximumFractionDigits(1); List<String> toolTip = e.toolTip; int startIndex = 1337; - TreeMultimap<Double, String> sellEntries = TreeMultimap.create(Ordering.natural().reverse(), Ordering.natural()); + Ordering<Double> tooltipOrdering = Ordering.natural(); + if("high โ low".equals(MooConfig.bazaarSellAllOrderAscDesc)) { + tooltipOrdering = tooltipOrdering.reverse(); + } + TreeMultimap<Double, String> sellEntries = TreeMultimap.create(tooltipOrdering, Ordering.natural()); for (int i = 0; i < toolTip.size(); i++) { Matcher bazaarSellMatcher = BAZAAR_SELL_ALL_PATTERN.matcher(toolTip.get(i)); if (bazaarSellMatcher.matches()) { diff --git a/src/main/java/de/cowtipper/cowlection/search/GuiSearch.java b/src/main/java/de/cowtipper/cowlection/search/GuiSearch.java index 21059ca..7e721a9 100644 --- a/src/main/java/de/cowtipper/cowlection/search/GuiSearch.java +++ b/src/main/java/de/cowtipper/cowlection/search/GuiSearch.java @@ -23,7 +23,6 @@ import net.minecraftforge.fml.client.config.IConfigElement; import net.minecraftforge.fml.relauncher.ReflectionHelper; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; -import org.apache.commons.lang3.tuple.ImmutableTriple; import org.lwjgl.input.Keyboard; import java.awt.*; @@ -79,10 +78,11 @@ public class GuiSearch extends GuiScreen { private boolean isSearchInProgress; private String analyzedFiles; private String analyzedFilesWithHits; + private String skippedFiles; private boolean areEntriesSearchResults; - public GuiSearch(File configDirectory, String initialSearchQuery) { - this.mcLogOutputFile = new File(configDirectory, "mc-log.txt"); + public GuiSearch(String initialSearchQuery) { + this.mcLogOutputFile = new File(Cowlection.getInstance().getModOutDirectory(), "cowlection-mc-log-search-temp.txt"); try { mcLogOutputFile.createNewFile(); } catch (IOException e) { @@ -287,19 +287,21 @@ public class GuiSearch extends GuiScreen { executorService.execute(() -> { try { - ImmutableTriple<Integer, Integer, List<LogEntry>> searchResultsData = new LogFilesSearcher().searchFor(this.fieldSearchQuery.getText(), checkboxChatOnly.isChecked(), checkboxMatchCase.isChecked(), checkboxRemoveFormatting.isChecked(), dateStart, dateEnd); - this.searchResults = searchResultsData.right; - this.analyzedFiles = "Analyzed files: " + EnumChatFormatting.WHITE + searchResultsData.left; - this.analyzedFilesWithHits = "Files with hits: " + EnumChatFormatting.WHITE + searchResultsData.middle; + LogSearchResults searchResultsData = new LogFilesSearcher().searchFor(this.fieldSearchQuery.getText(), checkboxChatOnly.isChecked(), checkboxMatchCase.isChecked(), checkboxRemoveFormatting.isChecked(), dateStart, dateEnd); + this.searchResults = searchResultsData.getSortedSearchResults(); + this.analyzedFiles = "Analyzed files: " + EnumChatFormatting.WHITE + searchResultsData.getAnalyzedFiles(); + this.analyzedFilesWithHits = "Files with hits: " + EnumChatFormatting.WHITE + searchResultsData.getAnalyzedFilesWithHits(); + this.skippedFiles = "Skipped files: " + EnumChatFormatting.WHITE + searchResultsData.getSkippedFiles(); if (this.searchResults.isEmpty()) { this.searchResults.add(new LogEntry(EnumChatFormatting.ITALIC + "No results")); areEntriesSearchResults = false; } else { - areEntriesSearchResults = true; + areEntriesSearchResults = searchResultsData.getAnalyzedFiles() != 0; } } catch (IOException e) { if (e.getStackTrace().length > 0) { searchResults.add(new LogEntry(StringUtils.replaceEach(ExceptionUtils.getStackTrace(e), new String[]{"\t", "\r\n"}, new String[]{" ", "\n"}))); + areEntriesSearchResults = false; } } Minecraft.getMinecraft().addScheduledTask(() -> { @@ -319,6 +321,9 @@ public class GuiSearch extends GuiScreen { this.searchResults.add(new LogEntry("" + EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + "Initial setup/configuration " + EnumChatFormatting.GRAY + EnumChatFormatting.ITALIC + "'Open Settings' (top right corner)")); this.searchResults.add(new LogEntry(EnumChatFormatting.GOLD + " 1) " + EnumChatFormatting.RESET + "Configure directories that should be scanned for log files (\"Directories with Minecraft log files\")")); this.searchResults.add(new LogEntry(EnumChatFormatting.GOLD + " 2) " + EnumChatFormatting.RESET + "Set default starting date (\"Start date for log file search\")")); + this.searchResults.add(new LogEntry(" โฃ can be a number (e.g. \"3\" means \"start searching 3 months ago\")")); + this.searchResults.add(new LogEntry(" โฃ or alternatively a fixed date (yyyy-mm-dd)")); + this.searchResults.add(new LogEntry(EnumChatFormatting.GOLD + " 3) " + EnumChatFormatting.RESET + "optional: change the maximum allowed log file size to be searched, but note that each log file must be unzipped before it can be analyzed, which can make the log file search take significantly longer for large files")); this.searchResults.add(new LogEntry("" + EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + "Performing a search " + EnumChatFormatting.GRAY + EnumChatFormatting.ITALIC + "/moo search [initial search term]")); this.searchResults.add(new LogEntry(EnumChatFormatting.GOLD + " 1) " + EnumChatFormatting.RESET + "Enter search term")); this.searchResults.add(new LogEntry(EnumChatFormatting.GOLD + " 2) " + EnumChatFormatting.RESET + "Adjust start and end date")); @@ -360,6 +365,7 @@ public class GuiSearch extends GuiScreen { guiSearchResults.clearResults(); analyzedFiles = null; analyzedFilesWithHits = null; + skippedFiles = null; } else { buttonSearch.displayString = "Search"; } @@ -441,13 +447,16 @@ public class GuiSearch extends GuiScreen { } } else if (areEntriesSearchResults) { if (analyzedFiles != null) { - drawString(fontRendererObj, analyzedFiles, 8, 22, 0xff888888); + drawString(fontRendererObj, analyzedFiles, 8, 15, 0xff888888); } if (analyzedFilesWithHits != null) { - drawString(fontRendererObj, analyzedFilesWithHits, 8, 32, 0xff888888); + drawString(fontRendererObj, analyzedFilesWithHits, 8, 25, 0xff888888); + } + if (skippedFiles != null) { + drawString(fontRendererObj, skippedFiles, 8, 35, 0xff888888); } if (resultsCount != null) { - drawString(fontRendererObj, resultsCount, 8, 48, 0xff888888); + drawString(fontRendererObj, resultsCount, 8, 50, 0xff888888); } } if (errorMessage != null) { diff --git a/src/main/java/de/cowtipper/cowlection/search/LogFilesSearcher.java b/src/main/java/de/cowtipper/cowlection/search/LogFilesSearcher.java index c6b647e..bbfd0fb 100644 --- a/src/main/java/de/cowtipper/cowlection/search/LogFilesSearcher.java +++ b/src/main/java/de/cowtipper/cowlection/search/LogFilesSearcher.java @@ -2,18 +2,15 @@ package de.cowtipper.cowlection.search; import de.cowtipper.cowlection.config.MooConfig; import net.minecraft.util.EnumChatFormatting; +import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.ImmutableTriple; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.time.*; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -32,9 +29,9 @@ class LogFilesSearcher { private static final Pattern LOG4J_PATTERN = Pattern.compile("^\\[(?<timeHours>[\\d]{2}):(?<timeMinutes>[\\d]{2}):(?<timeSeconds>[\\d]{2})] \\[(?<thread>[^/]+)/(?<logLevel>[A-Z]+)]:(?<isChat> \\[CHAT])? (?<message>.*)$"); private int analyzedFilesWithHits = 0; - ImmutableTriple<Integer, Integer, List<LogEntry>> searchFor(String searchQuery, boolean chatOnly, boolean matchCase, boolean removeFormatting, LocalDate dateStart, LocalDate dateEnd) throws IOException { - AtomicInteger foundLogs = new AtomicInteger(); - List<LogEntry> searchResults = Collections.synchronizedList(new ArrayList<>()); + LogSearchResults searchFor(String searchQuery, boolean chatOnly, boolean matchCase, boolean removeFormatting, LocalDate dateStart, LocalDate dateEnd) throws IOException { + LogSearchResults logSearchResults = new LogSearchResults(); + long fileSizeLimit = MooConfig.getMaxLogFileSize(); for (String logsDirPath : MooConfig.logsDirs) { File logsDir = new File(logsDirPath); if (!logsDir.exists() || !logsDir.isDirectory()) { @@ -55,15 +52,25 @@ class LogFilesSearcher { LocalDate fileLocalDate = LocalDate.of(Integer.parseInt(fileNameMatcher.group(1)), Integer.parseInt(fileNameMatcher.group(2)), Integer.parseInt(fileNameMatcher.group(3))); if (!fileLocalDate.isBefore(dateStart) && !fileLocalDate.isAfter(dateEnd)) { - foundLogs.incrementAndGet(); - searchResults.addAll(analyzeFile(path, true, fileLocalDate, searchQuery, chatOnly, matchCase, removeFormatting)); + if (path.toFile().length() > fileSizeLimit) { + // file too large + logSearchResults.addSkippedFile(); + } else { |
