aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java79
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt187
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListReader.kt192
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListRenderer.kt4
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,