diff options
Diffstat (limited to 'src')
4 files changed, 240 insertions, 222 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java index 343762d32..e1cbbf830 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java @@ -538,12 +538,13 @@ public class MiscConfig { @Expose @ConfigOption(name = "Compact Tab List", desc = "") @Accordion - public CompactTabList compactTabList = new CompactTabList(); + public CompactTabListConfig compactTabList = new CompactTabListConfig(); - public static class CompactTabList { + public static class CompactTabListConfig { @Expose @ConfigOption(name = "Enabled", desc = "Compacts the tablist to make it look much nicer like SBA did. Also " + - "doesn't break god-pot detection and shortens some other lines.") //made tablist one word here so both searches will pick it up + "doesn't break god-pot detection and shortens some other lines.") + //made tablist one word here so both searches will pick it up @ConfigEditorBoolean @FeatureToggle public boolean enabled = false; @@ -554,46 +555,54 @@ public class MiscConfig { public boolean hideAdverts = false; @Expose - @ConfigOption(name = "Player Sort", desc = "Change the sort order of player names in the tab list.") - @ConfigEditorDropdown(values = {"Rank (Default)", "SB Level", "Name (Abc)", "Ironman/Bingo", "Party/Friends/Guild", "Random"}) - @ConfigAccordionId(id = 1) - public int playerSortOrder = 0; + @ConfigOption(name = "Advanced Player List", desc = "") + @Accordion + public AdvancedPlayerList advancedPlayerList = new AdvancedPlayerList(); - @Expose - @ConfigOption(name = "Invert Sort", desc = "Flip the player list order on its head (also works with default rank).") - @ConfigEditorBoolean - public boolean reverseSort = false; + public static class AdvancedPlayerList { - @Expose - @ConfigOption(name = "Hide Player Icons", desc = "Hide the icons of player in the tab list.") - @ConfigEditorBoolean - public boolean hidePlayerIcons = false; + @Expose + @ConfigOption(name = "Player Sort", desc = "Change the sort order of player names in the tab list.") + @ConfigEditorDropdown(values = {"Rank (Default)", "SB Level", "Name (Abc)", "Ironman/Bingo", "Party/Friends/Guild", "Random"}) + @ConfigAccordionId(id = 1) + public int playerSortOrder = 0; - @Expose - @ConfigOption(name = "Hide Rank Color", desc = "Hide the player rank color.") - @ConfigEditorBoolean - public boolean hideRankColor = false; + @Expose + @ConfigOption(name = "Invert Sort", desc = "Flip the player list order on its head (also works with default rank).") + @ConfigEditorBoolean + public boolean reverseSort = false; - @Expose - @ConfigOption(name = "Hide Emblems", desc = "Hide the emblems behind the player name.") - @ConfigEditorBoolean - public boolean hideEmblem = false; + @Expose + @ConfigOption(name = "Hide Player Icons", desc = "Hide the icons of player in the tab list.") + @ConfigEditorBoolean + public boolean hidePlayerIcons = false; - @Expose - @ConfigOption(name = "Hide Level", desc = "Hide the SkyBlock level numbers.") - @ConfigEditorBoolean - public boolean hideLevel = false; + @Expose + @ConfigOption(name = "Hide Rank Color", desc = "Hide the player rank color.") + @ConfigEditorBoolean + public boolean hideRankColor = false; - @Expose - @ConfigOption(name = "Hide Level Brackets", desc = "Hide the emblems behind the player name.") - @ConfigEditorBoolean - public boolean hideLevelBrackets = false; + @Expose + @ConfigOption(name = "Hide Emblems", desc = "Hide the emblems behind the player name.") + @ConfigEditorBoolean + public boolean hideEmblem = false; - @Expose - @ConfigOption(name = "Level Color As Name", desc = "Use the color of the skyblock level as the player color.") - @ConfigEditorBoolean - public boolean useLevelColorForName = false; + @Expose + @ConfigOption(name = "Hide Level", desc = "Hide the SkyBlock level numbers.") + @ConfigEditorBoolean + public boolean hideLevel = false; + + @Expose + @ConfigOption(name = "Hide Level Brackets", desc = "Hide the gray brackets in front of and behind the level numbers.") + @ConfigEditorBoolean + public boolean hideLevelBrackets = false; + @Expose + @ConfigOption(name = "Level Color As Name", desc = "Use the color of the SkyBlock level for the player color.") + @ConfigEditorBoolean + public boolean useLevelColorForName = false; + + } } @Expose diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt new file mode 100644 index 000000000..1c3e41cb0 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt @@ -0,0 +1,187 @@ +package at.hannibal2.skyhanni.features.misc.compacttablist + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.FriendAPI +import at.hannibal2.skyhanni.data.PartyAPI +import at.hannibal2.skyhanni.features.misc.MarkedPlayerManager +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import com.google.common.cache.CacheBuilder +import java.util.concurrent.TimeUnit +import kotlin.random.Random + +object AdvancedPlayerList { + private val config get() = SkyHanniMod.feature.misc.compactTabList.advancedPlayerList + + private var playerDatas = mutableMapOf<String, PlayerData>() + + fun createTabLine(text: String, type: TabStringType) = playerDatas[text]?.let { + TabLine(text, type, createCustomName(it)) + } ?: TabLine(text, type) + + fun newSorting(original: List<String>): List<String> { + if (LorenzUtils.inKuudraFight) return original + if (LorenzUtils.inDungeons) return original + + if (ignoreCustomTabList()) return original + + val pattern = ".*\\[(?<level>.*)] (?<name>.*)".toPattern() + val newList = mutableListOf<String>() + val currentData = mutableMapOf<String, PlayerData>() + newList.add(original.first()) + + var extraTitles = 0 + var i = 0 + + for (line in original) { + i++ + if (i == 1) continue + if (line.isEmpty() || line.contains("Server Info")) break + if (line.contains("§r§a§lPlayers")) { + extraTitles++ + continue + } + pattern.matchMatcher(line) { + val levelText = group("level") + val removeColor = levelText.removeColor() + try { + val playerData = PlayerData(removeColor.toInt()) + currentData[line] = playerData + + val fullName = group("name") + val name = fullName.split(" ") + val coloredName = name[0] + playerData.coloredName = coloredName + playerData.name = coloredName.removeColor() + playerData.levelText = levelText + if (name.size > 1) { + val nameSuffix = name.drop(1).joinToString(" ") + playerData.nameSuffix = nameSuffix + if (nameSuffix.contains("♲")) { + playerData.ironman = true + } else { + playerData.bingoLevel = getBingoRank(line) + } + } else { + playerData.nameSuffix = "" + } + + } catch (e: NumberFormatException) { + val message = "Special user (youtube or admin?): '$line'" + LorenzUtils.debug(message) + println(message) + } + } + } + playerDatas = currentData + val prepare = currentData.entries + + val sorted = when (config.playerSortOrder) { + + // Rank (Default) + 1 -> prepare.sortedBy { -(it.value.sbLevel) } + + // Name (Abc) + 2 -> prepare.sortedBy { it.value.name.lowercase().replace("_", "") } + + // Ironman/Bingo + 3 -> prepare.sortedBy { -if (it.value.ironman) 10 else it.value.bingoLevel } + + // Party/Friends/Guild First + 4 -> prepare.sortedBy { -socialScore(it.value.name) } + + // Random + 5 -> prepare.sortedBy { getRandomOrder(it.value.name) } + + else -> prepare + } + + var newPlayerList = sorted.map { it.key }.toMutableList() + if (config.reverseSort) { + newPlayerList = newPlayerList.reversed().toMutableList() + } + if (extraTitles > 0) { + newPlayerList.add(19, original.first()) + } + newList.addAll(newPlayerList) + + val rest = original.drop(playerDatas.size + extraTitles + 1) + newList.addAll(rest) + return newList + } + + fun ignoreCustomTabList(): Boolean { + return LorenzUtils.isControlKeyDown() + } + + private fun createCustomName(data: PlayerData): String { + val playerName = if (config.useLevelColorForName) { + val c = data.levelText[3] + "§$c" + data.name + } else if (config.hideRankColor) "§b" + data.name else data.coloredName + + val level = if (!config.hideLevel) { + if (config.hideLevelBrackets) data.levelText else "§8[${data.levelText}§8]" + } else "" + + val suffix = if (config.hideEmblem) { + if (data.ironman) "§7♲" else getBingoIcon(data.bingoLevel) + } else data.nameSuffix + + return "$level $playerName $suffix" + } + + private var randomOrderCache = + CacheBuilder.newBuilder().expireAfterWrite(20, TimeUnit.MINUTES).build<String, Int>() + + private fun getRandomOrder(name: String): Int { + val saved = randomOrderCache.getIfPresent(name) + if (saved != null) { + return saved + } + val r = (Random.nextDouble() * 500).toInt() + randomOrderCache.put(name, r) + return r + } + + private fun socialScore(name: String) = when { + LorenzUtils.getPlayerName() == name -> 5 + MarkedPlayerManager.isMarkedPlayer(name) -> 4 + PartyAPI.partyMembers.contains(name) -> 3 + FriendAPI.getAllFriends().any { it.name == name } -> 2 + // TODO add guild + + else -> 1 + } + + private fun getBingoRank(text: String) = when { + text.contains("§7Ⓑ") -> 0 //No Rank + text.contains("§aⒷ") -> 1 //Rank 1 + text.contains("§9Ⓑ") -> 2 //Rank 2 + text.contains("§5Ⓑ") -> 3 //Rank 3 + text.contains("§6Ⓑ") -> 4 //Rank 4 + + else -> -1 + } + + private fun getBingoIcon(rank: Int) = when (rank) { + -1 -> "" // Not in Bingo + + 0 -> "§7Ⓑ" //No Rank + 1 -> "§aⒷ" //Rank 1 + 2 -> "§9Ⓑ" //Rank 2 + 3 -> "§5Ⓑ" //Rank 3 + 4 -> "§6Ⓑ" //Rank 4 + else -> "Bingo?" + } + + class PlayerData(val sbLevel: Int) { + var name: String = "?" + var coloredName: String = "?" + var nameSuffix: String = "?" + var levelText: String = "?" + var ironman: Boolean = false + var bingoLevel: Int = -1 + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListReader.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListReader.kt index 2144c672e..9a328fc89 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListReader.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListReader.kt @@ -1,22 +1,14 @@ package at.hannibal2.skyhanni.features.misc.compacttablist import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.data.FriendAPI -import at.hannibal2.skyhanni.data.PartyAPI import at.hannibal2.skyhanni.events.LorenzTickEvent -import at.hannibal2.skyhanni.features.misc.MarkedPlayerManager import at.hannibal2.skyhanni.mixins.transformers.AccessorGuiPlayerTabOverlay import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.StringUtils.removeResets import at.hannibal2.skyhanni.utils.StringUtils.trimWhiteSpaceAndResets import at.hannibal2.skyhanni.utils.TabListData -import com.google.common.cache.CacheBuilder import net.minecraft.client.Minecraft import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import java.util.concurrent.TimeUnit -import kotlin.random.Random // heavily inspired by SBA code object TabListReader { @@ -29,7 +21,6 @@ object TabListReader { private val dungeonBuffPattern = "Dungeon Buffs(?:§.)*(?:\\n(§.)*§7.+)*".toPattern() private val upgradesPattern = "(?<firstPart>§e[A-Za-z ]+)(?<secondPart> §f[\\w ]+)".toPattern() private val tabListSPattern = "(?i)§S".toPattern() - private var playerDatas = mutableMapOf<String, PlayerData>() val renderColumns = mutableListOf<RenderColumn>() @@ -62,7 +53,7 @@ object TabListReader { private fun parseColumns(original: List<String>): MutableList<TabColumn> { val columns = mutableListOf<TabColumn>() - val fullTabList = newSorting(original) + val fullTabList = AdvancedPlayerList.newSorting(original) for (entry in fullTabList.indices step 20) { val title = fullTabList[entry].trimWhiteSpaceAndResets() @@ -80,171 +71,6 @@ object TabListReader { return columns } - private fun newSorting(original: List<String>): List<String> { - if (LorenzUtils.inKuudraFight) return original - if (LorenzUtils.inDungeons) return original - - if (ignoreCustomTabList()) return original - - val pattern = ".*\\[(?<level>.*)] (?<name>.*)".toPattern() - val newList = mutableListOf<String>() - val currentData = mutableMapOf<String, PlayerData>() - newList.add(original.first()) - - var extraTitles = 0 - var i = 0 - - for (line in original) { - i++ - if (i == 1) continue - if (line.isEmpty() || line.contains("Server Info")) break - if (line.contains("§r§a§lPlayers")) { - extraTitles++ - continue - } - pattern.matchMatcher(line) { - val levelText = group("level") - val removeColor = levelText.removeColor() - try { - val playerData = PlayerData(removeColor.toInt()) - currentData[line] = playerData - - val fullName = group("name") - val name = fullName.split(" ") - val coloredName = name[0] - playerData.coloredName = coloredName - playerData.name = coloredName.removeColor() - playerData.levelText = levelText - if (name.size > 1) { - val nameSuffix = name.drop(1).joinToString(" ") - playerData.nameSuffix = nameSuffix - if (nameSuffix.contains("♲")) { - playerData.ironman = true - } else { - playerData.bingoLevel = getBingoRank(line) - } - } else { - playerData.nameSuffix = "" - } - - } catch (e: NumberFormatException) { - val message = "Special user (youtube or admin?): '$line'" - LorenzUtils.debug(message) - println(message) - } - } - } - playerDatas = currentData - val prepare = currentData.entries - - val sorted = when (config.playerSortOrder) { - - // Rank (Default) - 1 -> prepare.sortedBy { -(it.value.sbLevel) } - - // Name (Abc) - 2 -> prepare.sortedBy { it.value.name.lowercase().replace("_", "") } - - // Ironman/Bingo - 3 -> prepare.sortedBy { -if (it.value.ironman) 10 else it.value.bingoLevel } - - // Party/Friends/Guild First - 4 -> prepare.sortedBy { -socialScore(it.value.name) } - - // Random - 5 -> prepare.sortedBy { getRandomOrder(it.value.name) } - - else -> prepare - } - - var newPlayerList = sorted.map { it.key }.toMutableList() - if (config.reverseSort) { - newPlayerList = newPlayerList.reversed().toMutableList() - } - if (extraTitles > 0) { - newPlayerList.add(19, original.first()) - } - newList.addAll(newPlayerList) - - val rest = original.drop(playerDatas.size + extraTitles + 1) - newList.addAll(rest) - return newList - } - - fun ignoreCustomTabList(): Boolean { - return LorenzUtils.isControlKeyDown() - } - - private fun createCustomName(data: PlayerData): String { - val playerName = if (config.useLevelColorForName) { - val c = data.levelText[3] - "§$c" + data.name - } else if (config.hideRankColor) "§b" + data.name else data.coloredName - - val level = if (!config.hideLevel) { - if (config.hideLevelBrackets) data.levelText else "§8[${data.levelText}§8]" - } else "" - - val suffix = if (config.hideEmblem) { - if (data.ironman) "§7♲" else getBingoIcon(data.bingoLevel) - } else data.nameSuffix - - return "$level $playerName $suffix" - } - - private var randomOrderCache = - CacheBuilder.newBuilder().expireAfterWrite(20, TimeUnit.MINUTES).build<String, Int>() - - private fun getRandomOrder(name: String): Int { - val saved = randomOrderCache.getIfPresent(name) - if (saved != null) { - return saved - } - val r = (Random.nextDouble() * 500).toInt() - randomOrderCache.put(name, r) - return r - } - - private fun socialScore(name: String) = when { - LorenzUtils.getPlayerName() == name -> 5 - MarkedPlayerManager.isMarkedPlayer(name) -> 4 - PartyAPI.partyMembers.contains(name) -> 3 - FriendAPI.getAllFriends().any { it.name == name } -> 2 - // TODO add guild - - else -> 1 - } - - private fun getBingoRank(text: String) = when { - text.contains("§7Ⓑ") -> 0 //No Rank - text.contains("§aⒷ") -> 1 //Rank 1 - text.contains("§9Ⓑ") -> 2 //Rank 2 - text.contains("§5Ⓑ") -> 3 //Rank 3 - text.contains("§6Ⓑ") -> 4 //Rank 4 - - else -> -1 - } - - private fun getBingoIcon(rank: Int) = when (rank) { - -1 -> "" // Not in Bingo - - 0 -> "§7Ⓑ" //No Rank - 1 -> "§aⒷ" //Rank 1 - 2 -> "§9Ⓑ" //Rank 2 - 3 -> "§5Ⓑ" //Rank 3 - 4 -> "§6Ⓑ" //Rank 4 - else -> "Bingo?" - } - - class PlayerData(val sbLevel: Int) { - var name: String = "?" - var coloredName: String = "?" - var nameSuffix: String = "?" - var levelText: String = "?" - var ironman: Boolean = false - var bingoLevel: Int = -1 - } - private fun parseFooterAsColumn(): TabColumn? { val tabList = Minecraft.getMinecraft().ingameGUI.tabList as AccessorGuiPlayerTabOverlay @@ -354,13 +180,13 @@ object TabListReader { currentCount = 1 } else { if (firstColumnCopy.size() > 0) { - firstColumnCopy.addLine(createTabLine("", TabStringType.TEXT)) + firstColumnCopy.addLine(AdvancedPlayerList.createTabLine("", TabStringType.TEXT)) } } if (needsTitle) { lastTitle = section.columnValue.columnTitle - firstColumnCopy.addLine(createTabLine(lastTitle, TabStringType.TITLE)) + firstColumnCopy.addLine(AdvancedPlayerList.createTabLine(lastTitle, TabStringType.TITLE)) currentCount++ } @@ -370,7 +196,7 @@ object TabListReader { currentCount = 1 } - firstColumnCopy.addLine(createTabLine(line, TabStringType.fromLine(line))) + firstColumnCopy.addLine(AdvancedPlayerList.createTabLine(line, TabStringType.fromLine(line))) currentCount++ } } else { @@ -378,24 +204,20 @@ object TabListReader { renderColumns.add(RenderColumn().also { firstColumnCopy = it }) } else { if (firstColumnCopy.size() > 0) { - firstColumnCopy.addLine(createTabLine("", TabStringType.TEXT)) + firstColumnCopy.addLine(AdvancedPlayerList.createTabLine("", TabStringType.TEXT)) } } if (needsTitle) { lastTitle = section.columnValue.columnTitle - firstColumnCopy.addLine(createTabLine(lastTitle, TabStringType.TITLE)) + firstColumnCopy.addLine(AdvancedPlayerList.createTabLine(lastTitle, TabStringType.TITLE)) } for (line in section.lines) { - firstColumnCopy.addLine(createTabLine(line, TabStringType.fromLine(line))) + firstColumnCopy.addLine(AdvancedPlayerList.createTabLine(line, TabStringType.fromLine(line))) } } } } } - - private fun createTabLine(text: String, type: TabStringType) = playerDatas[text]?.let { - TabLine(text, type, createCustomName(it)) - } ?: TabLine(text, type) }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListRenderer.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListRenderer.kt index 8d3c1fab7..aeda16050 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListRenderer.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListRenderer.kt @@ -105,7 +105,7 @@ object TabListRenderer { for (tabLine in column.lines) { val savedX = middleX - if (tabLine.type == TabStringType.PLAYER && !config.hidePlayerIcons) { + if (tabLine.type == TabStringType.PLAYER && !config.advancedPlayerList.hidePlayerIcons) { val playerInfo = tabLine.getInfo() if (playerInfo != null) { minecraft.textureManager.bindTexture(playerInfo.locationSkin) @@ -120,7 +120,7 @@ object TabListRenderer { middleX += 8 + 2 } - val text = if (TabListReader.ignoreCustomTabList()) tabLine.text else tabLine.customName + val text = if (AdvancedPlayerList.ignoreCustomTabList()) tabLine.text else tabLine.customName if (tabLine.type == TabStringType.TITLE) { minecraft.fontRendererObj.drawStringWithShadow( text, |