From f7507f384459b57460af899bf9ceae4f52f1ea21 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Fri, 6 Dec 2024 19:27:07 +0100 Subject: refactor: Add DI and packages --- .../nea/ledger/modules/AuctionHouseDetection.kt | 100 +++++++++++++++++ .../kotlin/moe/nea/ledger/modules/BankDetection.kt | 42 +++++++ .../moe/nea/ledger/modules/BazaarDetection.kt | 47 ++++++++ .../moe/nea/ledger/modules/BazaarOrderDetection.kt | 78 +++++++++++++ .../kotlin/moe/nea/ledger/modules/BitsDetection.kt | 58 ++++++++++ .../moe/nea/ledger/modules/BitsShopDetection.kt | 59 ++++++++++ .../nea/ledger/modules/DungeonChestDetection.kt | 121 +++++++++++++++++++++ .../moe/nea/ledger/modules/MinionDetection.kt | 54 +++++++++ .../kotlin/moe/nea/ledger/modules/NpcDetection.kt | 46 ++++++++ 9 files changed, 605 insertions(+) create mode 100644 src/main/kotlin/moe/nea/ledger/modules/AuctionHouseDetection.kt create mode 100644 src/main/kotlin/moe/nea/ledger/modules/BankDetection.kt create mode 100644 src/main/kotlin/moe/nea/ledger/modules/BazaarDetection.kt create mode 100644 src/main/kotlin/moe/nea/ledger/modules/BazaarOrderDetection.kt create mode 100644 src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt create mode 100644 src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt create mode 100644 src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt create mode 100644 src/main/kotlin/moe/nea/ledger/modules/MinionDetection.kt create mode 100644 src/main/kotlin/moe/nea/ledger/modules/NpcDetection.kt (limited to 'src/main/kotlin/moe/nea/ledger/modules') diff --git a/src/main/kotlin/moe/nea/ledger/modules/AuctionHouseDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/AuctionHouseDetection.kt new file mode 100644 index 0000000..cbbff12 --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/AuctionHouseDetection.kt @@ -0,0 +1,100 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.events.BeforeGuiAction +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.ItemIdProvider +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.SHORT_NUMBER_PATTERN +import moe.nea.ledger.getInternalId +import moe.nea.ledger.getLore +import moe.nea.ledger.parseShortNumber +import moe.nea.ledger.unformattedString +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.Inject +import net.minecraft.client.gui.inventory.GuiChest +import net.minecraft.inventory.ContainerChest +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.regex.Pattern + +class AuctionHouseDetection @Inject constructor(val ledger: LedgerLogger, val ids: ItemIdProvider) { + data class LastViewedItem( + val count: Int, + val id: String, + ) + /* + You collected 8,712,000 coins from selling Ultimate Carrot Candy Upgrade to [VIP] kodokush in an auction! + You collected 60,000 coins from selling Walnut to [MVP++] Alea1337 in an auction! + You purchased 2x Walnut for 69 coins! + You purchased ◆ Ice Rune I for 4,000 coins! + */ + + val collectSold = + Pattern.compile("You collected (?$SHORT_NUMBER_PATTERN) coins? from selling (?.*) to (?.*) in an auction!") + val purchased = + Pattern.compile("You purchased (?:(?[0-9]+)x )?(?.*) for (?$SHORT_NUMBER_PATTERN) coins!") + var lastViewedItems: MutableList = mutableListOf() + + @SubscribeEvent + fun onEvent(event: ChatReceived) { + collectSold.useMatcher(event.message) { + val lastViewedItem = lastViewedItems.removeLastOrNull() + ledger.logEntry( + LedgerEntry( + "AUCTION_SOLD", + event.timestamp, + parseShortNumber(group("coins")), + lastViewedItem?.id, + lastViewedItem?.count + ) + ) + } + purchased.useMatcher(event.message) { + ledger.logEntry( + LedgerEntry( + "AUCTION_BOUGHT", + event.timestamp, + parseShortNumber(group("coins")), + ids.findForName(group("what")), + group("amount")?.toInt() ?: 1 + ) + ) + } + } + + @SubscribeEvent + fun onBeforeAuctionCollected(event: BeforeGuiAction) { + val chest = (event.gui as? GuiChest) ?: return + val slots = chest.inventorySlots as ContainerChest + val name = slots.lowerChestInventory.displayName.unformattedText.unformattedString() + + if (name == "BIN Auction View" || name == "Auction View") { + handleCollectSingleAuctionView(slots) + } + if (name == "Manage Auctions") { + handleCollectMultipleAuctionsView(slots) + } + } + + private fun handleCollectMultipleAuctionsView(slots: ContainerChest) { + lastViewedItems = + (0 until slots.lowerChestInventory.sizeInventory) + .mapNotNull { slots.lowerChestInventory.getStackInSlot(it) } + .filter { + it.getLore().contains("§7Status: §aSold!") // BINs + || it.getLore().contains("§7Status: §aEnded!") // Auctions + } + .mapNotNull { LastViewedItem(it.stackSize, it.getInternalId() ?: return@mapNotNull null) } + .toMutableList() + } + + + fun handleCollectSingleAuctionView(slots: ContainerChest) { + val soldItem = slots.lowerChestInventory.getStackInSlot(9 + 4) ?: return + val id = soldItem.getInternalId() ?: return + val count = soldItem.stackSize + lastViewedItems = mutableListOf(LastViewedItem(count, id)) + } + + +} \ No newline at end of file diff --git a/src/main/kotlin/moe/nea/ledger/modules/BankDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/BankDetection.kt new file mode 100644 index 0000000..8d0fd81 --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/BankDetection.kt @@ -0,0 +1,42 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.SHORT_NUMBER_PATTERN +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.parseShortNumber +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.Inject +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.regex.Pattern + + +class BankDetection @Inject constructor(val ledger: LedgerLogger) { + val withdrawPattern = + Pattern.compile("^(You have withdrawn|Withdrew) (?$SHORT_NUMBER_PATTERN) coins?! (?:There's now|You now have) (?$SHORT_NUMBER_PATTERN) coins? (?:left in the account!|in your account!)$") + val depositPattern = + Pattern.compile("^(?:You have deposited|Deposited) (?$SHORT_NUMBER_PATTERN) coins?! (?:There's now|You now have) (?$SHORT_NUMBER_PATTERN) coins? (?:in your account!|in the account!)$") + + @SubscribeEvent + fun onChat(event: ChatReceived) { + withdrawPattern.useMatcher(event.message) { + ledger.logEntry( + LedgerEntry( + "BANK_WITHDRAW", + event.timestamp, + parseShortNumber(group("amount")), + ) + ) + } + depositPattern.useMatcher(event.message) { + ledger.logEntry( + LedgerEntry( + "BANK_DEPOSIT", + event.timestamp, + parseShortNumber(group("amount")), + ) + ) + } + } + +} diff --git a/src/main/kotlin/moe/nea/ledger/modules/BazaarDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/BazaarDetection.kt new file mode 100644 index 0000000..01c8bbc --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/BazaarDetection.kt @@ -0,0 +1,47 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.ItemIdProvider +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.SHORT_NUMBER_PATTERN +import moe.nea.ledger.parseShortNumber +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.Inject +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.regex.Pattern + +class BazaarDetection @Inject constructor(val ledger: LedgerLogger, val ids: ItemIdProvider) { + + val instaBuyPattern = + Pattern.compile("\\[Bazaar\\] Bought (?$SHORT_NUMBER_PATTERN)x (?.*) for (?$SHORT_NUMBER_PATTERN) coins!") + val instaSellPattern = + Pattern.compile("\\[Bazaar\\] Sold (?$SHORT_NUMBER_PATTERN)x (?.*) for (?$SHORT_NUMBER_PATTERN) coins!") + + + @SubscribeEvent + fun onInstSellChat(event: ChatReceived) { + instaBuyPattern.useMatcher(event.message) { + ledger.logEntry( + LedgerEntry( + "BAZAAR_BUY_INSTANT", + event.timestamp, + parseShortNumber(group("coins")), + ids.findForName(group("what")), + parseShortNumber(group("count")).toInt(), + ) + ) + } + instaSellPattern.useMatcher(event.message) { + ledger.logEntry( + LedgerEntry( + "BAZAAR_SELL_INSTANT", + event.timestamp, + parseShortNumber(group("coins")), + ids.findForName(group("what")), + parseShortNumber(group("count")).toInt(), + ) + ) + } + } +} diff --git a/src/main/kotlin/moe/nea/ledger/modules/BazaarOrderDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/BazaarOrderDetection.kt new file mode 100644 index 0000000..7e611ac --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/BazaarOrderDetection.kt @@ -0,0 +1,78 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.ItemIdProvider +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.SHORT_NUMBER_PATTERN +import moe.nea.ledger.mixin.AccessorGuiEditSign +import moe.nea.ledger.parseShortNumber +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.Inject +import net.minecraft.client.gui.inventory.GuiEditSign +import net.minecraftforge.client.event.GuiScreenEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.regex.Pattern + +class BazaarOrderDetection @Inject constructor(val ledger: LedgerLogger, val ids: ItemIdProvider) { + + val buyOrderClaimed = + Pattern.compile("\\[Bazaar] Claimed (?$SHORT_NUMBER_PATTERN)x (?.*) worth (?$SHORT_NUMBER_PATTERN) coins? bought for $SHORT_NUMBER_PATTERN each!") + val sellOrderClaimed = + Pattern.compile("\\[Bazaar] Claimed (?$SHORT_NUMBER_PATTERN) coins? from selling (?$SHORT_NUMBER_PATTERN)x (?.*) at $SHORT_NUMBER_PATTERN each!") + val orderFlipped = + Pattern.compile("\\[Bazaar] Order Flipped! (?$SHORT_NUMBER_PATTERN)x (?.*) for (?$SHORT_NUMBER_PATTERN) coins? of total expected profit.") + val previousPricePattern = + Pattern.compile("(?$SHORT_NUMBER_PATTERN)/u") + var lastFlippedPreviousPrice = 0.0 + + @SubscribeEvent + fun detectSignFlip(event: GuiScreenEvent.InitGuiEvent) { + val gui = event.gui + if (gui !is GuiEditSign) return + gui as AccessorGuiEditSign + val text = gui.tileEntity_ledger.signText + if (text[2].unformattedText != "Previous price:") return + previousPricePattern.useMatcher(text[3].unformattedText) { + lastFlippedPreviousPrice = parseShortNumber(group("price")) + } + } + + @SubscribeEvent + fun detectBuyOrders(event: ChatReceived) { + orderFlipped.useMatcher(event.message) { + val amount = parseShortNumber(group("amount")).toInt() + ledger.logEntry( + LedgerEntry( + "BAZAAR_BUY_ORDER", + event.timestamp, + lastFlippedPreviousPrice * amount, + ids.findForName(group("what")), + amount, + ) + ) + } + buyOrderClaimed.useMatcher(event.message) { + ledger.logEntry( + LedgerEntry( + "BAZAAR_BUY_ORDER", + event.timestamp, + parseShortNumber(group("coins")), + ids.findForName(group("what")), + parseShortNumber(group("amount")).toInt(), + ) + ) + } + sellOrderClaimed.useMatcher(event.message) { + ledger.logEntry( + LedgerEntry( + "BAZAAR_SELL_ORDER", + event.timestamp, + parseShortNumber(group("coins")), + ids.findForName(group("what")), + parseShortNumber(group("amount")).toInt(), + ) + ) + } + } +} diff --git a/src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt new file mode 100644 index 0000000..22b5392 --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt @@ -0,0 +1,58 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.events.LateWorldLoadEvent +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.SHORT_NUMBER_PATTERN +import moe.nea.ledger.ScoreboardUtil +import moe.nea.ledger.parseShortNumber +import moe.nea.ledger.unformattedString +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.Inject +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.time.Instant + +class BitsDetection @Inject constructor(val ledger: LedgerLogger) { + + var lastBits = -1 + + val bitScoreboardRegex = "Bits: (?$SHORT_NUMBER_PATTERN)".toPattern() + + @SubscribeEvent + fun onWorldSwitch(event: LateWorldLoadEvent) { + ScoreboardUtil.getScoreboardStrings().forEach { + bitScoreboardRegex.useMatcher(it.unformattedString()) { + val bits = parseShortNumber(group("purse")).toInt() + if (lastBits != bits) { + ledger.logEntry( + LedgerEntry( + "BITS_PURSE_STATUS", + Instant.now(), + 0.0, + null, + bits + ) + ) + lastBits = bits + } + return + } + } + } + + @SubscribeEvent + fun onEvent(event: ChatReceived) { + if (event.message.startsWith("You consumed a Booster Cookie!")) { + ledger.logEntry( + LedgerEntry( + "BOOSTER_COOKIE_ATE", + Instant.now(), + 0.0, + null, + null, + ) + ) + } + } +} diff --git a/src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt new file mode 100644 index 0000000..2033d8d --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt @@ -0,0 +1,59 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.events.GuiClickEvent +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.SHORT_NUMBER_PATTERN +import moe.nea.ledger.getInternalId +import moe.nea.ledger.getLore +import moe.nea.ledger.parseShortNumber +import moe.nea.ledger.unformattedString +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.Inject +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.time.Instant + +class BitsShopDetection @Inject constructor(val ledger: LedgerLogger) { + + + data class BitShopEntry( + val id: String, + val bitPrice: Int, + val timestamp: Long = System.currentTimeMillis() + ) + + var lastClickedBitShopItem: BitShopEntry? = null + var bitCostPattern = "(?$SHORT_NUMBER_PATTERN) Bits".toPattern() + + @SubscribeEvent + fun recordLastBitPrice(event: GuiClickEvent) { + val slot = event.slotIn ?: return + val name = slot.inventory.displayName.unformattedText.unformattedString() + if (name != "Community Shop" && !name.startsWith("Bits Shop")) + return + val stack = slot.stack ?: return + val id = stack.getInternalId() ?: return + val bitPrice = stack.getLore() + .firstNotNullOfOrNull { bitCostPattern.useMatcher(it.unformattedString()) { parseShortNumber(group("cost")).toInt() } } + ?: return + lastClickedBitShopItem = BitShopEntry(id, bitPrice) + } + + @SubscribeEvent + fun onChat(event: ChatReceived) { + if (event.message.startsWith("You bought ")) { + val lastBit = lastClickedBitShopItem ?: return + if (System.currentTimeMillis() - lastBit.timestamp > 5000) return + ledger.logEntry( + LedgerEntry( + "COMMUNITY_SHOP_BUY", Instant.now(), + lastBit.bitPrice.toDouble(), + lastBit.id, + 1 + ) + ) + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt new file mode 100644 index 0000000..4bdd37c --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt @@ -0,0 +1,121 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.events.GuiClickEvent +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.SHORT_NUMBER_PATTERN +import moe.nea.ledger.getDisplayNameU +import moe.nea.ledger.getLore +import moe.nea.ledger.parseShortNumber +import moe.nea.ledger.unformattedString +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.Inject +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import java.time.Instant +import java.util.regex.Pattern + +class DungeonChestDetection @Inject constructor(val logger: LedgerLogger) { + + /*{ + id: "minecraft:chest", + Count: 1b, + tag: { + display: { + Lore: ["§7Purchase this chest to receive the", "§7rewards above. You can only open", "§7one chest per Dungeons run -", "§7choose wisely!", "", "§7Cost", "§625,000 Coins", "§9Dungeon Chest Key", "", "§7§cNOTE: Coins are withdrawn from your", "§cbank if you don't have enough in", "§cyour purse."], + Name: "§aOpen Reward Chest" + } + }, + Damage: 0s + } + + { + id: "minecraft:feather", + Count: 1b, + tag: { + overrideMeta: 1b, + ench: [], + HideFlags: 254, + display: { + Lore: ["§7Consume a §9Kismet Feather §7to reroll", "§7the loot within this chest.", "", "§7You may only use a feather once", "§7per dungeon run.", "", "§eClick to reroll this chest!"], + Name: "§aReroll Chest" + }, + AttributeModifiers: [] + }, + Damage: 0s +} + */ + val costPattern = Pattern.compile("(?$SHORT_NUMBER_PATTERN) Coins") + + + data class ChestCost( + val cost: Double, + val openTimestamp: Long, + val hasKey: Boolean, + ) + + var lastOpenedChest: ChestCost? = null + + @SubscribeEvent + fun onKismetClick(event: GuiClickEvent) { + val slot = event.slotIn ?: return + if (!slot.inventory.displayName.unformattedText.unformattedString().endsWith(" Chest")) return + val stack = slot.stack ?: return + if (stack.getDisplayNameU() == "§aReroll Chest") { + logger.logEntry( + LedgerEntry( + "KISMET_REROLL", + Instant.now(), + 0.0, + itemId = "KISMET_FEATHER", + itemAmount = 1 + ) + ) + } + } + + @SubscribeEvent + fun onRewardChestClick(event: GuiClickEvent) { + val slot = event.slotIn ?: return + if (!slot.inventory.displayName.unformattedText.unformattedString().endsWith(" Chest")) return + val stack = slot.stack ?: return + val name = stack.getDisplayNameU() + if (name != "§aOpen Reward Chest") return + val lore = stack.getLore() + val costIndex = lore.indexOf("§7Cost") + if (costIndex < 0 || costIndex + 1 !in lore.indices) return + val cost = costPattern.useMatcher(lore[costIndex + 1].unformattedString()) { + parseShortNumber(group("cost")) + } ?: 0.0 // Free chest! + val hasKey = lore.contains("§9Dungeon Chest Key") + lastOpenedChest?.let(::completeTransaction) + lastOpenedChest = ChestCost(cost, System.currentTimeMillis(), hasKey) + } + + @SubscribeEvent + fun onChatMessage(event: ChatReceived) { + if (event.message == "You don't have that many coins in the bank!") + lastOpenedChest = null + } + + fun completeTransaction(toOpen: ChestCost) { + lastOpenedChest = null + logger.logEntry( + LedgerEntry( + "DUNGEON_CHEST_OPEN", + Instant.ofEpochMilli(toOpen.openTimestamp), + toOpen.cost, + itemId = if (toOpen.hasKey) "DUNGEON_CHEST_KEY" else null + ) + ) + } + + @SubscribeEvent + fun onTick(event: TickEvent) { + val toOpen = lastOpenedChest + if (toOpen != null && toOpen.openTimestamp + 1000L < System.currentTimeMillis()) { + completeTransaction(toOpen) + } + } +} diff --git a/src/main/kotlin/moe/nea/ledger/modules/MinionDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/MinionDetection.kt new file mode 100644 index 0000000..73d06fa --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/MinionDetection.kt @@ -0,0 +1,54 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.events.BeforeGuiAction +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.ExpiringValue +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.ROMAN_NUMBER_PATTERN +import moe.nea.ledger.SHORT_NUMBER_PATTERN +import moe.nea.ledger.parseRomanNumber +import moe.nea.ledger.parseShortNumber +import moe.nea.ledger.unformattedString +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.Inject +import net.minecraft.client.gui.inventory.GuiChest +import net.minecraft.inventory.ContainerChest +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.time.Instant +import kotlin.time.Duration.Companion.seconds + +class MinionDetection @Inject constructor(val ledger: LedgerLogger) { + // §aYou received §r§6367,516.8 coins§r§a! + val hopperCollectPattern = "You received (?$SHORT_NUMBER_PATTERN) coins?!".toPattern() + val minionNamePattern = "(?.*) Minion (?$ROMAN_NUMBER_PATTERN)".toPattern() + + var lastOpenedMinion = ExpiringValue.empty() + + @SubscribeEvent + fun onBeforeClaim(event: BeforeGuiAction) { + val container = event.gui as? GuiChest ?: return + val inv = (container.inventorySlots as ContainerChest).lowerChestInventory + val invName = inv.displayName.unformattedText.unformattedString() + minionNamePattern.useMatcher(invName) { + val name = group("name") + val level = parseRomanNumber(group("level")) + lastOpenedMinion = ExpiringValue(name.uppercase().replace(" ", "_") + "_" + level) + } + } + + + @SubscribeEvent + fun onChat(event: ChatReceived) { + hopperCollectPattern.useMatcher(event.message) { + val minionName = lastOpenedMinion.consume(3.seconds) + ledger.logEntry(LedgerEntry( + "AUTOMERCHANT_PROFIT_COLLECT", + Instant.now(), + parseShortNumber(group("amount")), + minionName, // TODO: switch to its own column idk + )) + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/moe/nea/ledger/modules/NpcDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/NpcDetection.kt new file mode 100644 index 0000000..68f0257 --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/NpcDetection.kt @@ -0,0 +1,46 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.ItemIdProvider +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.SHORT_NUMBER_PATTERN +import moe.nea.ledger.parseShortNumber +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.Inject +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.regex.Pattern + +class NpcDetection @Inject constructor(val ledger: LedgerLogger, val ids: ItemIdProvider) { + + val npcBuyPattern = + Pattern.compile("You bought (back )?(?.*?) (x(?$SHORT_NUMBER_PATTERN) )?for (?$SHORT_NUMBER_PATTERN) Coins!") + val npcSellPattern = + Pattern.compile("You sold (?.*) (x(?$SHORT_NUMBER_PATTERN) )?for (?$SHORT_NUMBER_PATTERN) Coins!") + + @SubscribeEvent + fun onNpcBuy(event: ChatReceived) { + npcBuyPattern.useMatcher(event.message) { + ledger.logEntry( + LedgerEntry( + "NPC_BUY", + event.timestamp, + parseShortNumber(group("coins")), + ids.findForName(group("what")), + group("count")?.let(::parseShortNumber)?.toInt() ?: 1, + ) + ) + } + npcSellPattern.useMatcher(event.message) { + ledger.logEntry( + LedgerEntry( + "NPC_SELL", + event.timestamp, + parseShortNumber(group("coins")), + ids.findForName(group("what")), + group("count")?.let(::parseShortNumber)?.toInt() ?: 1, + ) + ) + } + } +} -- cgit