diff options
16 files changed, 63 insertions, 473 deletions
diff --git a/build.gradle.kts b/build.gradle.kts index 12b8bc6..fec1afb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -79,6 +79,7 @@ allprojects { } maven("https://repo.hypixel.net/repository/Hypixel/") maven("https://maven.azureaaron.net/snapshots") + maven("https://maven.azureaaron.net/releases") mavenLocal() } } @@ -128,6 +129,8 @@ dependencies { modImplementation(libs.moulconfig) modImplementation(libs.manninghamMills) modCompileOnly(libs.explosiveenhancement) + modImplementation(libs.hypixelmodapi) + include(libs.hypixelmodapi.fabric) compileOnly(project(":javaplugin")) annotationProcessor(project(":javaplugin")) include(libs.manninghamMills) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d4820e3..e723484 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,6 +29,8 @@ mixinextras = "0.3.5" jarvis = "1.1.3" nealisp = "1.0.0" moulconfig = "3.0.0-beta.14" +hypixelmodapi = "1.0.1" +hypixelmodapi_fabric = "1.0.1+build.1+mc1.21" manninghamMills = "2.4.1" [libraries] @@ -47,6 +49,9 @@ jarvis_fabric = { module = "moe.nea.jarvis:jarvis-fabric", version.ref = "jarvis nealisp = { module = "moe.nea:nealisp", version.ref = "nealisp" } explosiveenhancement = { module = "maven.modrinth:explosive-enhancement", version.ref = "explosiveenhancement" } manninghamMills = { module = "me.shedaniel:mm", version.ref = "manninghamMills" } +aaronhmapi = { module = "net.azureaaron:hm-api", version = "1.0.0+1.21" } +hypixelmodapi = { module = "net.hypixel:mod-api", version.ref = "hypixelmodapi" } +hypixelmodapi_fabric = { module = "maven.modrinth:hypixel-mod-api", version.ref = "hypixelmodapi_fabric" } # Runtime: notenoughanimations = { module = "maven.modrinth:not-enough-animations", version.ref = "notenoughanimations" } hotswap = { module = "virtual.github.hotswapagent:hotswap-agent", version.ref = "hotswap_agent" } @@ -67,11 +72,12 @@ runtime_required = [ "rei_fabric", "notenoughanimations", "femalegender", + "hypixelmodapi_fabric", ] runtime_optional = [ "devauth", "freecammod", -# "sodium", + "sodium", # "qolify", # "citresewn", # "ncr", diff --git a/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java b/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java index 2be11a6..ebb060c 100644 --- a/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java +++ b/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java @@ -60,7 +60,7 @@ public class SectionBuilderRiser extends RiserUtils { return; } } - new RuntimeException("Could not inject tesselation hook despite fabric renderer indigo being loaded").printStackTrace(); + System.err.println("Could not inject indigo rendering hook. Is a custom renderer installed (e.g. sodium)?"); } private void handleIndigo(MethodNode method) { diff --git a/src/main/java/moe/nea/firmament/mixins/custompayload/CustomPayloadEventDispatcher.java b/src/main/java/moe/nea/firmament/mixins/custompayload/CustomPayloadEventDispatcher.java deleted file mode 100644 index 2084821..0000000 --- a/src/main/java/moe/nea/firmament/mixins/custompayload/CustomPayloadEventDispatcher.java +++ /dev/null @@ -1,22 +0,0 @@ - -package moe.nea.firmament.mixins.custompayload; - -import moe.nea.firmament.apis.ingame.FirmamentCustomPayload; -import moe.nea.firmament.events.FirmamentCustomPayloadEvent; -import net.minecraft.client.network.ClientCommonNetworkHandler; -import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket; -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(value = ClientCommonNetworkHandler.class, priority = 500) -public class CustomPayloadEventDispatcher { - @Inject(method = "onCustomPayload(Lnet/minecraft/network/packet/s2c/common/CustomPayloadS2CPacket;)V", at = @At("HEAD"), cancellable = true) - private void handleFirmamentParsedPayload(CustomPayloadS2CPacket packet, CallbackInfo ci) { - if (packet.payload() instanceof FirmamentCustomPayload customPayload) { - FirmamentCustomPayloadEvent.Companion.publishSync(new FirmamentCustomPayloadEvent(customPayload)); - ci.cancel(); - } - } -} diff --git a/src/main/java/moe/nea/firmament/mixins/custompayload/InjectCustomCodecIntoC2SCustomPayloadPacket.java b/src/main/java/moe/nea/firmament/mixins/custompayload/InjectCustomCodecIntoC2SCustomPayloadPacket.java deleted file mode 100644 index baa091e..0000000 --- a/src/main/java/moe/nea/firmament/mixins/custompayload/InjectCustomCodecIntoC2SCustomPayloadPacket.java +++ /dev/null @@ -1,29 +0,0 @@ - -package moe.nea.firmament.mixins.custompayload; - -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import moe.nea.firmament.apis.ingame.InGameCodecWrapper; -import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.network.packet.c2s.common.CustomPayloadC2SPacket; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -import java.util.List; - -@Mixin(priority = 1001, value = CustomPayloadC2SPacket.class) -public class InjectCustomCodecIntoC2SCustomPayloadPacket { - - @WrapOperation(method = "<clinit>", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/CustomPayload;createCodec(Lnet/minecraft/network/packet/CustomPayload$CodecFactory;Ljava/util/List;)Lnet/minecraft/network/codec/PacketCodec;")) - private static PacketCodec<PacketByteBuf, CustomPayload> wrapFactory( - CustomPayload.CodecFactory<PacketByteBuf> unknownCodecFactory, - List<CustomPayload.Type<PacketByteBuf, ?>> types, - Operation<PacketCodec<PacketByteBuf, CustomPayload>> original) { - - var originalCodec = original.call(unknownCodecFactory, types); - - return new InGameCodecWrapper(originalCodec, InGameCodecWrapper.Direction.C2S); - } -} diff --git a/src/main/java/moe/nea/firmament/mixins/custompayload/InjectCustomCodecIntoS2CCustomPayloadPacket.java b/src/main/java/moe/nea/firmament/mixins/custompayload/InjectCustomCodecIntoS2CCustomPayloadPacket.java deleted file mode 100644 index 10c4ceb..0000000 --- a/src/main/java/moe/nea/firmament/mixins/custompayload/InjectCustomCodecIntoS2CCustomPayloadPacket.java +++ /dev/null @@ -1,29 +0,0 @@ - -package moe.nea.firmament.mixins.custompayload; - -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import moe.nea.firmament.apis.ingame.InGameCodecWrapper; -import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -import java.util.List; - -@Mixin(priority = 1001, value = CustomPayloadS2CPacket.class) -public abstract class InjectCustomCodecIntoS2CCustomPayloadPacket { - - @WrapOperation(method = "<clinit>", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/CustomPayload;createCodec(Lnet/minecraft/network/packet/CustomPayload$CodecFactory;Ljava/util/List;)Lnet/minecraft/network/codec/PacketCodec;")) - private static PacketCodec<PacketByteBuf, CustomPayload> wrapFactory( - CustomPayload.CodecFactory<PacketByteBuf> unknownCodecFactory, - List<CustomPayload.Type<PacketByteBuf, ?>> types, - Operation<PacketCodec<PacketByteBuf, CustomPayload>> original) { - - var originalCodec = original.call(unknownCodecFactory, types); - - return new InGameCodecWrapper(originalCodec, InGameCodecWrapper.Direction.S2C); - } -} diff --git a/src/main/java/moe/nea/firmament/mixins/custompayload/SplitJoinedCustomPayload.java b/src/main/java/moe/nea/firmament/mixins/custompayload/SplitJoinedCustomPayload.java deleted file mode 100644 index 5320a13..0000000 --- a/src/main/java/moe/nea/firmament/mixins/custompayload/SplitJoinedCustomPayload.java +++ /dev/null @@ -1,28 +0,0 @@ - -package moe.nea.firmament.mixins.custompayload; - -import moe.nea.firmament.apis.ingame.JoinedCustomPayload; -import net.minecraft.network.listener.ClientCommonPacketListener; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(CustomPayloadS2CPacket.class) -public abstract class SplitJoinedCustomPayload { - - @Shadow - public abstract CustomPayload payload(); - - @Inject(method = "apply(Lnet/minecraft/network/listener/ClientCommonPacketListener;)V", at = @At("HEAD"), cancellable = true) - private void onApply(ClientCommonPacketListener clientCommonPacketListener, CallbackInfo ci) { - if (payload() instanceof JoinedCustomPayload joinedCustomPayload) { - new CustomPayloadS2CPacket(joinedCustomPayload.getOriginal()).apply(clientCommonPacketListener); - new CustomPayloadS2CPacket(joinedCustomPayload.getSmuggled()).apply(clientCommonPacketListener); - ci.cancel(); - } - } -} 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") } - - } |