/*
* Copyright (C) 2022 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 .
*/
package io.github.moulberry.notenoughupdates.util;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.inventory.ContainerChest;
import net.minecraftforge.client.event.ClientChatReceivedEvent;
import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
public class HotmInformation {
private final NotEnoughUpdates neu;
public static final int[] EXPERIENCE_FOR_HOTM_LEVEL = {
// Taken from the wiki: https://hypixel-skyblock.fandom.com/wiki/Heart_of_the_Mountain#Experience_for_Each_Tier
0,
3000,
12000,
37000,
97000,
197000,
347000
};
public static final int[] QUICK_FORGE_MULTIPLIERS = {
985,
970,
955,
940,
925,
910,
895,
880,
865,
850,
845,
840,
835,
830,
825,
820,
815,
810,
805,
700
};
private final Map profiles = new ConcurrentHashMap<>();
public static class Tree {
private final Map levels = new HashMap<>();
private int totalMithrilPowder;
private int totalGemstonePowder;
private int hotmExp;
public int getHotmExp() {
return hotmExp;
}
public int getTotalGemstonePowder() {
return totalGemstonePowder;
}
public int getTotalMithrilPowder() {
return totalMithrilPowder;
}
public Set getAllUnlockedNodes() {
return levels.keySet();
}
public int getHotmLevel() {
for (int i = EXPERIENCE_FOR_HOTM_LEVEL.length - 1; i >= 0; i--) {
if (EXPERIENCE_FOR_HOTM_LEVEL[i] >= this.hotmExp)
return i;
}
return 0;
}
public int getLevel(String node) {
return levels.getOrDefault(node, 0);
}
}
private CompletableFuture updateTask = CompletableFuture.completedFuture(null);
private boolean shouldReloadSoon = false;
public HotmInformation(NotEnoughUpdates neu) {
this.neu = neu;
MinecraftForge.EVENT_BUS.register(this);
}
public Optional getInformationOn(String profile) {
if (profile == null) {
return Optional.empty();
}
return Optional.ofNullable(this.profiles.get(profile));
}
public Optional getInformationOnCurrentProfile() {
return getInformationOn(neu.manager.getCurrentProfile());
}
@SubscribeEvent
public synchronized void onLobbyJoin(WorldEvent.Load event) {
if (shouldReloadSoon) {
shouldReloadSoon = false;
requestUpdate(false);
}
}
@SubscribeEvent
public synchronized void onGuiOpen(GuiOpenEvent event) {
if (event.gui instanceof GuiChest) {
String containerName = ((ContainerChest) ((GuiChest) event.gui).inventorySlots)
.getLowerChestInventory()
.getDisplayName()
.getUnformattedText();
if (containerName.equals("Heart of the Mountain"))
shouldReloadSoon = true;
}
}
@SubscribeEvent
public synchronized void onChat(ClientChatReceivedEvent event) {
if (event.message.getUnformattedText().equals("Welcome to Hypixel SkyBlock!"))
requestUpdate(false);
}
public synchronized void requestUpdate(boolean force) {
if (updateTask.isDone() || force) {
updateTask = neu.manager.hypixelApi.getHypixelApiAsync(
neu.config.apiData.apiKey,
"skyblock/profiles",
new HashMap() {{
put("uuid", Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""));
}}
).thenAccept(this::updateInformation);
}
}
/*
* 1000 = 100% of the time left
* 700 = 70% of the time left
* */
public static int getQuickForgeMultiplier(int level) {
if (level <= 0) return 1000;
if (level > 20) return -1;
return QUICK_FORGE_MULTIPLIERS[level - 1];
}
public void updateInformation(JsonObject entireApiResponse) {
if (!entireApiResponse.has("success") || !entireApiResponse.get("success").getAsBoolean()) return;
JsonArray profiles = entireApiResponse.getAsJsonArray("profiles");
for (JsonElement element : profiles) {
JsonObject profile = element.getAsJsonObject();
String profileName = profile.get("cute_name").getAsString();
JsonObject player = profile.getAsJsonObject("members").getAsJsonObject(Minecraft.getMinecraft().thePlayer
.getUniqueID()
.toString()
.replace("-", ""));
if (!player.has("mining_core"))
continue;
JsonObject miningCore = player.getAsJsonObject("mining_core");
Tree tree = new Tree();
JsonObject nodes = miningCore.getAsJsonObject("nodes");
for (Map.Entry node : nodes.entrySet()) {
tree.levels.put(node.getKey(), node.getValue().getAsInt());
}
if (miningCore.has("powder_mithril_total")) {
tree.totalMithrilPowder = miningCore.get("powder_mithril_total").getAsInt();
}
if (miningCore.has("powder_gemstone_total")) {
tree.totalGemstonePowder = miningCore.get("powder_gemstone_total").getAsInt();
}
if (miningCore.has("experience")) {
tree.hotmExp = miningCore.get("experience").getAsInt();
}
this.profiles.put(profileName, tree);
}
}
}