diff options
18 files changed, 426 insertions, 43 deletions
diff --git a/build.gradle.kts b/build.gradle.kts index dad4b3e..440e815 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,20 @@ import com.github.gmazzo.buildconfig.BuildConfigExtension +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import com.google.gson.Gson import org.apache.commons.lang3.SystemUtils +import proguard.gradle.ProGuardTask import java.io.ByteArrayOutputStream +import java.net.URI +import java.util.zip.ZipInputStream + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath("com.guardsquare:proguard-gradle:7.6.1") + } +} plugins { idea @@ -92,6 +106,7 @@ dependencies { forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9") shadowImpl(kotlin("stdlib-jdk8")) + implementation("org.jspecify:jspecify:1.0.0") shadowImpl("org.spongepowered:mixin:0.7.11-SNAPSHOT") { isTransitive = false @@ -108,6 +123,11 @@ dependencies { // Tasks: +// Delete default shadow configuration +tasks.shadowJar { + doFirst { error("Incorrect shadow JAR built!") } +} + tasks.test { useJUnitPlatform() } @@ -116,6 +136,111 @@ tasks.withType(JavaCompile::class) { options.encoding = "UTF-8" } +abstract class GenerateItemIds : DefaultTask() { + @get: OutputDirectory + abstract val outputDirectory: DirectoryProperty + + @get: InputDirectory + abstract val repoFiles: DirectoryProperty + + @get: Input + abstract val repoHash: Property<String> + + @get: Input + abstract val packageName: Property<String> + + @get:Internal + val outputFile get() = outputDirectory.asFile.get().resolve(packageName.get().replace(".", "/") + "/ItemIds.java") + + @TaskAction + fun generateItemIds() { + val nonIdName = "[^A-Z0-9_]".toRegex() + + data class Item(val id: String) { + val javaName get() = id.replace(nonIdName, { "__" + it.value.single().code }) + } + + val items = mutableListOf<Item>() + for (listFile in repoFiles.asFile.get().resolve("items").listFiles() ?: emptyArray()) { + listFile ?: continue + if (listFile.extension != "json") { + error("Unknown file $listFile") + } + items.add(Item(listFile.nameWithoutExtension)) + } + items.sortedBy { it.id } + outputFile.parentFile.mkdirs() + val writer = outputFile.writer().buffered() + writer.appendLine("// @generated from " + repoHash.get()) + writer.appendLine("package " + packageName.get() + ";") + writer.appendLine() + writer.appendLine("import moe.nea.ledger.ItemId;") + writer.appendLine() + writer.appendLine("/**") + writer.appendLine(" * Automatically generated {@link ItemId} list.") + writer.appendLine(" */") + writer.appendLine("@org.jspecify.annotations.NullMarked") + writer.appendLine("public class ItemIds {") + val gson = Gson() + for (item in items) { + writer.appendLine("\t/**") + writer.appendLine("\t * @see <a href=${gson.toJson("https://github.com/NotEnoughUpdates/NotEnoughUpdates-REPO/blob/${repoHash.get()}/items/${item.id}.json")}>JSON definition</a>") + writer.appendLine("\t */") + writer.appendLine("\tpublic static final ItemId ${item.javaName} =" + + " ItemId.forName(${gson.toJson(item.id)});") + } + writer.appendLine("}") + writer.close() + } +} + +abstract class RepoDownload : DefaultTask() { + @get:Input + abstract val hash: Property<String> + + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty + + init { + outputDirectory.convention(project.layout.buildDirectory.dir("extracted-test-repo")) + } + + @TaskAction + fun performDownload() { + val outputDir = outputDirectory.asFile.get().absoluteFile + outputDir.mkdirs() + URI("https://github.com/notEnoughUpdates/notEnoughUpdates-rEPO/archive/${hash.get()}.zip").toURL().openStream() + .let(::ZipInputStream) + .use { zipInput -> + while (true) { + val entry = zipInput.nextEntry ?: break + val destination = outputDir.resolve( + entry.name.substringAfter('/')).absoluteFile + require(outputDir in generateSequence(destination) { it.parentFile }) + if (entry.isDirectory) continue + destination.parentFile.mkdirs() + destination.outputStream().use { output -> + zipInput.copyTo(output) + } + } + } + } +} + +val downloadRepo by tasks.register("downloadRepo", RepoDownload::class) { + hash.set("725ddb8") +} + +val generateItemIds by tasks.register("generateItemIds", GenerateItemIds::class) { + repoHash.set(downloadRepo.hash) + packageName.set("moe.nea.ledger.gen") + outputDirectory.set(layout.buildDirectory.dir("generated/sources/itemIds")) + repoFiles.set(downloadRepo.outputDirectory) +} +sourceSets.main { + java.srcDir(generateItemIds) +} + tasks.withType(Jar::class) { archiveBaseName.set(modid) manifest.attributes.run { @@ -142,10 +267,34 @@ tasks.processResources { } +val proguardOutJar = project.layout.buildDirectory.file("badjars/stripped.jar") +val proguard = tasks.register("proguard", ProGuardTask::class) { + dependsOn(tasks.jar) + injars(tasks.jar.map { it.archiveFile }) + outjars(proguardOutJar) + configuration(file("ledger-rules.pro")) + verbose() + val libJava = javaToolchains.launcherFor(java.toolchain) + .get() + .metadata.installationPath.file("jre/lib/rt.jar") + println(libJava) + libraryjars(libJava) + libraryjars(configurations.compileClasspath) +} + +val shadowJar2 = tasks.register("shadowJar2", ShadowJar::class) { + destinationDirectory.set(layout.buildDirectory.dir("badjars")) + archiveClassifier.set("all-dev") + from(proguardOutJar) + dependsOn(proguard) + configurations = listOf(shadowImpl) + relocate("moe.nea.libautoupdate", "moe.nea.ledger.deps.libautoupdate") + mergeServiceFiles() +} val remapJar by tasks.named<net.fabricmc.loom.task.RemapJarTask>("remapJar") { archiveClassifier.set("") - from(tasks.shadowJar) - input.set(tasks.shadowJar.get().archiveFile) + from(shadowJar2) + input.set(shadowJar2.get().archiveFile) } tasks.jar { @@ -153,13 +302,6 @@ tasks.jar { destinationDirectory.set(layout.buildDirectory.dir("badjars")) } -tasks.shadowJar { - destinationDirectory.set(layout.buildDirectory.dir("badjars")) - archiveClassifier.set("all-dev") - configurations = listOf(shadowImpl) - relocate("moe.nea.libautoupdate", "moe.nea.ledger.deps.libautoupdate") - mergeServiceFiles() -} tasks.assemble.get().dependsOn(tasks.remapJar) diff --git a/ledger-rules.pro b/ledger-rules.pro new file mode 100644 index 0000000..2d8459e --- /dev/null +++ b/ledger-rules.pro @@ -0,0 +1,3 @@ +-keep class !moe.nea.ledger.gen.** {*;} +-dontobfuscate +-assumenosideeffects class moe.nea.ledger.ItemId { *; }
\ No newline at end of file diff --git a/src/main/kotlin/moe/nea/ledger/DebouncedValue.kt b/src/main/kotlin/moe/nea/ledger/DebouncedValue.kt new file mode 100644 index 0000000..66fba8d --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/DebouncedValue.kt @@ -0,0 +1,38 @@ +package moe.nea.ledger + +import kotlin.time.Duration +import kotlin.time.Duration.Companion.nanoseconds +import kotlin.time.Duration.Companion.seconds + +class DebouncedValue<T>(private val value: T) { + companion object { + fun <T> farFuture(): DebouncedValue<T> { + val value = DebouncedValue(Unit) + value.take() + @Suppress("UNCHECKED_CAST") + return value as DebouncedValue<T> + } + } + + val lastSeenAt = System.nanoTime() + val age get() = (System.nanoTime() - lastSeenAt).nanoseconds + var taken = false + private set + + fun get(debounce: Duration): T? { + return if (!taken && age >= debounce) value + else null + } + + fun replace(): T? { + return consume(0.seconds) + } + + fun consume(debounce: Duration): T? { + return get(debounce)?.also { take() } + } + + fun take() { + taken = true + } +}
\ No newline at end of file diff --git a/src/main/kotlin/moe/nea/ledger/ExpiringValue.kt b/src/main/kotlin/moe/nea/ledger/ExpiringValue.kt index dac4751..b50b14e 100644 --- a/src/main/kotlin/moe/nea/ledger/ExpiringValue.kt +++ b/src/main/kotlin/moe/nea/ledger/ExpiringValue.kt @@ -7,8 +7,10 @@ class ExpiringValue<T>(private val value: T) { val lastSeenAt: Long = System.nanoTime() val age get() = (System.nanoTime() - lastSeenAt).nanoseconds var taken = false + private set + fun get(expiry: Duration): T? { - return if (!taken && expiry > age) value + return if (!taken && age < expiry) value else null } @@ -21,7 +23,7 @@ class ExpiringValue<T>(private val value: T) { } } - fun consume(expiry: Duration): T? = get(expiry).also { take() } + fun consume(expiry: Duration): T? = get(expiry)?.also { take() } fun take() { taken = true } diff --git a/src/main/kotlin/moe/nea/ledger/ItemId.kt b/src/main/kotlin/moe/nea/ledger/ItemId.kt index 56917e8..ade63fb 100644 --- a/src/main/kotlin/moe/nea/ledger/ItemId.kt +++ b/src/main/kotlin/moe/nea/ledger/ItemId.kt @@ -1,7 +1,6 @@ package moe.nea.ledger -@JvmInline -value class ItemId( +data class ItemId( val string: String ) { fun singleItem(): Pair<ItemId, Double> { @@ -14,26 +13,18 @@ value class ItemId( companion object { + + @JvmStatic + fun forName(string: String) = ItemId(string) fun skill(skill: String) = ItemId("SKYBLOCK_SKILL_$skill") val GARDEN = skill("GARDEN") val FARMING = skill("FARMING") + + + val COINS = ItemId("SKYBLOCK_COIN") val GEMSTONE_POWDER = ItemId("SKYBLOCK_POWDER_GEMSTONE") val MITHRIL_POWDER = ItemId("SKYBLOCK_POWDER_MITHRIL") - val GOLD_ESSENCE = ItemId("ESSENCE_GOLD") - val PELT = ItemId("SKYBLOCK_PELT") - val COINS = ItemId("SKYBLOCK_COIN") - val FINE_FLOUR = ItemId("FINE_FLOUR") - val BITS = ItemId("SKYBLOCK_BIT") - val COPPER = ItemId("SKYBLOCK_COPPER") val NIL = ItemId("SKYBLOCK_NIL") - val ARCHFIEND_LOW_CLASS = ItemId("ARCHFIEND_DICE") - val ARCHFIEND_HIGH_CLASS = ItemId("HIGH_CLASS_ARCHFIEND_DICE") - val ARCHFIEND_DYE = ItemId("DYE_ARCHFIEND") - val SLEEPING_EYE = ItemId("SLEEPING_EYE") - val SUMMONING_EYE = ItemId("SUMMONING_EYE") - val DUNGEON_CHEST_KEY = ItemId("DUNGEON_CHEST_KEY") - val BOOSTER_COOKIE = ItemId("BOOSTER_COOKIE") - val KISMET_FEATHER = ItemId("KISMET_FEATHER") } }
\ No newline at end of file diff --git a/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt b/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt index 7fe0206..0bacf32 100644 --- a/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt +++ b/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt @@ -4,6 +4,7 @@ import moe.nea.ledger.events.BeforeGuiAction import moe.nea.ledger.events.ExtraSupplyIdEvent import moe.nea.ledger.events.RegistrationFinishedEvent import moe.nea.ledger.events.SupplyDebugInfo +import moe.nea.ledger.gen.ItemIds import moe.nea.ledger.modules.ExternalDataProvider import net.minecraft.client.Minecraft import net.minecraft.item.ItemStack @@ -105,6 +106,7 @@ class ItemIdProvider { private val coinRegex = "(?<amount>$SHORT_NUMBER_PATTERN) Coins?".toPattern() private val stackedItemRegex = "(?<name>.*) x(?<count>$SHORT_NUMBER_PATTERN)".toPattern() + private val reverseStackedItemRegex = "(?<count>$SHORT_NUMBER_PATTERN)x (?<name>.*)".toPattern() private val essenceRegex = "(?<essence>.*) Essence x(?<count>$SHORT_NUMBER_PATTERN)".toPattern() private val numberedItemRegex = "(?<count>$SHORT_NUMBER_PATTERN) (?<what>.*)".toPattern() @@ -128,15 +130,15 @@ class ItemIdProvider { } etherialRewardPattern.useMatcher(properName) { val id = when (val id = group("what")) { - "Copper" -> ItemId.COPPER - "Bits" -> ItemId.BITS + "Copper" -> ItemIds.SKYBLOCK_COPPER + "Bits" -> ItemIds.SKYBLOCK_BIT "Garden Experience" -> ItemId.GARDEN "Farming XP" -> ItemId.FARMING - "Gold Essence" -> ItemId.GOLD_ESSENCE + "Gold Essence" -> ItemIds.ESSENCE_GOLD "Gemstone Powder" -> ItemId.GEMSTONE_POWDER "Mithril Powder" -> ItemId.MITHRIL_POWDER - "Pelts" -> ItemId.PELT - "Fine Flour" -> ItemId.FINE_FLOUR + "Pelts" -> ItemIds.SKYBLOCK_PELT + "Fine Flour" -> ItemIds.FINE_FLOUR else -> { id.ifDropLast(" Experience") { ItemId.skill(generateName(it).string) @@ -156,7 +158,14 @@ class ItemIdProvider { parseShortNumber(group("count"))) } stackedItemRegex.useMatcher(properName) { - var item = findForName(group("name"), fallbackToGenerated) + val item = findForName(group("name"), fallbackToGenerated) + if (item != null) { + val count = parseShortNumber(group("count")) + return Pair(item, count) + } + } + reverseStackedItemRegex.useMatcher(properName) { + val item = findForName(group("name"), fallbackToGenerated) if (item != null) { val count = parseShortNumber(group("count")) return Pair(item, count) diff --git a/src/main/kotlin/moe/nea/ledger/Ledger.kt b/src/main/kotlin/moe/nea/ledger/Ledger.kt index ee21efb..5682797 100644 --- a/src/main/kotlin/moe/nea/ledger/Ledger.kt +++ b/src/main/kotlin/moe/nea/ledger/Ledger.kt @@ -18,10 +18,14 @@ import moe.nea.ledger.modules.BazaarOrderDetection import moe.nea.ledger.modules.BitsDetection import moe.nea.ledger.modules.BitsShopDetection import moe.nea.ledger.modules.DragonEyePlacementDetection +import moe.nea.ledger.modules.`DragonSacrificeDetection` import moe.nea.ledger.modules.DungeonChestDetection import moe.nea.ledger.modules.ExternalDataProvider +import moe.nea.ledger.modules.EyedropsDetection import moe.nea.ledger.modules.ForgeDetection import moe.nea.ledger.modules.GambleDetection +import moe.nea.ledger.modules.GodPotionDetection +import moe.nea.ledger.modules.GodPotionMixinDetection import moe.nea.ledger.modules.KatDetection import moe.nea.ledger.modules.KuudraChestDetection import moe.nea.ledger.modules.MineshaftCorpseDetection @@ -122,11 +126,15 @@ class Ledger { Database::class.java, DebugDataCommand::class.java, DragonEyePlacementDetection::class.java, + DragonSacrificeDetection::class.java, DungeonChestDetection::class.java, ErrorUtil::class.java, ExternalDataProvider::class.java, + EyedropsDetection::class.java, ForgeDetection::class.java, GambleDetection::class.java, + GodPotionDetection::class.java, + GodPotionMixinDetection::class.java, ItemIdProvider::class.java, KatDetection::class.java, KuudraChestDetection::class.java, diff --git a/src/main/kotlin/moe/nea/ledger/LedgerEntry.kt b/src/main/kotlin/moe/nea/ledger/LedgerEntry.kt index dec0727..ec5548f 100644 --- a/src/main/kotlin/moe/nea/ledger/LedgerEntry.kt +++ b/src/main/kotlin/moe/nea/ledger/LedgerEntry.kt @@ -1,6 +1,7 @@ package moe.nea.ledger import com.google.gson.JsonObject +import moe.nea.ledger.gen.ItemIds import java.time.Instant import java.util.UUID @@ -10,8 +11,8 @@ data class LedgerEntry( val items: List<ItemChange>, ) { fun intoJson(profileId: UUID?): JsonObject { - val coinAmount = items.find { it.itemId == ItemId.COINS || it.itemId == ItemId.BITS }?.count - val nonCoins = items.find { it.itemId != ItemId.COINS && it.itemId != ItemId.BITS } + val coinAmount = items.find { it.itemId == ItemId.COINS || it.itemId == ItemIds.SKYBLOCK_BIT }?.count + val nonCoins = items.find { it.itemId != ItemId.COINS && it.itemId != ItemIds.SKYBLOCK_BIT } return JsonObject().apply { addProperty("transactionType", transactionType.name) addProperty("timestamp", timestamp.toEpochMilli().toString()) diff --git a/src/main/kotlin/moe/nea/ledger/TransactionType.kt b/src/main/kotlin/moe/nea/ledger/TransactionType.kt index 51105e2..26749d6 100644 --- a/src/main/kotlin/moe/nea/ledger/TransactionType.kt +++ b/src/main/kotlin/moe/nea/ledger/TransactionType.kt @@ -13,11 +13,15 @@ enum class TransactionType { BAZAAR_SELL_ORDER, BITS_PURSE_STATUS, BOOSTER_COOKIE_ATE, + CAPSAICIN_EYEDROPS_USED, COMMUNITY_SHOP_BUY, CORPSE_DESECRATED, DIE_ROLLED, + DRACONIC_SACRIFICE, DUNGEON_CHEST_OPEN, FORGED, + GOD_POTION_DRANK, + GOD_POTION_MIXIN_DRANK, KAT_TIMESKIP, KAT_UPGRADE, KISMET_REROLL, diff --git a/src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt index e4c3c98..44a0050 100644 --- a/src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt +++ b/src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt @@ -9,6 +9,7 @@ import moe.nea.ledger.LedgerLogger import moe.nea.ledger.SHORT_NUMBER_PATTERN import moe.nea.ledger.ScoreboardUtil import moe.nea.ledger.TransactionType +import moe.nea.ledger.gen.ItemIds import moe.nea.ledger.parseShortNumber import moe.nea.ledger.unformattedString import moe.nea.ledger.useMatcher @@ -33,7 +34,7 @@ class BitsDetection @Inject constructor(val ledger: LedgerLogger) { TransactionType.BITS_PURSE_STATUS, Instant.now(), listOf( - ItemChange(ItemId.BITS, bits.toDouble(), ItemChange.ChangeDirection.SYNC) + ItemChange(ItemIds.SKYBLOCK_BIT, bits.toDouble(), ItemChange.ChangeDirection.SYNC) ) ) ) @@ -52,7 +53,7 @@ class BitsDetection @Inject constructor(val ledger: LedgerLogger) { TransactionType.BOOSTER_COOKIE_ATE, Instant.now(), listOf( - ItemChange.lose(ItemId.BOOSTER_COOKIE, 1) + ItemChange.lose(ItemIds.BOOSTER_COOKIE, 1) ) ) ) diff --git a/src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt index d7e0a0d..553bebf 100644 --- a/src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt +++ b/src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt @@ -8,6 +8,7 @@ import moe.nea.ledger.LedgerEntry import moe.nea.ledger.LedgerLogger import moe.nea.ledger.SHORT_NUMBER_PATTERN import moe.nea.ledger.TransactionType +import moe.nea.ledger.gen.ItemIds import moe.nea.ledger.getInternalId import moe.nea.ledger.getLore import moe.nea.ledger.parseShortNumber @@ -54,8 +55,8 @@ class BitsShopDetection @Inject constructor(val ledger: LedgerLogger) { TransactionType.COMMUNITY_SHOP_BUY, Instant.now(), listOf( - ItemChange.lose(ItemId.BITS, lastBit.bitPrice.toDouble()), - ItemChange.gain(lastBit.id, lastBit.stackSize) + ItemChange.lose(ItemIds.SKYBLOCK_BIT, lastBit.bitPrice.toDouble()), + ItemChange.gain(lastBit.id, lastBit.stackSize) ) ) ) diff --git a/src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt index b9f70c4..e389ffb 100644 --- a/src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt +++ b/src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt @@ -7,6 +7,7 @@ import moe.nea.ledger.LedgerLogger import moe.nea.ledger.TransactionType import moe.nea.ledger.events.ChatReceived import moe.nea.ledger.events.WorldSwitchEvent +import moe.nea.ledger.gen.ItemIds import moe.nea.ledger.useMatcher import moe.nea.ledger.utils.di.Inject import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -34,7 +35,7 @@ class DragonEyePlacementDetection { TransactionType.WYRM_EVOKED, event.timestamp, listOf( - ItemChange.lose(ItemId.SUMMONING_EYE, eyeCount) + ItemChange.lose(ItemIds.SUMMONING_EYE, eyeCount) ) )) eyeCount = 0 diff --git a/src/main/kotlin/moe/nea/ledger/modules/DragonSacrificeDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/DragonSacrificeDetection.kt new file mode 100644 index 0000000..574cfcf --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/DragonSacrificeDetection.kt @@ -0,0 +1,72 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.DebouncedValue +import moe.nea.ledger.ItemChange +import moe.nea.ledger.ItemId +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.TransactionType +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.gen.ItemIds +import moe.nea.ledger.parseShortNumber +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.di.Inject +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import kotlin.time.Duration.Companion.seconds + +class DragonSacrificeDetection { + //SACRIFICE! You turned Holy Dragon Boots into 30 Dragon Essence! + //BONUS LOOT! You also received 17x Holy Dragon Fragment from your sacrifice! + @Inject + lateinit var itemIdProvider: ItemIdProvider + + @Inject + lateinit var logger: LedgerLogger + + val sacrificePattern = + "SACRIFICE! You turned (?<sacrifice>.*) into (?<amount>$SHORT_NUMBER_PATTERN) Dragon Essence!".toPattern() + val bonusLootPattern = "BONUS LOOT! You also received (?<bonus>.*) from your sacrifice!".toPattern() + + var lastSacrifice: DebouncedValue<LedgerEntry> = DebouncedValue.farFuture() + + + @SubscribeEvent + fun onChat(event: ChatReceived) { + sacrificePattern.useMatcher(event.message) { + val sacrifice = itemIdProvider.findForName(group("sacrifice")) ?: return + val lootEssence = parseShortNumber(group("amount")) + consume(lastSacrifice.replace()) + lastSacrifice = DebouncedValue(LedgerEntry( + TransactionType.DRACONIC_SACRIFICE, + event.timestamp, + listOf( + ItemChange.lose(sacrifice, 1), + ItemChange.gain(ItemIds.ESSENCE_DRAGON, lootEssence) + ) + )) + } + bonusLootPattern.useMatcher(event.message) { + val bonusItem = itemIdProvider.findStackableItemByName( + group("bonus"), true + ) ?: return + lastSacrifice.replace()?.let { + consume( + it.copy(items = it.items + ItemChange.unpairGain(bonusItem)) + ) + } + } + } + + @SubscribeEvent + fun onTick(event: TickEvent) { + consume(lastSacrifice.consume(4.seconds)) + } + + fun consume(entry: LedgerEntry?) { + if (entry != null) + logger.logEntry(entry) + } +}
\ 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 index feb452e..d61e386 100644 --- a/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt +++ b/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt @@ -9,6 +9,7 @@ import moe.nea.ledger.TransactionType import moe.nea.ledger.events.ChatReceived import moe.nea.ledger.events.ExtraSupplyIdEvent import moe.nea.ledger.events.GuiClickEvent +import moe.nea.ledger.gen.ItemIds import moe.nea.ledger.getDisplayNameU import moe.nea.ledger.unformattedString import moe.nea.ledger.useMatcher @@ -30,7 +31,7 @@ class DungeonChestDetection @Inject constructor(val logger: LedgerLogger) : Ches TransactionType.KISMET_REROLL, Instant.now(), listOf( - ItemChange.lose(ItemId.KISMET_FEATHER, 1) + ItemChange.lose(ItemIds.KISMET_FEATHER, 1) ) ) ) diff --git a/src/main/kotlin/moe/nea/ledger/modules/EyedropsDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/EyedropsDetection.kt new file mode 100644 index 0000000..04dbe80 --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/EyedropsDetection.kt @@ -0,0 +1,35 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.ItemChange +import moe.nea.ledger.ItemId +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.TransactionType +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.gen.ItemIds +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.di.Inject +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class EyedropsDetection { + + val capsaicinEyedropsUsed = "You applied the eyedrops on the minion and ran out!".toPattern() + + @Inject + lateinit var logger: LedgerLogger + + @SubscribeEvent + fun onChat(event: ChatReceived) { + capsaicinEyedropsUsed.useMatcher(event.message) { + logger.logEntry( + LedgerEntry( + TransactionType.CAPSAICIN_EYEDROPS_USED, + event.timestamp, + listOf( + ItemChange.lose(ItemIds.CAPSAICIN_EYEDROPS_NO_CHARGES, 1) + ) + ) + ) + } + } +}
\ No newline at end of file diff --git a/src/main/kotlin/moe/nea/ledger/modules/GambleDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/GambleDetection.kt index 6a339d7..a8f79c1 100644 --- a/src/main/kotlin/moe/nea/ledger/modules/GambleDetection.kt +++ b/src/main/kotlin/moe/nea/ledger/modules/GambleDetection.kt @@ -6,6 +6,7 @@ import moe.nea.ledger.LedgerEntry import moe.nea.ledger.LedgerLogger import moe.nea.ledger.TransactionType import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.gen.ItemIds import moe.nea.ledger.useMatcher import moe.nea.ledger.utils.di.Inject import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -23,7 +24,7 @@ class GambleDetection { fun onChat(event: ChatReceived) { dieRolled.useMatcher(event.message) { val isLowClass = group("isHighClass").isNullOrBlank() - val item = if (isLowClass) ItemId.ARCHFIEND_LOW_CLASS else ItemId.ARCHFIEND_HIGH_CLASS + val item = if (isLowClass) ItemIds.ARCHFIEND_DICE else ItemIds.HIGH_CLASS_ARCHFIEND_DICE val face = group("face") val rollCost = if (isLowClass) 666_000.0 else 6_600_000.0 if (face == "7") { @@ -33,7 +34,7 @@ class GambleDetection { listOf( ItemChange.lose(item, 1), ItemChange.loseCoins(rollCost), - ItemChange.gain(ItemId.ARCHFIEND_DYE, 1), + ItemChange.gain(ItemIds.DYE_ARCHFIEND, 1), ) )) } else if (face == "6") { diff --git a/src/main/kotlin/moe/nea/ledger/modules/GodPotionDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/GodPotionDetection.kt new file mode 100644 index 0000000..ae86519 --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/GodPotionDetection.kt @@ -0,0 +1,35 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.ItemChange +import moe.nea.ledger.ItemId +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.TransactionType +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.gen.ItemIds +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.di.Inject +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class GodPotionDetection { + + val godPotionDrank = "(SIP|SLURP|GULP|CHUGALUG)! The God Potion grants you powers for .*!".toPattern() + + @Inject + lateinit var logger: LedgerLogger + + @SubscribeEvent + fun onChat(event: ChatReceived) { + godPotionDrank.useMatcher(event.message) { + logger.logEntry( + LedgerEntry( + TransactionType.GOD_POTION_DRANK, + event.timestamp, + listOf( + ItemChange.lose(ItemIds.GOD_POTION_2, 1) + ) + ) + ) + } + } +}
\ No newline at end of file diff --git a/src/main/kotlin/moe/nea/ledger/modules/GodPotionMixinDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/GodPotionMixinDetection.kt new file mode 100644 index 0000000..b96a24a --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/GodPotionMixinDetection.kt @@ -0,0 +1,38 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.ItemChange +import moe.nea.ledger.ItemId +import moe.nea.ledger.ItemIdProvider +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.TransactionType +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.useMatcher +import moe.nea.ledger.utils.di.Inject +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class GodPotionMixinDetection { + + val godPotionMixinDrank = "SCHLURP! The (effects of the )?(?<what>.*?) (grants you effects|have been extended by) .*! They will pause if your God Potion expires.".toPattern() + + @Inject + lateinit var logger: LedgerLogger + + @Inject + lateinit var itemIdProvider: ItemIdProvider + + @SubscribeEvent + fun onChat(event: ChatReceived) { + godPotionMixinDrank.useMatcher(event.message) { + logger.logEntry( + LedgerEntry( + TransactionType.GOD_POTION_MIXIN_DRANK, + event.timestamp, + listOf( + ItemChange.lose(itemIdProvider.findForName(group("what")) ?: ItemId.NIL, 1) + ) + ) + ) + } + } +}
\ No newline at end of file |