diff options
Diffstat (limited to 'mod/src/main/kotlin/moe/nea/ledger/LedgerLogger.kt')
-rw-r--r-- | mod/src/main/kotlin/moe/nea/ledger/LedgerLogger.kt | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/mod/src/main/kotlin/moe/nea/ledger/LedgerLogger.kt b/mod/src/main/kotlin/moe/nea/ledger/LedgerLogger.kt new file mode 100644 index 0000000..6049aa2 --- /dev/null +++ b/mod/src/main/kotlin/moe/nea/ledger/LedgerLogger.kt @@ -0,0 +1,136 @@ +package moe.nea.ledger + +import com.google.gson.Gson +import com.google.gson.JsonArray +import moe.nea.ledger.database.DBItemEntry +import moe.nea.ledger.database.DBLogEntry +import moe.nea.ledger.database.Database +import moe.nea.ledger.events.ChatReceived +import moe.nea.ledger.utils.ULIDWrapper +import moe.nea.ledger.utils.di.Inject +import net.minecraft.client.Minecraft +import net.minecraft.util.ChatComponentText +import net.minecraft.util.IChatComponent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent +import java.io.File +import java.text.SimpleDateFormat +import java.util.Date +import java.util.UUID + +class LedgerLogger { + fun printOut(text: String) = printOut(ChatComponentText(text)) + fun printOut(comp: IChatComponent) { + Minecraft.getMinecraft().ingameGUI?.chatGUI?.printChatMessage(comp) + } + + val profileIdPattern = + "Profile ID: (?<profile>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})".toPattern() + + var currentProfile: UUID? = null + + var shouldLog by Ledger.managedConfig.instance.debug::logEntries + + @Inject + lateinit var database: Database + + @SubscribeEvent + fun onProfileSwitch(event: ChatReceived) { + profileIdPattern.useMatcher(event.message) { + currentProfile = UUID.fromString(group("profile")) + } + } + + + fun printToChat(entry: LedgerEntry) { + val items = entry.items.joinToString("\n§e") { " - ${it.direction} ${it.count}x ${it.itemId}" } + printOut( + """ + §e================= TRANSACTION START + §eTYPE: §a${entry.transactionType} + §eTIMESTAMP: §a${entry.timestamp} + §e%s + §ePROFILE: §a${currentProfile} + §e================= TRANSACTION END + """.trimIndent().replace("%s", items) + ) + } + + val entries = JsonArray() + var hasRecentlyMerged = false + var lastMergeTime = System.currentTimeMillis() + + fun doMerge() { + val allFiles = folder.listFiles()?.toList() ?: emptyList() + val mergedJson = allFiles + .filter { it.name != "merged.json" && it.extension == "json" } + .sortedDescending() + .map { it.readText().trim().removePrefix("[").removeSuffix("]") } + .joinToString(",", "[", "]") + folder.resolve("merged.json").writeText(mergedJson) + hasRecentlyMerged = true + } + + init { + Runtime.getRuntime().addShutdownHook(Thread { doMerge() }) + } + + @SubscribeEvent + fun onTick(event: ClientTickEvent) { + if (!hasRecentlyMerged && (System.currentTimeMillis() - lastMergeTime) > 60_000L) { + lastMergeTime = System.currentTimeMillis() + doMerge() + } + } + + fun logEntry(entry: LedgerEntry) { + if (shouldLog) + printToChat(entry) + Ledger.logger.info("Logging entry of type ${entry.transactionType}") + val transactionId = ULIDWrapper.createULIDAt(entry.timestamp) + DBLogEntry.insert(database.connection) { + it[DBLogEntry.profileId] = currentProfile ?: MCUUIDUtil.NIL_UUID + it[DBLogEntry.playerId] = MCUUIDUtil.getPlayerUUID() + it[DBLogEntry.type] = entry.transactionType + it[DBLogEntry.transactionId] = transactionId + } + entry.items.forEach { change -> + DBItemEntry.insert(database.connection) { + it[DBItemEntry.transactionId] = transactionId + it[DBItemEntry.mode] = change.direction + it[DBItemEntry.size] = change.count + it[DBItemEntry.itemId] = change.itemId + } + } + entries.add(entry.intoJson(currentProfile)) + commit() + } + + fun commit() { + try { + hasRecentlyMerged = false + file.writeText(gson.toJson(entries)) + } catch (ex: Exception) { + Ledger.logger.error("Could not save file", ex) + } + } + + val gson = Gson() + + val folder = Ledger.dataFolder + val file: File = run { + val date = SimpleDateFormat("yyyy.MM.dd").format(Date()) + + generateSequence(0) { it + 1 } + .map { + if (it == 0) + folder.resolve("$date.json") + else + folder.resolve("$date-$it.json") + } + .filter { !it.exists() } + .first() + } +} + + |