diff options
Diffstat (limited to 'src/main/java/de/cowtipper/cowlection/handler')
| -rw-r--r-- | src/main/java/de/cowtipper/cowlection/handler/DungeonCache.java | 106 |
1 files changed, 79 insertions, 27 deletions
diff --git a/src/main/java/de/cowtipper/cowlection/handler/DungeonCache.java b/src/main/java/de/cowtipper/cowlection/handler/DungeonCache.java index d7fd5da..e06ba7d 100644 --- a/src/main/java/de/cowtipper/cowlection/handler/DungeonCache.java +++ b/src/main/java/de/cowtipper/cowlection/handler/DungeonCache.java @@ -1,23 +1,31 @@ package de.cowtipper.cowlection.handler; +import com.google.common.collect.ComparisonChain; +import com.google.common.collect.Ordering; import de.cowtipper.cowlection.Cowlection; import de.cowtipper.cowlection.util.TickDelay; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiPlayerTabOverlay; +import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.scoreboard.Score; import net.minecraft.scoreboard.ScoreObjective; import net.minecraft.scoreboard.ScorePlayerTeam; import net.minecraft.scoreboard.Scoreboard; import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.WorldSettings; import java.util.*; import java.util.stream.Collectors; public class DungeonCache { + private static final Ordering<NetworkPlayerInfo> playerOrderer = Ordering.from(new PlayerComparator()); + private final Cowlection main; private final Map<String, Integer> deathCounter; private final Set<String> deadPlayers; private final Set<String> failedPuzzles; private final Set<UUID> destroyedCrypts; + private int cryptsOffset; private boolean isInDungeon; private int elapsedMinutes; @@ -32,6 +40,7 @@ public class DungeonCache { deadPlayers = new HashSet<>(); failedPuzzles = new HashSet<>(); destroyedCrypts = new HashSet<>(); + cryptsOffset = 0; } public boolean isInDungeon() { @@ -87,36 +96,63 @@ public class DungeonCache { nextPerformanceSend = System.currentTimeMillis() + 260; } - public void updateElapsedMinutesFromScoreboard() { + /** + * Fetch info from scoreboard (right) and tab list + */ + public void fetchScoreboardData() { long now = System.currentTimeMillis(); if (now - lastScoreboardCheck > 10000) { // run every 10 seconds lastScoreboardCheck = now; - Scoreboard scoreboard = Minecraft.getMinecraft().theWorld.getScoreboard(); - ScoreObjective scoreboardSidebar = scoreboard.getObjectiveInDisplaySlot(1); - if (scoreboardSidebar != null) { - Collection<Score> scoreboardLines = scoreboard.getSortedScores(scoreboardSidebar); - for (Score line : scoreboardLines) { - ScorePlayerTeam scorePlayerTeam = scoreboard.getPlayersTeam(line.getPlayerName()); - if (scorePlayerTeam != null) { - String lineWithoutFormatting = EnumChatFormatting.getTextWithoutFormattingCodes(scorePlayerTeam.getColorPrefix() + scorePlayerTeam.getColorSuffix()); - - String timeElapsed = "Time Elapsed: "; - if (lineWithoutFormatting.startsWith(timeElapsed)) { - // dungeon timer: 05m 22s - String timeString = lineWithoutFormatting.substring(timeElapsed.length()); - try { - int indexOfMinute = timeString.indexOf('m'); - if (indexOfMinute > -1) { - elapsedMinutes = (Integer.parseInt(timeString.substring(0, indexOfMinute))); + Minecraft mc = Minecraft.getMinecraft(); + if (mc.theWorld != null) { + Scoreboard scoreboard = mc.theWorld.getScoreboard(); + + // check scoreboard (right) + ScoreObjective scoreboardSidebar = scoreboard.getObjectiveInDisplaySlot(1); + if (scoreboardSidebar != null) { + Collection<Score> scoreboardLines = scoreboard.getSortedScores(scoreboardSidebar); + for (Score line : scoreboardLines) { + ScorePlayerTeam scorePlayerTeam = scoreboard.getPlayersTeam(line.getPlayerName()); + if (scorePlayerTeam != null) { + String lineWithoutFormatting = EnumChatFormatting.getTextWithoutFormattingCodes(scorePlayerTeam.getColorPrefix() + scorePlayerTeam.getColorSuffix()); + + String timeElapsed = "Time Elapsed: "; + if (lineWithoutFormatting.startsWith(timeElapsed)) { + // dungeon timer: 05m 22s + String timeString = lineWithoutFormatting.substring(timeElapsed.length()); + try { + int indexOfMinute = timeString.indexOf('m'); + if (indexOfMinute > -1) { + elapsedMinutes = (Integer.parseInt(timeString.substring(0, indexOfMinute))); + } + } catch (NumberFormatException ex) { + // couldn't parse dungeon time from scoreboard + ex.printStackTrace(); } - } catch (NumberFormatException ex) { - // couldn't parse dungeon time from scoreboard - ex.printStackTrace(); } } } } } + + // check tab list + Collection<NetworkPlayerInfo> playerInfoMap = mc.thePlayer.sendQueue.getPlayerInfoMap(); + List<NetworkPlayerInfo> networkPlayerInfos = playerOrderer.sortedCopy(playerInfoMap); + GuiPlayerTabOverlay tabList = mc.ingameGUI.getTabList(); + for (NetworkPlayerInfo playerInfo : networkPlayerInfos) { + if (playerInfo.getGameProfile().getName().startsWith("!")) { + String tabListEntry = EnumChatFormatting.getTextWithoutFormattingCodes(tabList.getPlayerName(playerInfo)); + if (tabListEntry != null && tabListEntry.startsWith(" Crypts: ")) { + try { + int cryptsFromTabList = Integer.parseInt(tabListEntry.substring(" Crypts: ".length()).trim()); + cryptsOffset = cryptsFromTabList - destroyedCrypts.size(); + } catch (NumberFormatException | IndexOutOfBoundsException ex) { + // couldn't parse crypts count from tab list + ex.printStackTrace(); + } + } + } + } } } @@ -125,9 +161,10 @@ public class DungeonCache { this.queuedFloor = floorNr; } - public void addDeath(String playerName, boolean ghostByDisconnecting) { - if (!deadPlayers.add(playerName) && ghostByDisconnecting) { - // dead player disconnected from the game; don't count again! + public void addDeath(String playerName) { + boolean playerWasDeadAlready = !deadPlayers.add(playerName); + if (playerWasDeadAlready) { + // dead player "died" again (e.g. caused by disconnecting while being dead); don't count again! return; } int previousPlayerDeaths = deathCounter.getOrDefault(playerName, 0); @@ -148,8 +185,8 @@ public class DungeonCache { this.classMilestone = classMilestone; } - public boolean addDestroyedCrypt(UUID uuid) { - return destroyedCrypts.add(uuid); + public void addDestroyedCrypt(UUID uuid) { + destroyedCrypts.add(uuid); } // getter @@ -182,7 +219,7 @@ public class DungeonCache { } public int getDestroyedCrypts() { - return destroyedCrypts.size(); + return destroyedCrypts.size() + cryptsOffset; } public int getElapsedMinutes() { @@ -195,9 +232,24 @@ public class DungeonCache { deadPlayers.clear(); failedPuzzles.clear(); destroyedCrypts.clear(); + cryptsOffset = 0; elapsedMinutes = 0; classMilestone = 0; nextPerformanceSend = 0; queuedFloor = null; } + + /** + * see: GuiPlayerTabOverlay.PlayerComparator + */ + static class PlayerComparator implements Comparator<NetworkPlayerInfo> { + private PlayerComparator() { + } + + public int compare(NetworkPlayerInfo playerInfo1, NetworkPlayerInfo playerInfo2) { + ScorePlayerTeam scorePlayerTeam1 = playerInfo1.getPlayerTeam(); + ScorePlayerTeam scorePlayerTeam2 = playerInfo2.getPlayerTeam(); + return ComparisonChain.start().compareTrueFirst(playerInfo1.getGameType() != WorldSettings.GameType.SPECTATOR, playerInfo2.getGameType() != WorldSettings.GameType.SPECTATOR).compare(scorePlayerTeam1 != null ? scorePlayerTeam1.getRegisteredName() : "", scorePlayerTeam2 != null ? scorePlayerTeam2.getRegisteredName() : "").compare(playerInfo1.getGameProfile().getName(), playerInfo2.getGameProfile().getName()).result(); + } + } } |
