aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authornea <nea@nea.moe>2023-06-09 18:08:38 +0200
committernea <nea@nea.moe>2023-06-09 18:08:38 +0200
commit428056ff805839e04443dcff3badd021eb4abe01 (patch)
tree1dfb5b4dc84bc0884dc319be7f8ad4e949decb81 /src/main
parente7a7b04d8cadbc08d12272e8c59bff711be4d463 (diff)
downloadfirmament-428056ff805839e04443dcff3badd021eb4abe01.tar.gz
firmament-428056ff805839e04443dcff3badd021eb4abe01.tar.bz2
firmament-428056ff805839e04443dcff3badd021eb4abe01.zip
Add support for other mods using /locraw
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/moe/nea/firmament/mixins/MixinChatHud.java21
-rw-r--r--src/main/java/moe/nea/firmament/mixins/MixinClientPacketHandler.java9
-rw-r--r--src/main/kotlin/moe/nea/firmament/events/ClientChatLineReceivedEvent.kt14
-rw-r--r--src/main/kotlin/moe/nea/firmament/events/OutgoingPacketEvent.kt7
-rw-r--r--src/main/kotlin/moe/nea/firmament/events/ServerChatLineReceivedEvent.kt6
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/SBData.kt57
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/data/ProfileSpecificDataHolder.kt11
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()
}
}