diff options
author | nea <nea@nea.moe> | 2023-06-09 18:08:38 +0200 |
---|---|---|
committer | nea <nea@nea.moe> | 2023-06-09 18:08:38 +0200 |
commit | 428056ff805839e04443dcff3badd021eb4abe01 (patch) | |
tree | 1dfb5b4dc84bc0884dc319be7f8ad4e949decb81 | |
parent | e7a7b04d8cadbc08d12272e8c59bff711be4d463 (diff) | |
download | firmament-428056ff805839e04443dcff3badd021eb4abe01.tar.gz firmament-428056ff805839e04443dcff3badd021eb4abe01.tar.bz2 firmament-428056ff805839e04443dcff3badd021eb4abe01.zip |
Add support for other mods using /locraw
7 files changed, 105 insertions, 20 deletions
diff --git a/src/main/java/moe/nea/firmament/mixins/MixinChatHud.java b/src/main/java/moe/nea/firmament/mixins/MixinChatHud.java new file mode 100644 index 0000000..f0db847 --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/MixinChatHud.java @@ -0,0 +1,21 @@ +package moe.nea.firmament.mixins; + +import moe.nea.firmament.events.ClientChatLineReceivedEvent; +import net.minecraft.client.gui.hud.ChatHud; +import net.minecraft.client.gui.hud.MessageIndicator; +import net.minecraft.network.message.MessageSignatureData; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ChatHud.class) +public class MixinChatHud { + @Inject(at = @At("HEAD"), method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;ILnet/minecraft/client/gui/hud/MessageIndicator;Z)V", cancellable = true) + public void onAddMessage(Text message, MessageSignatureData signature, int ticks, MessageIndicator indicator, boolean refresh, CallbackInfo ci) { + if (ClientChatLineReceivedEvent.Companion.publish(new ClientChatLineReceivedEvent(message)).getCancelled()) { + ci.cancel(); + } + } +} diff --git a/src/main/java/moe/nea/firmament/mixins/MixinClientPacketHandler.java b/src/main/java/moe/nea/firmament/mixins/MixinClientPacketHandler.java index 46ab08a..9d8463e 100644 --- a/src/main/java/moe/nea/firmament/mixins/MixinClientPacketHandler.java +++ b/src/main/java/moe/nea/firmament/mixins/MixinClientPacketHandler.java @@ -18,8 +18,10 @@ package moe.nea.firmament.mixins; +import moe.nea.firmament.events.OutgoingPacketEvent; import moe.nea.firmament.events.ParticleSpawnEvent; import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.s2c.play.ParticleS2CPacket; import net.minecraft.util.math.Vec3d; import org.spongepowered.asm.mixin.Mixin; @@ -38,4 +40,11 @@ public class MixinClientPacketHandler { packet.isLongDistance() )); } + + @Inject(method = "sendPacket(Lnet/minecraft/network/packet/Packet;)V", at = @At("HEAD"), cancellable = true) + public void onSendPacket(Packet<?> packet, CallbackInfo ci) { + if (OutgoingPacketEvent.Companion.publish(new OutgoingPacketEvent(packet)).getCancelled()) { + ci.cancel(); + } + } } 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() } } |