diff options
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt | 262 |
1 files changed, 156 insertions, 106 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt b/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt index 17b987c2b..675d98b97 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt @@ -1,125 +1,175 @@ package at.hannibal2.skyhanni.utils -import at.hannibal2.skyhanni.events.PacketEvent import at.hannibal2.skyhanni.events.TabListUpdateEvent -import at.hannibal2.skyhanni.utils.LorenzUtils.sorted -import net.minecraft.network.play.server.S38PacketPlayerListItem -import net.minecraftforge.event.world.WorldEvent +import com.google.common.collect.ComparisonChain +import com.google.common.collect.Ordering +import net.minecraft.client.Minecraft +import net.minecraft.client.network.NetworkPlayerInfo +import net.minecraft.world.WorldSettings import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import net.minecraftforge.fml.relauncher.Side +import net.minecraftforge.fml.relauncher.SideOnly import java.util.* class TabListData { - private val uuidMap = mutableMapOf<UUID, TabListPlayer>() - private val tabListMap = mutableMapOf<TabListPlayer, String>() - class TabListPlayer(var displayName: String, var internalName: String) + companion object { + private var cache = listOf<String>() - @SubscribeEvent - fun onWorldChange(event: WorldEvent.Load) { - uuidMap.clear() - tabListMap.clear() + // TODO replace with TabListUpdateEvent + fun getTabList() = cache } - @SubscribeEvent - fun onChatPacket(event: PacketEvent.ReceiveEvent) { - val packet = event.packet - if (packet is S38PacketPlayerListItem) { - val action = packet.action - if (action == S38PacketPlayerListItem.Action.UPDATE_LATENCY) return - - val entries = packet.entries - if (action == S38PacketPlayerListItem.Action.REMOVE_PLAYER) { -// println("REMOVE_PLAYER") -// println("old: " + uuidMap.size) - for (entry in entries) { - val profile = entry.profile - val id = profile.id - val key = uuidMap.remove(id) - tabListMap.remove(key) - } -// println("new: " + uuidMap.size) - update() - return - } - - val size = entries.size - if (size != 1) { - println("wrong size: $size") - return - } - val entry = entries[0] - val profile = entry.profile - val id = profile.id - val name = profile.name - if (name != null) { - if (!name.contains("-")) { - return - } - } - - val text = entry?.displayName?.formattedText ?: "" - val formattedName = LorenzUtils.stripVanillaMessage(text) - if (action == S38PacketPlayerListItem.Action.ADD_PLAYER) { -// println("ADD_PLAYER") - val tabList = TabListPlayer(formattedName, name) - - if (uuidMap.contains(id)) { - val key = uuidMap.remove(id) - val internalName = key!!.internalName - val displayName = key.displayName -// println("") -// println("internalName: $internalName") -// println("displayName: $displayName") - tabListMap.remove(key) - } - -// println("new name: $name") -// println("new formattedName: $formattedName") - - uuidMap[id] = tabList - tabListMap[tabList] = name - update() - return - } - - if (action == S38PacketPlayerListItem.Action.UPDATE_DISPLAY_NAME) { -// println("UPDATE_DISPLAY_NAME") - val listPlayer = uuidMap[id] - listPlayer?.let { - it.displayName = formattedName - update() - } -// println("old: '" + listPlayer.displayName + "'") -// println("new: '$formattedName'") - - return - } + + private val playerOrdering = Ordering.from(PlayerComparator()) + + @SideOnly(Side.CLIENT) + internal class PlayerComparator : Comparator<NetworkPlayerInfo> { + override fun compare(o1: NetworkPlayerInfo, o2: NetworkPlayerInfo): Int { + val team1 = o1.playerTeam + val team2 = o2.playerTeam + return ComparisonChain.start().compareTrueFirst( + o1.gameType != WorldSettings.GameType.SPECTATOR, + o2.gameType != WorldSettings.GameType.SPECTATOR + ) + .compare( + if (team1 != null) team1.registeredName else "", + if (team2 != null) team2.registeredName else "" + ) + .compare(o1.gameProfile.name, o2.gameProfile.name).result() } } - private fun update() { - val result = mutableListOf<String>() - if (uuidMap.size == 80) { - var i = 0 - for (tabList in tabListMap.sorted().keys) { - val contains = uuidMap.values.contains(tabList) - if (contains) { - val displayName = tabList.displayName - result.add(displayName) - i++ - } - } - } else if (uuidMap.isNotEmpty()) return - val list = result.toList() - cache = list - TabListUpdateEvent(list).postAndCatch() - + private fun readTabList(): List<String>? { + val thePlayer = Minecraft.getMinecraft()?.thePlayer ?: return null + val players = playerOrdering.sortedCopy(thePlayer.sendQueue.playerInfoMap) + val result: MutableList<String> = ArrayList() + for (info in players) { + val name = Minecraft.getMinecraft().ingameGUI.tabList.getPlayerName(info) + result.add(LorenzUtils.stripVanillaMessage(name)) + } + return result } - companion object { - private var cache = listOf<String>() + private var ticks = 0 - // TODO replace with TabListUpdateEvent - fun getTabList() = cache + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (event.phase != TickEvent.Phase.START) return + + if (ticks++ % 5 != 0) return + + val tabList = readTabList() ?: return + if (cache != tabList) { + cache = tabList + TabListUpdateEvent(cache).postAndCatch() + } } + + // private val uuidMap = mutableMapOf<UUID, TabListPlayer>() +// private val tabListMap = mutableMapOf<TabListPlayer, String>() + +// class TabListPlayer(var displayName: String, var internalName: String) + +// @SubscribeEvent +// fun onWorldChange(event: WorldEvent.Load) { +// uuidMap.clear() +// tabListMap.clear() +// } + +// @SubscribeEvent +// fun onChatPacket(event: PacketEvent.ReceiveEvent) { +// val packet = event.packet +// if (packet is S38PacketPlayerListItem) { +// val action = packet.action +// if (action == S38PacketPlayerListItem.Action.UPDATE_LATENCY) return +// +// val entries = packet.entries +// if (action == S38PacketPlayerListItem.Action.REMOVE_PLAYER) { +//// println("REMOVE_PLAYER") +//// println("old: " + uuidMap.size) +// for (entry in entries) { +// val profile = entry.profile +// val id = profile.id +// val key = uuidMap.remove(id) +// tabListMap.remove(key) +// } +//// println("new: " + uuidMap.size) +// update() +// return +// } +// +// val size = entries.size +// if (size != 1) { +// println("wrong size: $size") +// return +// } +// val entry = entries[0] +// val profile = entry.profile +// val id = profile.id +// val name = profile.name +// if (name != null) { +// if (!name.contains("-")) { +// return +// } +// } +// +// val text = entry?.displayName?.formattedText ?: "" +// val formattedName = LorenzUtils.stripVanillaMessage(text) +// if (action == S38PacketPlayerListItem.Action.ADD_PLAYER) { +//// println("ADD_PLAYER") +// val tabList = TabListPlayer(formattedName, name) +// +// if (uuidMap.contains(id)) { +// val key = uuidMap.remove(id) +// val internalName = key!!.internalName +// val displayName = key.displayName +//// println("") +//// println("internalName: $internalName") +//// println("displayName: $displayName") +// tabListMap.remove(key) +// } +// +//// println("new name: $name") +//// println("new formattedName: $formattedName") +// +// uuidMap[id] = tabList +// tabListMap[tabList] = name +// update() +// return +// } +// +// if (action == S38PacketPlayerListItem.Action.UPDATE_DISPLAY_NAME) { +//// println("UPDATE_DISPLAY_NAME") +// val listPlayer = uuidMap[id] +// listPlayer?.let { +// it.displayName = formattedName +// update() +// } +//// println("old: '" + listPlayer.displayName + "'") +//// println("new: '$formattedName'") +// +// return +// } +// } +// } + +// private fun update() { +// val result = mutableListOf<String>() +// if (uuidMap.size == 80) { +// var i = 0 +// for (tabList in tabListMap.sorted().keys) { +// val contains = uuidMap.values.contains(tabList) +// if (contains) { +// val displayName = tabList.displayName +// result.add(displayName) +// i++ +// } +// } +// } else if (uuidMap.isNotEmpty()) return +// val list = result.toList() +// cache = list +// TabListUpdateEvent(list).postAndCatch() +// } }
\ No newline at end of file |