aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/firmament
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-08-12 22:15:07 +0200
committerLinnea Gräf <nea@nea.moe>2024-08-12 22:15:07 +0200
commitb8a45b9a0438a12ba3c609f6e416d519829471be (patch)
treeaff190bb953d94f1187896b2c245644a29e6badf /src/main/kotlin/moe/nea/firmament
parent3c7e6b6177de6ef3cff8a46bb1726466a299cdde (diff)
downloadFirmament-b8a45b9a0438a12ba3c609f6e416d519829471be.tar.gz
Firmament-b8a45b9a0438a12ba3c609f6e416d519829471be.tar.bz2
Firmament-b8a45b9a0438a12ba3c609f6e416d519829471be.zip
Improve location and profile detection
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament')
-rw-r--r--src/main/kotlin/moe/nea/firmament/Firmament.kt2
-rw-r--r--src/main/kotlin/moe/nea/firmament/apis/ingame/FirmamentCustomPayload.kt31
-rw-r--r--src/main/kotlin/moe/nea/firmament/apis/ingame/HypixelModAPI.kt51
-rw-r--r--src/main/kotlin/moe/nea/firmament/apis/ingame/InGameCodecWrapper.kt48
-rw-r--r--src/main/kotlin/moe/nea/firmament/apis/ingame/JoinedCustomPayload.kt20
-rw-r--r--src/main/kotlin/moe/nea/firmament/apis/ingame/packets/PartyInfoRequest.kt134
-rw-r--r--src/main/kotlin/moe/nea/firmament/events/FirmamentCustomPayloadEvent.kt10
-rw-r--r--src/main/kotlin/moe/nea/firmament/events/ServerConnectedEvent.kt18
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/SBData.kt101
9 files changed, 52 insertions, 363 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/Firmament.kt b/src/main/kotlin/moe/nea/firmament/Firmament.kt
index 400dcf2..c1801f4 100644
--- a/src/main/kotlin/moe/nea/firmament/Firmament.kt
+++ b/src/main/kotlin/moe/nea/firmament/Firmament.kt
@@ -113,8 +113,6 @@ object Firmament {
ClientTickEvents.END_CLIENT_TICK.register(ClientTickEvents.EndTick { instance ->
TickEvent.publish(TickEvent(tick++))
})
- // TODO: remove me
- Class.forName(SectionBuilder::class.java.name)
IDataHolder.registerEvents()
RepoManager.initialize()
SBData.init()
diff --git a/src/main/kotlin/moe/nea/firmament/apis/ingame/FirmamentCustomPayload.kt b/src/main/kotlin/moe/nea/firmament/apis/ingame/FirmamentCustomPayload.kt
deleted file mode 100644
index 10af7d0..0000000
--- a/src/main/kotlin/moe/nea/firmament/apis/ingame/FirmamentCustomPayload.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-
-package moe.nea.firmament.apis.ingame
-
-import io.netty.buffer.ByteBuf
-import net.minecraft.network.codec.PacketCodec
-import net.minecraft.network.packet.CustomPayload
-import net.minecraft.util.Identifier
-
-interface FirmamentCustomPayload : CustomPayload {
-
- class Unhandled private constructor(val identifier: Identifier) : FirmamentCustomPayload {
- override fun getId(): CustomPayload.Id<out CustomPayload> {
- return CustomPayload.id(identifier.toString())
- }
-
- companion object {
- fun <B : ByteBuf> createCodec(identifier: Identifier): PacketCodec<B, Unhandled> {
- return object : PacketCodec<B, Unhandled> {
- override fun decode(buf: B): Unhandled {
- return Unhandled(identifier)
- }
-
- override fun encode(buf: B, value: Unhandled) {
- // we will never send an unhandled packet stealthy
- }
- }
- }
- }
-
- }
-}
diff --git a/src/main/kotlin/moe/nea/firmament/apis/ingame/HypixelModAPI.kt b/src/main/kotlin/moe/nea/firmament/apis/ingame/HypixelModAPI.kt
deleted file mode 100644
index fb01a2f..0000000
--- a/src/main/kotlin/moe/nea/firmament/apis/ingame/HypixelModAPI.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-
-package moe.nea.firmament.apis.ingame
-
-import net.minecraft.network.packet.c2s.common.CustomPayloadC2SPacket
-import net.minecraft.text.Text
-import moe.nea.firmament.annotations.Subscribe
-import moe.nea.firmament.apis.ingame.packets.PartyInfoRequest
-import moe.nea.firmament.apis.ingame.packets.PartyInfoResponse
-import moe.nea.firmament.commands.thenExecute
-import moe.nea.firmament.events.CommandEvent
-import moe.nea.firmament.events.FirmamentCustomPayloadEvent
-import moe.nea.firmament.events.subscription.SubscriptionOwner
-import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.features.debug.DeveloperFeatures
-import moe.nea.firmament.util.MC
-
-
-object HypixelModAPI : SubscriptionOwner {
- init {
- InGameCodecWrapper.Direction.C2S.customCodec =
- InGameCodecWrapper.createStealthyCodec(
- PartyInfoRequest.intoType()
- )
- InGameCodecWrapper.Direction.S2C.customCodec =
- InGameCodecWrapper.createStealthyCodec(
- PartyInfoResponse.intoType()
- )
- }
-
- @JvmStatic
- fun sendRequest(packet: FirmamentCustomPayload) {
- MC.networkHandler?.sendPacket(CustomPayloadC2SPacket(packet))
- }
-
- @Subscribe
- fun testCommand(event: CommandEvent.SubCommand) {
- event.subcommand("sendpartyrequest") {
- thenExecute {
- sendRequest(PartyInfoRequest(1))
- }
- }
- }
-
- @Subscribe
- fun logEvents(event: FirmamentCustomPayloadEvent) {
- MC.sendChat(Text.stringifiedTranslatable("firmament.modapi.event", event.toString()))
- }
-
- override val delegateFeature: FirmamentFeature
- get() = DeveloperFeatures
-}
diff --git a/src/main/kotlin/moe/nea/firmament/apis/ingame/InGameCodecWrapper.kt b/src/main/kotlin/moe/nea/firmament/apis/ingame/InGameCodecWrapper.kt
deleted file mode 100644
index 1a4710f..0000000
--- a/src/main/kotlin/moe/nea/firmament/apis/ingame/InGameCodecWrapper.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-
-package moe.nea.firmament.apis.ingame
-
-import net.minecraft.network.PacketByteBuf
-import net.minecraft.network.codec.PacketCodec
-import net.minecraft.network.packet.CustomPayload
-
-class InGameCodecWrapper(
- val wrapped: PacketCodec<PacketByteBuf, CustomPayload>,
- val direction: Direction,
-) : PacketCodec<PacketByteBuf, CustomPayload> {
- enum class Direction {
- S2C,
- C2S,
- ;
-
- var customCodec: PacketCodec<PacketByteBuf, FirmamentCustomPayload> = createStealthyCodec()
- }
-
- companion object {
- fun createStealthyCodec(vararg codecs: CustomPayload.Type<PacketByteBuf, out FirmamentCustomPayload>): PacketCodec<PacketByteBuf, FirmamentCustomPayload> {
- return CustomPayload.createCodec(
- { FirmamentCustomPayload.Unhandled.createCodec(it) },
- codecs.toList()
- ) as PacketCodec<PacketByteBuf, FirmamentCustomPayload>
- }
-
- }
-
- override fun decode(buf: PacketByteBuf): CustomPayload {
- val duplicateBuffer = PacketByteBuf(buf.slice())
- val original = wrapped.decode(buf)
- buf.skipBytes(buf.readableBytes())
- val duplicate = runCatching { direction.customCodec.decode(duplicateBuffer) }
- .getOrNull()
- if (duplicate is FirmamentCustomPayload.Unhandled || duplicate == null)
- return original
- return JoinedCustomPayload(original, duplicate)
- }
-
- override fun encode(buf: PacketByteBuf, value: CustomPayload) {
- if (value is FirmamentCustomPayload) {
- direction.customCodec.encode(buf, value)
- } else {
- wrapped.encode(buf, value)
- }
- }
-}
diff --git a/src/main/kotlin/moe/nea/firmament/apis/ingame/JoinedCustomPayload.kt b/src/main/kotlin/moe/nea/firmament/apis/ingame/JoinedCustomPayload.kt
deleted file mode 100644
index 4b6a6bc..0000000
--- a/src/main/kotlin/moe/nea/firmament/apis/ingame/JoinedCustomPayload.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-
-package moe.nea.firmament.apis.ingame
-
-import net.minecraft.network.packet.CustomPayload
-
-/**
- * A class to smuggle two parsed instances of the same custom payload packet.
- */
-class JoinedCustomPayload(
- val original: CustomPayload,
- val smuggled: FirmamentCustomPayload
-) : CustomPayload {
- companion object {
- val joinedId = CustomPayload.id<JoinedCustomPayload>("firmament:joined")
- }
-
- override fun getId(): CustomPayload.Id<out JoinedCustomPayload> {
- return joinedId
- }
-}
diff --git a/src/main/kotlin/moe/nea/firmament/apis/ingame/packets/PartyInfoRequest.kt b/src/main/kotlin/moe/nea/firmament/apis/ingame/packets/PartyInfoRequest.kt
deleted file mode 100644
index a1b4a71..0000000
--- a/src/main/kotlin/moe/nea/firmament/apis/ingame/packets/PartyInfoRequest.kt
+++ /dev/null
@@ -1,134 +0,0 @@
-
-package moe.nea.firmament.apis.ingame.packets
-
-import io.netty.buffer.ByteBuf
-import java.util.UUID
-import net.minecraft.network.PacketByteBuf
-import net.minecraft.network.codec.PacketCodec
-import net.minecraft.network.codec.PacketCodecs
-import net.minecraft.network.packet.CustomPayload
-import net.minecraft.util.Identifier
-import net.minecraft.util.Uuids
-import moe.nea.firmament.apis.ingame.FirmamentCustomPayload
-
-interface FirmamentCustomPayloadMeta<T : FirmamentCustomPayload> {
- val ID: CustomPayload.Id<T>
- val CODEC: PacketCodec<PacketByteBuf, T>
-
- fun id(name: String): CustomPayload.Id<T> {
- return CustomPayload.Id<T>(Identifier.of(name))
- }
-
- fun intoType(): CustomPayload.Type<PacketByteBuf, T> {
- return CustomPayload.Type(ID, CODEC)
- }
-}
-
-data class PartyInfoRequest(val version: Int) : FirmamentCustomPayload {
- companion object : FirmamentCustomPayloadMeta<PartyInfoRequest> {
- override val ID = id("hypixel:party_info")
- override val CODEC =
- PacketCodecs.VAR_INT.cast<PacketByteBuf>()
- .xmap(::PartyInfoRequest, PartyInfoRequest::version)
- }
-
- override fun getId(): CustomPayload.Id<out CustomPayload> {
- return ID
- }
-}
-
-sealed interface PartyInfoResponseV
-sealed interface HypixelVersionedPacketData<out T>
-data class HypixelSuccessfulResponse<T>(val data: T) : HypixelVersionedPacketData<T>
-data class HypixelUnknownVersion(val version: Int) : HypixelVersionedPacketData<Nothing>
-data class HypixelApiError(val label: String, val errorId: Int) : HypixelVersionedPacketData<Nothing> {
- companion object {
- fun <B : ByteBuf> createCodec(label: String): PacketCodec<B, HypixelApiError> {
- return PacketCodecs.VAR_INT
- .cast<B>()
- .xmap({ HypixelApiError(label, it) }, HypixelApiError::errorId)
- }
- }
-}
-
-object CodecUtils {
- fun <B : PacketByteBuf, T> dispatchVersioned(
- versions: Map<Int, PacketCodec<B, out T>>,
- errorCodec: PacketCodec<B, HypixelApiError>
- ): PacketCodec<B, HypixelVersionedPacketData<T>> {
- return object : PacketCodec<B, HypixelVersionedPacketData<T>> {
- override fun decode(buf: B): HypixelVersionedPacketData<T> {
- if (!buf.readBoolean()) {
- return errorCodec.decode(buf)
- }
- val version = buf.readVarInt()
- val versionCodec = versions[version]
- ?: return HypixelUnknownVersion(version)
- return HypixelSuccessfulResponse(versionCodec.decode(buf))
- }
-
- override fun encode(buf: B, value: HypixelVersionedPacketData<T>?) {
- error("Cannot encode a hypixel packet")
- }
- }
- }
-
- fun <B : PacketByteBuf, T> dispatchS2CBoolean(
- ifTrue: PacketCodec<B, out T>,
- ifFalse: PacketCodec<B, out T>
- ): PacketCodec<B, T> {
- return object : PacketCodec<B, T> {
- override fun decode(buf: B): T {
- return if (buf.readBoolean()) {
- ifTrue.decode(buf)
- } else {
- ifFalse.decode(buf)
- }
- }
-
- override fun encode(buf: B, value: T) {
- error("Cannot reverse dispatch boolean")
- }
- }
- }
-
-}
-
-
-data object PartyInfoResponseVUnknown : PartyInfoResponseV
-data class PartyInfoResponseV1(
- val leader: UUID?,
- val members: Set<UUID>,
-) : PartyInfoResponseV {
- data object PartyMember
- companion object {
- val CODEC: PacketCodec<PacketByteBuf, PartyInfoResponseV1> =
- CodecUtils.dispatchS2CBoolean(
- PacketCodec.tuple(
- Uuids.PACKET_CODEC, PartyInfoResponseV1::leader,
- Uuids.PACKET_CODEC.collect(PacketCodecs.toCollection(::HashSet)), PartyInfoResponseV1::members,
- ::PartyInfoResponseV1
- ),
- PacketCodec.unit(PartyInfoResponseV1(null, setOf())))
- }
-}
-
-
-data class PartyInfoResponse(val data: HypixelVersionedPacketData<PartyInfoResponseV>) : FirmamentCustomPayload {
- companion object : FirmamentCustomPayloadMeta<PartyInfoResponse> {
- override val ID = id("hypixel:party_info")
- override val CODEC =
- CodecUtils
- .dispatchVersioned<PacketByteBuf, PartyInfoResponseV>(
- mapOf(
- 1 to PartyInfoResponseV1.CODEC,
- ),
- HypixelApiError.createCodec("PartyInfoResponse"))
- .xmap(::PartyInfoResponse, PartyInfoResponse::data)
-
- }
-
- override fun getId(): CustomPayload.Id<out CustomPayload> {
- return ID
- }
-}
diff --git a/src/main/kotlin/moe/nea/firmament/events/FirmamentCustomPayloadEvent.kt b/src/main/kotlin/moe/nea/firmament/events/FirmamentCustomPayloadEvent.kt
deleted file mode 100644
index 779ca51..0000000
--- a/src/main/kotlin/moe/nea/firmament/events/FirmamentCustomPayloadEvent.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-
-package moe.nea.firmament.events
-
-import moe.nea.firmament.apis.ingame.FirmamentCustomPayload
-
-data class FirmamentCustomPayloadEvent(
- val payload: FirmamentCustomPayload
-) : FirmamentEvent() {
- companion object : FirmamentEventBus<FirmamentCustomPayloadEvent>()
-}
diff --git a/src/main/kotlin/moe/nea/firmament/events/ServerConnectedEvent.kt b/src/main/kotlin/moe/nea/firmament/events/ServerConnectedEvent.kt
new file mode 100644
index 0000000..26897f2
--- /dev/null
+++ b/src/main/kotlin/moe/nea/firmament/events/ServerConnectedEvent.kt
@@ -0,0 +1,18 @@
+package moe.nea.firmament.events
+
+import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents
+import net.minecraft.client.MinecraftClient
+import net.minecraft.client.network.ClientPlayNetworkHandler
+import net.minecraft.network.ClientConnection
+
+data class ServerConnectedEvent(
+ val connection: ClientConnection
+) : FirmamentEvent() {
+ companion object : FirmamentEventBus<ServerConnectedEvent>() {
+ init {
+ ClientPlayConnectionEvents.INIT.register(ClientPlayConnectionEvents.Init { clientPlayNetworkHandler: ClientPlayNetworkHandler, minecraftClient: MinecraftClient ->
+ publishSync(ServerConnectedEvent(clientPlayNetworkHandler.connection))
+ })
+ }
+ }
+}
diff --git a/src/main/kotlin/moe/nea/firmament/util/SBData.kt b/src/main/kotlin/moe/nea/firmament/util/SBData.kt
index 797cc0a..b30c6fb 100644
--- a/src/main/kotlin/moe/nea/firmament/util/SBData.kt
+++ b/src/main/kotlin/moe/nea/firmament/util/SBData.kt
@@ -1,37 +1,53 @@
-
-
package moe.nea.firmament.util
-import kotlinx.serialization.SerializationException
-import kotlinx.serialization.decodeFromString
-import moe.nea.firmament.Firmament
-import moe.nea.firmament.events.OutgoingPacketEvent
+import java.util.UUID
+import net.hypixel.modapi.HypixelModAPI
+import net.hypixel.modapi.packet.impl.clientbound.event.ClientboundLocationPacket
+import kotlin.jvm.optionals.getOrNull
+import kotlin.time.Duration.Companion.seconds
+import moe.nea.firmament.events.AllowChatEvent
import moe.nea.firmament.events.ProcessChatEvent
+import moe.nea.firmament.events.ServerConnectedEvent
import moe.nea.firmament.events.SkyblockServerUpdateEvent
import moe.nea.firmament.events.WorldReadyEvent
-import net.minecraft.network.packet.c2s.play.CommandExecutionC2SPacket
-import java.util.*
-import kotlin.time.Duration
-import kotlin.time.Duration.Companion.seconds
object SBData {
private val profileRegex = "Profile ID: ([a-z0-9\\-]+)".toRegex()
+ val profileSuggestTexts = listOf(
+ "CLICK THIS TO SUGGEST IT IN CHAT [DASHES]",
+ "CLICK THIS TO SUGGEST IT IN CHAT [NO DASHES]",
+ )
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: SkyBlockIsland? get() = locraw?.skyblockLocation
val hasValidLocraw get() = locraw?.server !in listOf("limbo", null)
val isOnSkyblock get() = locraw?.gametype == "SKYBLOCK"
-
+ var lastProfileIdRequest = TimeMark.farPast()
fun init() {
- OutgoingPacketEvent.subscribe { event ->
- if (event.packet is CommandExecutionC2SPacket && event.packet.command == "locraw") {
- anyLocrawSent.markNow()
+ ServerConnectedEvent.subscribe {
+ HypixelModAPI.getInstance().subscribeToEventPacket(ClientboundLocationPacket::class.java)
+ }
+ HypixelModAPI.getInstance().createHandler(ClientboundLocationPacket::class.java) {
+ MC.onMainThread {
+ val lastLocraw = locraw
+ locraw = Locraw(it.serverName,
+ it.serverType.getOrNull()?.name?.uppercase(),
+ it.mode.getOrNull(),
+ it.map.getOrNull())
+ SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, null))
+ }
+ }
+ SkyblockServerUpdateEvent.subscribe {
+ if (!hasReceivedProfile && isOnSkyblock && lastProfileIdRequest.passedTime() > 30.seconds) {
+ lastProfileIdRequest = TimeMark.now()
+ MC.sendServerCommand("profileid")
+ }
+ }
+ AllowChatEvent.subscribe { event ->
+ if (event.unformattedString in profileSuggestTexts && lastProfileIdRequest.passedTime() < 5.seconds) {
+ event.cancel()
}
}
ProcessChatEvent.subscribe(receivesCancelled = true) { event ->
@@ -40,60 +56,11 @@ object SBData {
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)) {
- if (lastLocrawSent.timePassed() < locrawRoundtripTime) {
- lastLocrawSent.markFarPast()
- event.cancel()
- }
- if (!hasValidLocraw && !hasSentLocraw && hasReceivedProfile) {
- sendLocraw()
- }
- }
- }
- }
-
- WorldReadyEvent.subscribe {
- val lastLocraw = locraw
- locraw = null
- SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, null))
- hasSentLocraw = false
- hasReceivedProfile = false
- }
- }
-
- private fun tryReceiveLocraw(unformattedString: String, update: Boolean = true): Boolean = try {
- val lastLocraw = locraw
- val n = Firmament.json.decodeFromString<Locraw>(unformattedString)
- if (update) {
- if (n.gametype != "SKYBLOCK")
- profileId = null
- locraw = n
- SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, locraw))
}
- true
- } catch (e: SerializationException) {
- e.printStackTrace()
- false
- } catch (e: IllegalArgumentException) {
- e.printStackTrace()
- false
- }
-
- fun sendLocraw() {
- hasSentLocraw = true
- lastLocrawSent.markNow()
- val nh = MC.player?.networkHandler ?: return
- nh.sendChatCommand("locraw")
}
-
-
}