11package com.lambda.module.modules
22
3+ import com.lambda.Lambda
34import com.lambda.Lambda.mc
45import com.lambda.event.EventFlow.lambdaScope
56import com.lambda.event.events.PacketEvent
7+ import com.lambda.event.events.TickEvent
68import com.lambda.event.listener.UnsafeListener.Companion.unsafeConcurrentListener
79import com.lambda.event.listener.UnsafeListener.Companion.unsafeListener
810import com.lambda.module.Module
11+ import com.lambda.util.Communication
912import com.lambda.util.Communication.info
1013import com.lambda.util.DynamicReflectionSerializer.dynamicString
1114import com.lambda.util.FolderRegister
1215import com.lambda.util.Formatting.getTime
16+ import com.lambda.util.text.*
1317import kotlinx.coroutines.Dispatchers
1418import kotlinx.coroutines.channels.BufferOverflow
1519import kotlinx.coroutines.flow.MutableSharedFlow
1620import kotlinx.coroutines.launch
1721import net.minecraft.network.packet.Packet
1822import java.io.File
23+ import java.nio.file.Path
1924import java.time.format.DateTimeFormatter
25+ import kotlin.io.path.pathString
2026
2127object Packetlogger : Module(
2228 name = " Packetlogger" ,
2329 description = " Logs packets" ,
2430 defaultTags = setOf()
2531) {
26- private val logConcurrent by setting(" Build String Concurrent" , false , " Whether to serialize packets concurrently. Will not save packets in chronological order but wont lag the game." )
32+ private val logIncoming by setting(" Log Incoming" , true , " Log incoming packets" )
33+ private val logOutgoing by setting(" Log Outgoing" , true , " Log outgoing packets" )
34+ private val logTicks by setting(" Log Ticks" , true , " Show game ticks in the log" )
35+ private val logWhitelist by setting(" Whitelist" , false , " Only log packets from the whitelist" )
36+ private val whitelist by setting(" Whitelist Packets" , emptyList<String >(), " Packets to whitelist" )
37+ private val logBlacklist by setting(" Blacklist" , false , " Log all packets except those from the blacklist" )
38+ private val blacklist by setting(" Blacklist Packets" , emptyList<String >(), " Packets to blacklist" )
39+ private val maxRecursionDepth by setting(" Max Recursion Depth" , 6 , 1 .. 10 , 1 , " Maximum recursion depth for packet serialization" )
40+ private val logConcurrent by setting(" Build Data Concurrent" , false , " Whether to serialize packets concurrently. Will not save packets in chronological order but wont lag the game." )
2741
2842 private var file: File ? = null
2943 private val entryFormatter: DateTimeFormatter = DateTimeFormatter .ofPattern(" HH:mm:ss.SSSS" )
@@ -33,6 +47,7 @@ object Packetlogger : Module(
3347 extraBufferCapacity = 1000 ,
3448 onBufferOverflow = BufferOverflow .DROP_OLDEST
3549 )
50+ private val File .relativePath: Path get() = mc.runDirectory.toPath().relativize(toPath())
3651
3752 init {
3853 lambdaScope.launch(Dispatchers .IO ) {
@@ -50,55 +65,95 @@ object Packetlogger : Module(
5065 if (! exists()) {
5166 createNewFile()
5267 }
53- this @Packetlogger.info(" Logging packets to $absolutePath " )
68+ val info = buildText {
69+ clickEvent(ClickEvents .openFile(relativePath.pathString)) {
70+ literal(" Packet logger started: " )
71+ color(Color .GOLD ) { literal(fileName) }
72+ literal(" (click to open)" )
73+ }
74+ }
75+ this @Packetlogger.info(info)
5476 }.apply {
5577 // ToDo: Add more rich and accurate data to the header
5678 StringBuilder ().apply {
79+ appendLine(Communication .ascii)
80+ appendLine(" ${Lambda .SYMBOL } - Lambda ${Lambda .VERSION } - Packet Log" )
81+
5782 val playerName = mc.player?.name?.string ? : " Unknown"
58- val serverInfo = mc.networkHandler?.serverInfo?.toNbt() ? : " Singleplayer"
59- appendLine(" Packet logger started at ${getTime()} by $playerName \n " )
60- appendLine(" Connected to $serverInfo \n " )
83+ appendLine(" Started at ${getTime()} by $playerName " )
84+ when {
85+ mc.isIntegratedServerRunning -> {
86+ appendLine(" Integrated server running." )
87+ }
88+ mc.currentServerEntry != null -> {
89+ appendLine(" Connected to ${mc.currentServerEntry?.name} at ${mc.currentServerEntry?.address} ." )
90+ }
91+ else -> {
92+ appendLine(" Started in Main Menu" )
93+ }
94+ }
95+ appendLine()
6196 }.toString().let { header ->
6297 storageFlow.tryEmit(header)
6398 }
6499 }
65100 }
66101
67102 onDisableUnsafe {
68- this @Packetlogger.info(" Stopped logging packets. Saved to ${file?.absolutePath} " )
69- file = null
103+ file?.let {
104+ val info = buildText {
105+ literal(" Stopped logging packets to " )
106+ clickEvent(ClickEvents .openFile(it.relativePath.pathString)) {
107+ color(Color .GOLD ) { literal(it.relativePath.pathString) }
108+ literal(" (click to open)" )
109+ }
110+ }
111+ this @Packetlogger.info(info)
112+
113+ file = null
114+ }
115+ }
116+
117+ unsafeListener<TickEvent .Pre > {
118+ if (! logTicks) return @unsafeListener
119+
120+ storageFlow.tryEmit(" \n Started tick at ${getTime(entryFormatter)} \n " )
70121 }
71122
72123 unsafeListener<PacketEvent .Receive .Pre > {
73- if (logConcurrent) return @unsafeListener
124+ if (logConcurrent || ! logIncoming || it.packet.notLog() ) return @unsafeListener
74125
75126 it.packet.logReceived()
76127 }
77128
78129 unsafeListener<PacketEvent .Send .Pre > {
79- if (logConcurrent) return @unsafeListener
130+ if (logConcurrent || ! logOutgoing || it.packet.notLog() ) return @unsafeListener
80131
81132 it.packet.logSent()
82133 }
83134
84135 unsafeConcurrentListener<PacketEvent .Receive .Pre > {
85- if (! logConcurrent) return @unsafeConcurrentListener
136+ if (! logConcurrent || ! logIncoming || it.packet.notLog() ) return @unsafeConcurrentListener
86137
87138 it.packet.logReceived()
88139 }
89140
90141 unsafeConcurrentListener<PacketEvent .Send .Pre > {
91- if (! logConcurrent) return @unsafeConcurrentListener
142+ if (! logConcurrent || ! logOutgoing || it.packet.notLog() ) return @unsafeConcurrentListener
92143
93144 it.packet.logSent()
94145 }
95146 }
96147
97148 private fun Packet <* >.logReceived () {
98- storageFlow.tryEmit(" Received at ${getTime(entryFormatter)} \n ${dynamicString()} \n " )
149+ storageFlow.tryEmit(" Received at ${getTime(entryFormatter)} \n ${dynamicString(maxRecursionDepth )} \n " )
99150 }
100151
101152 private fun Packet <* >.logSent () {
102- storageFlow.tryEmit(" Sent at ${getTime(entryFormatter)} \n ${dynamicString()} \n " )
153+ storageFlow.tryEmit(" Sent at ${getTime(entryFormatter)} \n ${dynamicString(maxRecursionDepth )} \n " )
103154 }
155+
156+ private fun Packet <* >.notLog () =
157+ (logWhitelist && this ::class .simpleName !in whitelist)
158+ || (logBlacklist && this ::class .simpleName in blacklist)
104159}
0 commit comments