aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/ledger
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/moe/nea/ledger')
-rw-r--r--src/main/kotlin/moe/nea/ledger/DebouncedValue.kt38
-rw-r--r--src/main/kotlin/moe/nea/ledger/ExpiringValue.kt6
-rw-r--r--src/main/kotlin/moe/nea/ledger/ItemId.kt3
-rw-r--r--src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt10
-rw-r--r--src/main/kotlin/moe/nea/ledger/Ledger.kt20
-rw-r--r--src/main/kotlin/moe/nea/ledger/TransactionType.kt4
-rw-r--r--src/main/kotlin/moe/nea/ledger/events/WorldSwitchEvent.kt6
-rw-r--r--src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt46
-rw-r--r--src/main/kotlin/moe/nea/ledger/modules/DragonSacrificeDetection.kt71
-rw-r--r--src/main/kotlin/moe/nea/ledger/modules/UpdateChecker.kt22
10 files changed, 213 insertions, 13 deletions
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 2b83357..f627d08 100644
--- a/src/main/kotlin/moe/nea/ledger/ItemId.kt
+++ b/src/main/kotlin/moe/nea/ledger/ItemId.kt
@@ -21,6 +21,7 @@ value class ItemId(
val GEMSTONE_POWDER = ItemId("SKYBLOCK_POWDER_GEMSTONE")
val MITHRIL_POWDER = ItemId("SKYBLOCK_POWDER_MITHRIL")
val GOLD_ESSENCE = ItemId("ESSENCE_GOLD")
+ val DRAGON_ESSENCE = ItemId("ESSENCE_DRAGON")
val PELT = ItemId("SKYBLOCK_PELT")
val COINS = ItemId("SKYBLOCK_COIN")
val FINE_FLOUR = ItemId("FINE_FLOUR")
@@ -30,6 +31,8 @@ value class ItemId(
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")
diff --git a/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt b/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt
index 7fe0206..4d85713 100644
--- a/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt
+++ b/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt
@@ -105,6 +105,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()
@@ -156,7 +157,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 72bd32f..ed3c6a2 100644
--- a/src/main/kotlin/moe/nea/ledger/Ledger.kt
+++ b/src/main/kotlin/moe/nea/ledger/Ledger.kt
@@ -9,6 +9,7 @@ import moe.nea.ledger.database.Database
import moe.nea.ledger.events.ChatReceived
import moe.nea.ledger.events.LateWorldLoadEvent
import moe.nea.ledger.events.RegistrationFinishedEvent
+import moe.nea.ledger.events.WorldSwitchEvent
import moe.nea.ledger.gen.BuildConfig
import moe.nea.ledger.modules.AuctionHouseDetection
import moe.nea.ledger.modules.BankDetection
@@ -16,6 +17,8 @@ import moe.nea.ledger.modules.BazaarDetection
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.ForgeDetection
@@ -114,29 +117,31 @@ class Ledger {
BankDetection::class.java,
BazaarDetection::class.java,
BazaarOrderDetection::class.java,
- DebugDataCommand::class.java,
BitsDetection::class.java,
BitsShopDetection::class.java,
ConfigCommand::class.java,
Database::class.java,
+ DebugDataCommand::class.java,
+ DragonEyePlacementDetection::class.java,
+ DragonSacrificeDetection::class.java,
DungeonChestDetection::class.java,
ErrorUtil::class.java,
ExternalDataProvider::class.java,
+ ForgeDetection::class.java,
+ GambleDetection::class.java,
ItemIdProvider::class.java,
KatDetection::class.java,
KuudraChestDetection::class.java,
LedgerLogger::class.java,
LogChatCommand::class.java,
- MinionDetection::class.java,
+ MinecraftExecutor::class.java,
MineshaftCorpseDetection::class.java,
- ForgeDetection::class.java,
+ MinionDetection::class.java,
NpcDetection::class.java,
- GambleDetection::class.java,
- MinecraftExecutor::class.java,
- UpdateChecker::class.java,
- TriggerCommand::class.java,
QueryCommand::class.java,
RequestUtil::class.java,
+ TriggerCommand::class.java,
+ UpdateChecker::class.java,
VisitorDetection::class.java,
)
val errorUtil = di.provide<ErrorUtil>()
@@ -160,6 +165,7 @@ class Ledger {
fun worldSwitchEvent(event: EntityJoinWorldEvent) {
if (event.entity == Minecraft.getMinecraft().thePlayer) {
lastJoin = System.currentTimeMillis()
+ MinecraftForge.EVENT_BUS.post(WorldSwitchEvent())
}
}
diff --git a/src/main/kotlin/moe/nea/ledger/TransactionType.kt b/src/main/kotlin/moe/nea/ledger/TransactionType.kt
index f6bbe6a..57f7535 100644
--- a/src/main/kotlin/moe/nea/ledger/TransactionType.kt
+++ b/src/main/kotlin/moe/nea/ledger/TransactionType.kt
@@ -15,9 +15,10 @@ enum class TransactionType {
BOOSTER_COOKIE_ATE,
COMMUNITY_SHOP_BUY,
CORPSE_DESECRATED,
- FORGED,
DIE_ROLLED,
+ DRACONIC_SACRIFICE,
DUNGEON_CHEST_OPEN,
+ FORGED,
KAT_TIMESKIP,
KAT_UPGRADE,
KISMET_REROLL,
@@ -25,4 +26,5 @@ enum class TransactionType {
NPC_BUY,
NPC_SELL,
VISITOR_BARGAIN,
+ WYRM_EVOKED,
} \ No newline at end of file
diff --git a/src/main/kotlin/moe/nea/ledger/events/WorldSwitchEvent.kt b/src/main/kotlin/moe/nea/ledger/events/WorldSwitchEvent.kt
new file mode 100644
index 0000000..22a97f7
--- /dev/null
+++ b/src/main/kotlin/moe/nea/ledger/events/WorldSwitchEvent.kt
@@ -0,0 +1,6 @@
+package moe.nea.ledger.events
+
+import net.minecraftforge.fml.common.eventhandler.Event
+
+class WorldSwitchEvent : Event() {
+} \ No newline at end of file
diff --git a/src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt
new file mode 100644
index 0000000..b9f70c4
--- /dev/null
+++ b/src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt
@@ -0,0 +1,46 @@
+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.events.WorldSwitchEvent
+import moe.nea.ledger.useMatcher
+import moe.nea.ledger.utils.di.Inject
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+class DragonEyePlacementDetection {
+ val eyePlaced = "☬ You placed a Summoning Eye!( Brace yourselves!)? \\(./.\\)".toPattern()
+//☬ You placed a Summoning Eye! Brace yourselves! (8/8)
+ var eyeCount = 0
+
+ @SubscribeEvent
+ fun onWorldSwap(event: WorldSwitchEvent) {
+ eyeCount = 0
+ }
+
+ @SubscribeEvent
+ fun onRetrieveEye(event: ChatReceived) {
+ if (event.message == "You recovered a Summoning Eye!") {
+ eyeCount--
+ }
+ eyePlaced.useMatcher(event.message) {
+ eyeCount++
+ }
+ if (event.message == "Your Sleeping Eyes have been awoken by the magic of the Dragon. They are now Remnants of the Eye!") {
+ logger.logEntry(LedgerEntry(
+ TransactionType.WYRM_EVOKED,
+ event.timestamp,
+ listOf(
+ ItemChange.lose(ItemId.SUMMONING_EYE, eyeCount)
+ )
+ ))
+ eyeCount = 0
+ }
+ }
+
+ @Inject
+ lateinit var logger: LedgerLogger
+} \ No newline at end of file
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..20934d2
--- /dev/null
+++ b/src/main/kotlin/moe/nea/ledger/modules/DragonSacrificeDetection.kt
@@ -0,0 +1,71 @@
+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.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(ItemId.DRAGON_ESSENCE, 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/UpdateChecker.kt b/src/main/kotlin/moe/nea/ledger/modules/UpdateChecker.kt
index 1d6e299..0d89ca1 100644
--- a/src/main/kotlin/moe/nea/ledger/modules/UpdateChecker.kt
+++ b/src/main/kotlin/moe/nea/ledger/modules/UpdateChecker.kt
@@ -1,5 +1,6 @@
package moe.nea.ledger.modules
+import com.google.gson.JsonElement
import com.google.gson.JsonPrimitive
import moe.nea.ledger.DevUtil
import moe.nea.ledger.LedgerLogger
@@ -38,7 +39,25 @@ class UpdateChecker @Inject constructor(
NightlyAwareGithubUpdateSource("nea89o", "LocalTransactionLedger"),
if (DevUtil.isDevEnv) UpdateTarget { listOf() }
else UpdateTarget.deleteAndSaveInTheSameFolder(UpdateChecker::class.java),
- CurrentVersion.ofTag(BuildConfig.GIT_COMMIT),
+ object : CurrentVersion {
+ override fun display(): String {
+ return BuildConfig.VERSION
+ }
+
+ override fun isOlderThan(element: JsonElement?): Boolean {
+ if (element !is JsonPrimitive || !element.isString) return true
+ val newHash = element.asString // TODO: change once i support non nightly update streams
+ val length = minOf(newHash.length, BuildConfig.GIT_COMMIT.length)
+ if (newHash.substring(0, length).equals(BuildConfig.GIT_COMMIT.substring(0, length), ignoreCase = true))
+ return false
+ return true
+ }
+
+
+ override fun toString(): String {
+ return "{gitversion:${BuildConfig.GIT_COMMIT}, version:${BuildConfig.FULL_VERSION}}"
+ }
+ },
"ledger"
)
@@ -112,7 +131,6 @@ class UpdateChecker @Inject constructor(
fun informAboutUpdates(potentialUpdate: PotentialUpdate) {
if (hasNotified) return
hasNotified = true
-// logger.printOut("Update: ${potentialUpdate}")
if (!potentialUpdate.isUpdateAvailable) return
logger.printOut(
ChatComponentText("§aThere is a new update for LocalTransactionLedger. Click here to automatically download and install it.")