aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/com/ambientaddons/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/com/ambientaddons/utils')
-rw-r--r--src/main/kotlin/com/ambientaddons/utils/DungeonFloor.kt32
-rw-r--r--src/main/kotlin/com/ambientaddons/utils/Extensions.kt73
-rw-r--r--src/main/kotlin/com/ambientaddons/utils/LocationUtils.kt87
-rw-r--r--src/main/kotlin/com/ambientaddons/utils/TabListUtils.kt38
4 files changed, 230 insertions, 0 deletions
diff --git a/src/main/kotlin/com/ambientaddons/utils/DungeonFloor.kt b/src/main/kotlin/com/ambientaddons/utils/DungeonFloor.kt
new file mode 100644
index 0000000..a64fed0
--- /dev/null
+++ b/src/main/kotlin/com/ambientaddons/utils/DungeonFloor.kt
@@ -0,0 +1,32 @@
+package com.ambientaddons.utils
+
+data class DungeonFloor(
+ val mode: Mode,
+ val floor: Int
+) {
+ override fun toString(): String {
+ return when {
+ floor == 0 -> "E"
+ mode == Mode.Normal -> "F$floor"
+ else -> "M$floor"
+ }
+ }
+
+ companion object {
+ fun String.toDungeonFloor(): DungeonFloor? {
+ if (this.isEmpty()) return null
+ if (this == "E") return DungeonFloor(Mode.Normal, 0)
+ val floorInt = this.last().digitToIntOrNull() ?: return null
+ if (floorInt !in 1..7) return null
+ return when (this.first()) {
+ 'F' -> DungeonFloor(Mode.Normal, floorInt)
+ 'M' -> DungeonFloor(Mode.Master, floorInt)
+ else -> null
+ }
+ }
+ }
+}
+
+enum class Mode { Normal, Master }
+
+
diff --git a/src/main/kotlin/com/ambientaddons/utils/Extensions.kt b/src/main/kotlin/com/ambientaddons/utils/Extensions.kt
new file mode 100644
index 0000000..3da5767
--- /dev/null
+++ b/src/main/kotlin/com/ambientaddons/utils/Extensions.kt
@@ -0,0 +1,73 @@
+package com.ambientaddons.utils
+
+import com.ambientaddons.utils.Extensions.enchants
+import com.ambientaddons.utils.Extensions.extraAttributes
+import com.ambientaddons.utils.Extensions.skyblockID
+import net.minecraft.client.gui.GuiScreen
+import net.minecraft.client.gui.inventory.GuiChest
+import net.minecraft.inventory.ContainerChest
+import net.minecraft.inventory.IInventory
+import net.minecraft.item.Item
+import net.minecraft.item.ItemStack
+import net.minecraft.nbt.NBTTagCompound
+import net.minecraft.util.StringUtils
+
+object Extensions {
+ fun String.substringBetween(start: String, end: String): String {
+ return this
+ .substringAfter("(", "")
+ .substringBefore(")", "")
+ }
+
+ fun String.stripControlCodes(): String {
+ return StringUtils.stripControlCodes(this)
+ }
+
+ fun String.cleanSB(): String {
+ return StringUtils.stripControlCodes(this)
+ ?.toCharArray()
+ ?.filter { it.code in 21..126 }
+ ?.joinToString("")
+ ?: ""
+ }
+
+ fun String.withModPrefix(): String {
+ return "§9§lAmbient §7» §r${this}"
+ }
+
+ val GuiScreen.chest: ContainerChest?
+ get() = (this as? GuiChest)?.inventorySlots as? ContainerChest
+
+ val IInventory.items: List<ItemStack?>
+ get() = (0 until this.sizeInventory).map { this.getStackInSlot(it) }
+
+
+ private val ItemStack.extraAttributes: NBTTagCompound?
+ get() {
+ if (!this.hasTagCompound()) return null
+ return this.getSubCompound("ExtraAttributes", false) ?: return null
+ }
+
+ val ItemStack.skyblockID: String?
+ get() = this.extraAttributes?.let {
+ if (!it.hasKey("id", 8)) return null
+ return it.getString("id")
+ }
+
+ val ItemStack.enchants: Map<String, Int>?
+ get() = this.extraAttributes?.let { extraAttributes ->
+ if (!extraAttributes.hasKey("enchantments", 10)) return null
+ val enchantments = extraAttributes.getCompoundTag("enchantments")
+ enchantments.keySet.associateWith { enchantments.getInteger(it) }
+ }
+
+ val ItemStack.lore: List<String>?
+ get() {
+ if (!this.hasTagCompound()) return null
+ val displayTag = this.getSubCompound("display", false) ?: return null
+ if (!displayTag.hasKey("Lore", 9)) return null
+ val loreList = displayTag.getTagList("Lore", 8)
+ return (0 until loreList.tagCount()).map { loreList.getStringTagAt(it) }
+ }
+
+}
diff --git a/src/main/kotlin/com/ambientaddons/utils/LocationUtils.kt b/src/main/kotlin/com/ambientaddons/utils/LocationUtils.kt
new file mode 100644
index 0000000..d185a08
--- /dev/null
+++ b/src/main/kotlin/com/ambientaddons/utils/LocationUtils.kt
@@ -0,0 +1,87 @@
+package com.ambientaddons.utils
+
+import AmbientAddons.Companion.mc
+import com.ambientaddons.utils.DungeonFloor.Companion.toDungeonFloor
+import com.ambientaddons.utils.Extensions.cleanSB
+import com.ambientaddons.utils.Extensions.stripControlCodes
+import com.ambientaddons.utils.Extensions.substringBetween
+import com.ambientaddons.utils.TabListUtils.fetchTabEntries
+import net.minecraft.scoreboard.Score
+import net.minecraft.scoreboard.ScorePlayerTeam
+import net.minecraftforge.event.world.WorldEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent
+import net.minecraftforge.fml.common.network.FMLNetworkEvent
+
+object LocationUtils {
+ private var areaRegex = Regex("^(?:Area|Dungeon): ([\\w ].+)\$")
+ private var onHypixel = false
+ var inSkyblock = false
+ var location: String? = null
+ var dungeonFloor: DungeonFloor? = null
+ var ticks = 0
+
+ @SubscribeEvent
+ fun onWorldUnload(event: WorldEvent.Unload) {
+ inSkyblock = false
+ dungeonFloor = null
+ location = null
+ }
+
+ @SubscribeEvent
+ fun onConnect(event: FMLNetworkEvent.ClientConnectedToServerEvent) {
+ onHypixel = mc.runCatching {
+ !event.isLocal && ((thePlayer?.clientBrand?.lowercase()?.contains("hypixel")
+ ?: currentServerData?.serverIP?.lowercase()?.contains("hypixel")) == true)
+ }.getOrDefault(false)
+ }
+
+ @SubscribeEvent
+ fun onDisconnect(event: FMLNetworkEvent.ClientDisconnectionFromServerEvent) {
+ onHypixel = false
+ }
+
+ // from Skytils, under AGPL 3.0
+ fun fetchScoreboardLines(): List<String> {
+ val scoreboard = mc.theWorld?.scoreboard ?: return emptyList()
+ val objective = scoreboard.getObjectiveInDisplaySlot(1) ?: return emptyList()
+ val scores = scoreboard.getSortedScores(objective).filter { input: Score? ->
+ input != null && input.playerName != null && !input.playerName
+ .startsWith("#")
+ }.take(15)
+ return scores.map {
+ ScorePlayerTeam.formatPlayerName(scoreboard.getPlayersTeam(it.playerName), it.playerName).cleanSB()
+ }.asReversed()
+ }
+
+ // modified from Harry282/Skyblock-Client, under AGPL 3.0
+ @SubscribeEvent
+ fun onTick(event: TickEvent.ClientTickEvent) {
+ if (!onHypixel || event.phase != TickEvent.Phase.START) return
+ if (ticks % 10 == 0) {
+ val title = mc.theWorld?.scoreboard?.getObjectiveInDisplaySlot(1)?.displayName?.cleanSB()
+ if (!inSkyblock) {
+ inSkyblock = title?.contains("SKYBLOCK") == true
+ }
+ if (inSkyblock) {
+ if (location == null) {
+ val tab = fetchTabEntries()
+ location = tab.firstNotNullOfOrNull { areaRegex.find(it.text.stripControlCodes()) }?.let {
+ it.groupValues.getOrNull(1)
+ }
+ }
+ if (location == "Catacombs" && dungeonFloor == null) {
+ val dungeonLine = fetchScoreboardLines().find {
+ it.run { contains("The Catacombs (") && !contains("Queue") }
+ }
+ dungeonFloor = dungeonLine?.substringBetween("(", ")")?.toDungeonFloor()
+ }
+ }
+ }
+ ticks++
+ }
+
+ override fun toString(): String =
+ "onHypixel: $onHypixel, inSkyblock: $inSkyblock, location: $location, floor: $dungeonFloor"
+
+} \ No newline at end of file
diff --git a/src/main/kotlin/com/ambientaddons/utils/TabListUtils.kt b/src/main/kotlin/com/ambientaddons/utils/TabListUtils.kt
new file mode 100644
index 0000000..6fd7fef
--- /dev/null
+++ b/src/main/kotlin/com/ambientaddons/utils/TabListUtils.kt
@@ -0,0 +1,38 @@
+package com.ambientaddons.utils
+
+import AmbientAddons.Companion.mc
+import com.google.common.collect.ComparisonChain
+import com.google.common.collect.Ordering
+import net.minecraft.client.network.NetworkPlayerInfo
+import net.minecraft.world.WorldSettings
+
+// From SkytilsMod/Skytils, under AGPL 3.0
+val NetworkPlayerInfo.text: String
+ get() = mc.ingameGUI.tabList.getPlayerName(this)
+
+object TabListUtils {
+ private val playerInfoOrdering = object : Ordering<NetworkPlayerInfo>() {
+ override fun compare(p_compare_1_: NetworkPlayerInfo?, p_compare_2_: NetworkPlayerInfo?): Int {
+ val scorePlayerTeam = p_compare_1_?.playerTeam
+ val scorePlayerTeam1 = p_compare_2_?.playerTeam
+ if (p_compare_1_ != null) {
+ if (p_compare_2_ != null) {
+ return ComparisonChain.start().compareTrueFirst(
+ p_compare_1_.gameType != WorldSettings.GameType.SPECTATOR,
+ p_compare_2_.gameType != WorldSettings.GameType.SPECTATOR
+ ).compare(
+ if (scorePlayerTeam != null) scorePlayerTeam.registeredName else "",
+ if (scorePlayerTeam1 != null) scorePlayerTeam1.registeredName else ""
+ ).compare(p_compare_1_.gameProfile.name, p_compare_2_.gameProfile.name).result()
+ }
+ return 0
+ }
+ return -1
+ }
+ }
+
+ fun fetchTabEntries(): List<NetworkPlayerInfo> =
+ if (mc.thePlayer == null) emptyList() else playerInfoOrdering.sortedCopy(
+ mc.thePlayer.sendQueue.playerInfoMap
+ )
+} \ No newline at end of file