diff options
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | me/Danker/TheMod.java | 39 | ||||
-rw-r--r-- | me/Danker/commands/LootCommand.java | 26 | ||||
-rw-r--r-- | me/Danker/commands/SlayerCommand.java | 133 | ||||
-rw-r--r-- | me/Danker/handlers/APIHandler.java | 51 |
5 files changed, 227 insertions, 26 deletions
@@ -5,6 +5,7 @@ QOL changes that enhances your Hypixel Skyblock experience. Created to add featu - Guild party desktop notifications (toggleable) - Coordinate and angle display (toggleable) - Slayer item tracker +- Slayer API command ## Commands - /toggle [gparty/coords/list] - Toggles features. /toggle list returns values of every toggle. @@ -13,6 +14,9 @@ QOL changes that enhances your Hypixel Skyblock experience. Created to add featu - /loot [zombie/spider/wolf] - Returns loot received from the slayer quest. - /display [zombie/spider/wolf/off] - Text display for slayer tracker. - /move [coords/display] [x] [y] - Moves text display to specified X and Y coordinates. +- /slayer <name> - Uses API to get slayer xp for a person. If no name is provided, it checks yours. ### Notes - Slayer tracker for token drops and 20% chance drops uses a 12x12x12 bounding box centered on the player to detect the drops. If you are out of the range of the item drop, it will not count on the tracker. +- API commands may take a while depending on your internet connection. +- API commands send one request to Mojang and two requests to the Hypixel API. This means doing more than 60 API commands/minute will get you rate-limited. If you have an unlimited Hypixel API key, this is changed to 600 API commands/10 minutes. diff --git a/me/Danker/TheMod.java b/me/Danker/TheMod.java index 39e6fc2..5fdaeaa 100644 --- a/me/Danker/TheMod.java +++ b/me/Danker/TheMod.java @@ -4,6 +4,7 @@ import java.awt.Image; import java.awt.SystemTray; import java.awt.Toolkit; import java.awt.TrayIcon; +import java.text.NumberFormat; import java.util.List; import me.Danker.commands.DisplayCommand; @@ -12,6 +13,7 @@ import me.Danker.commands.LootCommand; import me.Danker.commands.MoveCommand; import me.Danker.commands.ReloadConfigCommand; import me.Danker.commands.SetkeyCommand; +import me.Danker.commands.SlayerCommand; import me.Danker.commands.ToggleCommand; import me.Danker.handlers.ConfigHandler; import me.Danker.handlers.ScoreboardHandler; @@ -39,7 +41,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; public class TheMod { public static final String MODID = "Danker's Skyblock Mod"; - public static final String VERSION = "1.4.4"; + public static final String VERSION = "1.4.5"; static int checkItemsNow = 0; static int itemsChecked = 0; @@ -63,6 +65,7 @@ public class TheMod ClientCommandHandler.instance.registerCommand(new ReloadConfigCommand()); ClientCommandHandler.instance.registerCommand(new DisplayCommand()); ClientCommandHandler.instance.registerCommand(new MoveCommand()); + ClientCommandHandler.instance.registerCommand(new SlayerCommand()); } // It randomly broke, so I had to make it the highest priority @@ -287,7 +290,7 @@ public class TheMod if (lc.wolfBosses == -1) { bossesBetween = "Never"; } else { - bossesBetween = Integer.toString(lc.wolfBosses); + bossesBetween = NumberFormat.getIntegerInstance().format(lc.wolfBosses); } dropsText = EnumChatFormatting.GOLD + "Svens Killed:\n" + @@ -301,9 +304,9 @@ public class TheMod EnumChatFormatting.DARK_PURPLE + "Overfluxes:\n" + EnumChatFormatting.AQUA + "Time Since RNG:\n" + EnumChatFormatting.AQUA + "Bosses Since RNG:\n"; - countText = EnumChatFormatting.GOLD + "" + lc.wolfSvens + "\n" + - EnumChatFormatting.GREEN + lc.wolfTeeth + "\n" + - EnumChatFormatting.BLUE + lc.wolfWheels + "\n" + + countText = EnumChatFormatting.GOLD + "" + NumberFormat.getIntegerInstance().format(lc.wolfSvens) + "\n" + + EnumChatFormatting.GREEN + NumberFormat.getIntegerInstance().format(lc.wolfTeeth) + "\n" + + EnumChatFormatting.BLUE + NumberFormat.getIntegerInstance().format(lc.wolfWheels) + "\n" + EnumChatFormatting.AQUA + lc.wolfSpirits + "\n" + EnumChatFormatting.WHITE + lc.wolfBooks + "\n" + EnumChatFormatting.DARK_RED + lc.wolfEggs + "\n" + @@ -321,7 +324,7 @@ public class TheMod if (lc.spiderBosses == -1) { bossesBetween = "Never"; } else { - bossesBetween = Integer.toString(lc.spiderBosses); + bossesBetween = NumberFormat.getIntegerInstance().format(lc.spiderBosses); } dropsText = EnumChatFormatting.GOLD + "Tarantulas Killed:\n" + @@ -335,9 +338,9 @@ public class TheMod EnumChatFormatting.GOLD + "Digested Mosquitos:\n" + EnumChatFormatting.AQUA + "Time Since RNG:\n" + EnumChatFormatting.AQUA + "Bosses Since RNG:\n"; - countText = EnumChatFormatting.GOLD + "" + lc.spiderTarantulas + "\n" + - EnumChatFormatting.GREEN + lc.spiderWebs + "\n" + - EnumChatFormatting.DARK_GREEN + lc.spiderTAP + "\n" + + countText = EnumChatFormatting.GOLD + "" + NumberFormat.getIntegerInstance().format(lc.spiderTarantulas) + "\n" + + EnumChatFormatting.GREEN + NumberFormat.getIntegerInstance().format(lc.spiderWebs) + "\n" + + EnumChatFormatting.DARK_GREEN + NumberFormat.getIntegerInstance().format(lc.spiderTAP) + "\n" + EnumChatFormatting.DARK_GRAY + lc.spiderBites + "\n" + EnumChatFormatting.WHITE + lc.spiderBooks + "\n" + EnumChatFormatting.AQUA + lc.spiderCatalysts + "\n" + @@ -347,7 +350,17 @@ public class TheMod EnumChatFormatting.AQUA + timeBetween + "\n" + EnumChatFormatting.AQUA + bossesBetween + "\n"; } else { - // Zombie + if (lc.zombieTime == -1) { + timeBetween = "Never"; + } else { + timeBetween = lc.getTimeBetween(lc.zombieTime, timeNow); + } + if (lc.zombieBosses == -1) { + bossesBetween = "Never"; + } else { + bossesBetween = NumberFormat.getIntegerInstance().format(lc.zombieBosses); + } + dropsText = EnumChatFormatting.GOLD + "Revs Killed:\n" + EnumChatFormatting.GREEN + "Revenant Flesh:\n" + EnumChatFormatting.BLUE + "Foul Flesh:\n" + @@ -360,9 +373,9 @@ public class TheMod EnumChatFormatting.GOLD + "Scythe Blades:\n" + EnumChatFormatting.AQUA + "Time Since RNG:\n" + EnumChatFormatting.AQUA + "Bosses Since RNG:\n"; - countText = EnumChatFormatting.GOLD + "" + lc.zombieRevs + "\n" + - EnumChatFormatting.GREEN + lc.zombieRevFlesh + "\n" + - EnumChatFormatting.BLUE + lc.zombieFoulFlesh + "\n" + + countText = EnumChatFormatting.GOLD + "" + NumberFormat.getIntegerInstance().format(lc.zombieRevs) + "\n" + + EnumChatFormatting.GREEN + NumberFormat.getIntegerInstance().format(lc.zombieRevFlesh) + "\n" + + EnumChatFormatting.BLUE + NumberFormat.getIntegerInstance().format(lc.zombieFoulFlesh) + "\n" + EnumChatFormatting.DARK_GREEN + lc.zombiePestilences + "\n" + EnumChatFormatting.WHITE + lc.zombieBooks + "\n" + EnumChatFormatting.AQUA + lc.zombieUndeadCatas + "\n" + diff --git a/me/Danker/commands/LootCommand.java b/me/Danker/commands/LootCommand.java index 11382b3..046c729 100644 --- a/me/Danker/commands/LootCommand.java +++ b/me/Danker/commands/LootCommand.java @@ -1,6 +1,6 @@ package me.Danker.commands; -import java.util.List; +import java.text.NumberFormat; import net.minecraft.command.CommandBase; import net.minecraft.command.CommandException; @@ -118,9 +118,9 @@ public class LootCommand extends CommandBase { player.addChatMessage(new ChatComponentText(EnumChatFormatting.AQUA + "" + EnumChatFormatting.BOLD + "-------------------\n" + EnumChatFormatting.DARK_AQUA + "" + EnumChatFormatting.BOLD + " Sven Loot Summary:\n" + - EnumChatFormatting.GOLD + " Svens Killed: " + wolfSvens + "\n" + - EnumChatFormatting.GREEN + " Wolf Teeth: " + wolfTeeth + "\n" + - EnumChatFormatting.BLUE + " Hamster Wheels: " + wolfWheels + "\n" + + EnumChatFormatting.GOLD + " Svens Killed: " + NumberFormat.getIntegerInstance().format(wolfSvens) + "\n" + + EnumChatFormatting.GREEN + " Wolf Teeth: " + NumberFormat.getIntegerInstance().format(wolfTeeth) + "\n" + + EnumChatFormatting.BLUE + " Hamster Wheels: " + NumberFormat.getIntegerInstance().format(wolfWheels) + "\n" + EnumChatFormatting.AQUA + " Spirit Runes: " + wolfSpirits + "\n" + EnumChatFormatting.WHITE + " Critical VI Books: " + wolfBooks + "\n" + EnumChatFormatting.DARK_RED + " Red Claw Eggs: " + wolfEggs + "\n" + @@ -128,7 +128,7 @@ public class LootCommand extends CommandBase { EnumChatFormatting.AQUA + " Grizzly Baits: " + wolfBaits + "\n" + EnumChatFormatting.DARK_PURPLE + " Overfluxes: " + wolfFluxes + "\n" + EnumChatFormatting.AQUA + " Time Since RNG: " + timeBetween + "\n" + - EnumChatFormatting.AQUA + " Bosses Since RNG: " + bossesBetween + "\n" + + EnumChatFormatting.AQUA + " Bosses Since RNG: " + NumberFormat.getIntegerInstance().format(bossesBetween) + "\n" + EnumChatFormatting.AQUA + "" + EnumChatFormatting.BOLD + " -------------------")); } else if (arg1[0].equalsIgnoreCase("spider")) { if (spiderTime == -1) { @@ -144,9 +144,9 @@ public class LootCommand extends CommandBase { player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "" + EnumChatFormatting.BOLD + "-------------------\n" + EnumChatFormatting.DARK_RED + "" + EnumChatFormatting.BOLD + " Spider Loot Summary:\n" + - EnumChatFormatting.GOLD + " Tarantulas Killed: " + spiderTarantulas + "\n" + - EnumChatFormatting.GREEN + " Tarantula Webs: " + spiderWebs + "\n" + - EnumChatFormatting.DARK_GREEN + " Arrow Poison: " + spiderTAP + "\n" + + EnumChatFormatting.GOLD + " Tarantulas Killed: " + NumberFormat.getIntegerInstance().format(spiderTarantulas) + "\n" + + EnumChatFormatting.GREEN + " Tarantula Webs: " + NumberFormat.getIntegerInstance().format(spiderWebs) + "\n" + + EnumChatFormatting.DARK_GREEN + " Arrow Poison: " + NumberFormat.getIntegerInstance().format(spiderTAP) + "\n" + EnumChatFormatting.DARK_GRAY + " Bite Runes: " + spiderBites + "\n" + EnumChatFormatting.WHITE + " Bane VI Books: " + spiderBooks + "\n" + EnumChatFormatting.AQUA + " Spider Catalysts: " + spiderCatalysts + "\n" + @@ -154,7 +154,7 @@ public class LootCommand extends CommandBase { EnumChatFormatting.LIGHT_PURPLE + " Fly Swatters: " + spiderSwatters + "\n" + EnumChatFormatting.GOLD + " Digested Mosquitos: " + spiderMosquitos + "\n" + EnumChatFormatting.AQUA + " Time Since RNG: " + timeBetween + "\n" + - EnumChatFormatting.AQUA + " Bosses Since RNG: " + bossesBetween + "\n" + + EnumChatFormatting.AQUA + " Bosses Since RNG: " + NumberFormat.getIntegerInstance().format(bossesBetween) + "\n" + EnumChatFormatting.RED + "" + EnumChatFormatting.BOLD + " -------------------")); } else if (arg1[0].equalsIgnoreCase("zombie")) { if (zombieTime == -1) { @@ -170,9 +170,9 @@ public class LootCommand extends CommandBase { player.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "" + EnumChatFormatting.BOLD + "-------------------\n" + EnumChatFormatting.DARK_GREEN + "" + EnumChatFormatting.BOLD + " Zombie Loot Summary:\n" + - EnumChatFormatting.GOLD + " Revs Killed: " + zombieRevs + "\n" + - EnumChatFormatting.GREEN + " Revenant Flesh: " + zombieRevFlesh + "\n" + - EnumChatFormatting.BLUE + " Foul Flesh: " + zombieFoulFlesh + "\n" + + EnumChatFormatting.GOLD + " Revs Killed: " + NumberFormat.getIntegerInstance().format(zombieRevs) + "\n" + + EnumChatFormatting.GREEN + " Revenant Flesh: " + NumberFormat.getIntegerInstance().format(zombieRevFlesh) + "\n" + + EnumChatFormatting.BLUE + " Foul Flesh: " + NumberFormat.getIntegerInstance().format(zombieFoulFlesh) + "\n" + EnumChatFormatting.DARK_GREEN + " Pestilence Runes: " + zombiePestilences + "\n" + EnumChatFormatting.WHITE + " Smite VI Books: " + zombieBooks + "\n" + EnumChatFormatting.AQUA + " Undead Catalysts: " + zombieUndeadCatas + "\n" + @@ -181,7 +181,7 @@ public class LootCommand extends CommandBase { EnumChatFormatting.DARK_GREEN + " Snake Runes: " + zombieSnakes + "\n" + EnumChatFormatting.GOLD + " Scythe Blades: " + zombieScythes + "\n" + EnumChatFormatting.AQUA + " Time Since RNG: " + timeBetween + "\n" + - EnumChatFormatting.AQUA + " Bosses Since RNG: " + bossesBetween + "\n" + + EnumChatFormatting.AQUA + " Bosses Since RNG: " + NumberFormat.getIntegerInstance().format(bossesBetween) + "\n" + EnumChatFormatting.GREEN + "" + EnumChatFormatting.BOLD + " -------------------")); } else { player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Usage: /loot [zombie/spider/wolf]")); diff --git a/me/Danker/commands/SlayerCommand.java b/me/Danker/commands/SlayerCommand.java new file mode 100644 index 0000000..ec23606 --- /dev/null +++ b/me/Danker/commands/SlayerCommand.java @@ -0,0 +1,133 @@ +package me.Danker.commands; + +import java.text.NumberFormat; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import me.Danker.handlers.APIHandler; +import me.Danker.handlers.ConfigHandler; +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 SlayerCommand extends CommandBase { + + @Override + public String getCommandName() { + return "slayer"; + } + + @Override + public String getCommandUsage(ICommandSender arg0) { + return getCommandName() + " <name>"; + } + + @Override + public int getRequiredPermissionLevel() { + return 0; + } + + @Override + public void processCommand(ICommandSender arg0, String[] arg1) throws CommandException { + // MULTI THREAD DRIFTING + new Thread(() -> { + APIHandler ah = new APIHandler(); + ConfigHandler cf = new ConfigHandler(); + EntityPlayer player = (EntityPlayer) arg0; + + // Check key + String key = cf.getString("api", "APIKey"); + if (key.equals("")) { + player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "API key not set. Use /setkey.")); + } + + // Get UUID for Hypixel API requests + String username; + String uuid; + if (arg1.length == 0) { + username = player.getName(); + uuid = player.getUniqueID().toString().replaceAll("[\\-]", ""); + player.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Checking slayer of " + username)); + } else { + username = arg1[0]; + String uuidURL = "https://api.mojang.com/users/profiles/minecraft/" + username; + player.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Checking slayer of " + username)); + + JsonObject uuidResponse = ah.getResponse(uuidURL, player); + uuid = uuidResponse.get("id").getAsString(); + } + + // Get profiles + System.out.println("Fetching profiles..."); + String profilesURL = "https://api.hypixel.net/skyblock/profiles?uuid=" + uuid + "&key=" + key; + + JsonObject profilesResponse = ah.getResponse(profilesURL, player); + if (!profilesResponse.get("success").getAsBoolean()) { + String reason = profilesResponse.get("cause").getAsString(); + player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Failed with reason: " + reason)); + return; + } + if (profilesResponse.get("profiles").isJsonNull()) { + player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "This player doesn't appear to have played SkyBlock.")); + return; + } + + // Loop through profiles to find latest + System.out.println("Looping through profiles..."); + String latestProfile = ""; + int latestSave = 0; + JsonArray profilesArray = profilesResponse.get("profiles").getAsJsonArray(); + + for (JsonElement profile : profilesArray) { + JsonObject profileJSON = profile.getAsJsonObject(); + int profileLastSave = profileJSON.get("members").getAsJsonObject().get(uuid).getAsJsonObject().get("last_save").getAsInt(); + + if (profileLastSave > latestSave) { + latestProfile = profileJSON.get("profile_id").getAsString(); + latestSave = profileLastSave; + } + } + + // Find stats of latest profile + System.out.println("Fetching profile..."); + String profileURL = "https://api.hypixel.net/skyblock/profile?profile=" + latestProfile + "&key=" + key; + + JsonObject profileResponse = ah.getResponse(profileURL, player); + if (!profileResponse.get("success").getAsBoolean()) { + String reason = profilesResponse.get("cause").getAsString(); + player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Failed with reason: " + reason)); + return; + } + + System.out.println("Fetching slayer stats..."); + JsonObject slayersObject = profileResponse.get("profile").getAsJsonObject().get("members").getAsJsonObject().get(uuid).getAsJsonObject().get("slayer_bosses").getAsJsonObject(); + // Zombie + int zombieXP = 0; + if (slayersObject.get("zombie").getAsJsonObject().has("xp")) { + zombieXP = slayersObject.get("zombie").getAsJsonObject().get("xp").getAsInt(); + } + // Spider + int spiderXP = 0; + if (slayersObject.get("spider").getAsJsonObject().has("xp")) { + spiderXP = slayersObject.get("spider").getAsJsonObject().get("xp").getAsInt(); + } + // Wolf + int wolfXP = 0; + if (slayersObject.get("wolf").getAsJsonObject().has("xp")) { + wolfXP = slayersObject.get("wolf").getAsJsonObject().get("xp").getAsInt(); + } + + player.addChatMessage(new ChatComponentText(EnumChatFormatting.AQUA + username + "'s Total XP: " + EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + NumberFormat.getIntegerInstance().format(zombieXP + spiderXP + wolfXP) + "\n" + + EnumChatFormatting.AQUA + " Zombie XP: " + EnumChatFormatting.BLUE + EnumChatFormatting.BOLD + NumberFormat.getIntegerInstance().format(zombieXP) + "\n" + + EnumChatFormatting.AQUA + " Spider XP: " + EnumChatFormatting.BLUE + EnumChatFormatting.BOLD + NumberFormat.getIntegerInstance().format(spiderXP) + "\n" + + EnumChatFormatting.AQUA + " Wolf XP: " + EnumChatFormatting.BLUE + EnumChatFormatting.BOLD + NumberFormat.getIntegerInstance().format(wolfXP))); + + }).start(); + } + +} diff --git a/me/Danker/handlers/APIHandler.java b/me/Danker/handlers/APIHandler.java new file mode 100644 index 0000000..5997713 --- /dev/null +++ b/me/Danker/handlers/APIHandler.java @@ -0,0 +1,51 @@ +package me.Danker.handlers; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; + +public class APIHandler { + public static JsonObject getResponse(String urlString, EntityPlayer player) { + try { + URL url = new URL(urlString); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + + if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { + BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String input; + StringBuffer response = new StringBuffer(); + + while ((input = in.readLine()) != null) { + response.append(input); + } + in.close(); + + Gson gson = new Gson(); + JsonObject object = gson.fromJson(response.toString(), JsonObject.class); + + return object; + } else { + player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Request failed. Incorrect arguments?")); + } + } catch (MalformedURLException ex) { + player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "An error has occured. See logs for more details.")); + System.err.println(ex); + } catch (IOException ex) { + player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "An error has occured. See logs for more details.")); + System.err.println(ex); + } + + return new JsonObject(); + } +} |