aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java3
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java3
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java24
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MuseumPage.java536
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/SkyblockProfiles.java186
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java26
-rw-r--r--src/main/resources/assets/notenoughupdates/pv_inventories.pngbin0 -> 775 bytes
-rw-r--r--src/main/resources/assets/notenoughupdates/pv_museum.pngbin0 -> 1572 bytes
10 files changed, 759 insertions, 25 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index c6a0c04f..16e513a9 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -243,6 +243,9 @@ public class NotEnoughUpdates {
if (config.profileViewer.pageLayout.size() == 10) {
config.profileViewer.pageLayout.add(10);
}
+ if (config.profileViewer.pageLayout.size() == 11) {
+ config.profileViewer.pageLayout.add(11);
+ }
// Remove after 2.1 ig
if ("dangerous".equals(config.apiData.repoBranch)) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java
index 42a52639..9064ea49 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java
@@ -75,10 +75,11 @@ public class ProfileViewer {
"\u00a7eTrophy Fish",
"\u00a7eBestiary",
"\u00a7eCrimson Isle",
+ "\u00a7eMuseum",
},
allowDeleting = false
)
- public List<Integer> pageLayout = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
+ public List<Integer> pageLayout = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));
@Expose
@ConfigOption(
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
index 8a994a17..fb1b3364 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
@@ -36,10 +36,6 @@ import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import java.io.IOException;
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@@ -47,7 +43,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
-import java.util.TimeZone;
import java.util.TreeMap;
public class ExtraPage extends GuiProfileViewerPage {
@@ -562,24 +557,7 @@ public class ExtraPage extends GuiProfileViewerPage {
JsonElement lastSaveElement = Utils.getElement(profileInfo, path);
if (lastSaveElement != null && lastSaveElement.isJsonPrimitive()) {
- Instant lastSave = Instant.ofEpochMilli(lastSaveElement.getAsLong());
- LocalDateTime lastSaveTime = LocalDateTime.ofInstant(lastSave, TimeZone.getDefault().toZoneId());
- long timeDiff = System.currentTimeMillis() - lastSave.toEpochMilli();
- LocalDateTime sinceOnline = LocalDateTime.ofInstant(Instant.ofEpochMilli(timeDiff), ZoneId.of("UTC"));
- String renderText;
-
- if (timeDiff < 60000L) {
- renderText = sinceOnline.getSecond() + " seconds ago.";
- } else if (timeDiff < 3600000L) {
- renderText = sinceOnline.getMinute() + " minutes ago.";
- } else if (timeDiff < 86400000L) {
- renderText = sinceOnline.getHour() + " hours ago.";
- } else if (timeDiff < 31556952000L) {
- renderText = sinceOnline.getDayOfYear() + " days ago.";
- } else {
- renderText = lastSaveTime.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));
- }
- return renderText;
+ return Utils.timeSinceMillisecond(lastSaveElement.getAsLong());
}
return null;
}
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 e7476979..78c810a3 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
@@ -211,6 +211,7 @@ public class GuiProfileViewer extends GuiScreen {
pages.put(ProfileViewerPage.TROPHY_FISH, new TrophyFishPage(this));
pages.put(ProfileViewerPage.BESTIARY, new BestiaryPage(this));
pages.put(ProfileViewerPage.CRIMSON_ISLE, new CrimsonIslePage(this));
+ pages.put(ProfileViewerPage.MUSEUM, new MuseumPage(this));
}
public static int getGuiLeft() {
@@ -1202,7 +1203,8 @@ public class GuiProfileViewer extends GuiScreen {
BINGO(7, Items.filled_map, "§zBingo"),
TROPHY_FISH(8, Items.fishing_rod, "§3Trophy Fish"),
BESTIARY(9, Items.iron_sword, "§cBestiary"),
- CRIMSON_ISLE(10, Item.getItemFromBlock(Blocks.netherrack), "§4Crimson Isle");
+ CRIMSON_ISLE(10, Item.getItemFromBlock(Blocks.netherrack), "§4Crimson Isle"),
+ MUSEUM(11, Items.leather_chestplate, "§6Museum");
public final ItemStack stack;
public final int id;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MuseumPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MuseumPage.java
new file mode 100644
index 00000000..0b68f798
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MuseumPage.java
@@ -0,0 +1,536 @@
+/*
+ * Copyright (C) 2023 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.profileviewer;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.ResourceLocation;
+import org.apache.commons.lang3.tuple.Pair;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.input.Mouse;
+import org.lwjgl.opengl.GL11;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import static io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer.pv_elements;
+
+public class MuseumPage extends GuiProfileViewerPage {
+ private static final ResourceLocation pv_inventories =
+ new ResourceLocation("notenoughupdates:pv_inventories.png");
+ private static final ResourceLocation pv_museum = new ResourceLocation("notenoughupdates:pv_museum.png");
+ private static final LinkedHashMap<String, ItemStack> museumCategories = new LinkedHashMap<String, ItemStack>() {
+ {
+ put("weapons", Utils.createItemStack(Items.diamond_sword, EnumChatFormatting.GOLD + "Weapons"));
+ put("armor", Utils.createItemStack(Items.diamond_chestplate, EnumChatFormatting.GOLD + "Armor Sets"));
+ put(
+ "rarities", Utils.createSkull(
+ EnumChatFormatting.GOLD + "Rarities",
+ "b569ed03-94ae-3da9-a01d-9726633d5b8b",
+ "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODZhZGRiZDVkZWRhZDQwOTk5NDczYmU0YTdmNDhmNjIzNmE3OWEwZGNlOTcxYjVkYmQ3MzcyMDE0YWUzOTRkIn19fQ"
+ )
+ );
+ put("special", Utils.createItemStack(Items.cake, EnumChatFormatting.GOLD + "Special Items"));
+ }
+ };
+ private static final ResourceLocation CHEST_GUI_TEXTURE =
+ new ResourceLocation("textures/gui/container/generic_54.png");
+ private static String selectedMuseumCategory = "weapons";
+ JsonObject museum = Constants.MUSEUM;
+ int pageArrowsHeight = 164;
+ int pages = 0;
+ int onPage = 0;
+ String currentItemSelected = null;
+ JsonArray selectedItem = null;
+
+ public MuseumPage(GuiProfileViewer instance) {super(instance);}
+
+ @Override
+ public void drawPage(int mouseX, int mouseY, float partialTicks) {
+ int guiLeft = GuiProfileViewer.getGuiLeft();
+ int guiTop = GuiProfileViewer.getGuiTop();
+
+ SkyblockProfiles.SkyblockProfile selectedProfile = getSelectedProfile();
+ if (selectedProfile == null) {
+ return;
+ }
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(pv_museum);
+ Utils.drawTexturedRect(guiLeft, guiTop, getInstance().sizeX, getInstance().sizeY, GL11.GL_NEAREST);
+
+ SkyblockProfiles.SkyblockProfile.MuseumData museumData = selectedProfile.getMuseumData();
+ long value = museumData.getValue();
+
+ if (value == -2) {
+ String message = EnumChatFormatting.RED + "Museum API Disabled!";
+ Utils.drawStringCentered(message, guiLeft + 250, guiTop + 101, true, 0);
+ return;
+ }
+ if (value == -1) {
+ String message = EnumChatFormatting.YELLOW + "Museum Data Loading!";
+ Utils.drawStringCentered(message, guiLeft + 250, guiTop + 101, true, 0);
+ return;
+ }
+ if (value == -3 || museum == null) {
+ String message = EnumChatFormatting.RED + "Missing Repo Data!";
+ Utils.drawStringCentered(message, guiLeft + 250, guiTop + 101, true, 0);
+ return;
+ }
+
+ int xIndex = 0;
+ for (Map.Entry<String, ItemStack> entry : museumCategories.entrySet()) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements);
+
+ if (entry.getKey().equals(selectedMuseumCategory)) {
+ Utils.drawTexturedRect(
+ guiLeft + 16 + 34 * xIndex,
+ guiTop + 172,
+ 20,
+ 20,
+ 20 / 256f,
+ 0,
+ 20 / 256f,
+ 0,
+ GL11.GL_NEAREST
+ );
+ Utils.drawItemStackWithText(entry.getValue(), guiLeft + 19 + 34 * xIndex, guiTop + 175, "" + (xIndex + 1));
+ } else {
+ Utils.drawTexturedRect(
+ guiLeft + 16 + 34 * xIndex,
+ guiTop + 172,
+ 20,
+ 20,
+ 0,
+ 20 / 256f,
+ 0,
+ 20 / 256f,
+ GL11.GL_NEAREST
+ );
+ Utils.drawItemStackWithText(entry.getValue(), guiLeft + 18 + 34 * xIndex, guiTop + 174, "" + (xIndex + 1));
+ }
+ xIndex++;
+ }
+
+ Utils.renderAlignedString(
+ EnumChatFormatting.GOLD + "Museum Value",
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(value),
+ guiLeft + 21,
+ guiTop + 25,
+ 114
+ );
+
+ int donated =
+ museumData.getWeaponItems().size() + museumData.getArmorItems().size() + museumData.getRaritiesItems().size();
+ Utils.renderAlignedString(
+ EnumChatFormatting.BLUE + "Total Donations",
+ EnumChatFormatting.WHITE + "" + donated,
+ guiLeft + 21,
+ guiTop + 45,
+ 114
+ );
+ int maximum = getMaximum("total");
+ getInstance().renderBar(guiLeft + 20, guiTop + 55, 116, (float) donated / maximum);
+
+ donated = museumData.getWeaponItems().size();
+ Utils.renderAlignedString(
+ EnumChatFormatting.BLUE + "Weapons Donated",
+ EnumChatFormatting.WHITE + "" + donated,
+ guiLeft + 21,
+ guiTop + 70,
+ 114
+ );
+ maximum = getMaximum("weapons");
+ getInstance().renderBar(guiLeft + 20, guiTop + 80, 116, (float) donated / maximum);
+
+ donated = museumData.getArmorItems().size();
+ Utils.renderAlignedString(
+ EnumChatFormatting.BLUE + "Armor Donated",
+ EnumChatFormatting.WHITE + "" + donated,
+ guiLeft + 21,
+ guiTop + 95,
+ 114
+ );
+ maximum = getMaximum("armor");
+ getInstance().renderBar(guiLeft + 20, guiTop + 105, 116, (float) donated / maximum);
+
+ donated = museumData.getRaritiesItems().size();
+ Utils.renderAlignedString(
+ EnumChatFormatting.BLUE + "Rarities Donated",
+ EnumChatFormatting.WHITE + "" + donated,
+ guiLeft + 21,
+ guiTop + 120,
+ 114
+ );
+ maximum = getMaximum("rarities");
+ getInstance().renderBar(guiLeft + 20, guiTop + 130, 116, (float) donated / maximum);
+
+ donated = museumData.getSpecialItems().size();
+ Utils.renderAlignedString(
+ EnumChatFormatting.BLUE + "Special Items Donated",
+ EnumChatFormatting.WHITE + String.valueOf(donated),
+ guiLeft + 21,
+ guiTop + 145,
+ 114
+ );
+
+ Utils.drawStringCentered(
+ museumCategories.get(selectedMuseumCategory).getDisplayName(),
+ guiLeft + 251, guiTop + 14, true, 4210752
+ );
+
+ if (pages == 0) {
+ setPage(selectedMuseumCategory);
+ }
+
+ boolean leftHovered = false;
+ boolean rightHovered = false;
+ if (Mouse.isButtonDown(0)) {
+ if (mouseY > guiTop + pageArrowsHeight && mouseY < guiTop + pageArrowsHeight + 16) {
+ if (mouseX > guiLeft + 251 - 12 && mouseX < guiLeft + 251 + 12) {
+ if (mouseX < guiLeft + 251) {
+ leftHovered = true;
+ } else {
+ rightHovered = true;
+ }
+ }
+ }
+ }
+ Minecraft.getMinecraft().getTextureManager().bindTexture(GuiProfileViewer.resource_packs);
+
+ if (onPage > 0) {
+ Utils.drawTexturedRect(
+ guiLeft + 251 - 12,
+ guiTop + pageArrowsHeight,
+ 12,
+ 16,
+ 29 / 256f,
+ 53 / 256f,
+ !leftHovered ? 0 : 32 / 256f,
+ !leftHovered ? 32 / 256f : 64 / 256f,
+ GL11.GL_NEAREST
+ );
+ }
+ if (onPage < pages && pages > 1) {
+ Utils.drawTexturedRect(
+ guiLeft + 251,
+ guiTop + pageArrowsHeight,
+ 12,
+ 16,
+ 5 / 256f,
+ 29 / 256f,
+ !rightHovered ? 0 : 32 / 256f,
+ !rightHovered ? 32 / 256f : 64 / 256f,
+ GL11.GL_NEAREST
+ );
+ }
+
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
+
+ int inventoryRows = 4;
+ int invSizeY = inventoryRows * 18 + 17 + 7;
+
+ int inventoryX = guiLeft + 251 - 176 / 2;
+ int inventoryY = guiTop + 101 - invSizeY / 2;
+ getInstance().drawTexturedModalRect(inventoryX, inventoryY, 0, 0, 176, inventoryRows * 18 + 17);
+ getInstance().drawTexturedModalRect(inventoryX, inventoryY + inventoryRows * 18 + 17, 0, 215, 176, 7);
+
+ JsonArray categoryItems = new JsonArray();
+ Map<String, JsonArray> categoryDonated = new HashMap<>();
+ switch (selectedMuseumCategory) {
+ case "weapons":
+ categoryItems = museum.get("weapons").getAsJsonArray();
+ categoryDonated = museumData.getWeaponItems();
+ break;
+ case "armor":
+ categoryItems = museum.get("armor").getAsJsonArray();
+ categoryDonated = museumData.getArmorItems();
+ break;
+ case "rarities":
+ categoryItems = museum.get("rarities").getAsJsonArray();
+ categoryDonated = museumData.getRaritiesItems();
+ break;
+ case "special":
+ pages = (int) Math.floor(donated / 28.0);
+
+ List<JsonArray> specialItems = museumData.getSpecialItems();
+
+ int startIndex = onPage * 28;
+ int endIndex = Math.min(startIndex + 28, specialItems.size());
+
+ int row = 0;
+ int slot = 0;
+ for (int i = startIndex; i < endIndex; i++) {
+ JsonArray items = specialItems.get(i);
+ JsonObject item = (JsonObject) items.get(0);
+ ItemStack stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(item, true);
+
+ if (slot % 7 == 0 && slot > 1) {
+ slot = 0;
+ row++;
+ }
+
+ int x = guiLeft + (inventoryX - guiLeft) + 8 + (slot * 18) + 18;
+ int y = guiTop + 71 + (row * 18);
+ slot++;
+
+ if ((mouseX >= x && mouseX <= x + 16) &&
+ (mouseY >= y && mouseY <= y + 16)) {
+ getInstance().tooltipToDisplay = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ String itemID = item.get("internalname").getAsString();
+ if (Mouse.isButtonDown(0) && museumData.getSavedItems().containsKey(itemID)) {
+ selectedItem = items;
+ currentItemSelected = itemID;
+ }
+ }
+ Utils.drawItemStack(stack, x, y);
+ }
+ break;
+ default:
+ }
+
+ if (categoryItems != null) {
+ int row = 0;
+ int slot = 0;
+ int startIndex = onPage * 28;
+ int endIndex = Math.min(startIndex + 28, categoryItems.size());
+ for (int i = startIndex; i < endIndex; i++) {
+ boolean actualItem = false;
+ JsonElement donatedItem = categoryItems.get(i);
+ String itemID = donatedItem.getAsString();
+
+ if (slot % 7 == 0 && slot > 1) {
+ slot = 0;
+ row++;
+ }
+
+ int x = guiLeft + (inventoryX - guiLeft) + 8 + (slot * 18) + 18;
+ int y = guiTop + 71 + (row * 18);
+ slot++;
+
+ JsonObject nameMappings = museum.get("armor_to_id").getAsJsonObject();
+ String mappedName = itemID;
+ if (nameMappings.has(itemID)) {
+ mappedName = nameMappings.get(itemID).getAsString();
+ }
+ String displayName = NotEnoughUpdates.INSTANCE.manager.getDisplayName(mappedName);
+
+ ItemStack stack = Utils.createItemStack(Items.dye, displayName, 8, EnumChatFormatting.RED + "Missing");
+ JsonArray items = new JsonArray();
+ if (categoryDonated.containsKey(itemID)) {
+ items = categoryDonated.get(itemID);
+ JsonObject item = (JsonObject) items.get(0);
+ if (!Objects.equals(item.get("internalname").getAsString(), "_")) {
+ actualItem = true;
+ }
+ stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(item, true);
+ }
+
+ if ((mouseX >= x && mouseX <= x + 16) &&
+ (mouseY >= y && mouseY <= y + 16)) {
+ if (Mouse.isButtonDown(0) && museumData.getSavedItems().containsKey(itemID) && actualItem) {
+ selectedItem = items;
+ currentItemSelected = itemID;
+ }
+ getInstance().tooltipToDisplay = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ }
+ Utils.drawItemStack(stack, x, y);
+ }
+ }
+
+ if (currentItemSelected != null) {
+ int size = selectedItem.size();
+ int startX = guiLeft + 375 + 5;
+ Minecraft.getMinecraft().getTextureManager().bindTexture(pv_inventories);
+ switch (size) {
+ case 1:
+ Utils.drawTexturedRect(
+ guiLeft + 375,
+ guiTop + 100,
+ 26,
+ 32,
+ 75 / 101f,
+ 1,
+ 69 / 101f,
+ 1,
+ GL11.GL_NEAREST
+ );
+ break;
+ case 3:
+ Utils.drawTexturedRect(
+ guiLeft + 375,
+ guiTop + 100,
+ 26,
+ 68,
+ 75 / 101f,
+ 1,
+ 0,
+ 68 / 101f,
+ GL11.GL_NEAREST
+ );
+ break;
+ case 4:
+ Utils.drawTexturedRect(
+ guiLeft + 375,
+ guiTop + 100,
+ 26,
+ 86,
+ 47 / 101f,
+ 73 / 101f,
+ 0,
+ 86 / 101f,
+ GL11.GL_NEAREST
+ );
+ break;
+ case 8:
+ Utils.drawTexturedRect(
+ guiLeft + 365,
+ guiTop + 100,
+ 45,
+ 86,
+ 0,
+ 45 / 101f,
+ 0,
+ 86 / 101f,
+ GL11.GL_NEAREST
+ );
+ startX = guiLeft + 365 + 5;
+ break;
+ default:
+ }
+
+ int startY = guiTop + 100 + 8;
+ int row = 0;
+ int column = 0;
+ for (int i = 0; i < size; i++) {
+ JsonObject item = (JsonObject) selectedItem.get(i);
+
+ if (row % 4 == 0 && row > 1) {
+ column = 1;
+ row = 0;
+ }
+
+ int x = startX + (column * 18);
+ int y = startY + (row * 18);
+
+ ItemStack stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(item, true);
+ Utils.drawItemStack(stack, x, y);
+
+ if ((mouseX >= x && mouseX <= x + 16) &&
+ (mouseY >= y && mouseY <= y + 16)) {
+ getInstance().tooltipToDisplay = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ }
+ row++;
+ }
+
+ Pair<Long, Boolean> itemData = museumData.getSavedItems().get(currentItemSelected);
+ String donationStatus =
+ itemData.getRight() ? EnumChatFormatting.YELLOW + "Borrowing" : EnumChatFormatting.GREEN + "In Museum";
+ String donationTime = Utils.timeSinceMillisecond(itemData.getLeft());
+
+ Utils.drawStringCentered(EnumChatFormatting.BLUE + "Donated", guiLeft + 391, guiTop + 35, true, 4210752);
+ Utils.drawStringCentered(EnumChatFormatting.WHITE + donationTime, guiLeft + 391, guiTop + 47, true, 4210752);
+ Utils.drawStringCentered(EnumChatFormatting.BLUE + "Currently", guiLeft + 391, guiTop + 70, true, 4210752);
+ Utils.drawStringCentered(donationStatus, guiLeft + 391, guiTop + 82, true, 4210752);
+ }
+ }
+
+ @Override
+ public void mouseReleased(int mouseX, int mouseY, int mouseButton) {
+ int guiLeft = GuiProfileViewer.getGuiLeft();
+ int guiTop = GuiProfileViewer.getGuiTop();
+ int xIndex = 0;
+ for (Map.Entry<String, ItemStack> entry : museumCategories.entrySet()) {
+ if (mouseX > guiLeft + 16 + 34 * xIndex && mouseX < guiLeft + 16 + 34 * xIndex + 20) {
+ if (mouseY > guiTop + 172 && mouseY < guiTop + 172 + 20) {
+ setPage(entry.getKey());
+ Utils.playPressSound();
+ return;
+ }
+ }
+ xIndex++;
+ }
+
+ if (mouseY > guiTop + pageArrowsHeight && mouseY < guiTop + pageArrowsHeight + 16) {
+ if (mouseX > guiLeft + 251 - 12 && mouseX < guiLeft + 251 + 12) {
+ if (mouseX < guiLeft + 251) {
+ if (onPage > 0) onPage--;
+ } else {
+ if (onPage < pages) onPage++;
+ }
+ }
+ }
+ }
+
+ @Override
+ public void keyTyped(char typedChar, int keyCode) throws IOException {
+ switch (keyCode) {
+ case Keyboard.KEY_1:
+ case Keyboard.KEY_NUMPAD1:
+ setPage("weapons");
+ break;
+ case Keyboard.KEY_2:
+ case Keyboard.KEY_NUMPAD2:
+ setPage("armor");
+ break;
+ case Keyboard.KEY_3:
+ case Keyboard.KEY_NUMPAD3:
+ setPage("rarities");
+ break;
+ case Keyboard.KEY_4:
+ case Keyboard.KEY_NUMPAD4:
+ setPage("special");
+ break;
+ default:
+ return;
+ }
+ Utils.playPressSound();
+ }
+
+ private void setPage(String pageName) {
+ selectedMuseumCategory = pageName;
+ onPage = 0;
+ pages = (int) Math.floor(getMaximum(pageName) / 28.0);
+ }
+
+ private int getMaximum(String name) {
+ if (museum != null && museum.has("max_values")) {
+ JsonObject maxValues = museum.get("max_values").getAsJsonObject();
+ if (maxValues.has(name)) {
+ return maxValues.get(name).getAsInt();
+ }
+ }
+ return 0;
+ }
+}
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 1d8def80..88251d32 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/SkyblockProfiles.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/SkyblockProfiles.java
@@ -31,11 +31,13 @@ import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
import io.github.moulberry.notenoughupdates.util.hypixelapi.ProfileCollectionInfo;
import lombok.Getter;
+import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumChatFormatting;
+import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nullable;
import java.io.ByteArrayInputStream;
@@ -48,6 +50,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
public class SkyblockProfiles {
@@ -484,6 +487,180 @@ public class SkyblockProfiles {
private PlayerStats.Stats stats;
private Long networth = null;
private SoopyNetworth soopyNetworth = null;
+ private MuseumData museumData = null;
+ private final AtomicBoolean updatingMuseumData = new AtomicBoolean(false);
+
+ public class MuseumData {
+ private long museumValue;
+ private final Map<String, JsonArray> weaponItems = new HashMap<>();
+ private final Map<String, JsonArray> armorItems = new HashMap<>();
+ private final Map<String, JsonArray> raritiesItems = new HashMap<>();
+ private final List<JsonArray> specialItems = new ArrayList<>();
+ private final Map<String, Pair<Long, Boolean>> savedItems = new HashMap<>();
+
+ private MuseumData(JsonObject museumJson) {
+ JsonObject museum = Constants.MUSEUM;
+ if (museum == null) {
+ Utils.showOutdatedRepoNotification();
+ museumValue = -3;
+ return;
+ }
+ if (museumJson == null || museumJson.isJsonNull() || museumJson.get("members").isJsonNull()) {
+ museumValue = -2;
+ return;
+ }
+ JsonObject members = museumJson.get("members").getAsJsonObject();
+ if (members == null || members.isJsonNull() || !members.has(uuid)) {
+ museumValue = -2;
+ return;
+ }
+ JsonObject member = members.get(uuid).getAsJsonObject();
+ if (member == null || member.isJsonNull() || !member.has("value")) {
+ museumValue = -2;
+ return;
+ }
+ museumValue = member.get("value").getAsLong();
+ if (member.has("items")) {
+ JsonObject museumItemsData = member.get("items").getAsJsonObject();
+ if (museumItemsData != null) {
+ for (Map.Entry<String, JsonElement> entry : museumItemsData.entrySet()) {
+ JsonObject itemJson = entry.getValue().getAsJsonObject();
+ JsonArray contents = parseNbt(itemJson);
+ String itemName = entry.getKey();
+ Long donationTime = itemJson.get("donated_time").getAsLong();
+ boolean borrowing = false;
+ if (itemJson.has("borrowing")) {
+ borrowing = itemJson.get("borrowing").getAsBoolean();
+ }
+
+ getDataAndChildren(itemName, Pair.of(donationTime, borrowing));
+ processItems(itemName, contents);
+ }
+ }
+ }
+
+ if (member.has("special")) {
+ JsonArray specialItemsData = member.get("special").getAsJsonArray();
+ if (specialItemsData != null) {
+ for (JsonElement element : specialItemsData) {
+ JsonObject itemData = element.getAsJsonObject();
+ JsonArray contents = parseNbt(itemData);
+
+ long donationTime = itemData.get("donated_time").getAsLong();
+ JsonObject firstItem = contents.get(0).getAsJsonObject();
+ String itemID = firstItem.get("internalname").getAsString();
+ getDataAndChildren(itemID, Pair.of(donationTime, false));
+
+ specialItems.add(contents);
+ }
+ }
+ }
+ }
+
+ private JsonArray parseNbt(JsonObject nbt) {
+ JsonArray contents = new JsonArray();
+ JsonObject contentItems = nbt.get("items").getAsJsonObject();
+ String contentBytes = contentItems.get("data").getAsString();
+
+ try {
+ NBTTagList items = CompressedStreamTools.readCompressed(
+ new ByteArrayInputStream(Base64.getDecoder().decode(contentBytes))
+ ).getTagList("i", 10);
+ for (int j = 0; j < items.tagCount(); j++) {
+ JsonObject item = profileViewer.getManager().getJsonFromNBTEntry(items.getCompoundTagAt(j));
+ if (item == null) {
+ continue;
+ }
+ contents.add(item);
+ }
+ } catch (IOException ignored) {
+ }
+ return contents;
+ }
+
+ private void processItems(String itemName, JsonArray contents) {
+ JsonObject museum = Constants.MUSEUM;
+ storeItem(itemName, contents, museum.get("weapons").getAsJsonArray(), weaponItems);
+ storeItem(itemName, contents, museum.get("armor").getAsJsonArray(), armorItems);
+ storeItem(itemName, contents, museum.get("rarities").getAsJsonArray(), raritiesItems);
+ }
+
+ private void storeItem(String itemName, JsonArray contents, JsonArray items, Map<String, JsonArray> itemMap) {
+ for (JsonElement item : items) {
+ if (Objects.equals(item.getAsString(), itemName)) {
+ itemMap.put(itemName, contents);
+ return;
+ }
+ }
+ }
+
+ private void getDataAndChildren(String name, Pair<Long, Boolean> itemData) {
+ JsonObject children = Constants.MUSEUM.get("children").getAsJsonObject();
+ if (savedItems.containsKey(name)) return;
+ savedItems.put(name, itemData);
+ if (children.has(name)) {
+ String childId = children.get(name).getAsString();
+ String childName = childId;
+ JsonObject nameMappings = Constants.MUSEUM.get("armor_to_id").getAsJsonObject();
+ if (nameMappings.has(childId)) {
+ childName = nameMappings.get(childId).getAsString();
+ }
+ String displayName = NotEnoughUpdates.INSTANCE.manager.getDisplayName(childName);
+ ItemStack stack = Utils.createItemStack(Items.dye, displayName, 10, "Donated as higher tier");
+ JsonObject item = profileViewer.getManager().getJsonForItem(stack);
+ item.add("internalname", new JsonPrimitive("_"));
+ JsonArray itemArray = new JsonArray();
+ itemArray.add(item);
+ processItems(childId, itemArray);
+
+ getDataAndChildren(childId, itemData);
+ }
+ }
+
+ private MuseumData asLoading() {
+ museumValue = -1;
+ return this;
+ }
+
+ public long getValue() {
+ return museumValue;
+ }
+ public Map<String, JsonArray> getWeaponItems() {
+ return weaponItems;
+ }
+ public Map<String, JsonArray> getArmorItems() {
+ return armorItems;
+ }
+ public Map<String, JsonArray> getRaritiesItems() {
+ return raritiesItems;
+ }
+ public List<JsonArray> getSpecialItems() {
+ return specialItems;
+ }
+ public Map<String, Pair<Long, Boolean>> getSavedItems() {
+ return savedItems;
+ }
+ }
+
+ private void loadMuseumData() {
+ if (updatingMuseumData.get()) {
+ return;
+ }
+
+ updatingMuseumData.set(true);
+ String profileId = getOuterProfileJson().get("profile_id").getAsString();
+ profileViewer.getManager().apiUtils.newHypixelApiRequest("skyblock/museum")
+ .queryArgument("profile", profileId)
+ .requestJson()
+ .handle((museumJson, throwable) -> {
+ if (museumJson != null && museumJson.has("success")
+ && museumJson.get("success").getAsBoolean() && museumJson.has("members")) {
+ museumData = new MuseumData(museumJson);
+ return null;
+ }
+ return null;
+ });
+ }
public SkyblockProfile(JsonObject outerProfileJson) {
this.outerProfileJson = outerProfileJson;
@@ -986,5 +1163,14 @@ public class SkyblockProfiles {
loadSoopyData(callback);
return new SoopyNetworth(null).asLoading();
}
+
+ public MuseumData getMuseumData() {
+ if (museumData != null) {
+ return museumData;
+ }
+
+ loadMuseumData();
+ return new MuseumData(null).asLoading();
+ }
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java
index 6819ccc4..5f1cc247 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java
@@ -82,6 +82,7 @@ public class Constants {
public static JsonObject ABIPHONE;
public static JsonObject ESSENCESHOPS;
public static JsonObject SBLEVELS;
+ public static JsonObject MUSEUM;
private static final ReentrantLock lock = new ReentrantLock();
@@ -107,6 +108,7 @@ public class Constants {
ABIPHONE = Utils.getConstant("abiphone", gson);
ESSENCESHOPS = Utils.getConstant("essenceshops", gson);
SBLEVELS = Utils.getConstant("sblevels", gson);
+ MUSEUM = Utils.getConstant("museum", gson);
parseEssenceCosts();
} catch (Exception ex) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
index 54888935..7f607ab7 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
@@ -85,11 +85,16 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.text.DecimalFormat;
import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.TimeZone;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -2257,4 +2262,25 @@ public class Utils {
slot, 0, 0, Minecraft.getMinecraft().thePlayer
);
}
+
+ public static String timeSinceMillisecond(long time) {
+ Instant lastSave = Instant.ofEpochMilli(time);
+ LocalDateTime lastSaveTime = LocalDateTime.ofInstant(lastSave, TimeZone.getDefault().toZoneId());
+ long timeDiff = System.currentTimeMillis() - lastSave.toEpochMilli();
+ LocalDateTime sinceOnline = LocalDateTime.ofInstant(Instant.ofEpochMilli(timeDiff), ZoneId.of("UTC"));
+ String renderText;
+
+ if (timeDiff < 60000L) {
+ renderText = sinceOnline.getSecond() + " seconds ago";
+ } else if (timeDiff < 3600000L) {
+ renderText = sinceOnline.getMinute() + " minutes ago";
+ } else if (timeDiff < 86400000L) {
+ renderText = sinceOnline.getHour() + " hours ago";
+ } else if (timeDiff < 31556952000L) {
+ renderText = sinceOnline.getDayOfYear() + " days ago";
+ } else {
+ renderText = lastSaveTime.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));
+ }
+ return renderText;
+ }
}
diff --git a/src/main/resources/assets/notenoughupdates/pv_inventories.png b/src/main/resources/assets/notenoughupdates/pv_inventories.png
new file mode 100644
index 00000000..a4308e49
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/pv_inventories.png
Binary files differ
diff --git a/src/main/resources/assets/notenoughupdates/pv_museum.png b/src/main/resources/assets/notenoughupdates/pv_museum.png
new file mode 100644
index 00000000..eb988155
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/pv_museum.png
Binary files differ