diff options
8 files changed, 235 insertions, 30 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java index f355d5d7..9679b886 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java @@ -52,6 +52,7 @@ import io.github.moulberry.notenoughupdates.overlays.OverlayManager; import io.github.moulberry.notenoughupdates.overlays.RancherBootOverlay; import io.github.moulberry.notenoughupdates.overlays.TextOverlay; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; +import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewerUtils; import io.github.moulberry.notenoughupdates.util.ItemUtils; import io.github.moulberry.notenoughupdates.util.NotificationHandler; import io.github.moulberry.notenoughupdates.util.Rectangle; @@ -946,6 +947,7 @@ public class RenderListener { Utils.addChatMessage("${RED}Invalid player name/API key. Maybe the API is down? Try /api new."); } else { profile.resetCache(); + ProfileViewerUtils.saveSearch(username); NotEnoughUpdates.INSTANCE.openGui = new GuiProfileViewer(profile); } }); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index 7513a5b3..ece4b225 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -460,6 +460,8 @@ public class NEUConfig extends Config { @Expose public ArrayList<String> previousBazaarSearches = new ArrayList<>(); @Expose + public ArrayList<String> previousProfileSearches = new ArrayList<>(); + @Expose public ArrayList<String> eventFavourites = new ArrayList<>(); @Expose public ArrayList<String> quickCommands = createDefaultQuickCommands(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java index 5dabdeaa..2dcce1fb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -60,6 +60,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -283,11 +284,13 @@ public class GuiProfileViewer extends GuiScreen { GlStateManager.enableDepth(); GlStateManager.translate(0, 0, 5); renderTabs(true); + renderRecentPlayers(true); GlStateManager.translate(0, 0, -3); GlStateManager.disableDepth(); GlStateManager.translate(0, 0, -2); renderTabs(false); + renderRecentPlayers(false); GlStateManager.translate(0, 0, 2); GlStateManager.disableLighting(); @@ -623,6 +626,72 @@ public class GuiProfileViewer extends GuiScreen { Utils.drawItemStack(stack, x + 6, y + 9); } + private void renderRecentPlayers(boolean renderCurrent) { + String playerName = ""; + if (profile.getHypixelProfile() != null) { + playerName = profile.getHypixelProfile().get("displayname").getAsString(); + } + + boolean selected = Objects.equals(Minecraft.getMinecraft().thePlayer.getName(), playerName); + if (selected == renderCurrent) { + renderRecentPlayer(Minecraft.getMinecraft().thePlayer.getName().toLowerCase(), 0, selected); + } + + List<String> previousProfileSearches = NotEnoughUpdates.INSTANCE.config.hidden.previousProfileSearches; + + for (int i = 0; i < previousProfileSearches.size(); i++) { + selected = Objects.equals(previousProfileSearches.get(i), playerName.toLowerCase()); + if (selected == renderCurrent) { + renderRecentPlayer(previousProfileSearches.get(i), i + 1, selected); + } + } + } + + private void renderRecentPlayer(String name, int yIndex, boolean selected) { + GlStateManager.disableLighting(); + GlStateManager.enableBlend(); + GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); + GlStateManager.enableAlpha(); + GlStateManager.alphaFunc(GL11.GL_GREATER, 0.1F); + + int x = guiLeft + sizeX; + int y = guiTop + yIndex * 28; + + float uMin = 226 / 256f; + float uMax = 1f; + float vMin = 144 / 256f; + float vMax = 172 / 256f; + + if (yIndex != 0) { + vMin = 172 / 256f; + vMax = 200 / 256f; + } + + if (selected) { + uMin = 196 /256f; + uMax = 226 / 256f; + + renderBlurredBackground(width, height, x - 2, y + 2, 30 - 2, 28 - 4); + } else { + renderBlurredBackground(width, height, x, y + 2, 28 - 2, 28 - 4); + } + + GlStateManager.disableLighting(); + GlStateManager.enableBlend(); + GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); + GlStateManager.enableAlpha(); + GlStateManager.alphaFunc(GL11.GL_GREATER, 0.1F); + + Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements); + Utils.drawTexturedRect(x - 3, y, 32, 28, uMin, uMax, vMin, vMax, GL11.GL_NEAREST); + + GlStateManager.enableDepth(); + + ItemStack playerHead = ProfileViewerUtils.getPlayerData(name); + + Utils.drawItemStack(playerHead, x + 3, y + 6); + } + @Override protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { if (currentPage != ProfileViewerPage.LOADING && currentPage != ProfileViewerPage.INVALID_NAME) { @@ -658,6 +727,38 @@ public class GuiProfileViewer extends GuiScreen { } } + String playerName = ""; + if (profile.getHypixelProfile() != null) { + playerName = profile.getHypixelProfile().get("displayname").getAsString().toLowerCase(); + } + int x = guiLeft + sizeX; + int y = guiTop; + List<String> previousProfileSearches = NotEnoughUpdates.INSTANCE.config.hidden.previousProfileSearches; + + if (mouseX > x && mouseX < x + 29) { + if (mouseY > y && mouseY < y + 28) { + if (!playerName.equals(Minecraft.getMinecraft().thePlayer.getName().toLowerCase())) { + NotEnoughUpdates.profileViewer.loadPlayerByName(Minecraft.getMinecraft().thePlayer.getName(), profile -> { + profile.resetCache(); + NotEnoughUpdates.INSTANCE.openGui = new GuiProfileViewer(profile); + }); + } + } + } + + for (int i = 0; i < previousProfileSearches.size(); i++) { + if (mouseX > x && mouseX < x + 28) { + if (mouseY > y + 28 * (i + 1) && mouseY < y + 28 * (i + 2)) { + if (!playerName.equals(previousProfileSearches.get(i))) { + NotEnoughUpdates.profileViewer.loadPlayerByName(previousProfileSearches.get(i), profile -> { + profile.resetCache(); + NotEnoughUpdates.INSTANCE.openGui = new GuiProfileViewer(profile); + }); + } + } + } + } + if (mouseX > guiLeft + sizeX - 100 && mouseX < guiLeft + sizeX) { if (mouseY > guiTop + sizeY + 5 && mouseY < guiTop + sizeY + 25) { playerNameTextField.mouseClicked(mouseX, mouseY, mouseButton); @@ -748,7 +849,10 @@ public class GuiProfileViewer extends GuiScreen { NotEnoughUpdates.profileViewer.loadPlayerByName( playerNameTextField.getText(), profile -> { //todo: invalid name - if (profile != null) profile.resetCache(); + if (profile != null) { + profile.resetCache(); + ProfileViewerUtils.saveSearch(playerNameTextField.getText()); + } Minecraft.getMinecraft().displayGuiScreen(new GuiProfileViewer(profile)); } ); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java index 8c552146..edf106d5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java @@ -428,7 +428,7 @@ public class ProfileViewer { @Getter private final NEUManager manager; private final HashMap<String, SkyblockProfiles> uuidToSkyblockProfiles = new HashMap<>(); - private final HashMap<String, String> nameToUuid = new HashMap<>(); + final HashMap<String, String> nameToUuid = new HashMap<>(); public ProfileViewer(NEUManager manager) { this.manager = manager; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewerUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewerUtils.java index 5c7e4b29..030a9f19 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewerUtils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewerUtils.java @@ -28,6 +28,8 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.JsonUtils; import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.JsonToNBT; import net.minecraft.nbt.NBTTagCompound; @@ -39,17 +41,26 @@ import java.io.IOException; import java.util.AbstractMap; import java.util.Base64; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.function.Consumer; import java.util.stream.Collectors; public class ProfileViewerUtils { + static Map<String, ItemStack> playerSkullCache = new HashMap<>(); + static Map<String, Long> lastSoopyRequestTime = new HashMap<>(); + static Map<String, JsonObject> soopyDataCache = new HashMap<>(); public static JsonArray readInventoryInfo(JsonObject profileInfo, String bagName) { - String bytes = Utils.getElementAsString(Utils.getElement(profileInfo, bagName + ".data"), "Hz8IAAAAAAAAAD9iYD9kYD9kAAMAPwI/Gw0AAAA="); + String bytes = Utils.getElementAsString( + Utils.getElement(profileInfo, bagName + ".data"), + "Hz8IAAAAAAAAAD9iYD9kYD9kAAMAPwI/Gw0AAAA=" + ); NBTTagCompound nbt; try { @@ -86,7 +97,8 @@ public class ProfileViewerUtils { } JsonArray lastElementJsonArray = new JsonArray(); lastElementJsonArray.add(new JsonPrimitive(lastElement)); - return new AbstractMap.SimpleEntry<>(tag.getCompoundTag("ExtraAttributes").getString("id"), + return new AbstractMap.SimpleEntry<>( + tag.getCompoundTag("ExtraAttributes").getString("id"), Utils.getRarityFromLore(lastElementJsonArray) ); }).sorted(Comparator.comparingInt(e -> -e.getValue())).collect(Collectors.toMap( @@ -192,4 +204,75 @@ public class ProfileViewerUtils { levelObj.maxed = true; return levelObj; } + + public static void saveSearch(String username) { + String nameLower = username.toLowerCase(); + if (nameLower.equals(Minecraft.getMinecraft().thePlayer.getName().toLowerCase())) return; + List<String> previousProfileSearches = NotEnoughUpdates.INSTANCE.config.hidden.previousProfileSearches; + previousProfileSearches.remove(nameLower); + previousProfileSearches.add(0, nameLower); + while (previousProfileSearches.size() > 6) { + previousProfileSearches.remove(previousProfileSearches.size() - 1); + } + } + + private static ItemStack fallBackSkull() { + return Utils.createSkull( + "Simon", + "f3c4dfb91c7b40ac81fd462538538523", + "ewogICJ0aW1lc3RhbXAiIDogMTY4NzQwMTM4MjY4MywKICAicHJvZmlsZUlkIiA6ICJmM2M0ZGZiOTFjN2I0MGFjODFmZDQ2MjUzODUzODUyMyIsCiAgInByb2ZpbGVOYW1lIiA6ICJTaW1vbiIsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9kN2ViYThhZWU0ZmQxMTUxMmI3ZTFhMjc5YTE0YWM2NDhlNDQzNDgxYjlmMzcxMzZhNzEwMThkMzg3Mjk0Y2YzIgogICAgfQogIH0KfQ" + ); + } + + public static ItemStack getPlayerData(String username) { + String nameLower = username.toLowerCase(); + if (!playerSkullCache.containsKey(nameLower)) { + playerSkullCache.put(nameLower, fallBackSkull()); + + getPlayerSkull(nameLower, skull -> { + if (skull == null) { + skull = fallBackSkull(); + } + + playerSkullCache.put(nameLower, skull); + }); + } + return playerSkullCache.get(nameLower); + } + + private static void getPlayerSkull(String username, Consumer<ItemStack> callback) { + if (NotEnoughUpdates.profileViewer.nameToUuid.containsKey(username) && + NotEnoughUpdates.profileViewer.nameToUuid.get(username) == null) { + callback.accept(null); + return; + } + NotEnoughUpdates.profileViewer.getPlayerUUID(username, uuid -> { + if (uuid == null) { + callback.accept(null); + } else { + NotEnoughUpdates.INSTANCE.manager.apiUtils + .request() + .url("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid + "?unsigned=false") + .requestJson() + .thenAcceptAsync(jsonObject -> { + if (jsonObject.has("properties") && jsonObject.get("properties").isJsonArray()) { + JsonArray propertiesArray = jsonObject.getAsJsonArray("properties"); + if (propertiesArray.size() > 0) { + JsonObject textureObject = propertiesArray.get(0).getAsJsonObject(); + if (textureObject.has("value") && textureObject.get("value").isJsonPrimitive() + && textureObject.get("value").getAsJsonPrimitive().isString()) { + + ItemStack skull = Utils.createSkull( + username, + uuid, + textureObject.get("value").getAsString() + ); + callback.accept(skull); + } + } + } + }); + } + }); + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/SkyblockProfiles.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/SkyblockProfiles.java index fc836362..814db2ce 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/SkyblockProfiles.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/SkyblockProfiles.java @@ -242,36 +242,48 @@ public class SkyblockProfiles { return null; }); - profileViewer.getManager().apiUtils - .request() - .url("https://soopy.dev/api/v2/player_networth/" + this.uuid) - .method("POST") - .postData("application/json", profilesArray.toString()) - .requestJson() - .handle((jsonObject, throwable) -> { - if (jsonObject == null || !jsonObject.has("success") || !jsonObject.get("success").getAsBoolean()) { - for (Map.Entry<String, SkyblockProfile> entry : nameToProfile.entrySet()) { - entry.getValue().soopyNetworth = new SoopyNetworth(null); - } - updatingSoopyData.set(false); + long currentTime = System.currentTimeMillis(); + if (ProfileViewerUtils.lastSoopyRequestTime.containsKey(uuid)) { + if (currentTime - ProfileViewerUtils.lastSoopyRequestTime.get(uuid) < 5 * 1000 * 60) { + if (ProfileViewerUtils.soopyDataCache.containsKey(uuid)) { + updateSoopyNetworth(ProfileViewerUtils.soopyDataCache.get(uuid)); callback.run(); - return null; } + } + } else { + ProfileViewerUtils.lastSoopyRequestTime.put(uuid, currentTime); + profileViewer.getManager().apiUtils + .request() + .url("https://soopy.dev/api/v2/player_networth/" + this.uuid) + .method("POST") + .postData("application/json", profilesArray.toString()) + .requestJson() + .handle((jsonObject, throwable) -> { + updateSoopyNetworth(jsonObject); + ProfileViewerUtils.soopyDataCache.put(uuid, jsonObject); + callback.run(); + return null; + }); + } + } - for (Map.Entry<String, SkyblockProfile> entry : nameToProfile.entrySet()) { - String profileId = entry.getValue().getOuterProfileJson().get("profile_id").getAsString().replace("-", ""); - JsonElement curProfileData = jsonObject.getAsJsonObject("data").get(profileId); - if (curProfileData == null) { - entry.getValue().soopyNetworth = new SoopyNetworth(null); - } else { - entry.getValue().soopyNetworth = new SoopyNetworth(curProfileData.getAsJsonObject()); - } + private void updateSoopyNetworth(JsonObject jsonObject) { + if (jsonObject == null || !jsonObject.has("success") || !jsonObject.get("success").getAsBoolean()) { + for (Map.Entry<String, SkyblockProfile> entry : nameToProfile.entrySet()) { + entry.getValue().soopyNetworth = new SoopyNetworth(null); + } + } else { + for (Map.Entry<String, SkyblockProfile> entry : nameToProfile.entrySet()) { + String profileId = entry.getValue().getOuterProfileJson().get("profile_id").getAsString().replace("-", ""); + JsonElement curProfileData = jsonObject.getAsJsonObject("data").get(profileId); + if (curProfileData == null) { + entry.getValue().soopyNetworth = new SoopyNetworth(null); + } else { + entry.getValue().soopyNetworth = new SoopyNetworth(curProfileData.getAsJsonObject()); } - - updatingSoopyData.set(false); - callback.run(); - return null; - }); + } + } + updatingSoopyData.set(false); } public AtomicBoolean getUpdatingSkyblockProfilesState() { diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/ProfileViewerCommands.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/ProfileViewerCommands.kt index 41cd6b0f..d25e880b 100644 --- a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/ProfileViewerCommands.kt +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/ProfileViewerCommands.kt @@ -24,6 +24,7 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe import io.github.moulberry.notenoughupdates.events.RegisterBrigadierCommandEvent import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer +import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewerUtils import io.github.moulberry.notenoughupdates.util.brigadier.* import net.minecraft.client.Minecraft import net.minecraft.client.renderer.OpenGlHelper @@ -56,6 +57,7 @@ class ProfileViewerCommands { reply("${RED}Invalid player name/API key. Maybe the API is down? Try /api new.") } else { profile.resetCache() + ProfileViewerUtils.saveSearch(name) NotEnoughUpdates.INSTANCE.openGui = GuiProfileViewer(profile) } } diff --git a/src/main/resources/assets/notenoughupdates/pv_elements.png b/src/main/resources/assets/notenoughupdates/pv_elements.png Binary files differindex 7e9033bd..c11551c8 100644 --- a/src/main/resources/assets/notenoughupdates/pv_elements.png +++ b/src/main/resources/assets/notenoughupdates/pv_elements.png |