diff options
Diffstat (limited to 'src/main/java/eu/olli/cowmoonication')
33 files changed, 0 insertions, 4817 deletions
diff --git a/src/main/java/eu/olli/cowmoonication/Cowmoonication.java b/src/main/java/eu/olli/cowmoonication/Cowmoonication.java deleted file mode 100644 index ebadcde..0000000 --- a/src/main/java/eu/olli/cowmoonication/Cowmoonication.java +++ /dev/null @@ -1,116 +0,0 @@ -package eu.olli.cowmoonication; - -import eu.olli.cowmoonication.command.MooCommand; -import eu.olli.cowmoonication.command.ShrugCommand; -import eu.olli.cowmoonication.command.TabCompletableCommand; -import eu.olli.cowmoonication.config.MooConfig; -import eu.olli.cowmoonication.handler.FriendsHandler; -import eu.olli.cowmoonication.handler.PlayerCache; -import eu.olli.cowmoonication.listener.ChatListener; -import eu.olli.cowmoonication.listener.PlayerListener; -import eu.olli.cowmoonication.util.ChatHelper; -import eu.olli.cowmoonication.util.VersionChecker; -import net.minecraftforge.client.ClientCommandHandler; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.config.Configuration; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.Mod.EventHandler; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import org.apache.logging.log4j.Logger; - -import java.io.File; - -@Mod(modid = Cowmoonication.MODID, name = Cowmoonication.MODNAME, version = Cowmoonication.VERSION, - clientSideOnly = true, - guiFactory = "@PACKAGE@.config.MooGuiFactory", - updateJSON = "https://raw.githubusercontent.com/cow-mc/Cowmoonication/master/update.json") -public class Cowmoonication { - public static final String MODID = "@MODID@"; - public static final String VERSION = "@VERSION@"; - public static final String MODNAME = "@MODNAME@"; - public static final String GITURL = "@GITURL@"; - private static Cowmoonication instance; - private File configDir; - private File modsDir; - private MooConfig config; - private FriendsHandler friendsHandler; - private VersionChecker versionChecker; - private ChatHelper chatHelper; - private PlayerCache playerCache; - private Logger logger; - - @Mod.EventHandler - public void preInit(FMLPreInitializationEvent e) { - instance = this; - logger = e.getModLog(); - modsDir = e.getSourceFile().getParentFile(); - - this.configDir = new File(e.getModConfigurationDirectory(), MODID + File.separatorChar); - if (!configDir.exists()) { - configDir.mkdirs(); - } - - friendsHandler = new FriendsHandler(this, new File(configDir, "friends.json")); - config = new MooConfig(this, new Configuration(new File(configDir, MODID + ".cfg"))); - - chatHelper = new ChatHelper(); - } - - @EventHandler - public void init(FMLInitializationEvent e) { - MinecraftForge.EVENT_BUS.register(new ChatListener(this)); - MinecraftForge.EVENT_BUS.register(new PlayerListener(this)); - ClientCommandHandler.instance.registerCommand(new MooCommand(this)); - ClientCommandHandler.instance.registerCommand(new ShrugCommand(this)); - for (String tabCompletableNamesCommand : MooConfig.tabCompletableNamesCommands) { - ClientCommandHandler.instance.registerCommand(new TabCompletableCommand(this, tabCompletableNamesCommand)); - } - } - - @EventHandler - public void postInit(FMLPostInitializationEvent e) { - versionChecker = new VersionChecker(this); - playerCache = new PlayerCache(this); - } - - public MooConfig getConfig() { - return config; - } - - public FriendsHandler getFriendsHandler() { - return friendsHandler; - } - - public VersionChecker getVersionChecker() { - return versionChecker; - } - - public ChatHelper getChatHelper() { - return chatHelper; - } - - public PlayerCache getPlayerCache() { - return playerCache; - } - - public File getConfigDirectory() { - return configDir; - } - - public File getModsDirectory() { - return modsDir; - } - - public Logger getLogger() { - return logger; - } - - /** - * Get mod's instance; instead of this method use dependency injection where possible - */ - public static Cowmoonication getInstance() { - return instance; - } -} diff --git a/src/main/java/eu/olli/cowmoonication/command/MooCommand.java b/src/main/java/eu/olli/cowmoonication/command/MooCommand.java deleted file mode 100644 index 9a73cbe..0000000 --- a/src/main/java/eu/olli/cowmoonication/command/MooCommand.java +++ /dev/null @@ -1,517 +0,0 @@ -package eu.olli.cowmoonication.command; - -import com.mojang.realmsclient.util.Pair; -import eu.olli.cowmoonication.Cowmoonication; -import eu.olli.cowmoonication.command.exception.ApiContactException; -import eu.olli.cowmoonication.command.exception.InvalidPlayerNameException; -import eu.olli.cowmoonication.command.exception.MooCommandException; -import eu.olli.cowmoonication.config.MooConfig; -import eu.olli.cowmoonication.config.MooGuiConfig; -import eu.olli.cowmoonication.data.DataHelper; -import eu.olli.cowmoonication.data.Friend; -import eu.olli.cowmoonication.data.HySkyBlockStats; -import eu.olli.cowmoonication.data.HyStalkingData; -import eu.olli.cowmoonication.search.GuiSearch; -import eu.olli.cowmoonication.util.*; -import net.minecraft.client.Minecraft; -import net.minecraft.command.*; -import net.minecraft.entity.Entity; -import net.minecraft.entity.item.EntityArmorStand; -import net.minecraft.event.ClickEvent; -import net.minecraft.event.HoverEvent; -import net.minecraft.item.ItemSkull; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; -import net.minecraftforge.common.util.Constants; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang3.StringUtils; - -import java.awt.*; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -public class MooCommand extends CommandBase { - private final Cowmoonication main; - - public MooCommand(Cowmoonication main) { - this.main = main; - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if (args.length == 0) { - sendCommandUsage(sender); - return; - } - // sub commands: friends & other players - if (args[0].equalsIgnoreCase("stalk")) { - if (args.length != 2) { - throw new WrongUsageException("/" + getCommandName() + " stalk <playerName>"); - } else if (!Utils.isValidMcName(args[1])) { - throw new InvalidPlayerNameException(args[1]); - } else { - handleStalking(args[1]); - } - } else if (args[0].equalsIgnoreCase("stalksb") || args[0].equalsIgnoreCase("stalkskyblock") || args[0].equalsIgnoreCase("skyblockstalk")) { - if (args.length != 2) { - throw new WrongUsageException("/" + getCommandName() + " stalkskyblock <playerName>"); - } else if (!Utils.isValidMcName(args[1])) { - throw new InvalidPlayerNameException(args[1]); - } else { - handleStalkingSkyBlock(args[1]); - } - } else if (args[0].equalsIgnoreCase("analyzeIsland")) { - Map<String, String> minions = DataHelper.getMinions(); - - Map<String, Integer> detectedMinions = new HashMap<>(); - Map<Integer, Integer> detectedMinionsWithSkin = new HashMap<>(); - int detectedMinionCount = 0; - int minionsWithSkinCount = 0; - entityLoop: - for (Entity entity : sender.getEntityWorld().loadedEntityList) { - if (entity instanceof EntityArmorStand) { - EntityArmorStand minion = (EntityArmorStand) entity; - - if (minion.isInvisible() || !minion.isSmall() || minion.getHeldItem() == null) { - // not a minion: invisible, or not small armor stand, or no item in hand (= minion in a minion chair) - continue; - } - for (int slot = 0; slot < 4; slot++) { - if (minion.getCurrentArmor(slot) == null) { - // not a minion: missing equipment - continue entityLoop; - } - } - ItemStack skullItem = minion.getCurrentArmor(3); // head slot - if (skullItem.getItem() instanceof ItemSkull && skullItem.getMetadata() == 3 && skullItem.hasTagCompound()) { - // is a player head! - if (skullItem.getTagCompound().hasKey("SkullOwner", Constants.NBT.TAG_COMPOUND)) { - NBTTagCompound skullOwner = skullItem.getTagCompound().getCompoundTag("SkullOwner"); - String skullDataBase64 = skullOwner.getCompoundTag("Properties").getTagList("textures", Constants.NBT.TAG_COMPOUND).getCompoundTagAt(0).getString("Value"); - String skullData = new String(Base64.decodeBase64(skullDataBase64)); - String minionSkinId = StringUtils.substringBetween(skullData, "http://textures.minecraft.net/texture/", "\""); - String detectedMinion = minions.get(minionSkinId); - if (detectedMinion != null) { - // minion head matches one know minion tier - detectedMinions.put(detectedMinion, detectedMinions.getOrDefault(detectedMinion, 0) + 1); - detectedMinionCount++; - } else { - int minionTier = ImageUtils.getTierFromTexture(minionSkinId); - if (minionTier > 0) { - detectedMinionsWithSkin.put(minionTier, detectedMinionsWithSkin.getOrDefault(minionTier, 0) + 1); - minionsWithSkinCount++; - } else { - // looked like a minion but has no matching tier badge - main.getLogger().info("[/moo analyzeIsland] Found an armor stand that could be a minion but it is missing a tier badge: " + minionSkinId + "\t\t\t" + minion.serializeNBT()); - } - } - } - } - } - } - StringBuilder analysisResults = new StringBuilder("Found ").append(EnumChatFormatting.GOLD).append(detectedMinionCount).append(EnumChatFormatting.YELLOW).append(" minions"); - if (minionsWithSkinCount > 0) { - analysisResults.append(" + ").append(EnumChatFormatting.GOLD).append(minionsWithSkinCount).append(EnumChatFormatting.YELLOW).append(" unknown minions with skins"); - } - analysisResults.append(" on this island"); - detectedMinions.entrySet().stream() - .sorted(Map.Entry.comparingByKey()) // sort alphabetically by minion name and tier - .forEach(minion -> { - String minionWithTier = minion.getKey(); - int lastSpace = minionWithTier.lastIndexOf(' '); - - String tierRoman = minionWithTier.substring(lastSpace + 1); - - int tierArabic = Utils.convertRomanToArabic(tierRoman); - EnumChatFormatting tierColor = Utils.getMinionTierColor(tierArabic); - - minionWithTier = minionWithTier.substring(0, lastSpace) + " " + tierColor + (MooConfig.useRomanNumerals() ? tierRoman : tierArabic); - analysisResults.append("\n ").append(EnumChatFormatting.GOLD).append(minion.getValue()).append(minion.getValue() > 1 ? "✕ " : "⨉ ") - .append(EnumChatFormatting.YELLOW).append(minionWithTier); - }); - detectedMinionsWithSkin.entrySet().stream() - .sorted(Map.Entry.comparingByKey()) // sort by tier - .forEach(minionWithSkin -> { - EnumChatFormatting tierColor = Utils.getMinionTierColor(minionWithSkin.getKey()); - String minionTier = MooConfig.useRomanNumerals() ? Utils.convertArabicToRoman(minionWithSkin.getKey()) : String.valueOf(minionWithSkin.getKey()); - analysisResults.append("\n ").append(EnumChatFormatting.GOLD).append(minionWithSkin.getValue()).append(minionWithSkin.getValue() > 1 ? "✕ " : "⨉ ") - .append(EnumChatFormatting.RED).append("Unknown minion ").append(EnumChatFormatting.YELLOW).append("(new or with minion skin) ").append(tierColor).append(minionTier); - }); - main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, analysisResults.toString()); - } else if (args.length == 2 && args[0].equalsIgnoreCase("add")) { - handleBestFriendAdd(args[1]); - } else if (args.length == 2 && args[0].equalsIgnoreCase("remove")) { - handleBestFriendRemove(args[1]); - } else if (args[0].equalsIgnoreCase("list")) { - handleListBestFriends(); - } else if (args[0].equalsIgnoreCase("nameChangeCheck")) { - main.getChatHelper().sendMessage(EnumChatFormatting.GOLD, "Looking for best friends that have changed their name... This will take a few seconds..."); - main.getFriendsHandler().updateBestFriends(true); - } - // sub-commands: miscellaneous - else if (args[0].equalsIgnoreCase("config") || args[0].equalsIgnoreCase("toggle")) { - new TickDelay(() -> Minecraft.getMinecraft().displayGuiScreen(new MooGuiConfig(null)), 1); // delay by 1 tick, because the chat closing would close the new gui instantly as well. - } else if (args[0].equalsIgnoreCase("search")) { - new TickDelay(() -> Minecraft.getMinecraft().displayGuiScreen(new GuiSearch(main.getConfigDirectory())), 1); // delay by 1 tick, because the chat closing would close the new gui instantly as well. - } else if (args[0].equalsIgnoreCase("guiscale")) { - int currentGuiScale = (Minecraft.getMinecraft()).gameSettings.guiScale; - if (args.length == 1) { - main.getChatHelper().sendMessage(EnumChatFormatting.GREEN, "\u279C Current GUI scale: " + EnumChatFormatting.DARK_GREEN + currentGuiScale); - } else { - int scale = Math.min(10, MathHelper.parseIntWithDefault(args[1], 6)); - Minecraft.getMinecraft().gameSettings.guiScale = scale; - main.getChatHelper().sendMessage(EnumChatFormatting.GREEN, "\u2714 New GUI scale: " + EnumChatFormatting.DARK_GREEN + scale + EnumChatFormatting.GREEN + " (previous: " + EnumChatFormatting.DARK_GREEN + currentGuiScale + EnumChatFormatting.GREEN + ")"); - } - } else if (args[0].equalsIgnoreCase("shrug")) { - main.getChatHelper().sendShrug(buildString(args, 1)); - } else if (args[0].equalsIgnoreCase("apikey")) { - handleApiKey(args); - } - // sub-commands: update mod - else if (args[0].equalsIgnoreCase("update")) { - boolean updateCheckStarted = main.getVersionChecker().runUpdateCheck(true); - - if (updateCheckStarted) { - main.getChatHelper().sendMessage(EnumChatFormatting.GREEN, "\u279C Checking for a newer mod version..."); - // VersionChecker#handleVersionStatus will run with a 5 seconds delay - } else { - long nextUpdate = main.getVersionChecker().getNextCheck(); - String waitingTime = String.format("%02d:%02d", - TimeUnit.MILLISECONDS.toMinutes(nextUpdate), - TimeUnit.MILLISECONDS.toSeconds(nextUpdate) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(nextUpdate))); - throw new MooCommandException("\u26A0 Update checker is on cooldown. Please wait " + EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + waitingTime + EnumChatFormatting.RESET + EnumChatFormatting.RED + " more minutes before checking again."); - } - } else if (args[0].equalsIgnoreCase("updateHelp")) { - main.getChatHelper().sendMessage(new ChatComponentText("\u279C Update instructions:").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(true)) - .appendSibling(new ChatComponentText("\n\u278A" + EnumChatFormatting.YELLOW + " download latest mod version").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(false) - .setChatClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, main.getVersionChecker().getDownloadUrl())) - .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "Download the latest version of " + Cowmoonication.MODNAME + "\n\u279C Click to download latest mod file"))))) - .appendSibling(new ChatComponentText("\n\u278B" + EnumChatFormatting.YELLOW + " exit Minecraft").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(false) - .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.GOLD + "\u278B" + EnumChatFormatting.YELLOW + " Without closing Minecraft first,\n" + EnumChatFormatting.YELLOW + "you can't delete the old .jar file!"))))) - .appendSibling(new ChatComponentText("\n\u278C" + EnumChatFormatting.YELLOW + " copy " + EnumChatFormatting.GOLD + Cowmoonication.MODNAME.replace(" ", "") + "-" + main.getVersionChecker().getNewVersion() + ".jar" + EnumChatFormatting.YELLOW + " into mods directory").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(false) - .setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/moo directory")) - .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "Open mods directory with command " + EnumChatFormatting.GOLD + "/moo directory\n\u279C Click to open mods directory"))))) - .appendSibling(new ChatComponentText("\n\u278D" + EnumChatFormatting.YELLOW + " delete old mod file " + EnumChatFormatting.GOLD + Cowmoonication.MODNAME.replace(" ", "") + "-" + Cowmoonication.VERSION + ".jar ").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(false))) - .appendSibling(new ChatComponentText("\n\u278E" + EnumChatFormatting.YELLOW + " start Minecraft again").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(false)))); - } else if (args[0].equalsIgnoreCase("version")) { - main.getVersionChecker().handleVersionStatus(true); - } else if (args[0].equalsIgnoreCase("directory") || args[0].equalsIgnoreCase("folder")) { - try { - Desktop.getDesktop().open(main.getModsDirectory()); - } catch (IOException e) { - e.printStackTrace(); - throw new MooCommandException("\u2716 An error occurred trying to open the mod's directory. I guess you have to open it manually \u00af\\_(\u30c4)_/\u00af"); - } - } else if (args[0].equalsIgnoreCase("help")) { - sendCommandUsage(sender); - } - // "catch-all" remaining sub-commands - else { - main.getChatHelper().sendMessage(EnumChatFormatting.RED, "Command " + EnumChatFormatting.DARK_RED + "/" + getCommandName() + " " + args[0] + EnumChatFormatting.RED + " doesn't exist. Use " + EnumChatFormatting.DARK_RED + "/" + getCommandName() + " help " + EnumChatFormatting.RED + "to show command usage."); - } - } - - private void handleApiKey(String[] args) throws CommandException { - if (args.length == 1) { - String firstSentence; - EnumChatFormatting color; - EnumChatFormatting colorSecondary; - if (Utils.isValidUuid(MooConfig.moo)) { - firstSentence = "You already set your Hypixel API key."; - color = EnumChatFormatting.GREEN; - colorSecondary = EnumChatFormatting.DARK_GREEN; - } else { - firstSentence = "You haven't set your Hypixel API key yet."; - color = EnumChatFormatting.RED; - colorSecondary = EnumChatFormatting.DARK_RED; - } - main.getChatHelper().sendMessage(color, firstSentence + " Use " + colorSecondary + "/api new" + color + " to request a new API key from Hypixel or use " + colorSecondary + "/" + this.getCommandName() + " apikey <key>" + color + " to manually set your existing API key."); - } else { - String key = args[1]; - if (Utils.isValidUuid(key)) { - MooConfig.moo = key; - main.getConfig().syncFromFields(); - main.getChatHelper().sendMessage(EnumChatFormatting.GREEN, "Updated API key!"); - } else { - throw new SyntaxErrorException("That doesn't look like a valid API key..."); - } - } - } - - private void handleStalking(String playerName) throws CommandException { - if (!Utils.isValidUuid(MooConfig.moo)) { - throw new MooCommandException("You haven't set your Hypixel API key yet. Use " + EnumChatFormatting.DARK_RED + "/api new" + EnumChatFormatting.RED + " to request a new API key from Hypixel or use " + EnumChatFormatting.DARK_RED + "/" + this.getCommandName() + " apikey <key>" + EnumChatFormatting.RED + " to manually set your existing API key."); - } - main.getChatHelper().sendMessage(EnumChatFormatting.GRAY, "Stalking " + EnumChatFormatting.WHITE + playerName + EnumChatFormatting.GRAY + ". This may take a few seconds."); - boolean isBestFriend = main.getFriendsHandler().isBestFriend(playerName, true); - if (isBestFriend) { - Friend stalkedPlayer = main.getFriendsHandler().getBestFriend(playerName); - // we have the uuid already, so stalk the player - stalkPlayer(stalkedPlayer); - } else { - // fetch player uuid - ApiUtils.fetchFriendData(playerName, stalkedPlayer -> { - if (stalkedPlayer == null) { - throw new ApiContactException("Mojang", "couldn't stalk " + EnumChatFormatting.DARK_RED + playerName); - } else if (stalkedPlayer.equals(Friend.FRIEND_NOT_FOUND)) { - throw new PlayerNotFoundException("There is no player with the name " + EnumChatFormatting.DARK_RED + playerName + EnumChatFormatting.RED + "."); - } else { - // ... then stalk the player - stalkPlayer(stalkedPlayer); - } - }); - } - } - - private void stalkPlayer(Friend stalkedPlayer) { - ApiUtils.fetchPlayerStatus(stalkedPlayer, hyStalking -> { - if (hyStalking != null && hyStalking.isSuccess()) { - HyStalkingData.HySession session = hyStalking.getSession(); - if (session.isOnline()) { - main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, EnumChatFormatting.GOLD + stalkedPlayer.getName() + EnumChatFormatting.YELLOW + " is currently playing " + EnumChatFormatting.GOLD + session.getGameType() + EnumChatFormatting.YELLOW - + (session.getMode() != null ? ": " + EnumChatFormatting.GOLD + session.getMode() : "") - + (session.getMap() != null ? EnumChatFormatting.YELLOW + " (Map: " + EnumChatFormatting.GOLD + session.getMap() + EnumChatFormatting.YELLOW + ")" : "")); - } else { - ApiUtils.fetchPlayerOfflineStatus(stalkedPlayer, slothStalking -> { - if (slothStalking == null) { - throw new ApiContactException("Slothpixel", "couldn't stalk " + EnumChatFormatting.DARK_RED + stalkedPlayer.getName() + EnumChatFormatting.RED + " but they appear to be offline currently."); - } else if (slothStalking.hasNeverJoinedHypixel()) { - main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, EnumChatFormatting.GOLD + stalkedPlayer.getName() + EnumChatFormatting.YELLOW + " has " + EnumChatFormatting.GOLD + "never " + EnumChatFormatting.YELLOW + "been on Hypixel (or might be nicked)."); - } else if (slothStalking.isHidingOnlineStatus()) { - main.getChatHelper().sendMessage(new ChatComponentText(slothStalking.getPlayerNameFormatted()).appendSibling(new ChatComponentText(" is hiding their online status from the Hypixel API. You can see their online status with ").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW))) - .appendSibling(new ChatComponentText("/profile " + slothStalking.getPlayerName()).setChatStyle(new ChatStyle() - .setColor(EnumChatFormatting.GOLD) - .setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/profile " + slothStalking.getPlayerName())) - .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "Run " + EnumChatFormatting.GOLD + "/profile " + slothStalking.getPlayerName()))))) - .appendSibling(new ChatComponentText(" while you're in a lobby (tooltip of the player head on the top left).").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW)))); - } else if (slothStalking.hasNeverLoggedOut()) { - Pair<String, String> lastOnline = Utils.getDurationAsWords(slothStalking.getLastLogin()); - - main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, slothStalking.getPlayerNameFormatted() + EnumChatFormatting.YELLOW + " was last online " + EnumChatFormatting.GOLD + lastOnline.first() + EnumChatFormatting.YELLOW + " ago" - + (lastOnline.second() != null ? " (" + EnumChatFormatting.GOLD + lastOnline.second() + EnumChatFormatting.YELLOW + ")" : "") + "."); - } else { - Pair<String, String> lastOnline = Utils.getDurationAsWords(slothStalking.getLastLogout()); - - main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, slothStalking.getPlayerNameFormatted() + EnumChatFormatting.YELLOW + " is " + EnumChatFormatting.GOLD + "offline" + EnumChatFormatting.YELLOW + " for " + EnumChatFormatting.GOLD + lastOnline.first() + EnumChatFormatting.YELLOW - + ((lastOnline.second() != null || slothStalking.getLastGame() != null) ? (" (" - + (lastOnline.second() != null ? EnumChatFormatting.GOLD + lastOnline.second() + EnumChatFormatting.YELLOW : "") // = last online date - + (lastOnline.second() != null && slothStalking.getLastGame() != null ? "; " : "") // = delimiter - + (slothStalking.getLastGame() != null ? "last played gamemode: " + EnumChatFormatting.GOLD + slothStalking.getLastGame() + EnumChatFormatting.YELLOW : "") // = last gamemode - + ")") : "") + "."); - } - }); - } - } else { - String cause = (hyStalking != null) ? hyStalking.getCause() : null; - throw new ApiContactException("Hypixel", "couldn't stalk " + EnumChatFormatting.DARK_RED + stalkedPlayer.getName() + EnumChatFormatting.RED + (cause != null ? " (Reason: " + EnumChatFormatting.DARK_RED + cause + EnumChatFormatting.RED + ")" : "") + "."); - } - }); - } - - private void handleStalkingSkyBlock(String playerName) throws CommandException { - if (!Utils.isValidUuid(MooConfig.moo)) { - throw new MooCommandException("You haven't set your Hypixel API key yet. Use " + EnumChatFormatting.DARK_RED + "/api new" + EnumChatFormatting.RED + " to request a new API key from Hypixel or use " + EnumChatFormatting.DARK_RED + "/" + this.getCommandName() + " apikey <key>" + EnumChatFormatting.RED + " to manually set your existing API key."); - } - main.getChatHelper().sendMessage(EnumChatFormatting.GRAY, "Stalking " + EnumChatFormatting.WHITE + playerName + EnumChatFormatting.GRAY + "'s SkyBlock stats. This may take a few seconds."); - boolean isBestFriend = main.getFriendsHandler().isBestFriend(playerName, true); - if (isBestFriend) { - Friend stalkedPlayer = main.getFriendsHandler().getBestFriend(playerName); - // we have the uuid already, so stalk the player - stalkSkyBlockStats(stalkedPlayer); - } else { - // fetch player uuid - ApiUtils.fetchFriendData(playerName, stalkedPlayer -> { - if (stalkedPlayer == null) { - throw new ApiContactException("Mojang", "couldn't stalk " + EnumChatFormatting.DARK_RED + playerName); - } else if (stalkedPlayer.equals(Friend.FRIEND_NOT_FOUND)) { - throw new PlayerNotFoundException("There is no player with the name " + EnumChatFormatting.DARK_RED + playerName + EnumChatFormatting.RED + "."); - } else { - // ... then stalk the player - stalkSkyBlockStats(stalkedPlayer); - } - }); - } - } - - private void stalkSkyBlockStats(Friend stalkedPlayer) { - ApiUtils.fetchSkyBlockStats(stalkedPlayer, hySBStalking -> { - if (hySBStalking != null && hySBStalking.isSuccess()) { - HySkyBlockStats.Profile activeProfile = hySBStalking.getActiveProfile(stalkedPlayer.getUuid()); - - if (activeProfile == null) { - throw new MooCommandException("Looks like " + EnumChatFormatting.DARK_RED + stalkedPlayer.getName() + EnumChatFormatting.RED + " hasn't played SkyBlock yet."); - } - - String highestSkill = null; - int highestLevel = -1; - - MooChatComponent skillLevels = new MooChatComponent("Skill levels:").gold(); - HySkyBlockStats.Profile.Member member = activeProfile.getMember(stalkedPlayer.getUuid()); - for (Map.Entry<HySkyBlockStats.SkillLevel, Double> entry : member.getSkills().entrySet()) { - String skill = Utils.fancyCase(entry.getKey().name()); - int level = entry.getKey().getLevel(entry.getValue()); - if (level > 0) { - String skillLevel = MooConfig.useRomanNumerals() ? Utils.convertArabicToRoman(level) : String.valueOf(level); - skillLevels.appendFreshSibling(new MooChatComponent.KeyValueTooltipComponent(skill, skillLevel)); - } - - if (level > highestLevel) { - highestSkill = skill; - highestLevel = level; - } - } - - // output inspired by /profiles hover - String coinsBankAndPurse = (activeProfile.getCoinBank() >= 0) ? Utils.formatNumberWithAbbreviations(activeProfile.getCoinBank() + member.getCoinPurse()) : "API access disabled"; - Pair<String, String> fancyFirstJoined = member.getFancyFirstJoined(); - - MooChatComponent wealthHover = new MooChatComponent("Accessible coins:").gold() < |
