diff --git a/src/main/java/at/hannibal2/skyhanni/events/garden/contests/rewards/ContestRewardsClaimedEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/garden/contests/rewards/ContestRewardsClaimedEvent.kt index 562a6cebe3be..4cccc5eb377d 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/garden/contests/rewards/ContestRewardsClaimedEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/garden/contests/rewards/ContestRewardsClaimedEvent.kt @@ -12,5 +12,6 @@ data class ContestRewardSet( var carnivalTickets: Int = 0, var books: Map = emptyMap(), var medals: Map = emptyMap(), + var overclockers: Int = 0, var bits: Int = 0 ) : Resettable diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/CompactJacobClaim.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/CompactJacobClaim.kt index 8d2852a8aa55..0594396de8f7 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/CompactJacobClaim.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/CompactJacobClaim.kt @@ -11,9 +11,10 @@ import at.hannibal2.skyhanni.features.garden.CropType import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule import at.hannibal2.skyhanni.utils.ChatUtils import at.hannibal2.skyhanni.utils.DelayedRun -import at.hannibal2.skyhanni.utils.LorenzColor import at.hannibal2.skyhanni.utils.NumberUtil.formatInt +import at.hannibal2.skyhanni.utils.RegexUtils.groupOrNull import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher +import at.hannibal2.skyhanni.utils.StringUtils import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import kotlin.time.Duration.Companion.milliseconds @@ -26,58 +27,78 @@ object CompactJacobClaim { // /** - * REGEX-TEST: §r§6§lFARMING CONTEST REWARDS CLAIMED + * REGEX-TEST: FARMING CONTEST REWARDS CLAIMED */ private val openingPattern by patternGroup.pattern( - "opening", - " {2}§r§6§lFARMING CONTEST REWARDS CLAIMED", + "opening.colorless", + " {2}FARMING CONTEST REWARDS CLAIMED", ) /** - * REGEX-TEST: §r§a§lREWARDS + * REGEX-TEST: » Sunflower Contest on Autumn 31st, Year 472 + * REGEX-TEST: » Melon Slice Contest on Early Spring 17th, Year 473 */ - private val rewardsPattern by patternGroup.pattern( - "rewards", - " {2}§r§a§lREWARDS", + private val specificContestLine by patternGroup.pattern( + "contest.specific", + " {3}» (?[\\w ]+) Contest on (?[\\w ]+) (?\\d+[stndh]{2,3}), Year (?\\d+)", ) /** - * REGEX-TEST: §r§7§aJacob's Ticket §8x271 - * REGEX-TEST: §r§7§aCarnival Ticket §8x21 + * REGEX-TEST: REWARDS + */ + private val rewardsHeaderPattern by patternGroup.pattern( + "rewards.colorless", + " {2}REWARDS", + ) + + /** + * REGEX-TEST: Jacob's Ticket x271 + * REGEX-TEST: Carnival Ticket x21 + * REGEX-TEST: Carnival Ticket */ private val ticketPattern by patternGroup.pattern( - "tickets", - " {4}§r§7§a(?Jacob's|Carnival) Ticket §8x(?[\\d,]+)", + "tickets.colorless", + " {4}(?Jacob's|Carnival) Ticket(?: x(?[\\d,]+))?", ) /** - * REGEX-TEST: §r§7§81x §9Turbo-Cacti I Book - * REGEX-TEST: §r§7§81x §9Turbo-Pumpkin I Book - * REGEX-TEST: §r§7§84x §9Turbo-Wheat I Book - * REGEX-TEST: §r§7§86x §9Turbo-Mushrooms I Book - * REGEX-TEST: §r§7§81x §9Turbo-Warts I Book + * REGEX-TEST: 1x Turbo-Cacti I Book + * REGEX-TEST: 1x Turbo-Pumpkin I Book + * REGEX-TEST: 4x Turbo-Wheat I Book + * REGEX-TEST: 6x Turbo-Mushrooms I Book + * REGEX-TEST: 1x Turbo-Warts I Book + * REGEX-TEST: 1x Turbo-Sunflower I Book */ private val bookPattern by patternGroup.pattern( - "book", - " {4}§r§7§8(?[\\d,]+)x §9Turbo-(?[^ ]+) I Book", + "book.colorless", + " {4}(?[\\d,]+)x Turbo-(?[^ ]+) I Book", ) /** - * REGEX-TEST: §r§7§8+§e8 §7gold medals - * REGEX-TEST: §r§7§8+§e7 §7silver medals - * REGEX-TEST: §r§7§8+§e5 §7bronze medals + * REGEX-TEST: +8 gold medals + * REGEX-TEST: +7 silver medals + * REGEX-TEST: +5 bronze medals + * REGEX-TEST: +1 gold medal */ private val medalsPattern by patternGroup.pattern( - "medals", - " {4}§r§7§8\\+§e(?[\\d,]+) §7(?[^ ]+) medals?", + "medals.colorless", + " {4}\\+(?[\\d,]+) (?[^ ]+) medals?", ) /** - * REGEX-TEST: §r§8+§r§b2,293 Bits + * REGEX-TEST: +2,293 Bits */ private val bitsPattern by patternGroup.pattern( - "bits", - " {4}§r§8\\+§r§b(?[\\d,]+) Bits", + "bits.colorless", + " {4}\\+(?[\\d,]+) Bits", + ) + + /** + * REGEX-TEST: Overclocker 3000 + */ + private val overclockerPattern by patternGroup.pattern( + "overclocker", + " {4}Overclocker 3000", ) // @@ -91,26 +112,9 @@ object CompactJacobClaim { messageSet.clear() } - private val shorteningMap: Map> = mapOf( - CropType.CACTUS to Pair(LorenzColor.GREEN, "Ca"), - CropType.SUGAR_CANE to Pair(LorenzColor.GREEN, "Su"), - CropType.MELON to Pair(LorenzColor.GREEN, "Me"), - - CropType.MUSHROOM to Pair(LorenzColor.RED, "Mu"), - CropType.NETHER_WART to Pair(LorenzColor.RED, "Ne"), - CropType.WILD_ROSE to Pair(LorenzColor.RED, "Wr"), - - CropType.CARROT to Pair(LorenzColor.GOLD, "Ca"), - CropType.COCOA_BEANS to Pair(LorenzColor.GOLD, "Co"), - CropType.POTATO to Pair(LorenzColor.GOLD, "Po"), - CropType.PUMPKIN to Pair(LorenzColor.GOLD, "Pu"), - CropType.WHEAT to Pair(LorenzColor.GOLD, "Wh"), - CropType.SUNFLOWER to Pair(LorenzColor.GOLD, "Sf"), - - CropType.MOONFLOWER to Pair(LorenzColor.AQUA, "Mf"), - ) - + @Suppress("DEPRECATION") private fun SkyHanniChatEvent.Allow.block(reason: String) { + // We need the message with color for the hover messageSet.add(message) blockedReason = reason } @@ -118,7 +122,7 @@ object CompactJacobClaim { @HandleEvent(onlyOnIsland = IslandType.GARDEN) fun onChat(event: SkyHanniChatEvent.Allow) { if (!config.compactJacobClaim) return - val message = event.message + val message = event.cleanMessage var eventDelay = 300.milliseconds openingPattern.matchMatcher(message) { @@ -128,7 +132,11 @@ object CompactJacobClaim { if (!inLoop) return - rewardsPattern.matchMatcher(message) { + specificContestLine.matchMatcher(message) { + return event.block("compact_jacob_bulk_claim") + } + + rewardsHeaderPattern.matchMatcher(message) { return event.block("compact_jacob_bulk_claim") } @@ -136,13 +144,17 @@ object CompactJacobClaim { val startingHash = rewardSet.hashCode() ticketPattern.matchMatcher(message) { - val amount = group("amount").formatInt() + val amount = groupOrNull("amount")?.formatInt() ?: 1 when (group("type")) { "Jacob's" -> rewardSet.jacobTickets += amount "Carnival" -> rewardSet.carnivalTickets += amount } } + overclockerPattern.matchMatcher(message) { + rewardSet.overclockers++ + } + bookPattern.matchMatcher(message) { val crop = CropType.getByNameOrNull(group("crop")) ?: when (group("crop").lowercase()) { "cacti" -> CropType.CACTUS @@ -172,10 +184,9 @@ object CompactJacobClaim { val hashNow = rewardSet.hashCode() DelayedRun.runDelayed(eventDelay) { - if (rewardSet.hashCode() == hashNow) { - inLoop = false - publishEvent() - } + if (rewardSet.hashCode() != hashNow) return@runDelayed + inLoop = false + publishEvent() } } @@ -192,6 +203,7 @@ object CompactJacobClaim { getBooksFormat(), getMedalsFormat(), getBitsFormat(), + getOverclockersFormat(), ).filterNot { it.isEmpty() }.joinToString(separator = " §8§l| §r"), @@ -209,19 +221,18 @@ object CompactJacobClaim { } private fun ContestRewardsClaimedEvent.getBooksFormat() = buildString { - val books = rewards.books.takeIf { it.isNotEmpty() } ?: return@buildString + val books = rewards.books.filter { it.value > 0 }.takeIf { it.isNotEmpty() } ?: return@buildString val bookList = books.map { (crop, amount) -> - val (color, shortName) = shorteningMap[crop] ?: error("unknown crop type $crop") - "${color.getChatColor()}$amount $shortName".takeIf { amount > 0 }.orEmpty() - }.filterNot { it.isEmpty() }.sortedBy { it.removeColor() } + "${crop.cropColor.getChatColor()}$amount ${crop.cropShortName}" + }.sortedBy { it.removeColor() } append("Books: " + bookList.joinToString(separator = "§7, ") { it }) } private fun ContestRewardsClaimedEvent.getMedalsFormat() = buildString { - val medals = rewards.medals.takeIf { it.isNotEmpty() } ?: return@buildString + val medals = rewards.medals.filter { it.value > 0 }.takeIf { it.isNotEmpty() } ?: return@buildString val medalList = medals.toSortedMap(compareBy { it.ordinal }).map { (medalType, amount) -> - "${medalType.color.getChatColor()}$amount".takeIf { amount > 0 }.orEmpty() - }.filterNot { it.isEmpty() } + "${medalType.color.getChatColor()}$amount" + } append("Medals: " + medalList.joinToString(separator = "§7, ") { it }) } @@ -229,4 +240,10 @@ object CompactJacobClaim { if (rewards.bits == 0) return@buildString append("Bits: §b${rewards.bits}") } + + private fun ContestRewardsClaimedEvent.getOverclockersFormat() = buildString { + val ocCount = rewards.overclockers.takeIf { it > 0 } ?: return@buildString + val ocFormat = StringUtils.pluralize(ocCount, "Overclocker") + append("$ocFormat: §6$ocCount") + } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt index 3bbf0b2e424a..6e8b07cbf513 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt @@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.garden import at.hannibal2.skyhanni.features.garden.fortuneguide.FarmingItemType import at.hannibal2.skyhanni.utils.ItemUtils.overrideId +import at.hannibal2.skyhanni.utils.LorenzColor import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.ServerTime import net.minecraft.world.item.ItemStack @@ -19,20 +20,25 @@ enum class CropType( val farmingItem: FarmingItemType, val replenish: Boolean = false, val enchantName: String = cropName.lowercase(), - val eliteLbName: String = simpleName + val eliteLbName: String = simpleName, + val cropColor: LorenzColor = LorenzColor.GREEN, + val cropShortName: String = cropName.substring(0..1), ) { WHEAT( "Wheat", "THEORETICAL_HOE_WHEAT", "CROPIE", 1.0, { ItemStack(Items.WHEAT).overrideId("WHEAT") }, "wheat", FarmingItemType.WHEAT, + cropColor = LorenzColor.GOLD, ), CARROT( "Carrot", "THEORETICAL_HOE_CARROT", "CROPIE", 3.0, { ItemStack(Items.CARROT).overrideId("CARROT_ITEM") }, "carrot", FarmingItemType.CARROT, replenish = true, + cropColor = LorenzColor.GOLD, ), POTATO( "Potato", "THEORETICAL_HOE_POTATO", "CROPIE", 3.0, { ItemStack(Items.POTATO).overrideId("POTATO_ITEM") }, "potato", FarmingItemType.POTATO, replenish = true, + cropColor = LorenzColor.GOLD, ), NETHER_WART( "Nether Wart", @@ -44,20 +50,24 @@ enum class CropType( FarmingItemType.NETHER_WART, replenish = true, enchantName = "warts", - eliteLbName = "netherwart" + eliteLbName = "netherwart", + cropColor = LorenzColor.RED, ), PUMPKIN( "Pumpkin", "PUMPKIN_DICER", "SQUASH", 1.0, { ItemStack(Items.CARVED_PUMPKIN).overrideId("PUMPKIN") }, "pumpkin", FarmingItemType.PUMPKIN, + cropColor = LorenzColor.GOLD, ), MELON( "Melon Slice", "MELON_DICER", "SQUASH", 5.0, { ItemStack(Items.MELON_SLICE).overrideId("MELON") }, "melon", FarmingItemType.MELON, + cropColor = LorenzColor.GREEN, ), COCOA_BEANS( "Cocoa Beans", "COCO_CHOPPER", "SQUASH", 3.0, { ItemStack(Items.COCOA_BEANS).overrideId("INK_SACK:3") }, "cocoa", FarmingItemType.COCOA_BEANS, replenish = true, enchantName = "coco", + cropColor = LorenzColor.GOLD, ), SUGAR_CANE( "Sugar Cane", @@ -68,16 +78,19 @@ enum class CropType( "cane", FarmingItemType.SUGAR_CANE, enchantName = "cane", - eliteLbName = "sugarcane" + eliteLbName = "sugarcane", + cropColor = LorenzColor.GREEN, ), CACTUS( "Cactus", "CACTUS_KNIFE", "FERMENTO", 2.0, { ItemStack(Items.CACTUS).overrideId("CACTUS") }, "cactus", FarmingItemType.CACTUS, + cropColor = LorenzColor.GREEN, ), MUSHROOM( "Mushroom", "FUNGI_CUTTER", "FERMENTO", 1.0, { ItemStack(Items.RED_MUSHROOM_BLOCK).overrideId("HUGE_MUSHROOM_2") }, "mushroom", FarmingItemType.MUSHROOM, enchantName = "mushrooms", + cropColor = LorenzColor.RED, ), SUNFLOWER( "Sunflower", @@ -88,6 +101,8 @@ enum class CropType( "sunflower", FarmingItemType.SUNFLOWER, replenish = true, + cropColor = LorenzColor.GOLD, + cropShortName = "Sf", ), MOONFLOWER( "Moonflower", @@ -98,6 +113,8 @@ enum class CropType( "moonflower", FarmingItemType.MOONFLOWER, replenish = true, + cropColor = LorenzColor.AQUA, + cropShortName = "Mf", ), WILD_ROSE( "Wild Rose", @@ -108,7 +125,9 @@ enum class CropType( "rose", FarmingItemType.WILD_ROSE, replenish = true, - eliteLbName = "wildrose" + eliteLbName = "wildrose", + cropColor = LorenzColor.RED, + cropShortName = "Wr", ), ;