diff --git a/src/main/kotlin/gg/skytils/skytilsmod/features/impl/mining/CHWaypoints.kt b/src/main/kotlin/gg/skytils/skytilsmod/features/impl/mining/CHWaypoints.kt index b7020a162..4a39cb2d4 100644 --- a/src/main/kotlin/gg/skytils/skytilsmod/features/impl/mining/CHWaypoints.kt +++ b/src/main/kotlin/gg/skytils/skytilsmod/features/impl/mining/CHWaypoints.kt @@ -28,10 +28,17 @@ import gg.skytils.skytilsmod.Skytils import gg.skytils.skytilsmod.Skytils.Companion.mc import gg.skytils.skytilsmod.Skytils.Companion.prefix import gg.skytils.skytilsmod.core.structure.GuiElement +import gg.skytils.skytilsmod.events.impl.HypixelPacketEvent import gg.skytils.skytilsmod.events.impl.PacketEvent import gg.skytils.skytilsmod.features.impl.handlers.MayorInfo import gg.skytils.skytilsmod.utils.* import gg.skytils.skytilsmod.utils.graphics.colors.ColorFactory +import gg.skytils.skytilsws.client.WSClient +import gg.skytils.skytilsws.shared.packet.C2SPacketCHWaypoint +import gg.skytils.skytilsws.shared.packet.C2SPacketCHWaypointsSubscribe +import gg.skytils.skytilsws.shared.structs.CHWaypointType +import kotlinx.coroutines.launch +import net.hypixel.modapi.packet.impl.clientbound.event.ClientboundLocationPacket import net.minecraft.client.entity.EntityOtherPlayerMP import net.minecraft.client.renderer.GlStateManager import net.minecraft.client.renderer.vertex.DefaultVertexFormats @@ -47,6 +54,7 @@ import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent +import kotlin.jvm.optionals.getOrNull object CHWaypoints { var lastTPLoc: BlockPos? = null @@ -58,6 +66,22 @@ object CHWaypoints { Regex(".*?(?[a-zA-Z0-9_]{3,16}):.*?(?[0-9]{1,3}),? (?:y: )?(?[0-9]{1,3}),? (?:z: )?(?[0-9]{1,3}).*?") private val xzPattern = Regex(".*(?[a-zA-Z0-9_]{3,16}):.* (?[0-9]{1,3}),? (?[0-9]{1,3}).*") + val chWaypointsList = hashMapOf() + class CHInstance { + val waypoints = hashMapOf() + } + + + @SubscribeEvent + fun onHypixelPacket(event: HypixelPacketEvent.ReceiveEvent) { + if (event.packet is ClientboundLocationPacket) { + if (event.packet.mode.getOrNull() == SkyblockIsland.CrystalHollows.mode) { + Skytils.IO.launch { + WSClient.sendPacket(C2SPacketCHWaypointsSubscribe(event.packet.serverName)) + } + } + } + } @SubscribeEvent fun onReceivePacket(event: PacketEvent.ReceiveEvent) { @@ -187,7 +211,14 @@ object CHWaypoints { mc.thePlayer.canEntityBeSeen(event.entity) && event.entity.baseMaxHealth == if (MayorInfo.mayorPerks.contains("DOUBLE MOBS HP!!!")) 2_000_000.0 else 1_000_000.0 ) { - waypoints["Corleone"] = event.entity.position + if (!CrystalHollowsMap.Locations.Corleone.loc.exists()) { + CrystalHollowsMap.Locations.Corleone.apply { + loc.set() + Skytils.IO.launch { + WSClient.sendPacket(C2SPacketCHWaypoint(serverId = SBInfo.location, serverTime = mc.theWorld.worldTime, packetType, loc.locX!!.toInt(), loc.locY!!.toInt(), loc.locZ!!.toInt())) + } + } + } else CrystalHollowsMap.Locations.Corleone.loc.set() } } @@ -197,14 +228,27 @@ object CHWaypoints { if ((Skytils.config.crystalHollowWaypoints || Skytils.config.crystalHollowMapPlaces) && SBInfo.mode == SkyblockIsland.CrystalHollows.mode && waypointDelayTicks == 0 && mc.thePlayer != null ) { - CrystalHollowsMap.Locations.cleanNameToLocation[SBInfo.location]?.loc?.set() + CrystalHollowsMap.Locations.cleanNameToLocation[SBInfo.location]?.let { + if (!it.loc.exists()) { + it.loc.set() + Skytils.IO.launch { + WSClient.sendPacket(C2SPacketCHWaypoint(serverId = SBInfo.location, serverTime = mc.theWorld.worldTime, it.packetType, it.loc.locX!!.toInt(), it.loc.locY!!.toInt(), it.loc.locZ!!.toInt())) + } + } else it.loc.set() + } } else if (waypointDelayTicks > 0) waypointDelayTicks-- } - @SubscribeEvent + @SubscribeEvent(priority = EventPriority.HIGHEST) fun onWorldChange(event: WorldEvent.Unload) { - CrystalHollowsMap.Locations.entries.forEach { it.loc.reset() } + val instance = chWaypointsList.getOrPut(SBInfo.server ?: "") { CHInstance() } + CrystalHollowsMap.Locations.entries.forEach { + if (it.loc.exists()) { + instance.waypoints[it.packetType] = BlockPos(it.loc.locX!!, it.loc.locY!!, it.loc.locZ!!) + } + it.loc.reset() + } waypoints.clear() } @@ -212,15 +256,15 @@ object CHWaypoints { class CrystalHollowsMap : GuiElement(name = "Crystal Hollows Map", x = 0, y = 0) { val mapLocation = ResourceLocation("skytils", "crystalhollowsmap.png") - enum class Locations(val displayName: String, val id: String, val color: Int, val size: Int = 50) { - LostPrecursorCity("§fLost Precursor City", "internal_city", ColorFactory.WHITE.rgb), - JungleTemple("§aJungle Temple", "internal_temple", ColorFactory.GREEN.rgb), - GoblinQueensDen("§eGoblin Queen's Den", "internal_den", ColorFactory.YELLOW.rgb), - MinesOfDivan("§9Mines of Divan", "internal_mines", ColorFactory.BLUE.rgb), - KingYolkar("§6King Yolkar", "internal_king", ColorFactory.ORANGE.rgb, 25), - KhazadDum("§cKhazad-dûm", "internal_bal", ColorFactory.RED.rgb), - FairyGrotto("§dFairy Grotto", "internal_fairy", ColorFactory.PINK.rgb, 26), - Corleone("§bCorleone", "internal_corleone", ColorFactory.AQUA.rgb, 26); + enum class Locations(val displayName: String, val id: String, val color: Int, val packetType: CHWaypointType, val size: Int = 50) { + LostPrecursorCity("§fLost Precursor City", "internal_city", ColorFactory.WHITE.rgb, CHWaypointType.LostPrecursorCity), + JungleTemple("§aJungle Temple", "internal_temple", ColorFactory.GREEN.rgb, CHWaypointType.JungleTemple), + GoblinQueensDen("§eGoblin Queen's Den", "internal_den", ColorFactory.YELLOW.rgb, CHWaypointType.GoblinQueensDen), + MinesOfDivan("§9Mines of Divan", "internal_mines", ColorFactory.BLUE.rgb, CHWaypointType.MinesOfDivan), + KingYolkar("§6King Yolkar", "internal_king", ColorFactory.ORANGE.rgb, CHWaypointType.KingYolkar,25), + KhazadDum("§cKhazad-dûm", "internal_bal", ColorFactory.RED.rgb, CHWaypointType.KhazadDum), + FairyGrotto("§dFairy Grotto", "internal_fairy", ColorFactory.PINK.rgb, CHWaypointType.FairyGrotto, 26), + Corleone("§bCorleone", "internal_corleone", ColorFactory.AQUA.rgb, CHWaypointType.Corleone, 26); val loc = LocationObject() val cleanName = displayName.stripControlCodes() diff --git a/src/main/kotlin/gg/skytils/skytilsmod/listeners/DungeonListener.kt b/src/main/kotlin/gg/skytils/skytilsmod/listeners/DungeonListener.kt index 9e0bfedce..64d32f96d 100644 --- a/src/main/kotlin/gg/skytils/skytilsmod/listeners/DungeonListener.kt +++ b/src/main/kotlin/gg/skytils/skytilsmod/listeners/DungeonListener.kt @@ -51,7 +51,7 @@ import gg.skytils.skytilsws.client.WSClient import gg.skytils.skytilsws.shared.packet.C2SPacketDungeonEnd import gg.skytils.skytilsws.shared.packet.C2SPacketDungeonRoom import gg.skytils.skytilsws.shared.packet.C2SPacketDungeonRoomSecret -import gg.skytils.skytilsws.shared.packet.C2SPacketStartDungeon +import gg.skytils.skytilsws.shared.packet.C2SPacketDungeonStart import kotlinx.coroutines.async import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -212,7 +212,7 @@ object DungeonListener { } val partyMembers = party.await().members.ifEmpty { setOf(mc.thePlayer.uniqueID) }.mapTo(hashSetOf()) { it.toString() } val entrance = DungeonInfo.uniqueRooms.first { it.mainRoom.data.type == RoomType.ENTRANCE } - WSClient.sendPacket(C2SPacketStartDungeon( + WSClient.sendPacket(C2SPacketDungeonStart( serverId = SBInfo.server ?: return@launch, floor = DungeonFeatures.dungeonFloor!!, members = partyMembers, diff --git a/src/main/kotlin/gg/skytils/skytilsmod/utils/SBInfo.kt b/src/main/kotlin/gg/skytils/skytilsmod/utils/SBInfo.kt index 444fb82b6..80cf6ade6 100644 --- a/src/main/kotlin/gg/skytils/skytilsmod/utils/SBInfo.kt +++ b/src/main/kotlin/gg/skytils/skytilsmod/utils/SBInfo.kt @@ -23,7 +23,6 @@ import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* -import net.hypixel.modapi.HypixelModAPI import net.hypixel.modapi.packet.impl.clientbound.event.ClientboundLocationPacket import net.minecraft.client.gui.inventory.GuiChest import net.minecraft.inventory.ContainerChest @@ -84,7 +83,7 @@ object SBInfo { lastLocationPacket = null } - @SubscribeEvent + @SubscribeEvent(priority = EventPriority.HIGH) fun onHypixelPacket(event: HypixelPacketEvent.ReceiveEvent) { if (event.packet is ClientboundLocationPacket) { Utils.checkThreadAndQueue { diff --git a/src/main/kotlin/gg/skytils/skytilsws/client/PacketHandler.kt b/src/main/kotlin/gg/skytils/skytilsws/client/PacketHandler.kt index 4a5d4323b..f4b0bb0ed 100644 --- a/src/main/kotlin/gg/skytils/skytilsws/client/PacketHandler.kt +++ b/src/main/kotlin/gg/skytils/skytilsws/client/PacketHandler.kt @@ -24,11 +24,16 @@ import gg.skytils.skytilsmod.features.impl.dungeons.catlas.core.map.Room import gg.skytils.skytilsmod.features.impl.dungeons.catlas.core.map.Unknown import gg.skytils.skytilsmod.features.impl.dungeons.catlas.handlers.DungeonInfo import gg.skytils.skytilsmod.features.impl.dungeons.catlas.utils.ScanUtils +import gg.skytils.skytilsmod.features.impl.mining.CHWaypoints +import gg.skytils.skytilsmod.features.impl.mining.CHWaypoints.CHInstance +import gg.skytils.skytilsmod.features.impl.mining.CHWaypoints.chWaypointsList +import gg.skytils.skytilsmod.utils.SBInfo import gg.skytils.skytilsws.shared.IPacketHandler import gg.skytils.skytilsws.shared.SkytilsWS import gg.skytils.skytilsws.shared.packet.* import io.ktor.websocket.* import kotlinx.coroutines.coroutineScope +import net.minecraft.util.BlockPos import java.util.* object PacketHandler : IPacketHandler { @@ -68,6 +73,27 @@ object PacketHandler : IPacketHandler { } } } + is S2CPacketCHReset -> { + CHWaypoints.waypoints.remove(packet.serverId) + } + is S2CPacketCHWaypoint -> { + if (SBInfo.server == packet.serverId) { + if (mc.theWorld.worldTime < packet.serverTime) { + WSClient.sendPacket(C2SPacketCHReset(packet.serverId)) + } else { + CHWaypoints.CrystalHollowsMap.Locations.entries.find { it.packetType == packet.type }?.let { + if (!it.loc.exists()) { + it.loc.locX = packet.x.toDouble() + it.loc.locY = packet.y.toDouble() + it.loc.locZ = packet.z.toDouble() + } + } + } + } else { + val instance = chWaypointsList.getOrPut(SBInfo.server ?: "") { CHInstance() } + instance.waypoints[packet.type] = BlockPos(packet.x, packet.y, packet.z) + } + } else -> { session.close(CloseReason(CloseReason.Codes.CANNOT_ACCEPT, "Unknown packet type")) } diff --git a/src/main/kotlin/gg/skytils/skytilsws/client/WSClient.kt b/src/main/kotlin/gg/skytils/skytilsws/client/WSClient.kt index 22a027524..e8662bf42 100644 --- a/src/main/kotlin/gg/skytils/skytilsws/client/WSClient.kt +++ b/src/main/kotlin/gg/skytils/skytilsws/client/WSClient.kt @@ -67,7 +67,7 @@ object WSClient { suspend fun openConnection() { if (session != null) error("Session already open") - client.webSocketSession("wss://ws.skytils.gg/ws").apply { + wsClient.webSocketSession("ws://localhost:9998/ws").apply { session = this try { sendSerialized(C2SPacketConnect(SkytilsWS.version, Skytils.VERSION)) diff --git a/ws-shared b/ws-shared index 51e490538..2ddcfba18 160000 --- a/ws-shared +++ b/ws-shared @@ -1 +1 @@ -Subproject commit 51e4905381c9875a9283091d4ff628c904b42e66 +Subproject commit 2ddcfba1864c4c621dc61cfcaff373ed740cb559