From 5915c13b1390b613ceefe67011d1f66939e138c2 Mon Sep 17 00:00:00 2001 From: bowser0000 Date: Fri, 2 Oct 2020 14:03:12 -0400 Subject: Add command to see skill levels of lobby --- src/main/java/me/Danker/commands/DHelpCommand.java | 1 + .../me/Danker/commands/LobbySkillsCommand.java | 215 +++++++++++++++++++++ 2 files changed, 216 insertions(+) create mode 100644 src/main/java/me/Danker/commands/LobbySkillsCommand.java (limited to 'src/main/java/me/Danker/commands') diff --git a/src/main/java/me/Danker/commands/DHelpCommand.java b/src/main/java/me/Danker/commands/DHelpCommand.java index 0afa767..2cefb9b 100644 --- a/src/main/java/me/Danker/commands/DHelpCommand.java +++ b/src/main/java/me/Danker/commands/DHelpCommand.java @@ -43,6 +43,7 @@ public class DHelpCommand extends CommandBase { EnumChatFormatting.GOLD + " /scale " + EnumChatFormatting.AQUA + " - Scales text display to a specified multipler between 0.1x and 10x.\n" + EnumChatFormatting.GOLD + " /slayer [player]" + EnumChatFormatting.AQUA + " - Uses API to get slayer xp of a person. If no name is provided, it checks yours.\n" + EnumChatFormatting.GOLD + " /skills [player]" + EnumChatFormatting.AQUA + " - Uses API to get skill levels of a person. If no name is provided, it checks yours.\n" + + EnumChatFormatting.GOLD + " /lobbyskills" + EnumChatFormatting.AQUA + " - Uses API to find the average skills of the lobby, as well the three players with the highest skill average.\n" EnumChatFormatting.GOLD + " /guildof [player]" + EnumChatFormatting.AQUA + " - Uses API to get guild name and guild master of a person. If no name is provided, it checks yours.\n" + EnumChatFormatting.GOLD + " /petsof [player]" + EnumChatFormatting.AQUA + " - Uses API to get pets of a person. If no name is provided, it checks yours.\n" + EnumChatFormatting.GOLD + " /bank [player]" + EnumChatFormatting.AQUA + " - Uses API to get bank and purse coins of a person. If no name is provided, it checks yours.\n" + diff --git a/src/main/java/me/Danker/commands/LobbySkillsCommand.java b/src/main/java/me/Danker/commands/LobbySkillsCommand.java new file mode 100644 index 0000000..1bcd38a --- /dev/null +++ b/src/main/java/me/Danker/commands/LobbySkillsCommand.java @@ -0,0 +1,215 @@ +package me.Danker.commands; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +import me.Danker.handlers.APIHandler; +import me.Danker.handlers.ConfigHandler; +import me.Danker.utils.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.command.CommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; + +public class LobbySkillsCommand extends CommandBase { + + Thread mainThread = null; + + @Override + public String getCommandName() { + return "lobbyskills"; + } + + @Override + public String getCommandUsage(ICommandSender arg0) { + return "/" + getCommandName(); + } + + @Override + public int getRequiredPermissionLevel() { + return 0; + } + + @Override + public void processCommand(ICommandSender arg0, String[] arg1) throws CommandException { + EntityPlayer playerSP = (EntityPlayer) arg0; + ConfigHandler cf = new ConfigHandler(); + APIHandler ah = new APIHandler(); + boolean someErrored = false; + Map unsortedSAList = new HashMap(); + ArrayList lobbySkills = new ArrayList(); + // Check key + String key = cf.getString("api", "APIKey"); + if (key.equals("")) { + playerSP.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "API key not set. Use /setkey.")); + return; + } + + mainThread = new Thread(() -> { + try { + // Create deep copy of players to prevent passing reference and ConcurrentModificationException + Collection players = new ArrayList(Minecraft.getMinecraft().getNetHandler().getPlayerInfoMap()); + playerSP.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Checking skill average of lobby. Estimated time: " + (int) (players.size() * 1.2 + 1) + " seconds.")); + // Send request every .6 seconds, leaving room for another 20 requests per minute + + for (final NetworkPlayerInfo player : players) { + // Manually get latest profile to use reduced requests on extra achievement API + System.out.println("Now parsing " + player.getGameProfile().getName()); + String UUID = player.getGameProfile().getId().toString().replaceAll("-", ""); + long biggestLastSave = 0; + int profileIndex = -1; + Thread.sleep(600); + JsonObject profileResponse = ah.getResponse("https://api.hypixel.net/skyblock/profiles?uuid=" + UUID + "&key=" + key); + if (!profileResponse.get("success").getAsBoolean()) { + String reason = profileResponse.get("cause").getAsString(); + System.out.println("User " + player.getGameProfile().getName() + " failed with reason: " + reason); + continue; + } + if (profileResponse.get("profiles").isJsonNull()) continue; + + JsonArray profiles = profileResponse.get("profiles").getAsJsonArray(); + for (int i = 0; i < profiles.size(); i++) { + JsonObject profile = profiles.get(i).getAsJsonObject(); + if (!profile.get("members").getAsJsonObject().get(UUID).getAsJsonObject().has("last_save")) continue; + if (profile.get("members").getAsJsonObject().get(UUID).getAsJsonObject().get("last_save").getAsLong() > biggestLastSave) { + biggestLastSave = profile.get("members").getAsJsonObject().get(UUID).getAsJsonObject().get("last_save").getAsLong(); + profileIndex = i; + } + } + if (profileIndex == -1 || biggestLastSave == 0) continue; + JsonObject latestProfile = profiles.get(profileIndex).getAsJsonObject().get("members").getAsJsonObject().get(UUID).getAsJsonObject(); + + // Get SA + double farmingLevel = 0; + double miningLevel = 0; + double combatLevel = 0; + double foragingLevel = 0; + double fishingLevel = 0; + double enchantingLevel = 0; + double alchemyLevel = 0; + double tamingLevel = 0; + + if (latestProfile.has("experience_skill_farming") || latestProfile.has("experience_skill_mining") || latestProfile.has("experience_skill_combat") || latestProfile.has("experience_skill_foraging") || latestProfile.has("experience_skill_fishing") || latestProfile.has("experience_skill_enchanting") || latestProfile.has("experience_skill_alchemy")) { + if (latestProfile.has("experience_skill_farming")) { + farmingLevel = Utils.xpToSkillLevel(latestProfile.get("experience_skill_farming").getAsDouble()); + farmingLevel = (double) Math.round(farmingLevel * 100) / 100; + } + if (latestProfile.has("experience_skill_mining")) { + miningLevel = Utils.xpToSkillLevel(latestProfile.get("experience_skill_mining").getAsDouble()); + miningLevel = (double) Math.round(miningLevel * 100) / 100; + } + if (latestProfile.has("experience_skill_combat")) { + combatLevel = Utils.xpToSkillLevel(latestProfile.get("experience_skill_combat").getAsDouble()); + combatLevel = (double) Math.round(combatLevel * 100) / 100; + } + if (latestProfile.has("experience_skill_foraging")) { + foragingLevel = Utils.xpToSkillLevel(latestProfile.get("experience_skill_foraging").getAsDouble()); + foragingLevel = (double) Math.round(foragingLevel * 100) / 100; + } + if (latestProfile.has("experience_skill_fishing")) { + fishingLevel = Utils.xpToSkillLevel(latestProfile.get("experience_skill_fishing").getAsDouble()); + fishingLevel = (double) Math.round(fishingLevel * 100) / 100; + } + if (latestProfile.has("experience_skill_enchanting")) { + enchantingLevel = Utils.xpToSkillLevel(latestProfile.get("experience_skill_enchanting").getAsDouble()); + enchantingLevel = (double) Math.round(enchantingLevel * 100) / 100; + } + if (latestProfile.has("experience_skill_alchemy")) { + alchemyLevel = Utils.xpToSkillLevel(latestProfile.get("experience_skill_alchemy").getAsDouble()); + alchemyLevel = (double) Math.round(alchemyLevel * 100) / 100; + } + if (latestProfile.has("experience_skill_taming")) { + tamingLevel = Utils.xpToSkillLevel(latestProfile.get("experience_skill_taming").getAsDouble()); + tamingLevel = (double) Math.round(tamingLevel * 100) / 100; + } + } else { + Thread.sleep(600); // Sleep for another request + System.out.println("Fetching skills from achievement API"); + JsonObject playerObject = ah.getResponse("https://api.hypixel.net/player?uuid=" + UUID + "&key=" + key); + + if (!playerObject.get("success").getAsBoolean()) { + String reason = profileResponse.get("cause").getAsString(); + System.out.println("User " + player.getGameProfile().getName() + " failed with reason: " + reason); + continue; + } + + JsonObject achievementObject = playerObject.get("player").getAsJsonObject().get("achievements").getAsJsonObject(); + if (achievementObject.has("skyblock_harvester")) { + farmingLevel = achievementObject.get("skyblock_harvester").getAsInt(); + } + if (achievementObject.has("skyblock_excavator")) { + miningLevel = achievementObject.get("skyblock_excavator").getAsInt(); + } + if (achievementObject.has("skyblock_combat")) { + combatLevel = achievementObject.get("skyblock_combat").getAsInt(); + } + if (achievementObject.has("skyblock_gatherer")) { + foragingLevel = achievementObject.get("skyblock_gatherer").getAsInt(); + } + if (achievementObject.has("skyblock_angler")) { + fishingLevel = achievementObject.get("skyblock_angler").getAsInt(); + } + if (achievementObject.has("skyblock_augmentation")) { + enchantingLevel = achievementObject.get("skyblock_augmentation").getAsInt(); + } + if (achievementObject.has("skyblock_concoctor")) { + alchemyLevel = achievementObject.get("skyblock_concoctor").getAsInt(); + } + if (achievementObject.has("skyblock_domesticator")) { + tamingLevel = achievementObject.get("skyblock_domesticator").getAsInt(); + } + } + + double skillAvg = (farmingLevel + miningLevel + combatLevel + foragingLevel + fishingLevel + enchantingLevel + alchemyLevel + tamingLevel) / 8; + skillAvg = (double) Math.round(skillAvg * 100) / 100; + unsortedSAList.put(player.getGameProfile().getName(), skillAvg); // Put SA in HashMap + lobbySkills.add(skillAvg); // Add SA to lobby skills + } + + // I have no idea how this works, or even what :: does but this sorts the skill averages + Map sortedSAList = unsortedSAList.entrySet().stream() + .sorted(Entry.comparingByValue().reversed()) + .collect(Collectors.toMap(Entry::getKey, Entry::getValue, + (e1, e2) -> e1, LinkedHashMap::new)); + + String[] sortedSAListKeys = sortedSAList.keySet().toArray(new String[sortedSAList.keySet().size()]); + String top3 = ""; + for (int i = 0; i < 3 && i < sortedSAListKeys.length; i++) { + top3 += "\n " + EnumChatFormatting.AQUA + sortedSAListKeys[i] + ": " + EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + sortedSAList.get(sortedSAListKeys[i]); + } + + // Get lobby sa + double lobbySA = 0; + for (int i = 0; i < lobbySkills.size(); i++) { + lobbySA += lobbySkills.get(i); + } + lobbySA = (double) Math.round((lobbySA / lobbySkills.size()) * 100) / 100; + + // Finally say skill lobby avg and highest SA users + playerSP.addChatMessage(new ChatComponentText(EnumChatFormatting.AQUA + "" + EnumChatFormatting.BOLD + "-------------------\n" + + EnumChatFormatting.GREEN + " Lobby Skill Average: " + EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + lobbySA + "\n" + + EnumChatFormatting.GREEN + " Highest Skill Averages:" + top3 + "\n" + + EnumChatFormatting.AQUA + "" + EnumChatFormatting.BOLD + " -------------------")); + } catch (InterruptedException ex) { + System.out.println("Current skill average list: " + unsortedSAList.toString()); + Thread.currentThread().interrupt(); + System.out.println("Interrupted /lobbyskills thread."); + } + + }); + mainThread.start(); + } + +} -- cgit