From f43e45e79d91e15e787545efb8421814318ba2b6 Mon Sep 17 00:00:00 2001 From: "Erymanthus[#5074] | (u/)RayDeeUx" <51521765+RayDeeUx@users.noreply.github.com> Date: Fri, 10 Nov 2023 22:19:38 -0500 Subject: Fixes: Countdown Calculator Improvements (#923) --- .../miscfeatures/CountdownCalculator.kt | 110 -------------------- .../miscfeatures/WardrobeMouseButtons.kt | 108 -------------------- .../notenoughupdates/miscgui/CalendarOverlay.java | 57 +++++++---- .../miscfeatures/CountdownCalculator.kt | 111 +++++++++++++++++++++ .../miscfeatures/WardrobeMouseButtons.kt | 108 ++++++++++++++++++++ 5 files changed, 257 insertions(+), 237 deletions(-) delete mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CountdownCalculator.kt delete mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt create mode 100644 src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/CountdownCalculator.kt create mode 100644 src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CountdownCalculator.kt b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CountdownCalculator.kt deleted file mode 100644 index 11c6b721..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CountdownCalculator.kt +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2022-2023 NotEnoughUpdates contributors - * - * This file is part of NotEnoughUpdates. - * - * NotEnoughUpdates is free software: you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation, either - * version 3 of the License, or (at your option) any later version. - * - * NotEnoughUpdates is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with NotEnoughUpdates. If not, see . - */ -package io.github.moulberry.notenoughupdates.miscfeatures - -import io.github.moulberry.notenoughupdates.NotEnoughUpdates -import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe -import net.minecraft.client.Minecraft -import net.minecraftforge.event.entity.player.ItemTooltipEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import java.time.ZonedDateTime -import java.time.format.DateTimeFormatter - -/* - * CountdownCalculator.kt - * A Kotlin class by: - * — Erymanthus / RayDeeUx (code base, math, timestamp wrangling, adaptation into overall NEU codebase) - * — nea89 (enum, regex wrangling, ItemTooltipEvent integration, cleanup) - * - * Intended to detect countdowns within item tooltips, converting the time remaining into - * units of seconds, and then adding that result to the user's current system time - * in Unix epoch form converted into a human readable timestamp, timezones included. - * - * Formerly a feature from SkyBlockCatia, then later attempted to be ported into Skytils. - * Now has a comfy home in the NotEnoughUpdates codebase. - */ - -@NEUAutoSubscribe -class CountdownCalculator { - - val regex = - "(?:(?\\d+)d)? ?(?:(?\\d+)h)? ?(?:(?\\d+)m)? ?(?:(?\\d+)s)?\\b".toRegex() - val formatter12h = DateTimeFormatter.ofPattern("EEEE, MMM d h:mm a")!! - val formatter24h = DateTimeFormatter.ofPattern("EEEE, MMM d HH:mm")!! - - @Suppress("unused") - private enum class CountdownTypes( - val match: String, - val label: String, - val isRelative: Boolean = false, - ) { - STARTING("Starting in:", "Starts at"), - STARTS("Starts in:", "Starts at"), - INTEREST("Interest in:", "Interest at"), - UNTILINTEREST("Until interest:", "Interest at"), - ENDS("Ends in:", "Ends at"), - REMAINING("Remaining:", "Ends at"), - DURATION("Duration:", "Finishes at"), - TIMELEFT("Time left:", "Ends at"), - EVENTTIMELEFT("Event lasts for", "Ends at", isRelative = true), - SHENSUCKS("Auction ends in:", "Auction ends at"), - CALENDARDETAILS("(§e", "Starts at"); // Calendar details - } - - @SubscribeEvent - fun onTooltip(event: ItemTooltipEvent) { - val useFormatter = when (NotEnoughUpdates.INSTANCE.config.misc.showWhenCountdownEnds) { - 1 -> formatter12h - 2 -> formatter24h - else -> return - } - if (event.itemStack != null && Minecraft.getMinecraft().thePlayer?.openContainer != null) { - var i = -1 - var lastTimer: ZonedDateTime? = null - while (++i < event.toolTip.size) { - val tooltipLine = event.toolTip[i] - val countdownKind = CountdownTypes.values().find { it.match in tooltipLine } ?: continue - val match = regex.findAll(tooltipLine).maxByOrNull { it.value.length } ?: continue - - val days = match.groups["days"]?.value?.toInt() ?: 0 - val hours = match.groups["hours"]?.value?.toInt() ?: 0 - val minutes = match.groups["minutes"]?.value?.toInt() ?: 0 - val seconds = match.groups["seconds"]?.value?.toInt() ?: 0 - val totalSeconds = days * 86400L + hours * 3600L + minutes * 60L + seconds - if (totalSeconds == 0L) continue - val countdownTarget = if (countdownKind.isRelative) { - if (lastTimer == null) { - event.toolTip.add( - ++i, - "§r§cThe above countdown is relative, but I can't find another countdown. [NEU]" - ) - continue - } else lastTimer.plusSeconds(totalSeconds) - } else ZonedDateTime.now().plusSeconds(totalSeconds) - val countdownTargetFormatted = useFormatter.format(countdownTarget) - event.toolTip.add( - ++i, - "§r§b${countdownKind.label}: $countdownTargetFormatted" - ) - lastTimer = countdownTarget - } - } - } - -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt deleted file mode 100644 index ea01eb2e..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2022-2023 NotEnoughUpdates contributors - * - * This file is part of NotEnoughUpdates. - * - * NotEnoughUpdates is free software: you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation, either - * version 3 of the License, or (at your option) any later version. - * - * NotEnoughUpdates is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with NotEnoughUpdates. If not, see . - */ -package io.github.moulberry.notenoughupdates.miscfeatures - -import io.github.moulberry.notenoughupdates.NotEnoughUpdates -import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe -import io.github.moulberry.notenoughupdates.core.config.KeybindHelper -import io.github.moulberry.notenoughupdates.util.Utils -import net.minecraft.client.gui.inventory.GuiChest -import net.minecraft.inventory.ContainerChest -import net.minecraftforge.client.event.GuiScreenEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -@NEUAutoSubscribe -class WardrobeMouseButtons { - - private val keybinds: List get() = listOf( - NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot1, - NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot2, - NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot3, - NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot4, - NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot5, - NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot6, - NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot7, - NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot8, - NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot9, - NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobePageUnequip, - NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobePagePrevious, - NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobePageNext, - ) - private var lastClick = -1L - - @SubscribeEvent - fun onGuiKeyboardInput(event: GuiScreenEvent.KeyboardInputEvent.Pre) { - checkKeybinds(event) - } - - @SubscribeEvent - fun onGuiMouseInput(event: GuiScreenEvent.MouseInputEvent.Pre) { - checkKeybinds(event) - } - - @Suppress("InvalidSubscribeEvent") - private fun checkKeybinds(event: GuiScreenEvent) { - if (!NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.enableWardrobeKeybinds || !NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return - val gui = event.gui as? GuiChest ?: return - if (!Utils.getOpenChestName().contains("Wardrobe")) return - val chestName = Utils.getOpenChestName() - val chestNameRegex = "Wardrobe (\\((?[0-9]+)\\/(?[0-9]+)\\))".toRegex() - val chestNameMatch = chestNameRegex.matchEntire(chestName) - if (chestNameMatch == null) return - val totalPages = chestNameMatch.groups["total"]!!.value.toInt() - val currentPage = chestNameMatch.groups["current"]!!.value.toInt() - val guiChes = event.gui as GuiChest - val container = guiChes.inventorySlots as ContainerChest - var slotNum = 0 - - if ((currentPage != totalPages) && KeybindHelper.isKeyDown(NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobePageNext)) { - slotNum = 53 - } else if ((currentPage != 1) && KeybindHelper.isKeyDown(NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobePagePrevious)) { - slotNum = 45 - } else if (KeybindHelper.isKeyDown(NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobePageUnequip)) { - var notEquipped = 0 - for (j in 36..44) { - val stackItem = container.getSlot(j).getStack() ?: return - if (stackItem.getDisplayName().contains("Equipped")) { - slotNum = j - } - else { - notEquipped++ - } - } - if (notEquipped == 9) return - } else { - for (i in keybinds.indices) { - if (KeybindHelper.isKeyDown(keybinds[i])) { - if (System.currentTimeMillis() - lastClick > 300) { - slotNum = (36 + i) - } - } - } - } - - val thatItemStack = container.getSlot(slotNum).getStack() ?: return - if (thatItemStack.getDisplayName().isEmpty()) return - if (slotNum < 36 || ((slotNum > 45) && (slotNum != 53))) return - Utils.sendLeftMouseClick(gui.inventorySlots.windowId, slotNum) - lastClick = System.currentTimeMillis() - event.isCanceled = true - } - -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java index 4e4b147e..1a50dfe4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java @@ -311,8 +311,8 @@ public class CalendarOverlay { STAR_CULT_STACK, Arrays.asList( "§3The Cult of the Fallen Star meets then.", - "§3Attending may give a reward", - "§3You can find them near the Star in the Dwarven Mines" + "§3Attending may give a reward.", + "§3You can find them near the Star in the Dwarven Mines." ), STAR_CULT_DURATION, true @@ -352,7 +352,6 @@ public class CalendarOverlay { ) ); } - } } @@ -453,42 +452,42 @@ public class CalendarOverlay { addEvent( new SkyBlockTime(thisBaseYear + scorpiusOffset, 3, 27, 0, 0, 0), new SBEvent("special_mayor:scorpius", - "§dScorpius", + "§dScorpius' Candidacy", true, Utils.createSkull( "Scorpius", "ba2cd37d-a0e4-4dc5-b15c-d79ee1051aae", "ewogICJ0aW1lc3RhbXAiIDogMTU5Nzc4MTc1NzIxOSwKICAicHJvZmlsZUlkIiA6ICI0MWQzYWJjMmQ3NDk0MDBjOTA5MGQ1NDM0ZDAzODMxYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJNZWdha2xvb24iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGYyNmZhMGM0NzUzNmU3OGUzMzcyNTdkODk4YWY4YjFlYmM4N2MwODk0NTAzMzc1MjM0MDM1ZmYyYzdlZjhmMCIKICAgIH0KICB9Cn0" ), - Arrays.asList("§eScorpius is a special Mayor candidate"), -1, true + Arrays.asList("§eScorpius becomes a special Mayor candidate"), -1, true ) ); addEvent( new SkyBlockTime(thisBaseYear + derpyOffset, 3, 27, 0, 0, 0), new SBEvent( "special_mayor:derpy", - "§dDerpy", + "§dDerpy's Candidacy", true, Utils.createSkull( "Derpy", "ab36a707-96d3-3db1-ab36-a70796d3adb1", "e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZjQ1MGQxMjY5Mjg4NmM0N2IwNzhhMzhmNGQ0OTJhY2ZlNjEyMTZlMmQwMjM3YWI4MjQzMzQwOWIzMDQ2YjQ2NCJ9fX0" ), - Arrays.asList("§eDerpy is a special Mayor candidate"), -1, true + Arrays.asList("§eDerpy becomes a special Mayor candidate"), -1, true ) ); addEvent( new SkyBlockTime(thisBaseYear + jerryOffset, 3, 27, 0, 0, 0), new SBEvent( "special_mayor:jerry", - "§dJerry", + "§dJerry's Candidacy", true, Utils.createSkull( "Jerry", "0a9e8efb-9191-4c81-80f5-e27ca5433156", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODIyZDhlNzUxYzhmMmZkNGM4OTQyYzQ0YmRiMmY1Y2E0ZDhhZThlNTc1ZWQzZWIzNGMxOGE4NmU5M2IifX19" ), - Arrays.asList("§eJerry is a special Mayor candidate"), -1, true + Arrays.asList("§eJerry becomes a special Mayor candidate"), -1, true ) ); } @@ -734,15 +733,21 @@ public class CalendarOverlay { sbEvent.display, EnumChatFormatting.GRAY + "Starts in: " + EnumChatFormatting.YELLOW + prettyTime(timeUntilMillis, false) ); - addCountdownCalculatorToTooltip(timeUntilMillis, tooltipToDisplay); + if (!(prettyTime(timeUntilMillis, false).equals("Now!"))) { + addCountdownCalculatorToTooltip(timeUntilMillis, tooltipToDisplay); + } if (sbEvent.lastsFor >= 0) { tooltipToDisplay.add(EnumChatFormatting.GRAY + "Lasts for: " + EnumChatFormatting.YELLOW + prettyTime(sbEvent.lastsFor, true)); - addCountdownCalculatorToTooltip(sbEvent.lastsFor + timeUntilMillis, tooltipToDisplay); + if (!(prettyTime(timeUntilMillis, false).equals("Now!"))) { + addCountdownCalculatorToTooltip(sbEvent.lastsFor + timeUntilMillis, tooltipToDisplay); + } if (timeUntilMillis < 0) { tooltipToDisplay.add(EnumChatFormatting.GRAY + "Time left: " + EnumChatFormatting.YELLOW + prettyTime(sbEvent.lastsFor + timeUntilMillis, true)); - addCountdownCalculatorToTooltip(timeUntilMillis, tooltipToDisplay); + if ((prettyTime(timeUntilMillis, false).equals("Now!"))) { + addCountdownCalculatorToTooltip(sbEvent.lastsFor + timeUntilMillis, tooltipToDisplay); + } } } if (sbEvent.desc != null) { @@ -788,7 +793,9 @@ public class CalendarOverlay { if (mouseX >= x && mouseX <= x + 16) { if (mouseY >= y && mouseY <= y + 16) { - tooltipToDisplay = new ArrayList<>(sbEvent.desc); + tooltipToDisplay = new ArrayList<>(); + tooltipToDisplay.add(sbEvent.display); + tooltipToDisplay.addAll(sbEvent.desc); tooltipToDisplay.add(Utils.prettyTime(Duration.between( Instant.now(), Instant.ofEpochMilli(pair.getFirst()) @@ -841,15 +848,21 @@ public class CalendarOverlay { nextEvent.display, EnumChatFormatting.GRAY + "Starts in: " + EnumChatFormatting.YELLOW + prettyTime(timeUntilNext, false) ); - addCountdownCalculatorToTooltip(timeUntilNext, tooltipToDisplay); + if (!(prettyTime(timeUntilNext, false).equals("Now!"))) { + addCountdownCalculatorToTooltip(timeUntilNext, tooltipToDisplay); + } if (nextEvent.lastsFor >= 0) { tooltipToDisplay.add(EnumChatFormatting.GRAY + "Lasts for: " + EnumChatFormatting.YELLOW + prettyTime(nextEvent.lastsFor, true)); - addCountdownCalculatorToTooltip(nextEvent.lastsFor + timeUntilNext, tooltipToDisplay); + if (!(prettyTime(timeUntilNext, false).equals("Now!"))) { + addCountdownCalculatorToTooltip(nextEvent.lastsFor + timeUntilNext, tooltipToDisplay); + } if (timeUntilNext < 0) { tooltipToDisplay.add(EnumChatFormatting.GRAY + "Time left: " + EnumChatFormatting.YELLOW + prettyTime(nextEvent.lastsFor + timeUntilNext, true)); - addCountdownCalculatorToTooltip(nextEvent.lastsFor + timeUntilNext, tooltipToDisplay); + if ((prettyTime(timeUntilNext, false).equals("Now!"))) { + addCountdownCalculatorToTooltip(nextEvent.lastsFor + timeUntilNext, tooltipToDisplay); + } } } @@ -1485,15 +1498,21 @@ public class CalendarOverlay { tooltipToDisplay.add(sbEvent.display); tooltipToDisplay.add( EnumChatFormatting.GRAY + "Starts in: " + EnumChatFormatting.YELLOW + prettyTime(timeUntil, false)); - addCountdownCalculatorToTooltip(timeUntil, tooltipToDisplay); + if (!(prettyTime(timeUntil, false).equals("Now!"))) { + addCountdownCalculatorToTooltip(timeUntil, tooltipToDisplay); + } if (sbEvent.lastsFor >= 0) { tooltipToDisplay.add(EnumChatFormatting.GRAY + "Lasts for: " + EnumChatFormatting.YELLOW + prettyTime(sbEvent.lastsFor, true)); - addCountdownCalculatorToTooltip(sbEvent.lastsFor + timeUntil, tooltipToDisplay); + if (!(prettyTime(timeUntilNext, false).equals("Now!"))) { + addCountdownCalculatorToTooltip(sbEvent.lastsFor + timeUntil, tooltipToDisplay); + } if (timeUntil < 0) { tooltipToDisplay.add(EnumChatFormatting.GRAY + "Time left: " + EnumChatFormatting.YELLOW + prettyTime(sbEvent.lastsFor + timeUntil, true)); - addCountdownCalculatorToTooltip(sbEvent.lastsFor + timeUntil, tooltipToDisplay); + if ((prettyTime(timeUntil, false).equals("Now!"))) { + addCountdownCalculatorToTooltip(sbEvent.lastsFor + timeUntil, tooltipToDisplay); + } } } if (sbEvent.id.split(":")[0].equals("jacob_farming") && sbEvent.desc != null) { diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/CountdownCalculator.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/CountdownCalculator.kt new file mode 100644 index 00000000..068e735b --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/CountdownCalculator.kt @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2022-2023 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ +package io.github.moulberry.notenoughupdates.miscfeatures + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates +import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe +import net.minecraft.client.Minecraft +import net.minecraftforge.event.entity.player.ItemTooltipEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter + +/* + CountdownCalculator.kt + A Kotlin class by: + — Erymanthus / RayDeeUx (code base, math, timestamp wrangling, adaptation into overall NEU codebase) + — nea89 (enum, regex wrangling, ItemTooltipEvent integration, cleanup) + + Intended to detect countdowns within item tooltips, converting the time remaining into + units of seconds, and then adding that result to the user's current system time + in Unix epoch form converted into a human-readable timestamp, timezones included. + + Formerly a feature from SkyBlockCatia, then later attempted to be ported into Skytils. + Now has a comfy home in the NotEnoughUpdates codebase. + */ + +@NEUAutoSubscribe +class CountdownCalculator { + + private val regex = + "(?:(?\\d+)y )?(?:(?\\d+)d)? ?(?:(?\\d+)h)? ?(?:(?\\d+)m)? ?(?:(?\\d+)s)?\\b".toRegex() + + @Suppress("unused") + private enum class CountdownTypes( + val match: String, + val label: String, + val isRelative: Boolean = false, + ) { + STARTING("Starting in:", "Starts at"), + STARTS("Starts in:", "Starts at"), + INTEREST("Interest in:", "Interest at"), + UNTILINTEREST("Until interest:", "Interest at"), + ENDS("Ends in:", "Ends at"), + REMAINING("Remaining:", "Ends at"), + DURATION("Duration:", "Finishes at"), + TIMELEFT("Time left:", "Ends at"), + EVENTTIMELEFT("Event lasts for", "Ends at", isRelative = true), + SHENSUCKS("Auction ends in:", "Auction ends at"), + CALENDARDETAILS(" (§e", "Starts at"); // Calendar details + } + + @SubscribeEvent + fun onTooltip(event: ItemTooltipEvent) { + var formatterAsString = when (NotEnoughUpdates.INSTANCE.config.misc.showWhenCountdownEnds) { + 1 -> "EEEE, MMM d h:mm a" + 2 -> "EEEE, MMM d HH:mm" + else -> return + } + if (event.itemStack != null && Minecraft.getMinecraft().thePlayer?.openContainer != null) { + var i = -1 + var lastTimer: ZonedDateTime? = null + while (++i < event.toolTip.size) { + val tooltipLine = event.toolTip[i] + val countdownKind = CountdownTypes.values().find { it.match in tooltipLine } ?: continue + val match = regex.findAll(tooltipLine).maxByOrNull { it.value.length } ?: continue + + val years = match.groups["years"]?.value?.toInt() ?: 0 + val days = match.groups["days"]?.value?.toInt() ?: 0 + val hours = match.groups["hours"]?.value?.toInt() ?: 0 + val minutes = match.groups["minutes"]?.value?.toInt() ?: 0 + val seconds = match.groups["seconds"]?.value?.toInt() ?: 0 + val totalSeconds = (years * 31_536_000L) + (days * 86_400L) + (hours * 3_600L) + (minutes * 60L) + seconds + if (totalSeconds == 0L) continue + if (years != 0) formatterAsString = "${formatterAsString} yyyy" + val useFormatter = DateTimeFormatter.ofPattern(formatterAsString)!! + val countdownTarget = if (countdownKind.isRelative) { + if (lastTimer == null) { + event.toolTip.add( + ++i, + "§r§cThe above countdown is relative, but I can't find another countdown. [NEU]" + ) + continue + } else lastTimer.plusSeconds(totalSeconds) + } else ZonedDateTime.now().plusSeconds(totalSeconds) + val countdownTargetFormatted = useFormatter.format(countdownTarget) + event.toolTip.add( + ++i, + "§r§b${countdownKind.label}: $countdownTargetFormatted" + ) + lastTimer = countdownTarget + } + } + } + +} diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt new file mode 100644 index 00000000..ea01eb2e --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2022-2023 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ +package io.github.moulberry.notenoughupdates.miscfeatures + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates +import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe +import io.github.moulberry.notenoughupdates.core.config.KeybindHelper +import io.github.moulberry.notenoughupdates.util.Utils +import net.minecraft.client.gui.inventory.GuiChest +import net.minecraft.inventory.ContainerChest +import net.minecraftforge.client.event.GuiScreenEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +@NEUAutoSubscribe +class WardrobeMouseButtons { + + private val keybinds: List get() = listOf( + NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot1, + NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot2, + NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot3, + NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot4, + NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot5, + NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot6, + NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot7, + NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot8, + NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobeSlot9, + NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobePageUnequip, + NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobePagePrevious, + NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobePageNext, + ) + private var lastClick = -1L + + @SubscribeEvent + fun onGuiKeyboardInput(event: GuiScreenEvent.KeyboardInputEvent.Pre) { + checkKeybinds(event) + } + + @SubscribeEvent + fun onGuiMouseInput(event: GuiScreenEvent.MouseInputEvent.Pre) { + checkKeybinds(event) + } + + @Suppress("InvalidSubscribeEvent") + private fun checkKeybinds(event: GuiScreenEvent) { + if (!NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.enableWardrobeKeybinds || !NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return + val gui = event.gui as? GuiChest ?: return + if (!Utils.getOpenChestName().contains("Wardrobe")) return + val chestName = Utils.getOpenChestName() + val chestNameRegex = "Wardrobe (\\((?[0-9]+)\\/(?[0-9]+)\\))".toRegex() + val chestNameMatch = chestNameRegex.matchEntire(chestName) + if (chestNameMatch == null) return + val totalPages = chestNameMatch.groups["total"]!!.value.toInt() + val currentPage = chestNameMatch.groups["current"]!!.value.toInt() + val guiChes = event.gui as GuiChest + val container = guiChes.inventorySlots as ContainerChest + var slotNum = 0 + + if ((currentPage != totalPages) && KeybindHelper.isKeyDown(NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobePageNext)) { + slotNum = 53 + } else if ((currentPage != 1) && KeybindHelper.isKeyDown(NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobePagePrevious)) { + slotNum = 45 + } else if (KeybindHelper.isKeyDown(NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.wardrobePageUnequip)) { + var notEquipped = 0 + for (j in 36..44) { + val stackItem = container.getSlot(j).getStack() ?: return + if (stackItem.getDisplayName().contains("Equipped")) { + slotNum = j + } + else { + notEquipped++ + } + } + if (notEquipped == 9) return + } else { + for (i in keybinds.indices) { + if (KeybindHelper.isKeyDown(keybinds[i])) { + if (System.currentTimeMillis() - lastClick > 300) { + slotNum = (36 + i) + } + } + } + } + + val thatItemStack = container.getSlot(slotNum).getStack() ?: return + if (thatItemStack.getDisplayName().isEmpty()) return + if (slotNum < 36 || ((slotNum > 45) && (slotNum != 53))) return + Utils.sendLeftMouseClick(gui.inventorySlots.windowId, slotNum) + lastClick = System.currentTimeMillis() + event.isCanceled = true + } + +} -- cgit