aboutsummaryrefslogtreecommitdiff
path: root/mod/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'mod/src/main')
-rw-r--r--mod/src/main/java/moe/nea/ledger/init/AutoDiscoveryMixinPlugin.java2
-rw-r--r--mod/src/main/java/moe/nea/ledger/mixin/AccessorContainerDispenser.java12
-rw-r--r--mod/src/main/java/moe/nea/ledger/mixin/AccessorContainerHopper.java13
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/ItemChange.kt84
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/ItemId.kt35
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt4
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/Ledger.kt25
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/NumberUtil.kt35
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/QueryCommand.kt4
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/TransactionType.kt35
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/config/DebugOptions.kt3
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/database/DBLogEntry.kt24
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/database/DBUpgrade.kt68
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/database/Database.kt57
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/database/Upgrades.kt20
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/database/schema.dot23
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/events/BeforeGuiAction.kt12
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/events/LedgerEvent.kt22
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/AccessorySwapperDetection.kt6
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/BankInterestDetection.kt44
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/BasicReforgeDetection.kt71
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt5
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt8
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/CaducousFeederDetection.kt48
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt1
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/DragonSacrificeDetection.kt1
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt2
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/ExternalDataProvider.kt5
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/EyedropsDetection.kt7
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/ForgeDetection.kt3
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/GambleDetection.kt1
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/GhostCoinDropDetection.kt38
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/GodPotionDetection.kt7
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/GodPotionMixinDetection.kt6
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/GummyPolarBearDetection.kt34
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/KuudraChestDetection.kt3
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/PestRepellentDetection.kt47
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/StonksAuctionDetection.kt59
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/modules/VisitorDetection.kt3
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/telemetry/GuiContextValue.kt16
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/telemetry/TelemetryProvider.kt (renamed from mod/src/main/kotlin/moe/nea/ledger/TelemetryProvider.kt)6
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/utils/NoSideEffects.kt4
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/utils/ScreenUtil.kt29
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/utils/network/RequestTrace.kt21
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/utils/network/RequestUtil.kt9
-rw-r--r--mod/src/main/kotlin/moe/nea/ledger/utils/telemetry/Span.kt3
46 files changed, 571 insertions, 394 deletions
diff --git a/mod/src/main/java/moe/nea/ledger/init/AutoDiscoveryMixinPlugin.java b/mod/src/main/java/moe/nea/ledger/init/AutoDiscoveryMixinPlugin.java
index 56841b5..64fa6c2 100644
--- a/mod/src/main/java/moe/nea/ledger/init/AutoDiscoveryMixinPlugin.java
+++ b/mod/src/main/java/moe/nea/ledger/init/AutoDiscoveryMixinPlugin.java
@@ -96,6 +96,8 @@ public class AutoDiscoveryMixinPlugin implements IMixinConfigPlugin {
* @param className the name or path of a class to be registered as a mixin.
*/
public void tryAddMixinClass(String className) {
+ if (!className.endsWith(".class")) return;
+ if (className.indexOf('$') >= 0) return;
String norm = (className.endsWith(".class") ? className.substring(0, className.length() - ".class".length()) : className)
.replace("\\", "/")
.replace("/", ".");
diff --git a/mod/src/main/java/moe/nea/ledger/mixin/AccessorContainerDispenser.java b/mod/src/main/java/moe/nea/ledger/mixin/AccessorContainerDispenser.java
new file mode 100644
index 0000000..a3d32c4
--- /dev/null
+++ b/mod/src/main/java/moe/nea/ledger/mixin/AccessorContainerDispenser.java
@@ -0,0 +1,12 @@
+package moe.nea.ledger.mixin;
+
+import net.minecraft.inventory.ContainerDispenser;
+import net.minecraft.inventory.IInventory;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+@Mixin(ContainerDispenser.class)
+public interface AccessorContainerDispenser {
+ @Accessor("dispenserInventory")
+ IInventory getDispenserInventory_ledger();
+}
diff --git a/mod/src/main/java/moe/nea/ledger/mixin/AccessorContainerHopper.java b/mod/src/main/java/moe/nea/ledger/mixin/AccessorContainerHopper.java
new file mode 100644
index 0000000..ee29d4f
--- /dev/null
+++ b/mod/src/main/java/moe/nea/ledger/mixin/AccessorContainerHopper.java
@@ -0,0 +1,13 @@
+package moe.nea.ledger.mixin;
+
+import net.minecraft.inventory.ContainerDispenser;
+import net.minecraft.inventory.ContainerHopper;
+import net.minecraft.inventory.IInventory;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+@Mixin(ContainerHopper.class)
+public interface AccessorContainerHopper {
+ @Accessor("hopperInventory")
+ IInventory getHopperInventory_ledger();
+}
diff --git a/mod/src/main/kotlin/moe/nea/ledger/ItemChange.kt b/mod/src/main/kotlin/moe/nea/ledger/ItemChange.kt
deleted file mode 100644
index fda709c..0000000
--- a/mod/src/main/kotlin/moe/nea/ledger/ItemChange.kt
+++ /dev/null
@@ -1,84 +0,0 @@
-package moe.nea.ledger
-
-import moe.nea.ledger.database.DBItemEntry
-import moe.nea.ledger.database.ResultRow
-import net.minecraft.event.HoverEvent
-import net.minecraft.util.ChatComponentText
-import net.minecraft.util.ChatStyle
-import net.minecraft.util.EnumChatFormatting
-import net.minecraft.util.IChatComponent
-
-data class ItemChange(
- val itemId: ItemId,
- val count: Double,
- val direction: ChangeDirection,
-) {
- fun formatChat(): IChatComponent {
- return ChatComponentText(" ")
- .appendSibling(direction.chatFormat)
- .appendText(" ")
- .appendSibling(ChatComponentText("$count").setChatStyle(ChatStyle().setColor(EnumChatFormatting.WHITE)))
- .appendSibling(ChatComponentText("x").setChatStyle(ChatStyle().setColor(EnumChatFormatting.DARK_GRAY)))
- .appendText(" ")
- .appendSibling(ChatComponentText(itemId.string).setChatStyle(ChatStyle().setParentStyle(ChatStyle().setColor(
- EnumChatFormatting.WHITE))))
- }
-
- enum class ChangeDirection {
- GAINED,
- TRANSFORM,
- SYNC,
- CATALYST,
- LOST;
-
- val chatFormat by lazy { formatChat0() }
- private fun formatChat0(): IChatComponent {
- val (text, color) = when (this) {
- GAINED -> "+" to EnumChatFormatting.GREEN
- TRANSFORM -> "~" to EnumChatFormatting.YELLOW
- SYNC -> "=" to EnumChatFormatting.BLUE
- CATALYST -> "*" to EnumChatFormatting.DARK_PURPLE
- LOST -> "-" to EnumChatFormatting.RED
- }
- return ChatComponentText(text)
- .setChatStyle(
- ChatStyle()
- .setColor(color)
- .setChatHoverEvent(HoverEvent(HoverEvent.Action.SHOW_TEXT,
- ChatComponentText(name).setChatStyle(ChatStyle().setColor(color)))))
- }
- }
-
- companion object {
- fun gainCoins(number: Double): ItemChange {
- return gain(ItemId.COINS, number)
- }
-
- fun unpair(direction: ChangeDirection, pair: Pair<ItemId, Double>): ItemChange {
- return ItemChange(pair.first, pair.second, direction)
- }
-
- fun unpairGain(pair: Pair<ItemId, Double>) = unpair(ChangeDirection.GAINED, pair)
- fun unpairLose(pair: Pair<ItemId, Double>) = unpair(ChangeDirection.LOST, pair)
-
- fun gain(itemId: ItemId, amount: Number): ItemChange {
- return ItemChange(itemId, amount.toDouble(), ChangeDirection.GAINED)
- }
-
- fun lose(itemId: ItemId, amount: Number): ItemChange {
- return ItemChange(itemId, amount.toDouble(), ChangeDirection.LOST)
- }
-
- fun loseCoins(number: Double): ItemChange {
- return lose(ItemId.COINS, number)
- }
-
- fun from(result: ResultRow): ItemChange {
- return ItemChange(
- result[DBItemEntry.itemId],
- result[DBItemEntry.size],
- result[DBItemEntry.mode],
- )
- }
- }
-} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/ItemId.kt b/mod/src/main/kotlin/moe/nea/ledger/ItemId.kt
deleted file mode 100644
index 8211cd3..0000000
--- a/mod/src/main/kotlin/moe/nea/ledger/ItemId.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package moe.nea.ledger
-
-import moe.nea.ledger.utils.NoSideEffects
-
-data class ItemId(
- val string: String
-) {
- @NoSideEffects
- fun singleItem(): Pair<ItemId, Double> {
- return withStackSize(1)
- }
-
- @NoSideEffects
- fun withStackSize(size: Number): Pair<ItemId, Double> {
- return Pair(this, size.toDouble())
- }
-
-
- companion object {
-
- @JvmStatic
- @NoSideEffects
- 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 NIL = ItemId("SKYBLOCK_NIL")
- }
-} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt b/mod/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt
index 0bacf32..ff2c691 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt
@@ -20,12 +20,12 @@ class ItemIdProvider {
@SubscribeEvent
fun onMouseInput(event: GuiScreenEvent.MouseInputEvent.Pre) {
if (Mouse.getEventButton() == -1) return
- MinecraftForge.EVENT_BUS.post(BeforeGuiAction(event.gui))
+ BeforeGuiAction(event.gui).post()
}
@SubscribeEvent
fun onKeyInput(event: GuiScreenEvent.KeyboardInputEvent.Pre) {
- MinecraftForge.EVENT_BUS.post(BeforeGuiAction(event.gui))
+ BeforeGuiAction(event.gui).post()
}
private val knownNames = mutableMapOf<String, ItemId>()
diff --git a/mod/src/main/kotlin/moe/nea/ledger/Ledger.kt b/mod/src/main/kotlin/moe/nea/ledger/Ledger.kt
index bc667e4..87c990c 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/Ledger.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/Ledger.kt
@@ -16,26 +16,34 @@ import moe.nea.ledger.modules.AccessorySwapperDetection
import moe.nea.ledger.modules.AllowanceDetection
import moe.nea.ledger.modules.AuctionHouseDetection
import moe.nea.ledger.modules.BankDetection
+import moe.nea.ledger.modules.BankInterestDetection
+import moe.nea.ledger.modules.BasicReforgeDetection
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.CaducousFeederDetection
import moe.nea.ledger.modules.DragonEyePlacementDetection
-import moe.nea.ledger.modules.`DragonSacrificeDetection`
+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.GhostCoinDropDetection
import moe.nea.ledger.modules.GodPotionDetection
import moe.nea.ledger.modules.GodPotionMixinDetection
+import moe.nea.ledger.modules.GummyPolarBearDetection
import moe.nea.ledger.modules.KatDetection
import moe.nea.ledger.modules.KuudraChestDetection
import moe.nea.ledger.modules.MineshaftCorpseDetection
import moe.nea.ledger.modules.MinionDetection
import moe.nea.ledger.modules.NpcDetection
+import moe.nea.ledger.modules.PestRepellentDetection
+import moe.nea.ledger.modules.StonksAuctionDetection
import moe.nea.ledger.modules.UpdateChecker
import moe.nea.ledger.modules.VisitorDetection
+import moe.nea.ledger.telemetry.TelemetryProvider
import moe.nea.ledger.utils.ErrorUtil
import moe.nea.ledger.utils.MinecraftExecutor
import moe.nea.ledger.utils.di.DI
@@ -88,7 +96,7 @@ class Ledger {
// You sold Cactus x1 for 3 Coins!
// You bought back Potato x3 for 9 Coins!
- TODO: TRADING, FORGE, VISITORS / COPPER, CORPSES ÖFFNEN, HIGH / LOW GAMBLES, MINION ITEMS (maybe inferno refuel)
+ TODO: TRADING, FORGE, MINION ITEMS (maybe inferno refuel)
TODO: PET LEVELING COSTS AT FANN, SLAYER / MOB DROPS, SLAYER START COST
*/
companion object {
@@ -106,7 +114,9 @@ class Ledger {
tickQueue.add(runnable)
}
- val di = DI()
+ private val di = DI()
+
+ fun leakDI() = di
}
@Mod.EventHandler
@@ -119,17 +129,20 @@ class Ledger {
di.registerSingleton(gson)
di.register(LedgerConfig::class.java, DIProvider { managedConfig.instance })
di.register(Config::class.java, DIProvider.fromInheritance(LedgerConfig::class.java))
+ di.register(Database::class.java, DIProvider { Database(dataFolder) })
di.registerInjectableClasses(
AccessorySwapperDetection::class.java,
AllowanceDetection::class.java,
AuctionHouseDetection::class.java,
BankDetection::class.java,
+ BankInterestDetection::class.java,
+ BasicReforgeDetection::class.java,
BazaarDetection::class.java,
BazaarOrderDetection::class.java,
BitsDetection::class.java,
BitsShopDetection::class.java,
+ CaducousFeederDetection::class.java,
ConfigCommand::class.java,
- Database::class.java,
DebugDataCommand::class.java,
DragonEyePlacementDetection::class.java,
DragonSacrificeDetection::class.java,
@@ -139,8 +152,10 @@ class Ledger {
EyedropsDetection::class.java,
ForgeDetection::class.java,
GambleDetection::class.java,
+ GhostCoinDropDetection::class.java,
GodPotionDetection::class.java,
GodPotionMixinDetection::class.java,
+ GummyPolarBearDetection::class.java,
ItemIdProvider::class.java,
KatDetection::class.java,
KuudraChestDetection::class.java,
@@ -150,8 +165,10 @@ class Ledger {
MineshaftCorpseDetection::class.java,
MinionDetection::class.java,
NpcDetection::class.java,
+ PestRepellentDetection::class.java,
QueryCommand::class.java,
RequestUtil::class.java,
+ StonksAuctionDetection::class.java,
TriggerCommand::class.java,
UpdateChecker::class.java,
VisitorDetection::class.java,
diff --git a/mod/src/main/kotlin/moe/nea/ledger/NumberUtil.kt b/mod/src/main/kotlin/moe/nea/ledger/NumberUtil.kt
index 438f342..fa295b0 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/NumberUtil.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/NumberUtil.kt
@@ -115,3 +115,38 @@ fun Instant.formatChat(): IChatComponent {
.setColor(EnumChatFormatting.AQUA))
return text
}
+
+private val formatChatDirection = run {
+ fun ItemChange.ChangeDirection.formatChat0(): IChatComponent {
+ val (text, color) = when (this) {
+ ItemChange.ChangeDirection.GAINED -> "+" to EnumChatFormatting.GREEN
+ ItemChange.ChangeDirection.TRANSFORM -> "~" to EnumChatFormatting.YELLOW
+ ItemChange.ChangeDirection.SYNC -> "=" to EnumChatFormatting.BLUE
+ ItemChange.ChangeDirection.CATALYST -> "*" to EnumChatFormatting.DARK_PURPLE
+ ItemChange.ChangeDirection.LOST -> "-" to EnumChatFormatting.RED
+ }
+ return ChatComponentText(text)
+ .setChatStyle(
+ ChatStyle()
+ .setColor(color)
+ .setChatHoverEvent(HoverEvent(HoverEvent.Action.SHOW_TEXT,
+ ChatComponentText(name).setChatStyle(ChatStyle().setColor(color)))))
+ }
+ ItemChange.ChangeDirection.entries.associateWith { it.formatChat0() }
+}
+
+fun ItemChange.ChangeDirection.formatChat(): IChatComponent {
+ return formatChatDirection[this]!!
+}
+
+fun ItemChange.formatChat(): IChatComponent {
+ return ChatComponentText(" ")
+ .appendSibling(direction.formatChat())
+ .appendText(" ")
+ .appendSibling(ChatComponentText("$count").setChatStyle(ChatStyle().setColor(EnumChatFormatting.WHITE)))
+ .appendSibling(ChatComponentText("x").setChatStyle(ChatStyle().setColor(EnumChatFormatting.DARK_GRAY)))
+ .appendText(" ")
+ .appendSibling(ChatComponentText(itemId.string).setChatStyle(ChatStyle().setParentStyle(ChatStyle().setColor(
+ EnumChatFormatting.WHITE))))
+}
+
diff --git a/mod/src/main/kotlin/moe/nea/ledger/QueryCommand.kt b/mod/src/main/kotlin/moe/nea/ledger/QueryCommand.kt
index 19bd5d0..80dd54c 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/QueryCommand.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/QueryCommand.kt
@@ -103,7 +103,7 @@ class QueryCommand : CommandBase() {
val timestamp = transactionId.getTimestamp()
val items = DBItemEntry.selectAll(database.connection)
.where(Clause { column(DBItemEntry.transactionId) eq string(transactionId.wrapped) })
- .map { ItemChange.from(it) }
+ .map { DBItemEntry.objMap(it) }
val text = ChatComponentText("")
.setChatStyle(ChatStyle().setColor(EnumChatFormatting.YELLOW))
.appendSibling(
@@ -172,7 +172,7 @@ class QueryCommand : CommandBase() {
override val name: String
get() = "withitem"
- private val itemIdProvider = Ledger.di.provide<ItemIdProvider>() // TODO: close this escape hatch
+ private val itemIdProvider = Ledger.leakDI().provide<ItemIdProvider>() // TODO: close this escape hatch
override fun getFilter(text: String): BooleanExpression {
return Clause { column(DBItemEntry.itemId) like text }
}
diff --git a/mod/src/main/kotlin/moe/nea/ledger/TransactionType.kt b/mod/src/main/kotlin/moe/nea/ledger/TransactionType.kt
deleted file mode 100644
index 33c633d..0000000
--- a/mod/src/main/kotlin/moe/nea/ledger/TransactionType.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package moe.nea.ledger
-
-enum class TransactionType {
- ACCESSORIES_SWAPPING,
- ALLOWANCE_GAIN,
- AUCTION_BOUGHT,
- AUCTION_LISTING_CHARGE,
- AUCTION_SOLD,
- AUTOMERCHANT_PROFIT_COLLECT,
- BANK_DEPOSIT,
- BANK_WITHDRAW,
- BAZAAR_BUY_INSTANT,
- BAZAAR_BUY_ORDER,
- BAZAAR_SELL_INSTANT,
- 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,
- KUUDRA_CHEST_OPEN,
- NPC_BUY,
- NPC_SELL,
- VISITOR_BARGAIN,
- WYRM_EVOKED,
-} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/config/DebugOptions.kt b/mod/src/main/kotlin/moe/nea/ledger/config/DebugOptions.kt
index fd5ed3d..6b4e51c 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/config/DebugOptions.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/config/DebugOptions.kt
@@ -2,6 +2,7 @@ package moe.nea.ledger.config
import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorBoolean
import io.github.notenoughupdates.moulconfig.annotations.ConfigOption
+import moe.nea.ledger.DevUtil
class DebugOptions {
@ConfigOption(name = "Log entries to chat",
@@ -9,5 +10,5 @@ class DebugOptions {
@Transient
@ConfigEditorBoolean
@JvmField
- var logEntries = false
+ var logEntries = DevUtil.isDevEnv
}
diff --git a/mod/src/main/kotlin/moe/nea/ledger/database/DBLogEntry.kt b/mod/src/main/kotlin/moe/nea/ledger/database/DBLogEntry.kt
deleted file mode 100644
index b162c6f..0000000
--- a/mod/src/main/kotlin/moe/nea/ledger/database/DBLogEntry.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package moe.nea.ledger.database
-
-import moe.nea.ledger.ItemChange
-import moe.nea.ledger.ItemId
-import moe.nea.ledger.TransactionType
-import moe.nea.ledger.database.columns.DBDouble
-import moe.nea.ledger.database.columns.DBEnum
-import moe.nea.ledger.database.columns.DBString
-import moe.nea.ledger.database.columns.DBUlid
-import moe.nea.ledger.database.columns.DBUuid
-
-object DBLogEntry : Table("LogEntry") {
- val transactionId = column("transactionId", DBUlid)
- val type = column("type", DBEnum<TransactionType>())
- val profileId = column("profileId", DBUuid)
- val playerId = column("playerId", DBUuid)
-}
-
-object DBItemEntry : Table("ItemEntry") {
- val transactionId = column("transactionId", DBUlid) // TODO: add foreign keys
- val mode = column("mode", DBEnum<ItemChange.ChangeDirection>())
- val itemId = column("item", DBString.mapped(ItemId::string, ::ItemId))
- val size = column("size", DBDouble)
-}
diff --git a/mod/src/main/kotlin/moe/nea/ledger/database/DBUpgrade.kt b/mod/src/main/kotlin/moe/nea/ledger/database/DBUpgrade.kt
deleted file mode 100644
index 7d1782a..0000000
--- a/mod/src/main/kotlin/moe/nea/ledger/database/DBUpgrade.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-package moe.nea.ledger.database
-
-import java.sql.Connection
-
-interface DBUpgrade {
- val toVersion: Long
- val fromVersion get() = toVersion - 1
- fun performUpgrade(connection: Connection)
-
- companion object {
-
- fun performUpgrades(
- connection: Connection,
- upgrades: Iterable<DBUpgrade>,
- ) {
- for (upgrade in upgrades) {
- upgrade.performUpgrade(connection)
- }
- }
-
- fun performUpgradeChain(
- connection: Connection,
- from: Long, to: Long,
- upgrades: Iterable<DBUpgrade>,
- afterEach: (newVersion: Long) -> Unit,
- ) {
- val table = buildLookup(upgrades)
- for (version in (from + 1)..(to)) {
- val currentUpgrades = table[version] ?: listOf()
- println("Scheduled ${currentUpgrades.size} upgrades to reach DB version $version")
- performUpgrades(connection, currentUpgrades)
- afterEach(version)
- }
- }
-
- fun buildLookup(upgrades: Iterable<DBUpgrade>): Map<Long, List<DBUpgrade>> {
- return upgrades.groupBy { it.toVersion }
- }
-
- fun createTable(to: Long, table: Table, vararg columns: Column<*>): DBUpgrade {
- require(columns.all { it in table.columns })
- return of("Create table ${table}", to) {
- table.createIfNotExists(it, columns.toList())
- }
- }
-
- fun addColumns(to: Long, table: Table, vararg columns: Column<*>): DBUpgrade {
- return of("Add columns to table $table", to) {
- table.alterTableAddColumns(it, columns.toList())
- }
- }
-
- fun of(name: String, to: Long, block: (Connection) -> Unit): DBUpgrade {
- return object : DBUpgrade {
- override val toVersion: Long
- get() = to
-
- override fun performUpgrade(connection: Connection) {
- block(connection)
- }
-
- override fun toString(): String {
- return name
- }
- }
- }
- }
-} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/database/Database.kt b/mod/src/main/kotlin/moe/nea/ledger/database/Database.kt
deleted file mode 100644
index 025888c..0000000
--- a/mod/src/main/kotlin/moe/nea/ledger/database/Database.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-package moe.nea.ledger.database
-
-import moe.nea.ledger.Ledger
-import moe.nea.ledger.database.columns.DBString
-import java.sql.Connection
-import java.sql.DriverManager
-
-class Database {
- lateinit var connection: Connection
-
- object MetaTable : Table("LedgerMeta") {
- val key = column("key", DBString)
- val value = column("value", DBString)
-
- init {
- unique(key)
- }
- }
-
- data class MetaKey(val name: String) {
- companion object {
- val DATABASE_VERSION = MetaKey("databaseVersion")
- val LAST_LAUNCH = MetaKey("lastLaunch")
- }
- }
-
- fun setMetaKey(key: MetaKey, value: String) {
- MetaTable.insert(connection, Table.OnConflict.REPLACE) {
- it[MetaTable.key] = key.name
- it[MetaTable.value] = value
- }
- }
-
- val databaseVersion: Long = 1
-
- fun loadAndUpgrade() {
- connection = DriverManager.getConnection("jdbc:sqlite:${Ledger.dataFolder.resolve("database.db")}")
- MetaTable.createIfNotExists(connection)
- val meta = MetaTable.selectAll(connection).associate { MetaKey(it[MetaTable.key]) to it[MetaTable.value] }
- val lastLaunch = meta[MetaKey.LAST_LAUNCH]?.toLong() ?: 0L
- println("Last launch $lastLaunch")
- setMetaKey(MetaKey.LAST_LAUNCH, System.currentTimeMillis().toString())
-
- val oldVersion = meta[MetaKey.DATABASE_VERSION]?.toLong() ?: -1
- println("Old Database Version: $oldVersion; Current version: $databaseVersion")
- if (oldVersion > databaseVersion)
- error("Outdated software. Database is newer than me!")
- // TODO: create a backup if there is a db version upgrade happening
- DBUpgrade.performUpgradeChain(
- connection, oldVersion, databaseVersion,
- Upgrades().upgrades
- ) { version ->
- setMetaKey(MetaKey.DATABASE_VERSION, version.toString())
- }
- }
-
-} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/database/Upgrades.kt b/mod/src/main/kotlin/moe/nea/ledger/database/Upgrades.kt
deleted file mode 100644
index e83abe7..0000000
--- a/mod/src/main/kotlin/moe/nea/ledger/database/Upgrades.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package moe.nea.ledger.database
-
-class Upgrades {
- val upgrades = mutableListOf<DBUpgrade>()
-
- fun add(upgrade: DBUpgrade) = upgrades.add(upgrade)
-
- init {
- add(DBUpgrade.createTable(
- 0, DBLogEntry,
- DBLogEntry.type, DBLogEntry.playerId, DBLogEntry.profileId,
- DBLogEntry.transactionId))
- add(DBUpgrade.createTable(
- 0, DBItemEntry,
- DBItemEntry.itemId, DBItemEntry.size, DBItemEntry.mode, DBItemEntry.transactionId
- ))
- }
-
-
-} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/database/schema.dot b/mod/src/main/kotlin/moe/nea/ledger/database/schema.dot
deleted file mode 100644
index d932f6a..0000000
--- a/mod/src/main/kotlin/moe/nea/ledger/database/schema.dot
+++ /dev/null
@@ -1,23 +0,0 @@
-digraph {
- node [shape=plain];
- rankdir=LR;
- entry [label=<
- <table border="0" cellborder="1" cellspacing="0">
- <tr><td>Log Entry</td></tr>
- <tr><td port="player">playerId</td></tr>
- <tr><td port="profile">profileId</td></tr>
- <tr><td port="date">timestamp</td></tr>
- <tr><td port="type">Type</td></tr>
- </table>
- >];
- item [label=<
- <table border="0" cellborder="1" cellspacing="0">
- <tr><td>Item Stack</td><tr>
- <tr><td port="transaction">Transaction</td></tr>
- <tr><td port="id">Item ID</td></tr>
- <tr><td port="count">Count</td></tr>
- <tr><td port="direction">Transfer Direction</td></tr>
- </table>
- >];
-// item:transaction -> entry;
-} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/events/BeforeGuiAction.kt b/mod/src/main/kotlin/moe/nea/ledger/events/BeforeGuiAction.kt
index 098912a..7f6eae9 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/events/BeforeGuiAction.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/events/BeforeGuiAction.kt
@@ -1,11 +1,21 @@
package moe.nea.ledger.events
+import com.google.gson.JsonElement
+import com.google.gson.JsonObject
+import moe.nea.ledger.telemetry.GuiContextValue
+import moe.nea.ledger.utils.telemetry.ContextValue
import net.minecraft.client.gui.GuiScreen
import net.minecraft.client.gui.inventory.GuiChest
+import net.minecraft.client.gui.inventory.GuiContainer
import net.minecraft.inventory.ContainerChest
import net.minecraftforge.fml.common.eventhandler.Event
-data class BeforeGuiAction(val gui: GuiScreen) : Event() {
+data class BeforeGuiAction(val gui: GuiScreen) : LedgerEvent() {
val chest = gui as? GuiChest
val chestSlots = chest?.inventorySlots as ContainerChest?
+ override fun serialize(): JsonElement {
+ return JsonObject().apply {
+ add("gui", GuiContextValue(gui).serialize())
+ }
+ }
}
diff --git a/mod/src/main/kotlin/moe/nea/ledger/events/LedgerEvent.kt b/mod/src/main/kotlin/moe/nea/ledger/events/LedgerEvent.kt
new file mode 100644
index 0000000..cbb3f81
--- /dev/null
+++ b/mod/src/main/kotlin/moe/nea/ledger/events/LedgerEvent.kt
@@ -0,0 +1,22 @@
+package moe.nea.ledger.events
+
+import moe.nea.ledger.Ledger
+import moe.nea.ledger.utils.ErrorUtil
+import moe.nea.ledger.utils.telemetry.CommonKeys
+import moe.nea.ledger.utils.telemetry.ContextValue
+import net.minecraftforge.common.MinecraftForge
+import net.minecraftforge.fml.common.eventhandler.Event
+
+abstract class LedgerEvent : Event(), ContextValue {
+ fun post() {
+ Ledger.leakDI()
+ .provide<ErrorUtil>()
+ .catch(
+ CommonKeys.EVENT_MESSAGE to ContextValue.string("Error during event execution"),
+ "event_instance" to this,
+ "event_type" to ContextValue.string(javaClass.name)
+ ) {
+ MinecraftForge.EVENT_BUS.post(this)
+ }
+ }
+} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/AccessorySwapperDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/AccessorySwapperDetection.kt
index 1c228ff..808ac5c 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/AccessorySwapperDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/AccessorySwapperDetection.kt
@@ -22,9 +22,9 @@ class AccessorySwapperDetection {
swapperUsed.useMatcher(event.message) {
logger.logEntry(
LedgerEntry(
- TransactionType.ACCESSORIES_SWAPPING,
- event.timestamp,
- listOf(
+ TransactionType.ACCESSORIES_SWAPPING,
+ event.timestamp,
+ listOf(
ItemChange.lose(ItemIds.TALISMAN_ENRICHMENT_SWAPPER, 1)
)
)
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/BankInterestDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/BankInterestDetection.kt
new file mode 100644
index 0000000..5069930
--- /dev/null
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/BankInterestDetection.kt
@@ -0,0 +1,44 @@
+package moe.nea.ledger.modules
+
+import moe.nea.ledger.ItemChange
+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 java.util.regex.Matcher
+import java.util.regex.Pattern
+
+class BankInterestDetection {
+
+ val bankInterestPattern =
+ Pattern.compile("You have just received (?<coins>$SHORT_NUMBER_PATTERN) coins as interest in your (co-op|personal) bank account!")
+ val offlineBankInterestPattern =
+ Pattern.compile("Since you've been away you earned (?<coins>$SHORT_NUMBER_PATTERN) coins as interest in your personal bank account!")
+
+ @Inject
+ lateinit var logger: LedgerLogger
+
+
+ @SubscribeEvent
+ fun onChat(event: ChatReceived) {
+ fun Matcher.logInterest() {
+ logger.logEntry(
+ LedgerEntry(
+ TransactionType.BANK_INTEREST,
+ event.timestamp,
+ listOf(
+ ItemChange.gainCoins(parseShortNumber(group("coins"))),
+ )
+ )
+ )
+ }
+
+ bankInterestPattern.useMatcher(event.message) { logInterest() }
+ offlineBankInterestPattern.useMatcher(event.message) { logInterest() }
+ }
+}
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/BasicReforgeDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/BasicReforgeDetection.kt
new file mode 100644
index 0000000..17e2983
--- /dev/null
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/BasicReforgeDetection.kt
@@ -0,0 +1,71 @@
+package moe.nea.ledger.modules
+
+import moe.nea.ledger.ExpiringValue
+import moe.nea.ledger.ItemChange
+import moe.nea.ledger.ItemId
+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.events.GuiClickEvent
+import moe.nea.ledger.getDisplayNameU
+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.di.Inject
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.seconds
+
+class BasicReforgeDetection {
+
+ var costPattern = "(?<cost>$SHORT_NUMBER_PATTERN) Coins".toPattern()
+
+ @Inject
+ lateinit var logger: LedgerLogger
+
+ data class ReforgeInstance(
+ val price: Double,
+ val item: ItemId,
+ )
+
+ var lastReforge = ExpiringValue.empty<ReforgeInstance>()
+
+ @SubscribeEvent
+ fun onReforgeClick(event: GuiClickEvent) {
+ val slot = event.slotIn ?: return
+ val displayName = slot.inventory.displayName.unformattedText
+ if (!displayName.unformattedString().contains("Reforge Item") &&
+ !displayName.unformattedString().startsWith("The Hex")
+ ) return
+ val stack = slot.stack ?: return
+ val cost = stack.getLore()
+ .firstNotNullOfOrNull { costPattern.useMatcher(it.unformattedString()) { parseShortNumber(group("cost")) } }
+ ?: return
+
+ if (stack.getDisplayNameU() == "§aReforge Item" || stack.getDisplayNameU() == "§aRandom Basic Reforge") {
+ lastReforge = ExpiringValue(ReforgeInstance(cost, ItemId.NIL /*TODO: read out item stack that is being reforged to save it as a transformed item!*/))
+ }
+ }
+
+ val reforgeChatNotification = "You reforged your .* into a .*!".toPattern()
+
+ @SubscribeEvent
+ fun onReforgeChat(event: ChatReceived) {
+ reforgeChatNotification.useMatcher(event.message) {
+ val reforge = lastReforge.get(3.seconds) ?: return
+ logger.logEntry(
+ LedgerEntry(
+ TransactionType.BASIC_REFORGE,
+ event.timestamp,
+ listOf(
+ ItemChange.loseCoins(reforge.price),
+ ItemChange(reforge.item, 1.0, ItemChange.ChangeDirection.TRANSFORM)
+ )
+ )
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt
index 44a0050..f6dad12 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/BitsDetection.kt
@@ -1,7 +1,6 @@
package moe.nea.ledger.modules
import moe.nea.ledger.ItemChange
-import moe.nea.ledger.ItemId
import moe.nea.ledger.events.ChatReceived
import moe.nea.ledger.events.LateWorldLoadEvent
import moe.nea.ledger.LedgerEntry
@@ -51,8 +50,8 @@ class BitsDetection @Inject constructor(val ledger: LedgerLogger) {
ledger.logEntry(
LedgerEntry(
TransactionType.BOOSTER_COOKIE_ATE,
- Instant.now(),
- listOf(
+ Instant.now(),
+ listOf(
ItemChange.lose(ItemIds.BOOSTER_COOKIE, 1)
)
)
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt
index 553bebf..84185bf 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/BitsShopDetection.kt
@@ -22,10 +22,10 @@ class BitsShopDetection @Inject constructor(val ledger: LedgerLogger) {
data class BitShopEntry(
- val id: ItemId,
- val stackSize: Int,
- val bitPrice: Int,
- val timestamp: Long = System.currentTimeMillis()
+ val id: ItemId,
+ val stackSize: Int,
+ val bitPrice: Int,
+ val timestamp: Long = System.currentTimeMillis()
)
var lastClickedBitShopItem: BitShopEntry? = null
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/CaducousFeederDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/CaducousFeederDetection.kt
new file mode 100644
index 0000000..b64c7e5
--- /dev/null
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/CaducousFeederDetection.kt
@@ -0,0 +1,48 @@
+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.GuiClickEvent
+import moe.nea.ledger.gen.ItemIds
+import moe.nea.ledger.getDisplayNameU
+import moe.nea.ledger.getInternalId
+import moe.nea.ledger.unformattedString
+import moe.nea.ledger.utils.di.Inject
+import net.minecraft.client.Minecraft
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import java.time.Instant
+
+class CaducousFeederDetection {
+
+ @Inject
+ lateinit var logger: LedgerLogger
+
+ @Inject
+ lateinit var minecraft: Minecraft
+
+ @SubscribeEvent
+ fun onFeederClick(event: GuiClickEvent) {
+ val slot = event.slotIn ?: return
+ val displayName = slot.inventory.displayName.unformattedText
+ if (!displayName.unformattedString().contains("Confirm Caducous Feeder")) return
+ val stack = slot.stack ?: return
+ val player = minecraft.thePlayer ?: return
+ if (!player.inventory.mainInventory.any { it?.getInternalId() == ItemIds.ULTIMATE_CARROT_CANDY }) return
+ if (stack.getDisplayNameU() != "§aUse Caducous Feeder") return
+ val petId = slot.inventory.getStackInSlot(13)?.getInternalId() ?: ItemId.NIL
+
+ logger.logEntry(
+ LedgerEntry(
+ TransactionType.CADUCOUS_FEEDER_USED,
+ Instant.now(),
+ listOf(
+ ItemChange.lose(ItemIds.ULTIMATE_CARROT_CANDY, 1),
+ ItemChange(petId, 1.0, ItemChange.ChangeDirection.TRANSFORM),
+ )
+ )
+ )
+ }
+} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt
index e389ffb..b7b9de1 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/DragonEyePlacementDetection.kt
@@ -1,7 +1,6 @@
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
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/DragonSacrificeDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/DragonSacrificeDetection.kt
index 574cfcf..3bf36f9 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/DragonSacrificeDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/DragonSacrificeDetection.kt
@@ -2,7 +2,6 @@ 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
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt
index e747be9..37d0e9c 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt
@@ -76,7 +76,7 @@ class DungeonChestDetection @Inject constructor(val logger: LedgerLogger) : Ches
}
}
- val rewardMessage = " (WOOD|GOLD|DIAMOND|EMERALD|OBSIDIAN|BEDROCK) CHEST REWARDS".toPattern()
+ val rewardMessage = " *(WOOD|GOLD|DIAMOND|EMERALD|OBSIDIAN|BEDROCK) CHEST REWARDS".toPattern()
@SubscribeEvent
fun onChatMessage(event: ChatReceived) {
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/ExternalDataProvider.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/ExternalDataProvider.kt
index 93bb453..42a1f42 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/ExternalDataProvider.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/ExternalDataProvider.kt
@@ -14,6 +14,7 @@ import java.util.concurrent.CompletableFuture
class ExternalDataProvider @Inject constructor(
val requestUtil: RequestUtil
) {
+ // TODO: Save all the data locally, so in case of a failed request older versions can be used
fun createAuxillaryDataRequest(path: String): Request {
return requestUtil.createRequest("https://github.com/nea89o/ledger-auxiliary-data/raw/refs/heads/master/$path")
@@ -22,7 +23,9 @@ class ExternalDataProvider @Inject constructor(
private val itemNameFuture: CompletableFuture<Map<String, String>> = CompletableFuture.supplyAsync {
val request = createAuxillaryDataRequest("data/item_names.json")
val response = request.execute(requestUtil)
- val nameMap = response.json(GsonUtil.typeToken<Map<String, String>>())
+ val nameMap =
+ response?.json(GsonUtil.typeToken<Map<String, String>>())
+ ?: mapOf()
return@supplyAsync nameMap
}
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/EyedropsDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/EyedropsDetection.kt
index 04dbe80..c90f8d9 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/EyedropsDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/EyedropsDetection.kt
@@ -1,7 +1,6 @@
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
@@ -23,9 +22,9 @@ class EyedropsDetection {
capsaicinEyedropsUsed.useMatcher(event.message) {
logger.logEntry(
LedgerEntry(
- TransactionType.CAPSAICIN_EYEDROPS_USED,
- event.timestamp,
- listOf(
+ TransactionType.CAPSAICIN_EYEDROPS_USED,
+ event.timestamp,
+ listOf(
ItemChange.lose(ItemIds.CAPSAICIN_EYEDROPS_NO_CHARGES, 1)
)
)
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/ForgeDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/ForgeDetection.kt
index 95811ed..b8974c0 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/ForgeDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/ForgeDetection.kt
@@ -9,6 +9,7 @@ import moe.nea.ledger.getInternalId
import moe.nea.ledger.matches
import moe.nea.ledger.unformattedString
import moe.nea.ledger.utils.di.Inject
+import net.minecraft.item.EnumDyeColor
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.time.Instant
@@ -20,7 +21,9 @@ class ForgeDetection {
fun onClick(event: GuiClickEvent) {
val slot = event.slotIn ?: return
val clickedItem = slot.stack ?: return
+ val dyeColor = EnumDyeColor.byMetadata(clickedItem.itemDamage)
if (clickedItem.displayName.unformattedString() != "Confirm") return
+ if (dyeColor == EnumDyeColor.RED) return
val furnaceSlotName = slot.inventory.getStackInSlot(furnaceSlot)?.displayName?.unformattedString() ?: return
if (!furnaceName.matches(furnaceSlotName))
return
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/GambleDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/GambleDetection.kt
index a8f79c1..9149e14 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/GambleDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/GambleDetection.kt
@@ -1,7 +1,6 @@
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
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/GhostCoinDropDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/GhostCoinDropDetection.kt
new file mode 100644
index 0000000..42084e2
--- /dev/null
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/GhostCoinDropDetection.kt
@@ -0,0 +1,38 @@
+package moe.nea.ledger.modules
+
+import moe.nea.ledger.ItemChange
+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 java.util.regex.Pattern
+
+class GhostCoinDropDetection {
+
+ val ghostCoinPattern =
+ Pattern.compile("The ghost's death materialized (?<coins>$SHORT_NUMBER_PATTERN) coins from the mists!")
+
+ @Inject
+ lateinit var logger: LedgerLogger
+
+ @SubscribeEvent
+ fun onGhostCoinDrop(event: ChatReceived) {
+ ghostCoinPattern.useMatcher(event.message) {
+ logger.logEntry(
+ LedgerEntry(
+ // TODO: merge this into a generic mob drop tt
+ TransactionType.GHOST_COIN_DROP,
+ event.timestamp,
+ listOf(
+ ItemChange.gainCoins(parseShortNumber(group("coins"))),
+ )
+ )
+ )
+ }
+ }
+}
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/GodPotionDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/GodPotionDetection.kt
index ae86519..56e2b69 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/GodPotionDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/GodPotionDetection.kt
@@ -1,7 +1,6 @@
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
@@ -23,9 +22,9 @@ class GodPotionDetection {
godPotionDrank.useMatcher(event.message) {
logger.logEntry(
LedgerEntry(
- TransactionType.GOD_POTION_DRANK,
- event.timestamp,
- listOf(
+ TransactionType.GOD_POTION_DRANK,
+ event.timestamp,
+ listOf(
ItemChange.lose(ItemIds.GOD_POTION_2, 1)
)
)
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/GodPotionMixinDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/GodPotionMixinDetection.kt
index b96a24a..072503f 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/GodPotionMixinDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/GodPotionMixinDetection.kt
@@ -26,9 +26,9 @@ class GodPotionMixinDetection {
godPotionMixinDrank.useMatcher(event.message) {
logger.logEntry(
LedgerEntry(
- TransactionType.GOD_POTION_MIXIN_DRANK,
- event.timestamp,
- listOf(
+ TransactionType.GOD_POTION_MIXIN_DRANK,
+ event.timestamp,
+ listOf(
ItemChange.lose(itemIdProvider.findForName(group("what")) ?: ItemId.NIL, 1)
)
)
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/GummyPolarBearDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/GummyPolarBearDetection.kt
new file mode 100644
index 0000000..d69df83
--- /dev/null
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/GummyPolarBearDetection.kt
@@ -0,0 +1,34 @@
+package moe.nea.ledger.modules
+
+import moe.nea.ledger.ItemChange
+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 GummyPolarBearDetection {
+
+ val ateGummyPolarBear = "You ate a Re-heated Gummy Polar Bear!".toPattern()
+
+ @Inject
+ lateinit var logger: LedgerLogger
+
+ @SubscribeEvent
+ fun onChat(event: ChatReceived) {
+ ateGummyPolarBear.useMatcher(event.message) {
+ logger.logEntry(
+ LedgerEntry(
+ TransactionType.GUMMY_POLAR_BEAR_ATE,
+ event.timestamp,
+ listOf(
+ ItemChange.lose(ItemIds.REHEATED_GUMMY_POLAR_BEAR, 1)
+ )
+ )
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/KuudraChestDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/KuudraChestDetection.kt
index e0e9322..88c45d2 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/KuudraChestDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/KuudraChestDetection.kt
@@ -36,6 +36,9 @@ class KuudraChestDetection : ChestDetection() {
if (requiredKey != null && !hasKey(requiredKey)) {
return
}
+ if (requiredKey == null && event.slotIn.inventory.name != "Free Chest") {
+ return
+ }
log.logEntry(LedgerEntry(
TransactionType.KUUDRA_CHEST_OPEN,
diffs.timestamp,
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/PestRepellentDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/PestRepellentDetection.kt
new file mode 100644
index 0000000..f627393
--- /dev/null
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/PestRepellentDetection.kt
@@ -0,0 +1,47 @@
+package moe.nea.ledger.modules
+
+import moe.nea.ledger.ItemChange
+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 PestRepellentDetection {
+
+ val pestRepellent = "YUM! Pests will now spawn (?<reduction>[2-4])x less while you break crops for the next 60m!".toPattern()
+
+ @Inject
+ lateinit var logger: LedgerLogger
+
+ @SubscribeEvent
+ fun onChat(event: ChatReceived) {
+ pestRepellent.useMatcher(event.message) {
+ val reductionAmount = group("reduction")
+ if (reductionAmount == "2") {
+ logger.logEntry(
+ LedgerEntry(
+ TransactionType.PEST_REPELLENT_USED,
+ event.timestamp,
+ listOf(
+ ItemChange.lose(ItemIds.PEST_REPELLENT, 1),
+ )
+ )
+ )
+ } else if (reductionAmount == "4"){
+ logger.logEntry(
+ LedgerEntry(
+ TransactionType.PEST_REPELLENT_USED,
+ event.timestamp,
+ listOf(
+ ItemChange.lose(ItemIds.PEST_REPELLENT_MAX, 1),
+ )
+ )
+ )
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/StonksAuctionDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/StonksAuctionDetection.kt
new file mode 100644
index 0000000..4f3706c
--- /dev/null
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/StonksAuctionDetection.kt
@@ -0,0 +1,59 @@
+package moe.nea.ledger.modules
+
+import moe.nea.ledger.ItemChange
+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 java.util.regex.Matcher
+import java.util.regex.Pattern
+
+class StonksAuctionDetection {
+
+ val stonksPlacedBid =
+ Pattern.compile("Successfully placed your Stonk bid of (?<coins>$SHORT_NUMBER_PATTERN) Coins!")
+ val stonksIncreaseBid =
+ Pattern.compile("Successfully increased your Stonk bid by (?<coins>$SHORT_NUMBER_PATTERN) Coins!")
+ val stonksClaim =
+ Pattern.compile("You claimed (?<count>$SHORT_NUMBER_PATTERN)x Stock of Stonks from the Stonks Auction!")
+
+ @Inject
+ lateinit var logger: LedgerLogger
+
+ @SubscribeEvent
+ fun onChat(event: ChatReceived) {
+ fun Matcher.logBidding() {
+ logger.logEntry(
+ LedgerEntry(
+ TransactionType.STONKS_AUCTION,
+ event.timestamp,
+ listOf(
+ ItemChange.loseCoins(parseShortNumber(group("coins"))),
+ )
+ )
+ )
+ }
+
+ fun Matcher.logClaim() {
+ logger.logEntry(
+ LedgerEntry(
+ TransactionType.STONKS_AUCTION,
+ event.timestamp,
+ listOf(
+ ItemChange.gain(ItemIds.STOCK_OF_STONKS, parseShortNumber(group("count")))
+ )
+ )
+ )
+ }
+
+ stonksPlacedBid.useMatcher(event.message) { logBidding() }
+ stonksIncreaseBid.useMatcher(event.message) { logBidding() }
+ stonksClaim.useMatcher(event.message) { logClaim() }
+ }
+}
diff --git a/mod/src/main/kotlin/moe/nea/ledger/modules/VisitorDetection.kt b/mod/src/main/kotlin/moe/nea/ledger/modules/VisitorDetection.kt
index f457ae4..5178e9f 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/modules/VisitorDetection.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/modules/VisitorDetection.kt
@@ -5,15 +5,12 @@ 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.ExtraSupplyIdEvent
import moe.nea.ledger.events.GuiClickEvent
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.di.Inject
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.time.Instant
diff --git a/mod/src/main/kotlin/moe/nea/ledger/telemetry/GuiContextValue.kt b/mod/src/main/kotlin/moe/nea/ledger/telemetry/GuiContextValue.kt
new file mode 100644
index 0000000..2d7db39
--- /dev/null
+++ b/mod/src/main/kotlin/moe/nea/ledger/telemetry/GuiContextValue.kt
@@ -0,0 +1,16 @@
+package moe.nea.ledger.telemetry
+
+import com.google.gson.JsonElement
+import com.google.gson.JsonObject
+import moe.nea.ledger.utils.ScreenUtil
+import moe.nea.ledger.utils.telemetry.ContextValue
+import net.minecraft.client.gui.GuiScreen
+
+class GuiContextValue(val gui: GuiScreen) : ContextValue {
+ override fun serialize(): JsonElement {
+ return JsonObject().apply {
+ addProperty("class", gui.javaClass.name)
+ addProperty("name", ScreenUtil.estimateName(gui))
+ }
+ }
+}
diff --git a/mod/src/main/kotlin/moe/nea/ledger/TelemetryProvider.kt b/mod/src/main/kotlin/moe/nea/ledger/telemetry/TelemetryProvider.kt
index d9c7108..c2fff23 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/TelemetryProvider.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/telemetry/TelemetryProvider.kt
@@ -1,8 +1,10 @@
-package moe.nea.ledger
+package moe.nea.ledger.telemetry
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
+import moe.nea.ledger.DevUtil
+import moe.nea.ledger.Ledger
import moe.nea.ledger.gen.BuildConfig
import moe.nea.ledger.utils.di.DI
import moe.nea.ledger.utils.di.DIProvider
@@ -40,7 +42,7 @@ object TelemetryProvider {
}
fun setupDefaultSpan() {
- val sp = Span.current()
+ val sp = Span.rootSpan
sp.add(USER, MinecraftUser(Minecraft.getMinecraft().session))
sp.add(MINECRAFT_VERSION, ContextValue.compound(
"static" to "1.8.9",
diff --git a/mod/src/main/kotlin/moe/nea/ledger/utils/NoSideEffects.kt b/mod/src/main/kotlin/moe/nea/ledger/utils/NoSideEffects.kt
deleted file mode 100644
index 9b0e7a3..0000000
--- a/mod/src/main/kotlin/moe/nea/ledger/utils/NoSideEffects.kt
+++ /dev/null
@@ -1,4 +0,0 @@
-package moe.nea.ledger.utils
-
-@Retention(AnnotationRetention.BINARY)
-annotation class NoSideEffects
diff --git a/mod/src/main/kotlin/moe/nea/ledger/utils/ScreenUtil.kt b/mod/src/main/kotlin/moe/nea/ledger/utils/ScreenUtil.kt
new file mode 100644
index 0000000..0305126
--- /dev/null
+++ b/mod/src/main/kotlin/moe/nea/ledger/utils/ScreenUtil.kt
@@ -0,0 +1,29 @@
+package moe.nea.ledger.utils
+
+import moe.nea.ledger.mixin.AccessorContainerDispenser
+import moe.nea.ledger.mixin.AccessorContainerHopper
+import net.minecraft.client.gui.GuiScreen
+import net.minecraft.client.gui.inventory.GuiContainer
+import net.minecraft.inventory.ContainerChest
+import net.minecraft.inventory.IInventory
+
+object ScreenUtil {
+ fun estimateInventory(screen: GuiScreen?): IInventory? {
+ if (screen !is GuiContainer) {
+ return null
+ }
+ val container = screen.inventorySlots ?: return null
+ if (container is ContainerChest)
+ return container.lowerChestInventory
+ if (container is AccessorContainerDispenser)
+ return container.dispenserInventory_ledger
+ if (container is AccessorContainerHopper)
+ return container.hopperInventory_ledger
+ return null
+
+ }
+
+ fun estimateName(screen: GuiScreen?): String? {
+ return estimateInventory(screen)?.name
+ }
+} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/utils/network/RequestTrace.kt b/mod/src/main/kotlin/moe/nea/ledger/utils/network/RequestTrace.kt
new file mode 100644
index 0000000..3953e09
--- /dev/null
+++ b/mod/src/main/kotlin/moe/nea/ledger/utils/network/RequestTrace.kt
@@ -0,0 +1,21 @@
+package moe.nea.ledger.utils.network
+
+import com.google.gson.JsonElement
+import com.google.gson.JsonObject
+import moe.nea.ledger.utils.telemetry.ContextValue
+
+class RequestTrace(val request: Request) : ContextValue {
+ override fun serialize(): JsonElement {
+ return JsonObject().apply {
+ addProperty("url", request.url.toString())
+ addProperty("method", request.method.name)
+ addProperty("content-type", request.headers["content-type"])
+ addProperty("accept", request.headers["accept"])
+ }
+ }
+
+ companion object {
+ val KEY = "http_request"
+ fun createTrace(request: Request): Pair<String, RequestTrace> = KEY to RequestTrace(request)
+ }
+} \ No newline at end of file
diff --git a/mod/src/main/kotlin/moe/nea/ledger/utils/network/RequestUtil.kt b/mod/src/main/kotlin/moe/nea/ledger/utils/network/RequestUtil.kt
index a49c65a..8101527 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/utils/network/RequestUtil.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/utils/network/RequestUtil.kt
@@ -2,6 +2,8 @@ package moe.nea.ledger.utils.network
import moe.nea.ledger.utils.ErrorUtil
import moe.nea.ledger.utils.di.Inject
+import moe.nea.ledger.utils.telemetry.CommonKeys
+import moe.nea.ledger.utils.telemetry.ContextValue
import java.net.URL
import java.net.URLConnection
import java.security.KeyStore
@@ -38,7 +40,10 @@ class RequestUtil @Inject constructor(val errorUtil: ErrorUtil) {
fun createRequest(url: String) = createRequest(URL(url))
fun createRequest(url: URL) = Request(url, Request.Method.GET, null, mapOf())
- fun executeRequest(request: Request): Response {
+ fun executeRequest(request: Request): Response? = errorUtil.catch(
+ CommonKeys.EVENT_MESSAGE to ContextValue.string("Failed to execute request"),
+ RequestTrace.createTrace(request)
+ ) {
val connection = request.url.openConnection()
enhanceConnection(connection)
connection.setRequestProperty("accept-encoding", "gzip")
@@ -56,7 +61,7 @@ class RequestUtil @Inject constructor(val errorUtil: ErrorUtil) {
val text = stream.bufferedReader().readText()
stream.close()
// Do NOT call connection.disconnect() to allow for connection reuse
- return Response(request, text, connection.headerFields)
+ return@catch Response(request, text, connection.headerFields)
}
diff --git a/mod/src/main/kotlin/moe/nea/ledger/utils/telemetry/Span.kt b/mod/src/main/kotlin/moe/nea/ledger/utils/telemetry/Span.kt
index 0d680a9..8b8e284 100644
--- a/mod/src/main/kotlin/moe/nea/ledger/utils/telemetry/Span.kt
+++ b/mod/src/main/kotlin/moe/nea/ledger/utils/telemetry/Span.kt
@@ -2,9 +2,10 @@ package moe.nea.ledger.utils.telemetry
class Span(val parent: Span?) : AutoCloseable {
companion object {
+ val rootSpan = Span(null)
private val _current = object : InheritableThreadLocal<Span>() {
override fun initialValue(): Span {
- return Span(null)
+ return Span(rootSpan)
}
override fun childValue(parentValue: Span?): Span {