diff options
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament')
5 files changed, 75 insertions, 20 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/events/ClientChatLineReceivedEvent.kt b/src/main/kotlin/moe/nea/firmament/events/ClientChatLineReceivedEvent.kt new file mode 100644 index 0000000..604422d --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/events/ClientChatLineReceivedEvent.kt @@ -0,0 +1,14 @@ +package moe.nea.firmament.events + +import net.minecraft.text.Text +import moe.nea.firmament.util.unformattedString + +/** + * Published just before a message is added to the chat gui. Cancelling only prevents rendering, not logging to the + * console. + */ +data class ClientChatLineReceivedEvent(val text: Text) : FirmamentEvent.Cancellable() { + val unformattedString = text.unformattedString + + companion object : FirmamentEventBus<ClientChatLineReceivedEvent>() +} diff --git a/src/main/kotlin/moe/nea/firmament/events/OutgoingPacketEvent.kt b/src/main/kotlin/moe/nea/firmament/events/OutgoingPacketEvent.kt new file mode 100644 index 0000000..4263d9d --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/events/OutgoingPacketEvent.kt @@ -0,0 +1,7 @@ +package moe.nea.firmament.events + +import net.minecraft.network.packet.Packet + +data class OutgoingPacketEvent(val packet: Packet<*>) : FirmamentEvent.Cancellable() { + companion object : FirmamentEventBus<OutgoingPacketEvent>() +} diff --git a/src/main/kotlin/moe/nea/firmament/events/ServerChatLineReceivedEvent.kt b/src/main/kotlin/moe/nea/firmament/events/ServerChatLineReceivedEvent.kt index c7e950f..57879a1 100644 --- a/src/main/kotlin/moe/nea/firmament/events/ServerChatLineReceivedEvent.kt +++ b/src/main/kotlin/moe/nea/firmament/events/ServerChatLineReceivedEvent.kt @@ -23,9 +23,9 @@ import moe.nea.firmament.util.unformattedString /** * This event gets published whenever the client receives a chat message from the server. - */ + * This event is cancellable, but should not get cancelled. Use [ClientChatLineReceivedEvent] for that instead. */ data class ServerChatLineReceivedEvent(val text: Text) : FirmamentEvent.Cancellable() { - companion object : FirmamentEventBus<ServerChatLineReceivedEvent>() - val unformattedString = text.unformattedString + + companion object : FirmamentEventBus<ServerChatLineReceivedEvent>() } diff --git a/src/main/kotlin/moe/nea/firmament/util/SBData.kt b/src/main/kotlin/moe/nea/firmament/util/SBData.kt index f2f1d1d..1d97dfa 100644 --- a/src/main/kotlin/moe/nea/firmament/util/SBData.kt +++ b/src/main/kotlin/moe/nea/firmament/util/SBData.kt @@ -18,49 +18,81 @@ package moe.nea.firmament.util +import java.util.UUID import kotlinx.serialization.SerializationException import kotlinx.serialization.decodeFromString import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds +import net.minecraft.network.packet.c2s.play.CommandExecutionC2SPacket import moe.nea.firmament.Firmament +import moe.nea.firmament.events.ClientChatLineReceivedEvent +import moe.nea.firmament.events.OutgoingPacketEvent import moe.nea.firmament.events.ServerChatLineReceivedEvent import moe.nea.firmament.events.SkyblockServerUpdateEvent import moe.nea.firmament.events.WorldReadyEvent object SBData { - val profileRegex = "(?:Your profile was changed to: |You are playing on profile: )(.+)".toRegex() - var profileCuteName: String? = null + private val profileRegex = "Profile ID: ([a-z0-9\\-]+)".toRegex() + var profileId: UUID? = null private var lastLocrawSent = Timer() + private val anyLocrawSent = Timer() private val locrawRoundtripTime: Duration = 5.seconds + private var hasReceivedProfile = false + private var hasSentLocraw = false var locraw: Locraw? = null - val skyblockLocation get() = locraw?.skyblockLocation - + val skyblockLocation: String? get() = locraw?.skyblockLocation + val hasValidLocraw get() = locraw?.server !in listOf("limbo", null) fun init() { + OutgoingPacketEvent.subscribe { event -> + if (event.packet is CommandExecutionC2SPacket && event.packet.command == "locraw") { + anyLocrawSent.markNow() + } + } ServerChatLineReceivedEvent.subscribe { event -> val profileMatch = profileRegex.matchEntire(event.unformattedString) if (profileMatch != null) { - profileCuteName = profileMatch.groupValues[1] + try { + profileId = UUID.fromString(profileMatch.groupValues[1]) + hasReceivedProfile = true + if (!hasValidLocraw && !hasSentLocraw && anyLocrawSent.timePassed() > locrawRoundtripTime) { + sendLocraw() + } + } catch (e: IllegalArgumentException) { + profileId = null + e.printStackTrace() + } } if (event.unformattedString.startsWith("{")) { - if (tryReceiveLocraw(event.unformattedString) && lastLocrawSent.timePassed() < locrawRoundtripTime) { - lastLocrawSent.markFarPast() - event.cancel() + if (tryReceiveLocraw(event.unformattedString)) { + if (!hasValidLocraw && !hasSentLocraw && hasReceivedProfile) { + sendLocraw() + } } } } + ClientChatLineReceivedEvent.subscribe { event -> + if (event.unformattedString.startsWith("{") && tryReceiveLocraw(event.unformattedString) && lastLocrawSent.timePassed() < locrawRoundtripTime) { + lastLocrawSent.markFarPast() + event.cancel() + } + } WorldReadyEvent.subscribe { - sendLocraw() locraw = null + hasSentLocraw = false + hasReceivedProfile = false } } - private fun tryReceiveLocraw(unformattedString: String): Boolean = try { + private fun tryReceiveLocraw(unformattedString: String, update: Boolean = true): Boolean = try { val lastLocraw = locraw - locraw = Firmament.json.decodeFromString<Locraw>(unformattedString) - SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, locraw)) + val n = Firmament.json.decodeFromString<Locraw>(unformattedString) + if (update) { + locraw = n + SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, locraw)) + } true } catch (e: SerializationException) { e.printStackTrace() @@ -71,6 +103,7 @@ object SBData { } fun sendLocraw() { + hasSentLocraw = true lastLocrawSent.markNow() val nh = MC.player?.networkHandler ?: return nh.sendChatCommand("locraw") diff --git a/src/main/kotlin/moe/nea/firmament/util/data/ProfileSpecificDataHolder.kt b/src/main/kotlin/moe/nea/firmament/util/data/ProfileSpecificDataHolder.kt index 7111344..06523c3 100644 --- a/src/main/kotlin/moe/nea/firmament/util/data/ProfileSpecificDataHolder.kt +++ b/src/main/kotlin/moe/nea/firmament/util/data/ProfileSpecificDataHolder.kt @@ -19,6 +19,7 @@ package moe.nea.firmament.util.data import java.nio.file.Path +import java.util.UUID import kotlinx.serialization.KSerializer import kotlin.io.path.createDirectories import kotlin.io.path.deleteExisting @@ -37,10 +38,10 @@ abstract class ProfileSpecificDataHolder<S>( private val configDefault: () -> S ) : IDataHolder<S?> { - var allConfigs: MutableMap<String, S> + var allConfigs: MutableMap<UUID, S> override val data: S? - get() = SBData.profileCuteName?.let { + get() = SBData.profileId?.let { allConfigs.computeIfAbsent(it) { configDefault() } } @@ -52,7 +53,7 @@ abstract class ProfileSpecificDataHolder<S>( private val configDirectory: Path get() = Firmament.CONFIG_DIR.resolve("profiles").resolve(configName) - private fun readValues(): MutableMap<String, S> { + private fun readValues(): MutableMap<UUID, S> { if (!configDirectory.exists()) { configDirectory.createDirectories() } @@ -61,7 +62,7 @@ abstract class ProfileSpecificDataHolder<S>( .filter { it.extension == "json" } .mapNotNull { try { - it.nameWithoutExtension to Firmament.json.decodeFromString(dataSerializer, it.readText()) + UUID.fromString(it.nameWithoutExtension) to Firmament.json.decodeFromString(dataSerializer, it.readText()) } catch (e: Exception) { /* Expecting IOException and SerializationException, but Kotlin doesn't allow multi catches*/ IDataHolder.badLoads.add(configName) Firmament.logger.error( @@ -79,7 +80,7 @@ abstract class ProfileSpecificDataHolder<S>( } val c = allConfigs configDirectory.listDirectoryEntries().forEach { - if (it.nameWithoutExtension !in c) { + if (it.nameWithoutExtension !in c.mapKeys { it.toString() }) { it.deleteExisting() } } |