From dd7a4209752715db544b2fef804da9762c532cdc Mon Sep 17 00:00:00 2001
From: kokoniara <70776766+kingstefan26@users.noreply.github.com>
Date: Fri, 7 Oct 2022 14:50:22 +0200
Subject: fix player profile not never loading in chat (#63)
* fix player profile not never loading in chat
* cut out hychat like a cancer
* ApiFetchur now caches whole players not single profiles,
added a switch profile button in gui
* ugh git
* Revert "cut out hychat like a cancer"
This reverts commit 2ee11afa
* ugh git x2
* I tried, good luck maintaining this
* forgot to uncomment hychat fix
* now shows which profile is now selected
put button on top
a lil refactor
* fix player profile sometimes not loading
Co-authored-by: syeyoung <42869671+cyoung06@users.noreply.github.com>
---
.../commands/CommandDungeonsGuide.java | 22 +-
.../dungeonsguide/features/FeatureRegistry.java | 4 +-
.../impl/etc/FeatureAutoAcceptReparty.java | 2 -
.../features/impl/party/FeatureGoodParties.java | 11 -
.../features/impl/party/api/ApiFetchur.java | 697 --------------------
.../features/impl/party/api/CachedData.java | 29 -
.../features/impl/party/api/ClassSpecificData.java | 29 -
.../features/impl/party/api/DungeonClass.java | 46 --
.../impl/party/api/DungeonSpecificData.java | 29 -
.../features/impl/party/api/DungeonStat.java | 54 --
.../features/impl/party/api/DungeonType.java | 39 --
.../features/impl/party/api/FloorSpecificData.java | 29 -
.../dungeonsguide/features/impl/party/api/Pet.java | 31 -
.../features/impl/party/api/PlayerProfile.java | 91 ---
.../features/impl/party/api/Skill.java | 32 -
.../features/impl/party/api/SkinFetchur.java | 89 ---
.../party/customgui/PanelPartyFinderSettings.java | 1 -
.../playerpreview/DataRenderDungeonFloorStat.java | 100 ---
.../DataRenderDungeonHighestFloorStat.java | 102 ---
.../impl/party/playerpreview/DataRenderer.java | 33 -
.../party/playerpreview/DataRendererClassLv.java | 85 ---
.../party/playerpreview/DataRendererDungeonLv.java | 81 ---
.../party/playerpreview/DataRendererEditor.java | 356 -----------
.../playerpreview/DataRendererFairySouls.java | 49 --
.../playerpreview/DataRendererLilyWeight.java | 72 ---
.../party/playerpreview/DataRendererRegistry.java | 63 --
.../party/playerpreview/DataRendererSecrets.java | 53 --
.../playerpreview/DataRendererSelectedClassLv.java | 76 ---
.../party/playerpreview/DataRendererSetUrOwn.java | 56 --
.../party/playerpreview/DataRendererSkillLv.java | 79 ---
.../party/playerpreview/DataRendererTalismans.java | 123 ----
.../impl/party/playerpreview/FakePlayer.java | 101 +++
.../playerpreview/FeatureViewPlayerOnJoin.java | 620 ------------------
.../FeatureViewPlayerStatsOnJoin.java | 703 +++++++++++++++++++++
.../impl/party/playerpreview/api/ApiFetcher.java | 387 ++++++++++++
.../impl/party/playerpreview/api/CachedData.java | 29 +
.../playerpreview/api/PlayerSkyblockData.java | 10 +
.../impl/party/playerpreview/api/SkinFetcher.java | 90 +++
.../api/playerprofile/PlayerProfile.java | 92 +++
.../api/playerprofile/PlayerProfileParser.java | 449 +++++++++++++
.../dataclasses/ClassSpecificData.java | 29 +
.../playerprofile/dataclasses/DungeonClass.java | 46 ++
.../dataclasses/DungeonSpecificData.java | 29 +
.../api/playerprofile/dataclasses/DungeonStat.java | 54 ++
.../api/playerprofile/dataclasses/DungeonType.java | 39 ++
.../dataclasses/FloorSpecificData.java | 29 +
.../api/playerprofile/dataclasses/Pet.java | 31 +
.../api/playerprofile/dataclasses/Skill.java | 31 +
.../datarenders/DataRendererEditor.java | 357 +++++++++++
.../datarenders/DataRendererRegistry.java | 64 ++
.../playerpreview/datarenders/IDataRenderer.java | 33 +
.../impl/DataRenderDungeonFloorStat.java | 105 +++
.../impl/DataRenderDungeonHighestFloorStat.java | 107 ++++
.../datarenders/impl/DataRendererClassLv.java | 88 +++
.../datarenders/impl/DataRendererDungeonLv.java | 82 +++
.../datarenders/impl/DataRendererFairySouls.java | 50 ++
.../datarenders/impl/DataRendererLilyWeight.java | 71 +++
.../datarenders/impl/DataRendererSecrets.java | 53 ++
.../impl/DataRendererSelectedClassLv.java | 77 +++
.../datarenders/impl/DataRendererSetUrOwn.java | 57 ++
.../datarenders/impl/DataRendererSkillLv.java | 80 +++
.../datarenders/impl/DataRendererTalismans.java | 123 ++++
.../kr/syeyoung/dungeonsguide/utils/XPUtils.java | 2 +-
63 files changed, 3505 insertions(+), 3176 deletions(-)
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ApiFetchur.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/CachedData.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ClassSpecificData.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonClass.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonSpecificData.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonStat.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonType.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/FloorSpecificData.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/Pet.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/PlayerProfile.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/Skill.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/SkinFetchur.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonFloorStat.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonHighestFloorStat.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderer.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererClassLv.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererDungeonLv.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererEditor.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererFairySouls.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererLilyWeight.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererRegistry.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSecrets.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSelectedClassLv.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSetUrOwn.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSkillLv.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererTalismans.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/FakePlayer.java
delete mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/FeatureViewPlayerOnJoin.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/FeatureViewPlayerStatsOnJoin.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/ApiFetcher.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/CachedData.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/PlayerSkyblockData.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/SkinFetcher.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/PlayerProfile.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/PlayerProfileParser.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/ClassSpecificData.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonClass.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonSpecificData.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonStat.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonType.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/FloorSpecificData.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/Pet.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/Skill.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/DataRendererEditor.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/DataRendererRegistry.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/IDataRenderer.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRenderDungeonFloorStat.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRenderDungeonHighestFloorStat.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererClassLv.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererDungeonLv.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererFairySouls.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererLilyWeight.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSecrets.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSelectedClassLv.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSetUrOwn.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSkillLv.java
create mode 100644 src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererTalismans.java
(limited to 'src/main/java/kr')
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/commands/CommandDungeonsGuide.java b/src/main/java/kr/syeyoung/dungeonsguide/commands/CommandDungeonsGuide.java
index 50f5aa7f..95850fdc 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/commands/CommandDungeonsGuide.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/commands/CommandDungeonsGuide.java
@@ -40,8 +40,8 @@ import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoomInfoRegistry;
import kr.syeyoung.dungeonsguide.events.DungeonLeftEvent;
import kr.syeyoung.dungeonsguide.features.AbstractFeature;
import kr.syeyoung.dungeonsguide.features.FeatureRegistry;
-import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.FeatureViewPlayerOnJoin;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.ApiFetchur;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.FeatureViewPlayerStatsOnJoin;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.ApiFetcher;
import kr.syeyoung.dungeonsguide.roomedit.EditingContext;
import kr.syeyoung.dungeonsguide.roomedit.gui.GuiDungeonRoomEdit;
import kr.syeyoung.dungeonsguide.roomprocessor.GeneralRoomProcessor;
@@ -270,17 +270,7 @@ public class CommandDungeonsGuide extends CommandBase {
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §cNot in Party"));
return;
}
- for (String member : context.getPartyRawMembers()) {
- ApiFetchur.fetchUUIDAsync(member)
- .thenAccept(a -> {
- if (a == null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e"+member+"§f's Profile §cCouldn't fetch uuid"));
- } else {
- ApiFetchur.fetchMostRecentProfileAsync(a.get(), FeatureRegistry.PARTYKICKER_APIKEY.getAPIKey());
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e" + member + "§f's Profile ").appendSibling(new ChatComponentText("§7view").setChatStyle(new ChatStyle().setChatHoverEvent(new FeatureViewPlayerOnJoin.HoverEventRenderPlayer(a.orElse(null))))));
- }
- });
- }
+ FeatureViewPlayerStatsOnJoin.processPartyMembers(context);
});
// } else if (args[0].equals("fixschematic")) {
// File root = new File(e.getDungeonsGuide().getConfigDir(), "schematics");
@@ -388,15 +378,15 @@ public class CommandDungeonsGuide extends CommandBase {
}
} else if (args[0].equals("pv")) {
try {
- ApiFetchur.fetchUUIDAsync(args[1])
+ ApiFetcher.fetchUUIDAsync(args[1])
.thenAccept(a -> {
- sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e" + args[1] + "§f's Profile ").appendSibling(new ChatComponentText("§7view").setChatStyle(new ChatStyle().setChatHoverEvent(new FeatureViewPlayerOnJoin.HoverEventRenderPlayer(a.orElse(null))))));
+ sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e" + args[1] + "§f's Profile ").appendSibling(new ChatComponentText("§7view").setChatStyle(new ChatStyle().setChatHoverEvent(new FeatureViewPlayerStatsOnJoin.HoverEventRenderPlayer(a.orElse(null))))));
});
} catch (Exception e) {
e.printStackTrace();
}
} else if (args[0].equals("purge")) {
- ApiFetchur.purgeCache();
+ ApiFetcher.purgeCache();
CosmeticsManager cosmeticsManager = DungeonsGuide.getDungeonsGuide().getCosmeticsManager();
cosmeticsManager.requestPerms();
cosmeticsManager.requestCosmeticsList();
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java
index 7ef483e1..bf3be41d 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java
@@ -36,7 +36,7 @@ import kr.syeyoung.dungeonsguide.features.impl.party.APIKey;
import kr.syeyoung.dungeonsguide.features.impl.party.FeaturePartyList;
import kr.syeyoung.dungeonsguide.features.impl.party.FeaturePartyReady;
import kr.syeyoung.dungeonsguide.features.impl.party.customgui.FeatureCustomPartyFinder;
-import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.FeatureViewPlayerOnJoin;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.FeatureViewPlayerStatsOnJoin;
import kr.syeyoung.dungeonsguide.features.impl.secret.*;
import kr.syeyoung.dungeonsguide.features.impl.secret.mechanicbrowser.FeatureMechanicBrowse;
import kr.syeyoung.dungeonsguide.features.impl.solvers.*;
@@ -161,7 +161,7 @@ public class FeatureRegistry {
public static final FeatureSimonSaysSolver BOSSFIGHT_SIMONSAYS_SOLVER = register(new FeatureSimonSaysSolver());
public static final APIKey PARTYKICKER_APIKEY = register(new APIKey());
- public static final FeatureViewPlayerOnJoin PARTYKICKER_VIEWPLAYER = register(new FeatureViewPlayerOnJoin());
+ public static final FeatureViewPlayerStatsOnJoin PARTYKICKER_VIEWPLAYER = register(new FeatureViewPlayerStatsOnJoin());
public static final FeatureCustomPartyFinder PARTYKICKER_CUSTOM = register(new FeatureCustomPartyFinder());
public static final FeaturePartyList PARTY_LIST = register(new FeaturePartyList());
public static final FeaturePartyReady PARTY_READY = register(new FeaturePartyReady());
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/etc/FeatureAutoAcceptReparty.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/etc/FeatureAutoAcceptReparty.java
index 3a469793..0cb126ef 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/etc/FeatureAutoAcceptReparty.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/etc/FeatureAutoAcceptReparty.java
@@ -22,10 +22,8 @@ import kr.syeyoung.dungeonsguide.SkyblockStatus;
import kr.syeyoung.dungeonsguide.DungeonsGuide;
import kr.syeyoung.dungeonsguide.chat.ChatProcessor;
import kr.syeyoung.dungeonsguide.features.SimpleFeature;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.ApiFetchur;
import kr.syeyoung.dungeonsguide.features.listener.ChatListener;
import kr.syeyoung.dungeonsguide.utils.TextUtils;
-import net.minecraft.client.Minecraft;
import net.minecraftforge.client.event.ClientChatReceivedEvent;
public class FeatureAutoAcceptReparty extends SimpleFeature implements ChatListener {
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/FeatureGoodParties.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/FeatureGoodParties.java
index 7f292e13..6d33ebc9 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/FeatureGoodParties.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/FeatureGoodParties.java
@@ -18,22 +18,15 @@
package kr.syeyoung.dungeonsguide.features.impl.party;
-import kr.syeyoung.dungeonsguide.features.FeatureRegistry;
import kr.syeyoung.dungeonsguide.features.SimpleFeature;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.ApiFetchur;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.DungeonType;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile;
import kr.syeyoung.dungeonsguide.features.listener.GuiPostRenderListener;
-import kr.syeyoung.dungeonsguide.features.listener.TickListener;
import kr.syeyoung.dungeonsguide.utils.TextUtils;
-import kr.syeyoung.dungeonsguide.utils.XPUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.init.Items;
-import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerChest;
import net.minecraft.inventory.Slot;
import net.minecraft.nbt.NBTTagCompound;
@@ -42,10 +35,6 @@ import net.minecraftforge.client.event.GuiScreenEvent;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
public class FeatureGoodParties extends SimpleFeature implements GuiPostRenderListener {
public FeatureGoodParties() {
super("Party Kicker", "Highlight parties in party viewer", "Highlight parties you can't join with red", "partykicker.goodparty",true);
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ApiFetchur.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ApiFetchur.java
deleted file mode 100644
index 0d929697..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ApiFetchur.java
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.api;
-
-import com.google.gson.*;
-import com.mojang.authlib.GameProfile;
-import kr.syeyoung.dungeonsguide.utils.TextUtils;
-import kr.syeyoung.dungeonsguide.utils.XPUtils;
-import net.minecraft.client.Minecraft;
-import net.minecraft.init.Blocks;
-import net.minecraft.item.ItemStack;
-import net.minecraft.nbt.CompressedStreamTools;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.nbt.NBTTagList;
-import org.json.JSONObject;
-import scala.tools.cmd.Opt;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.function.BiFunction;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-public class ApiFetchur {
- private static final Gson gson = new Gson();
-
- private static final Map> playerProfileCache = new ConcurrentHashMap<>();
- private static final Map> nicknameToUID = new ConcurrentHashMap<>();
- private static final Map> UIDtoNickname = new ConcurrentHashMap<>();
- private static final Map> UIDtoGameProfile = new ConcurrentHashMap<>();
-
- private static final ExecutorService ex = Executors.newFixedThreadPool(4);
-
- private static final Set invalidKeys = new HashSet<>();
- public static void purgeCache() {
- playerProfileCache.clear();
- nicknameToUID.clear();
- UIDtoNickname.clear();
- UIDtoGameProfile.clear();
-
- completableFutureMap.clear();
- completableFutureMap2.clear();
- completableFutureMap3.clear();
- completableFutureMap4.clear();
- invalidKeys.clear();
- constants = null;
-
- ex.submit(ApiFetchur::getLilyWeightConstants);
- }
- static {
- ex.submit(ApiFetchur::getLilyWeightConstants);
- }
-
- public static JsonObject getJson(String url) throws IOException {
- URLConnection connection = new URL(url).openConnection();
- connection.setConnectTimeout(10000);
- connection.setReadTimeout(10000);
- return gson.fromJson(new InputStreamReader(connection.getInputStream()), JsonObject.class);
- }
- public static JsonArray getJsonArr(String url) throws IOException {
- URLConnection connection = new URL(url).openConnection();
- connection.setConnectTimeout(10000);
- connection.setReadTimeout(10000);
- return gson.fromJson(new InputStreamReader(connection.getInputStream()), JsonArray.class);
- }
-
- private static volatile JsonObject constants;
- public static JsonObject getLilyWeightConstants() {
- if (constants != null) return constants;
- try {
- JsonObject jsonObject = getJson("https://raw.githubusercontent.com/Antonio32A/lilyweight/master/lib/constants.json");
- constants = jsonObject;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- return constants;
- }
-
- private static final Map>> completableFutureMap4 = new ConcurrentHashMap<>();
- public static CompletableFuture> getSkinGameProfileByUUIDAsync(String uid) {
- if (UIDtoGameProfile.containsKey(uid)) {
- CachedData cachedData = UIDtoGameProfile.get(uid);
- if (cachedData.getExpire() > System.currentTimeMillis()) {
- return CompletableFuture.completedFuture(Optional.ofNullable(cachedData.getData()));
- }
- UIDtoGameProfile.remove(uid);
- }
- if (completableFutureMap4.containsKey(uid)) return completableFutureMap4.get(uid);
-
- CompletableFuture> completableFuture = new CompletableFuture<>();
- fetchNicknameAsync(uid).thenAccept(nick -> {
- if (!nick.isPresent()) {
- completableFuture.complete(Optional.empty());
- return;
- }
- ex.submit(() -> {
- try {
- Optional playerProfile = getSkinGameProfileByUUID(uid,nick.get());
- UIDtoGameProfile.put(uid, new CachedData(System.currentTimeMillis()+1000*60*30, playerProfile.orElse(null)));
- completableFuture.complete(playerProfile);
- completableFutureMap4.remove(uid);
- return;
- } catch (IOException e) {
- e.printStackTrace();
- }
- completableFuture.complete(Optional.empty());
- completableFutureMap4.remove(uid);
- });
- });
- completableFutureMap4.put(uid, completableFuture);
- return completableFuture;
- }
-
- public static Optional getSkinGameProfileByUUID(String uid, String nickname) throws IOException {
- GameProfile gameProfile = new GameProfile(UUID.fromString(uid), nickname);
- GameProfile newProf = Minecraft.getMinecraft().getSessionService().fillProfileProperties(gameProfile, true);
- return newProf == gameProfile ? Optional.empty() : Optional.of(newProf);
- }
-
-
- private static final Map>> completableFutureMap = new ConcurrentHashMap<>();
- public static CompletableFuture> fetchMostRecentProfileAsync(String uid, String apiKey) {
- if (playerProfileCache.containsKey(uid)) {
- CachedData cachedData = playerProfileCache.get(uid);
- if (cachedData.getExpire() > System.currentTimeMillis()) {
- return CompletableFuture.completedFuture(Optional.ofNullable(cachedData.getData()));
- }
- playerProfileCache.remove(uid);
- }
- if (completableFutureMap.containsKey(uid)) return completableFutureMap.get(uid);
- if (invalidKeys.contains(apiKey)) {
- CompletableFuture cf = new CompletableFuture();
- cf.completeExceptionally(new IOException("403 for url"));
- return cf;
- }
-
- CompletableFuture> completableFuture = new CompletableFuture<>();
- ex.submit(() -> {
- try {
- Optional playerProfile = fetchMostRecentProfile(uid, apiKey);
- playerProfileCache.put(uid, new CachedData(System.currentTimeMillis()+1000*60*30, playerProfile.orElse(null)));
- completableFuture.complete(playerProfile);
- completableFutureMap.remove(uid);
- return;
- } catch (IOException e) {
- if (e.getMessage().contains("403 for URL")) {
- completableFuture.completeExceptionally(e);
- completableFutureMap.remove(uid);
- invalidKeys.add(apiKey);
- } else {
- completableFuture.completeExceptionally(e);
- completableFutureMap.remove(uid);
- }
- e.printStackTrace();
- }
- });
- completableFutureMap.put(uid, completableFuture);
- return completableFuture;
- }
-
- private static final Map>> completableFutureMap3 = new ConcurrentHashMap<>();
- public static CompletableFuture> fetchNicknameAsync(String uid) {
- if (UIDtoNickname.containsKey(uid)) {
- CachedData cachedData = UIDtoNickname.get(uid);
- if (cachedData.getExpire() > System.currentTimeMillis()) {
- return CompletableFuture.completedFuture(Optional.ofNullable(cachedData.getData()));
- }
- UIDtoNickname.remove(uid);
- }
- if (completableFutureMap3.containsKey(uid)) return completableFutureMap3.get(uid);
-
-
- CompletableFuture> completableFuture = new CompletableFuture<>();
-
- ex.submit(() -> {
- try {
- Optional playerProfile = fetchNickname(uid);
- UIDtoNickname.put(uid, new CachedData(System.currentTimeMillis()+1000*60*60*12,playerProfile.orElse(null)));
- if (playerProfile.isPresent())
- nicknameToUID.put(playerProfile.orElse(null), new CachedData<>(System.currentTimeMillis()+1000*60*60*12, uid));
- completableFuture.complete(playerProfile);
- completableFutureMap3.remove(uid);
- return;
- } catch (IOException e) {
- e.printStackTrace();
- }
- completableFuture.complete(Optional.empty());
- completableFutureMap3.remove(uid);
- });
- completableFutureMap3.put(uid, completableFuture);
-
- return completableFuture;
- }
-
- private static final Map>> completableFutureMap2 = new ConcurrentHashMap<>();
- public static CompletableFuture> fetchUUIDAsync(String nickname) {
- if (nicknameToUID.containsKey(nickname)) {
- CachedData cachedData = nicknameToUID.get(nickname);
- if (cachedData.getExpire() > System.currentTimeMillis()) {
- return CompletableFuture.completedFuture(Optional.ofNullable(cachedData.getData()));
- }
- nicknameToUID.remove(nickname);
- }
- if (completableFutureMap2.containsKey(nickname)) return completableFutureMap2.get(nickname);
-
-
- CompletableFuture> completableFuture = new CompletableFuture<>();
-
- ex.submit(() -> {
- try {
- Optional playerProfile = fetchUUID(nickname);
- nicknameToUID.put(nickname, new CachedData(System.currentTimeMillis()+1000*60*60*12,playerProfile.orElse(null)));
- if (playerProfile.isPresent())
- UIDtoNickname.put(playerProfile.orElse(null), new CachedData<>(System.currentTimeMillis()+1000*60*60*12, nickname));
-
- completableFuture.complete(playerProfile);
- completableFutureMap2.remove(nickname);
- return;
- } catch (IOException e) {
- e.printStackTrace();
- }
- completableFuture.complete(Optional.empty());
- completableFutureMap2.remove(nickname);
- });
- completableFutureMap2.put(nickname, completableFuture);
-
- return completableFuture;
- }
-
- public static Optional fetchUUID(String nickname) throws IOException {
- JsonObject json = getJson("https://api.mojang.com/users/profiles/minecraft/"+nickname);
- if (json.has("error")) return Optional.empty();
- return Optional.of(TextUtils.insertDashUUID(json.get("id").getAsString()));
- }
- public static Optional fetchNickname(String uuid) throws IOException {
- try {
- JsonArray json = getJsonArr("https://api.mojang.com/user/profiles/" + uuid.replace("-", "") + "/names");
- return Optional.of(json.get(json.size()-1).getAsJsonObject().get("name").getAsString());
- } catch (Exception e) {return Optional.empty();}
- }
-
- public static List fetchPlayerProfiles(String uid, String apiKey) throws IOException {
- JsonObject json = getJson("https://api.hypixel.net/skyblock/profiles?uuid="+uid+"&key="+apiKey);
- if (!json.get("success").getAsBoolean()) return new ArrayList<>();
- JsonArray profiles = json.getAsJsonArray("profiles");
- String dashTrimmed = uid.replace("-", "");
-
- ArrayList playerProfiles = new ArrayList<>();
- for (JsonElement jsonElement : profiles) {
- JsonObject semiProfile = jsonElement.getAsJsonObject();
- if (!semiProfile.has(dashTrimmed)) continue;
- playerProfiles.add(parseProfile(semiProfile, dashTrimmed));
- }
- return playerProfiles;
- }
-
- public static Optional fetchMostRecentProfile(String uid, String apiKey) throws IOException {
- JsonObject json = getJson("https://api.hypixel.net/skyblock/profiles?uuid="+uid+"&key="+apiKey);
- if (!json.get("success").getAsBoolean()) return Optional.empty();
- JsonArray profiles = json.getAsJsonArray("profiles");
- String dashTrimmed = uid.replace("-", "");
-
- JsonObject profile = null;
- long lastSave = Long.MIN_VALUE;
- for (JsonElement jsonElement : profiles) {
- JsonObject semiProfile = jsonElement.getAsJsonObject();
- if (!semiProfile.getAsJsonObject("members").has(dashTrimmed)) continue;
- long lastSave2 = semiProfile.getAsJsonObject("members").getAsJsonObject(dashTrimmed).get("last_save").getAsLong();
- if (lastSave2 > lastSave) {
- profile = semiProfile;
- lastSave = lastSave2;
- }
- }
-
- if (profile == null) return Optional.empty();
- PlayerProfile pp = parseProfile(profile, dashTrimmed);
- json = getJson("https://api.hypixel.net/player?uuid="+uid+"&key="+apiKey);
- if (json.has("player")) {
- JsonObject treasures = json.getAsJsonObject("player");
- if (treasures.has("achievements")) {
- treasures = treasures.getAsJsonObject("achievements");
- if (treasures.has("skyblock_treasure_hunter")) {
- pp.setTotalSecrets(treasures.get("skyblock_treasure_hunter").getAsInt());
- }
- }
- }
-
- return Optional.of(pp);
- }
-
- public static int getOrDefault(JsonObject jsonObject, String key, int value) {
- if (jsonObject == null || !jsonObject.has(key) || jsonObject.get(key) instanceof JsonNull) return value;
- return jsonObject.get(key).getAsInt();
- }
- public static long getOrDefault(JsonObject jsonObject, String key, long value) {
- if (jsonObject == null || !jsonObject.has(key) || jsonObject.get(key) instanceof JsonNull) return value;
- return jsonObject.get(key).getAsLong();
- }
- public static double getOrDefault(JsonObject jsonObject, String key, double value) {
- if (jsonObject == null || !jsonObject.has(key) || jsonObject.get(key) instanceof JsonNull) return value;
- return jsonObject.get(key).getAsDouble();
- }
- public static String getOrDefault(JsonObject jsonObject, String key, String value) {
- if (jsonObject == null || !jsonObject.has(key) || jsonObject.get(key) instanceof JsonNull) return value;
- return jsonObject.get(key).getAsString();
- }
- public static Double getOrDefaultNullable(JsonObject jsonObject, String key, Double value) {
- if (jsonObject == null || !jsonObject.has(key) || jsonObject.get(key) instanceof JsonNull) return value;
- return jsonObject.get(key).getAsDouble();
- }
- public static NBTTagCompound parseBase64NBT(String nbt) throws IOException {
- return CompressedStreamTools.readCompressed(new ByteArrayInputStream(Base64.getDecoder().decode(nbt)));
- }
-
- public static ItemStack deserializeNBT(NBTTagCompound nbtTagCompound) {
- if (nbtTagCompound.hasNoTags()) return null;
- ItemStack itemStack = new ItemStack(Blocks.stone);
- itemStack.deserializeNBT(nbtTagCompound);
- return itemStack;
- }
-
- public static PlayerProfile parseProfile(JsonObject profile, String dashTrimmed) throws IOException {
- PlayerProfile playerProfile = new PlayerProfile();
- playerProfile.setProfileUID(getOrDefault(profile, "profile_id", ""));
- playerProfile.setMemberUID(dashTrimmed);
- playerProfile.setProfileName(getOrDefault(profile, "cute_name", ""));
-
- JsonObject playerData = profile.getAsJsonObject("members").getAsJsonObject(dashTrimmed);
- playerProfile.setLastSave(getOrDefault(playerData, "last_save", 0L));
- playerProfile.setFairySouls(getOrDefault(playerData, "fairy_souls_collected", 0));
- playerProfile.setFairyExchanges(getOrDefault(playerData, "fairy_exchanges", 0));
-
- if (playerData.has("inv_armor")) {
- playerProfile.setCurrentArmor(new PlayerProfile.Armor());
- NBTTagCompound armor = parseBase64NBT(playerData.getAsJsonObject("inv_armor")
- .get("data")
- .getAsString());
- NBTTagList array = armor.getTagList("i", 10);
- for (int i = 0; i < 4; i++) {
- NBTTagCompound item = array.getCompoundTagAt(i);
- playerProfile.getCurrentArmor().getArmorSlots()[i] = deserializeNBT(item);
- }
- }
-
- if (playerData.has("wardrobe_contents")) {
- NBTTagCompound armor = parseBase64NBT(playerData.getAsJsonObject("wardrobe_contents").get("data").getAsString());
- NBTTagList array = armor.getTagList("i", 10);
- for (int i = 0; i < array.tagCount(); i++) {
- if (i % 4 == 0) playerProfile.getWardrobe().add(new PlayerProfile.Armor());
- NBTTagCompound item = array.getCompoundTagAt(i);
- playerProfile.getWardrobe().get(i/4).getArmorSlots()[i%4] = deserializeNBT(item);
- }
-
- }
- playerProfile.setSelectedWardrobe(getOrDefault(playerData, "wardrobe_equipped_slot", -1));
-
- if (playerData.has("inv_contents")) {
- NBTTagCompound armor = parseBase64NBT(playerData.getAsJsonObject("inv_contents").get("data").getAsString());
- NBTTagList array = armor.getTagList("i", 10);
- playerProfile.setInventory(new ItemStack[array.tagCount()]);
- for (int i = 0; i < array.tagCount(); i++) {
- NBTTagCompound item = array.getCompoundTagAt(i);
- playerProfile.getInventory()[i] = deserializeNBT(item);
- }
- }
- if (playerData.has("ender_chest_contents")) {
- NBTTagCompound armor = parseBase64NBT(playerData.getAsJsonObject("ender_chest_contents").get("data").getAsString());
- NBTTagList array = armor.getTagList("i", 10);
- playerProfile.setEnderchest(new ItemStack[array.tagCount()]);
- for (int i = 0; i < array.tagCount(); i++) {
- NBTTagCompound item = array.getCompoundTagAt(i);
- playerProfile.getEnderchest()[i] = deserializeNBT(item);
- }
- }
- if (playerData.has("talisman_bag")) {
- NBTTagCompound armor = parseBase64NBT(playerData.getAsJsonObject("talisman_bag").get("data").getAsString());
- NBTTagList array = armor.getTagList("i", 10);
- playerProfile.setTalismans(new ItemStack[array.tagCount()]);
- for (int i = 0; i < array.tagCount(); i++) {
- NBTTagCompound item = array.getCompoundTagAt(i);
- playerProfile.getTalismans()[i] = deserializeNBT(item);
- }
- }
-
- playerProfile.setSkillXp(new HashMap<>());
- for (Skill value : Skill.values()) {
- playerProfile.getSkillXp().put(value, getOrDefaultNullable(playerData, "experience_skill_"+value.getJsonName(), null));
- }
-
- if (playerData.has("pets")) {
- for (JsonElement pets : playerData.getAsJsonArray("pets")) {
- JsonObject pet = pets.getAsJsonObject();
- Pet petObj = new Pet();
- petObj.setActive(pet.get("active").getAsBoolean());
- petObj.setExp(getOrDefault(pet, "exp", 0.0));
- petObj.setHeldItem(getOrDefault(pet, "heldItem", null));
- petObj.setSkin(getOrDefault(pet, "skin", null));
- petObj.setType(getOrDefault(pet, "type", null));
- petObj.setUuid(getOrDefault(pet, "uuid", null));
-
- playerProfile.getPets().add(petObj);
- }
- }
-
- if (playerData.has("dungeons") && playerData.getAsJsonObject("dungeons").has("dungeon_types")) {
- JsonObject types = playerData.getAsJsonObject("dungeons")
- .getAsJsonObject("dungeon_types");
- for (DungeonType value : DungeonType.values()) {
- DungeonStat dungeonStat = new DungeonStat();
- DungeonSpecificData dungeonSpecificData = new DungeonSpecificData<>(value, dungeonStat);
- playerProfile.getDungeonStats().put(value, dungeonSpecificData);
-
- if (!types.has(value.getJsonName())) continue;
-
- JsonObject dungeonObj = types.getAsJsonObject(value.getJsonName());
-
- dungeonStat.setHighestCompleted(getOrDefault(dungeonObj, "highest_tier_completed", -1));
-
- for (Integer validFloor : value.getValidFloors()) {
- DungeonStat.PlayedFloor playedFloor = new DungeonStat.PlayedFloor();
- playedFloor.setBestScore(getOrDefault(dungeonObj.getAsJsonObject("best_score"), ""+validFloor, 0));
- playedFloor.setCompletions(getOrDefault(dungeonObj.getAsJsonObject("tier_completions"), ""+validFloor, 0));
- playedFloor.setFastestTime(getOrDefault(dungeonObj.getAsJsonObject("fastest_time"), ""+validFloor, -1));
- playedFloor.setFastestTimeS(getOrDefault(dungeonObj.getAsJsonObject("fastest_time_s"), ""+validFloor, -1));
- playedFloor.setFastestTimeSPlus(getOrDefault(dungeonObj.getAsJsonObject("fastest_time_s_plus"), ""+validFloor, -1));
- playedFloor.setMobsKilled(getOrDefault(dungeonObj.getAsJsonObject("mobs_killed"), ""+validFloor, 0));
- playedFloor.setMostMobsKilled(getOrDefault(dungeonObj.getAsJsonObject("most_mobs_killed"), ""+validFloor, 0));
- playedFloor.setMostHealing(getOrDefault(dungeonObj.getAsJsonObject("most_healing"), ""+validFloor, 0));
- playedFloor.setTimes_played(getOrDefault(dungeonObj.getAsJsonObject("times_played"), ""+validFloor, 0));
- playedFloor.setWatcherKills(getOrDefault(dungeonObj.getAsJsonObject("watcher_kills"), ""+validFloor, 0));
-
- for (DungeonClass dungeonClass : DungeonClass.values()) {
- DungeonStat.PlayedFloor.ClassStatistics classStatistics = new DungeonStat.PlayedFloor.ClassStatistics();
- classStatistics.setMostDamage(getOrDefault(dungeonObj.getAsJsonObject("most_damage_"+dungeonClass.getJsonName()), ""+validFloor, 0));
- ClassSpecificData classStatisticsClassSpecificData = new ClassSpecificData<>(dungeonClass, classStatistics);
-
- playedFloor.getClassStatistics().put(dungeonClass, classStatisticsClassSpecificData);
- }
-
- FloorSpecificData playedFloorFloorSpecificData = new FloorSpecificData<>(validFloor, playedFloor);
- dungeonStat.getPlays().put(validFloor, playedFloorFloorSpecificData);
- }
-
- dungeonStat.setExperience(getOrDefault(dungeonObj, "experience", 0));
-
-
- }
- }
- if (playerData.has("dungeons") && playerData.getAsJsonObject("dungeons").has("player_classes")) {
- JsonObject classes = playerData.getAsJsonObject("dungeons")
- .getAsJsonObject("player_classes");
- for (DungeonClass dungeonClass : DungeonClass.values()) {
- PlayerProfile.PlayerClassData classStatistics = new PlayerProfile.PlayerClassData();
- classStatistics.setExperience(getOrDefault(classes.getAsJsonObject(dungeonClass.getJsonName()), "experience", 0));
- ClassSpecificData classStatisticsClassSpecificData = new ClassSpecificData<>(dungeonClass, classStatistics);
-
- playerProfile.getPlayerClassData().put(dungeonClass, classStatisticsClassSpecificData);
- }
- }
- if (playerData.has("dungeons")) {
- String id = getOrDefault(playerData.getAsJsonObject("dungeons"), "selected_dungeon_class", null);
- DungeonClass dungeonClass = DungeonClass.getClassByJsonName(id);
- playerProfile.setSelectedClass(dungeonClass);
- }
- try {
- calculateLilyWeight(playerProfile, playerData);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return playerProfile;
- }
-
- private static void calculateLilyWeight(PlayerProfile playerProfile, JsonObject playerData) throws ExecutionException, InterruptedException {
- JsonObject constants = getLilyWeightConstants();
- double[] slayerXP = new double[4];
- if (playerData.has("slayer_bosses")) {
- slayerXP[0] = getOrDefault(playerData.getAsJsonObject("slayer_bosses").getAsJsonObject("zombie"), "xp", 0);
- slayerXP[1] = getOrDefault(playerData.getAsJsonObject("slayer_bosses").getAsJsonObject("spider"), "xp", 0);
- slayerXP[2] = getOrDefault(playerData.getAsJsonObject("slayer_bosses").getAsJsonObject("wolf"), "xp", 0);
- slayerXP[3] = getOrDefault(playerData.getAsJsonObject("slayer_bosses").getAsJsonObject("enderman"), "xp", 0);
- }
- double skillWeight = 0;
- double overflowWeight = 0;
- {
- JsonObject srw = constants.getAsJsonObject("skillRatioWeight");
- int skillMaxXP = constants.get("skillMaxXP").getAsInt();
- JsonArray overflowMultiplier = constants.getAsJsonArray("skillOverflowMultipliers");
- JsonArray skillFactor = constants.getAsJsonArray("skillFactors");
-
- double skillAvg = playerProfile.getSkillXp().entrySet().stream()
- .filter(a -> a.getValue() != null)
- .filter(a -> srw.has(a.getKey().getJsonName()))
- .map(a -> XPUtils.getSkillXp(a.getKey(), a.getValue()).getLevel()).collect(Collectors.averagingInt(a -> a));
-
- double n = 12 * (skillAvg/60)*(skillAvg/60);
- double r2 = Math.sqrt(2);
-
- for (Map.Entry skillDoubleEntry : playerProfile.getSkillXp().entrySet()) {
- String jsonName = skillDoubleEntry.getKey().getJsonName();
- JsonArray temp_srw = srw.getAsJsonArray(jsonName);
- if (temp_srw == null) continue;
- int lv = XPUtils.getSkillXp(skillDoubleEntry.getKey(), skillDoubleEntry.getValue()).getLevel();
- skillWeight += n * temp_srw.get(lv).getAsDouble()
- * temp_srw.get(temp_srw.size() - 1).getAsDouble();
- skillWeight += temp_srw.get(temp_srw.size() - 1).getAsDouble() * Math.pow(lv/60.0, r2);
- }
-
- int cnt = 0;
- for (Map.Entry skillNames : constants.getAsJsonObject("skillNames").entrySet()) {
- Skill s = getSkillByLilyName(skillNames.getKey());
- double factor = skillFactor.get(cnt).getAsDouble();
- double effectiveOver;
- Double xp = playerProfile.getSkillXp().get(s);
- if (xp == null) continue; xp -= skillMaxXP;
- {
- if (xp < skillMaxXP) effectiveOver = xp;
- else {
- double remainingXP = xp;
- double z = 0;
- for (int i = 0; i<= xp/skillMaxXP; i++) {
- if (remainingXP >= skillMaxXP) {
- remainingXP -= skillMaxXP;
- z += Math.pow(factor, i);
- }
- }
- effectiveOver = z * skillMaxXP;
- }
- }
- double rating = effectiveOver / skillMaxXP;
- double overflowMult = overflowMultiplier.get(cnt).getAsDouble();
- double t = rating * overflowMult;
- if (t > 0) overflowWeight += t;
- cnt++;
- }
- }
- double cataCompWeight, masterCompWeight;
- {
- JsonArray completionFactor = constants.getAsJsonArray("dungeonCompletionWorth");
- JsonObject dungeonCompletionBuffs = constants.getAsJsonObject("dungeonCompletionBuffs");
- double max1000 = 0;
- double mMax1000 = 0;
- for (int i = 0; i < completionFactor.size(); i++) {
- if (i < 8) max1000 += completionFactor.get(i).getAsDouble();
- else mMax1000 += completionFactor.get(i).getAsDouble();
- }
-
- max1000 *= 1000;
- mMax1000 *= 1000;
-
- double upperBound = 1500; double score = 0;
-
- DungeonStat dStat = playerProfile.getDungeonStats().get(DungeonType.CATACOMBS).getData();
- for (FloorSpecificData value : dStat.getPlays().values()) {
- int runs = value.getData().getCompletions();
- int excess = 0; if (runs > 1000) {
- excess = runs - 1000; runs = 1000;
- }
-
- double floorScore = runs * completionFactor.get(value.getFloor()).getAsDouble();
- if (excess > 0)
- floorScore *= Math.log10(excess / 1000.0 + 1) / Math.log10(7.5) + 1;
- score += floorScore;
- }
- cataCompWeight = (score / max1000 * upperBound);
-
- dStat = playerProfile.getDungeonStats().get(DungeonType.MASTER_CATACOMBS).getData();
- for (FloorSpecificData value : dStat.getPlays().values()) {
- if (dungeonCompletionBuffs.has(value.getFloor()+"")) {
- double threshold = 20;
- if (value.getData().getCompletions() >= threshold) upperBound += dungeonCompletionBuffs.get(value.getFloor()+"").getAsDouble();
- else upperBound += dungeonCompletionBuffs.get(value.getFloor()+"").getAsDouble() * Math.pow(value.getData().getCompletions()/threshold, 1.840896416);
- }
- }
- score = 0;
- for (FloorSpecificData value : dStat.getPlays().values()) {
- int runs = value.getData().getCompletions();
- int excess = 0; if (runs > 1000) {
- excess = runs - 1000; runs = 1000;
- }
-
- double floorScore = runs * completionFactor.get(value.getFloor()+7).getAsDouble();
- if (excess > 0)
- floorScore *= Math.log10(excess / 1000.0 + 1) / Math.log10(5) + 1;
- score += floorScore;
- }
-
- masterCompWeight = score / mMax1000 * upperBound;
- }
- double dungeonXPWeight = 0;
- {
- double dungeonOverall = constants.get("dungeonOverall").getAsDouble();
- double dungeonMaxXP = constants.get("dungeonMaxXP").getAsDouble();
-
- double cataXP = playerProfile.getDungeonStats().get(DungeonType.CATACOMBS).getData().getExperience();
- XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(cataXP);
- double level = xpCalcResult.getLevel();
- if (xpCalcResult.getLevel() != 50) {
- double progress = Math.floor(xpCalcResult.getRemainingXp() / xpCalcResult.getNextLvXp() * 1000) / 1000.0;
- level += progress;
- }
-
- double n; double tempLevel = 0;
- if (cataXP < dungeonMaxXP)
- n = 0.2 * Math.pow(level / 50.0, 2.967355422);
- else {
- double part = 142452410;
- tempLevel = 50 + (cataXP - dungeonMaxXP) / part;
- n = 0.2 * Math.pow(1 + ((tempLevel - 50) / 50), 2.967355422);
- }
- if (level != 0) {
- if (cataXP < 569809640) dungeonXPWeight = dungeonOverall * (Math.pow(1.18340401286164044, (level + 1)) - 1.05994990217254) * (1 + n);
- else dungeonXPWeight =4000 * (n / 0.15465244570598540);
- } else dungeonXPWeight = 0;
- }
- double slayerWeight = 0;
- {
- JsonArray slayerDeprecationScaling = constants.getAsJsonArray("slayerDeprecationScaling");
- BiFunction getSlayerWeight = (xp, type) -> {
- double score = 0;
- {
- double d = xp / 100000;
- if (xp >= 6416) {
- double D = (d - Math.pow(3, (-5 / 2.0))) * (d + Math.pow(3, -5 / 2.0));
- double u = Math.cbrt(3 * (d + Math.sqrt(D)));
- double v = Math.cbrt(3 * (d - Math.sqrt(D)));
- score = u + v - 1;
- } else {
- score = Math.sqrt(4 / 3.0) * Math.cos(Math.acos(d * Math.pow(3, 5 / 2.0)) / 3) - 1;
- }
- }
- score = Math.floor(score);
- double scaling = slayerDeprecationScaling.get(type).getAsDouble();
- double effectiveXP = 0;
- for (int i = 1; i <= score; i++)
- effectiveXP += (i * i + i) * Math.pow(scaling, i);
- effectiveXP = Math.round((1000000 * effectiveXP * (0.05 / scaling)) * 100) / 100.0;
- double actualXP = ((score*score*score / 6) + (score*score / 2) + (score / 3)) * 100000;
- double distance = xp - actualXP;
- double effectiveDistance = distance * Math.pow(scaling, score);
- return effectiveXP + effectiveDistance;
- };
-
- double zombie = getSlayerWeight.apply(slayerXP[0], 0);
- double spider = getSlayerWeight.apply(slayerXP[1], 1);
- double wolf = getSlayerWeight.apply(slayerXP[2], 2);
- double enderman = getSlayerWeight.apply(slayerXP[3], 3);
- double individual = zombie / 7000 + spider / 4800 + wolf / 2200 + enderman / 1000;
- double extra = (slayerXP[0] + 1.6 * slayerXP[1] + 3.6 * slayerXP[2] + 10 * slayerXP[3]) / 900000;
- slayerWeight = (individual + extra);
- }
-
- PlayerProfile.LilyWeight lilyWeight = new PlayerProfile.LilyWeight();
- lilyWeight.setCatacombs_base(cataCompWeight);
- lilyWeight.setCatacombs_master(masterCompWeight);
- lilyWeight.setCatacombs_exp(dungeonXPWeight);
- lilyWeight.setSkill_base(skillWeight);
- lilyWeight.setSkill_overflow(overflowWeight);
- lilyWeight.setSlayer(slayerWeight);
-
- playerProfile.setLilyWeight(lilyWeight);
- }
-
- private static Skill getSkillByLilyName(String lilyName) {
- switch(lilyName) {
- case "experience_skill_enchanting": return Skill.ENCHANTING;
- case "experience_skill_taming": return Skill.TAMING;
- case "experience_skill_alchemy": return Skill.ALCHEMY;
- case "experience_skill_mining": return Skill.MINING;
- case "experience_skill_farming": return Skill.FARMING;
- case "experience_skill_foraging": return Skill.FORAGING;
- case "experience_skill_combat": return Skill.COMBAT;
- case "experience_skill_fishing": return Skill.FISHING;
- default: return null;
- }
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/CachedData.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/CachedData.java
deleted file mode 100644
index 39b04088..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/CachedData.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.api;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-
-@Data
-@AllArgsConstructor
-public class CachedData {
- private final long expire;
- private final T data;
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ClassSpecificData.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ClassSpecificData.java
deleted file mode 100644
index f977b46a..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ClassSpecificData.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.api;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-@AllArgsConstructor
-@Getter
-public class ClassSpecificData {
- private final DungeonClass dungeonClass;
- private final T data;
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonClass.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonClass.java
deleted file mode 100644
index bc0d15f2..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonClass.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.api;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.util.HashMap;
-import java.util.Map;
-
-@Getter
-@AllArgsConstructor
-public enum DungeonClass {
- MAGE("mage", "Mage"), ARCHER("archer","Archer"), HEALER("healer", "Healer"), TANK("tank", "Tank"), BERSERK("berserk", "Berserk");
-
-
- private final String jsonName;
- private final String familarName;
- private static final Map jsonNameToClazz = new HashMap<>();
- static {
- for (DungeonClass value : values()) {
- jsonNameToClazz.put(value.getJsonName(), value);
- }
- }
-
- public static DungeonClass getClassByJsonName(String name) {
- return jsonNameToClazz.get(name);
- }
-
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonSpecificData.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonSpecificData.java
deleted file mode 100644
index a70b8ba0..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonSpecificData.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.api;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-@Getter
-@AllArgsConstructor
-public class DungeonSpecificData {
- private final DungeonType type;
- private final T data;
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonStat.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonStat.java
deleted file mode 100644
index fb3be9ac..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonStat.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.api;
-
-import lombok.Data;
-
-import java.util.HashMap;
-import java.util.Map;
-
-@Data
-public class DungeonStat {
- private int highestCompleted;
- private double experience;
-
- private Map> plays = new HashMap<>();
- @Data
- public static class PlayedFloor {
- private int times_played;
- private int completions;
- private int watcherKills;
-
- private int fastestTime;
- private int fastestTimeS;
- private int fastestTimeSPlus;
- private int bestScore;
-
- private int mostMobsKilled;
- private int mobsKilled;
-
- private Map> classStatistics = new HashMap<>();
- @Data
- public static class ClassStatistics {
- private double mostDamage;
- }
-
- private double mostHealing;
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonType.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonType.java
deleted file mode 100644
index 00ca208b..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonType.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.api;
-
-import com.google.common.collect.Sets;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.util.Set;
-
-@Getter
-@AllArgsConstructor
-public enum DungeonType {
- CATACOMBS("catacombs", "The Catacombs",
- Sets.newHashSet(0,1,2,3,4,5,6,7)),
- MASTER_CATACOMBS("master_catacombs", "MasterMode Catacombs", Sets.newHashSet(
- 1,2,3,4,5,6
- ));
-
- private final String jsonName;
- private final String familiarName;
- private final Set validFloors ;
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/FloorSpecificData.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/FloorSpecificData.java
deleted file mode 100644
index 3f3c4f35..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/FloorSpecificData.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.api;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-@Getter
-@AllArgsConstructor
-public class FloorSpecificData {
- private final int floor;
- private final T data;
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/Pet.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/Pet.java
deleted file mode 100644
index eb1427eb..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/Pet.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.api;
-
-import lombok.Data;
-
-@Data
-public class Pet {
- private String uuid;
- private String type;
- private double exp;
- private boolean active;
- private String heldItem;
- private String skin;
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/PlayerProfile.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/PlayerProfile.java
deleted file mode 100644
index a9c1a272..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/PlayerProfile.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.api;
-
-import lombok.Data;
-import net.minecraft.item.ItemStack;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@Data
-public class PlayerProfile {
- private String profileUID;
- private String memberUID;
- private String profileName;
-
- private long lastSave;
-
- private int fairySouls;
- private int fairyExchanges;
-
- private Armor currentArmor;
- private List wardrobe = new ArrayList<>();
- private int selectedWardrobe = -1;
-
- private ItemStack[] inventory;
- private ItemStack[] enderchest;
- private ItemStack[] talismans;
-
- private int totalSecrets;
-
- @Data
- public static class Armor {
- private final ItemStack[] armorSlots = new ItemStack[4];
-
- public ItemStack getHelmet() { return armorSlots[3]; }
- public ItemStack getChestPlate() { return armorSlots[2]; }
- public ItemStack getLeggings() { return armorSlots[1]; }
- public ItemStack getBoots() { return armorSlots[0]; }
- }
-
- private Map> dungeonStats = new HashMap<>();
-
- private Map> playerClassData = new HashMap<>();
- private DungeonClass selectedClass;
- @Data
- public static class PlayerClassData {
- private double experience;
- }
-
- private Map skillXp;
-
- private List pets = new ArrayList<>();
-
-
- private Map additionalProperties = new HashMap<>();
-
- private LilyWeight lilyWeight;
-
- @Data
- public static class LilyWeight {
- private double skill_base;
- private double skill_overflow;
- private double catacombs_base;
- private double catacombs_master;
- private double catacombs_exp;
- private double slayer;
-
- public double getTotal() {
- return skill_base + skill_overflow + catacombs_base + catacombs_exp + catacombs_master + slayer;
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/Skill.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/Skill.java
deleted file mode 100644
index 47900ef3..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/Skill.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.api;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.Getter;
-
-@Getter
-@AllArgsConstructor
-public enum Skill {
- RUNECRAFTING("runecrafting", "Runecrafting"), COMBAT("combat", "Combat"), MINING("mining", "Mining"), ALCHEMY("alchemy", "Alchemy"), FARMING("farming", "Farming"), TAMING("taming", "Taming"), ENCHANTING("enchanting", "Enchanting"), FISHING("fishing", "Fishing"), FORAGING("foraging", "Foraging"), CARPENTRY("carpentry", "Carpentry");
-
- private final String jsonName;
- private final String friendlyName;
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/SkinFetchur.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/SkinFetchur.java
deleted file mode 100644
index e2c08d58..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/SkinFetchur.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.api;
-
-import com.mojang.authlib.GameProfile;
-import com.mojang.authlib.minecraft.MinecraftProfileTexture;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.resources.DefaultPlayerSkin;
-import net.minecraft.client.resources.SkinManager;
-import net.minecraft.util.ResourceLocation;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class SkinFetchur {
-
- private static final Map> skinSetMap = new ConcurrentHashMap<>();
-
- private static final Map> currentReq = new HashMap<>();
-
- public static CompletableFuture getSkinSet(GameProfile gameProfile) {
- if (gameProfile == null) {
- return CompletableFuture.completedFuture(new SkinSet(DefaultPlayerSkin.getDefaultSkinLegacy(), null, "default"));
- }
- if (skinSetMap.containsKey(gameProfile.getId().toString())) {
- CachedData ss = skinSetMap.get(gameProfile.getId().toString());
- if (ss.getExpire() > System.currentTimeMillis())
- CompletableFuture.completedFuture(skinSetMap.get(gameProfile.getId().toString()).getData());
- skinSetMap.remove(gameProfile.getId().toString());
- }
- if (currentReq.containsKey(gameProfile.getId().toString()))
- return currentReq.get(gameProfile.getId().toString());
-
- SkinSet skinSet = new SkinSet();
- CompletableFuture skinSet2 = new CompletableFuture<>();
- currentReq.put(gameProfile.getId().toString(), skinSet2);
- Minecraft.getMinecraft().getSkinManager().loadProfileTextures(gameProfile, new SkinManager.SkinAvailableCallback() {
- public void skinAvailable(MinecraftProfileTexture.Type p_180521_1_, ResourceLocation location, MinecraftProfileTexture profileTexture) {
- switch (p_180521_1_) {
- case SKIN:
- skinSet.setSkinLoc(location);
- skinSet.setSkinType(profileTexture.getMetadata("model"));
- if (skinSet.getSkinType() == null) {
- skinSet.setSkinType("default");
- }
- skinSet2.complete(skinSet);
- skinSetMap.put(gameProfile.getId().toString(), new CachedData<>(System.currentTimeMillis() + 1000*60*60*3, skinSet));
- currentReq.get(gameProfile.getId().toString());
- break;
- case CAPE:
- skinSet.setCapeLoc(location);
- }
- }
- }, true);
-
- return skinSet2;
- }
-
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- public static class SkinSet {
- private ResourceLocation skinLoc;
- private ResourceLocation capeLoc;
- private String skinType;
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/customgui/PanelPartyFinderSettings.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/customgui/PanelPartyFinderSettings.java
index 46107ff8..fe719de2 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/customgui/PanelPartyFinderSettings.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/customgui/PanelPartyFinderSettings.java
@@ -21,7 +21,6 @@ package kr.syeyoung.dungeonsguide.features.impl.party.customgui;
import kr.syeyoung.dungeonsguide.chat.ChatProcessor;
import kr.syeyoung.dungeonsguide.chat.PartyManager;
import kr.syeyoung.dungeonsguide.features.FeatureRegistry;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.ApiFetchur;
import kr.syeyoung.dungeonsguide.gui.elements.*;
import kr.syeyoung.dungeonsguide.utils.TextUtils;
import lombok.Getter;
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonFloorStat.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonFloorStat.java
deleted file mode 100644
index 627b1881..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonFloorStat.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.*;
-import kr.syeyoung.dungeonsguide.utils.TextUtils;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraftforge.fml.client.config.GuiUtils;
-
-import java.awt.*;
-import java.util.Arrays;
-
-public class DataRenderDungeonFloorStat implements DataRenderer {
- private final DungeonType dungeonType;
- private final int floor;
- public DataRenderDungeonFloorStat(DungeonType dungeonType, int floor) {
- this.dungeonType = dungeonType;
- this.floor = floor;
- }
-
- @Override
- public Dimension renderData(PlayerProfile playerProfile) {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- String floorName = (dungeonType == DungeonType.CATACOMBS ? "F" : "M") + floor;
-
- boolean flag = false;
- DungeonSpecificData dungeonStatDungeonSpecificData = playerProfile.getDungeonStats().get(dungeonType);
- if (dungeonStatDungeonSpecificData != null) {
- FloorSpecificData playedFloorFloorSpecificData = dungeonStatDungeonSpecificData.getData().getPlays().get(floor);
- if (playedFloorFloorSpecificData != null) {
- flag = true;
- fr.drawString("§b" + floorName + " §a" + playedFloorFloorSpecificData.getData().getBestScore() + " §f" + playedFloorFloorSpecificData.getData().getCompletions() + "§7/§f" + playedFloorFloorSpecificData.getData().getWatcherKills() + "§7/§f" + playedFloorFloorSpecificData.getData().getTimes_played() + " §7(" + (int) (playedFloorFloorSpecificData.getData().getCompletions()*100 / (double) playedFloorFloorSpecificData.getData().getWatcherKills()) + "%)", 0, 0, -1);
- fr.drawString("§6S+ §e" + (playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "§7N/A") + " §6S §e" + (playedFloorFloorSpecificData.getData().getFastestTimeS() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "§7N/A"), 0, fr.FONT_HEIGHT, -1);
- }
- }
- if (!flag) {
- fr.drawString("§cNo Stat for "+floorName, 0,0,-1);
- }
-
- return getDimension();
- }
-
- @Override
- public Dimension renderDummy() {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- String floorName = (dungeonType == DungeonType.CATACOMBS ? "F" : "M") + floor;
-
-
- fr.drawString("§b"+floorName+" §a305 §f10§7/§f35§7/§f50 §7("+(int)(1000.0/35.0)+"%)", 0,0,-1);
- fr.drawString("§6S+ §e10m 53s §6S §e15m 13s", 0, fr.FONT_HEIGHT, -1);
- return getDimension();
- }
-
- @Override
- public Dimension getDimension() {
- return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*2);
- }
-
- @Override
- public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
-
- DungeonSpecificData dungeonStatDungeonSpecificData = playerProfile.getDungeonStats().get(dungeonType);
- if (dungeonStatDungeonSpecificData == null) return;
- FloorSpecificData playedFloorFloorSpecificData = dungeonStatDungeonSpecificData.getData().getPlays().get(floor);
- if (playedFloorFloorSpecificData == null) return;
- String floorName = (dungeonType == DungeonType.CATACOMBS ? "F" : "M") + floor;
-
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
- GuiUtils.drawHoveringText(Arrays.asList(
- "§bFloor "+floorName,
- "§bBest Score§7: §f"+playedFloorFloorSpecificData.getData().getBestScore(),
- "§bTotal Completions§7: §f"+playedFloorFloorSpecificData.getData().getCompletions(),
- "§bTotal Watcher kills§7: §f"+playedFloorFloorSpecificData.getData().getWatcherKills(),
- "§bTotal Runs§7: §f"+playedFloorFloorSpecificData.getData().getTimes_played(),
- "§bFastest S+§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "§7N/A"),
- "§bFastest S§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeS() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "§7N/A"),
- "§bFastest Run§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTime() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTime()) : "§7N/A"),
- "§bMost Mobs Killed§7: §f"+playedFloorFloorSpecificData.getData().getMostMobsKilled(),
- "§bTotal Mobs Killed§7: §f"+playedFloorFloorSpecificData.getData().getMobsKilled()
- ), mouseX, mouseY, scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonHighestFloorStat.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonHighestFloorStat.java
deleted file mode 100644
index d19fa2f1..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonHighestFloorStat.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.*;
-import kr.syeyoung.dungeonsguide.utils.TextUtils;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraftforge.fml.client.config.GuiUtils;
-
-import java.awt.*;
-import java.util.Arrays;
-
-public class DataRenderDungeonHighestFloorStat implements DataRenderer {
- private final DungeonType dungeonType;
- public DataRenderDungeonHighestFloorStat(DungeonType dungeonType) {
- this.dungeonType = dungeonType;
- }
-
- @Override
- public Dimension renderData(PlayerProfile playerProfile) {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
-
- boolean flag = false;
- DungeonSpecificData dungeonStatDungeonSpecificData = playerProfile.getDungeonStats().get(dungeonType);
- if (dungeonStatDungeonSpecificData != null) {
- if (dungeonStatDungeonSpecificData.getData().getHighestCompleted() != -1) {
- FloorSpecificData playedFloorFloorSpecificData = dungeonStatDungeonSpecificData.getData().getPlays().get(dungeonStatDungeonSpecificData.getData().getHighestCompleted());
- String floorName = (dungeonType == DungeonType.CATACOMBS ? "F" : "M") + dungeonStatDungeonSpecificData.getData().getHighestCompleted();
- if (playedFloorFloorSpecificData != null) {
- flag = true;
- fr.drawString("§bH: " + floorName + " §a" + playedFloorFloorSpecificData.getData().getBestScore() + " §f" + playedFloorFloorSpecificData.getData().getCompletions() + "§7/§f" + playedFloorFloorSpecificData.getData().getWatcherKills() + "§7/§f" + playedFloorFloorSpecificData.getData().getTimes_played() + " §7(" + (int) (playedFloorFloorSpecificData.getData().getCompletions() *100/ (double) playedFloorFloorSpecificData.getData().getWatcherKills()) + "%)", 0, 0, -1);
- fr.drawString("§6S+ §e" + (playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "§7N/A") + " §6S §e" + (playedFloorFloorSpecificData.getData().getFastestTimeS() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "§7N/A"), 0, fr.FONT_HEIGHT, -1);
- }
- }
- }
- if (!flag) {
- fr.drawString("§cNo Highest Floor for ", 0,0,-1);
- fr.drawString("§c"+dungeonType.getFamiliarName(), 0,fr.FONT_HEIGHT,-1);
- }
-
- return getDimension();
- }
-
- @Override
- public Dimension renderDummy() {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- String floorName = (dungeonType == DungeonType.CATACOMBS ? "F" : "M") + "9";
-
-
- fr.drawString("§bH: "+floorName+" §a305 §f10§7/§f35§7/§f50 §7("+(int)(1000.0/35.0)+"%)", 0,0,-1);
- fr.drawString("§6S+ §e10m 53s §6S §e15m 13s", 0, fr.FONT_HEIGHT, -1);
- return getDimension();
- }
-
- @Override
- public Dimension getDimension() {
- return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*2);
- }
-
- @Override
- public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
-
- DungeonSpecificData dungeonStatDungeonSpecificData = playerProfile.getDungeonStats().get(dungeonType);
- if (dungeonStatDungeonSpecificData == null) return;
- if (dungeonStatDungeonSpecificData.getData().getHighestCompleted() == -1) return;
- FloorSpecificData playedFloorFloorSpecificData = dungeonStatDungeonSpecificData.getData().getPlays().get( dungeonStatDungeonSpecificData.getData().getHighestCompleted());
- if (playedFloorFloorSpecificData == null) return;
- String floorName = (dungeonType == DungeonType.CATACOMBS ? "F" : "M") + dungeonStatDungeonSpecificData.getData().getHighestCompleted();
-
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
- GuiUtils.drawHoveringText(Arrays.asList(
- "§bFloor "+floorName,
- "§bBest Score§7: §f"+playedFloorFloorSpecificData.getData().getBestScore(),
- "§bTotal Completions§7: §f"+playedFloorFloorSpecificData.getData().getCompletions(),
- "§bTotal Watcher kills§7: §f"+playedFloorFloorSpecificData.getData().getWatcherKills(),
- "§bTotal Runs§7: §f"+playedFloorFloorSpecificData.getData().getTimes_played(),
- "§bFastest S+§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "§7N/A"),
- "§bFastest S§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeS() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "§7N/A"),
- "§bFastest Run§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTime() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTime()) : "§7N/A"),
- "§bMost Mobs Killed§7: §f"+playedFloorFloorSpecificData.getData().getMostMobsKilled(),
- "§bTotal Mobs Killed§7: §f"+playedFloorFloorSpecificData.getData().getMobsKilled()
- ), mouseX, mouseY, scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderer.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderer.java
deleted file mode 100644
index df72647e..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderer.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile;
-
-import java.awt.*;
-
-public interface DataRenderer {
- Dimension renderData(PlayerProfile playerProfile);
- void onHover(PlayerProfile playerProfile, int mouseX, int mouseY);
-
-
- Dimension renderDummy();
-
- Dimension getDimension();
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererClassLv.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererClassLv.java
deleted file mode 100644
index 3f47f373..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererClassLv.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.*;
-import kr.syeyoung.dungeonsguide.utils.RenderUtils;
-import kr.syeyoung.dungeonsguide.utils.TextUtils;
-import kr.syeyoung.dungeonsguide.utils.XPUtils;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraftforge.fml.client.config.GuiUtils;
-
-import java.awt.*;
-import java.util.Arrays;
-
-public class DataRendererClassLv implements DataRenderer {
- private final DungeonClass dungeonClass;
- public DataRendererClassLv(DungeonClass dungeonClass) {
- this.dungeonClass = dungeonClass;
- }
- @Override
- public Dimension renderData(PlayerProfile playerProfile) {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- ClassSpecificData dungeonStatDungeonSpecificData = playerProfile.getPlayerClassData().get(dungeonClass);
- boolean selected = playerProfile.getSelectedClass() == dungeonClass;
- if (dungeonStatDungeonSpecificData == null) {
- fr.drawString(dungeonClass.getFamilarName(), 0,0, 0xFF55ffff);
- fr.drawString("Unknown", fr.getStringWidth(dungeonClass.getFamilarName()+" "),0,0xFFFFFFFF);
- if (selected)
- fr.drawString("★", fr.getStringWidth(dungeonClass.getFamilarName()+" Unknown "),0,0xFFAAAAAA);
- } else {
- XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(dungeonStatDungeonSpecificData.getData().getExperience());
- fr.drawString(dungeonClass.getFamilarName(), 0,0, 0xFF55ffff);
- fr.drawString(xpCalcResult.getLevel()+"", fr.getStringWidth(dungeonClass.getFamilarName()+" "),0,0xFFFFFFFF);
- if (selected)
- fr.drawString("★", fr.getStringWidth(dungeonClass.getFamilarName()+" "+xpCalcResult.getLevel()+" "),0,0xFFAAAAAA);
-
- RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,xpCalcResult.getRemainingXp() == 0 ? 1 : (float) (xpCalcResult.getRemainingXp() / xpCalcResult.getNextLvXp()));
- }
-
- return new Dimension(100, fr.FONT_HEIGHT*2);
- }
-
- @Override
- public Dimension renderDummy() {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- fr.drawString(dungeonClass.getFamilarName(), 0,0, 0xFF55ffff);
- fr.drawString("99", fr.getStringWidth(dungeonClass.getFamilarName()+" "),0,0xFFFFFFFF);
- fr.drawString("★", fr.getStringWidth(dungeonClass.getFamilarName()+" 99 "),0,0xFFAAAAAA);
- RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,1.0f);
- return new Dimension(100, fr.FONT_HEIGHT*2);
- }
- @Override
- public Dimension getDimension() {
- return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*2);
- }
-
- @Override
- public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
- ClassSpecificData dungeonStatDungeonSpecificData = playerProfile.getPlayerClassData().get(dungeonClass);
- if (dungeonStatDungeonSpecificData == null) return;
- XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(dungeonStatDungeonSpecificData.getData().getExperience());
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
-
- GuiUtils.drawHoveringText(Arrays.asList("§bCurrent Lv§7: §e"+xpCalcResult.getLevel(),"§bExp§7: §e"+ TextUtils.format((long)xpCalcResult.getRemainingXp()) + "§7/§e"+TextUtils.format((long)xpCalcResult.getNextLvXp()), "§bTotal Xp§7: §e"+ TextUtils.format((long)dungeonStatDungeonSpecificData.getData().getExperience())),mouseX, mouseY,
- scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererDungeonLv.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererDungeonLv.java
deleted file mode 100644
index 80a918ef..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererDungeonLv.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.DungeonSpecificData;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.DungeonStat;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.DungeonType;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile;
-import kr.syeyoung.dungeonsguide.utils.RenderUtils;
-import kr.syeyoung.dungeonsguide.utils.TextUtils;
-import kr.syeyoung.dungeonsguide.utils.XPUtils;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraftforge.fml.client.config.GuiUtils;
-
-import java.awt.*;
-import java.util.Arrays;
-
-public class DataRendererDungeonLv implements DataRenderer {
- private final DungeonType dungeonType;
- public DataRendererDungeonLv(DungeonType dungeonType) {
- this.dungeonType = dungeonType;
- }
- @Override
- public Dimension renderData(PlayerProfile playerProfile) {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- DungeonSpecificData dungeonStatDungeonSpecificData = playerProfile.getDungeonStats().get(dungeonType);
- if (dungeonStatDungeonSpecificData == null) {
- fr.drawString(dungeonType.getFamiliarName(), 0,0, 0xFFFF5555);
- fr.drawString("Unknown", fr.getStringWidth(dungeonType.getFamiliarName()+" "),0,0xFFFFFFFF);
- } else {
- XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(dungeonStatDungeonSpecificData.getData().getExperience());
- fr.drawString(dungeonType.getFamiliarName(), 0,0, 0xFFFF5555);
- fr.drawString(xpCalcResult.getLevel()+"", fr.getStringWidth(dungeonType.getFamiliarName()+" "),0,0xFFFFFFFF);
-
- RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,xpCalcResult.getRemainingXp() == 0 ? 1 : (float) (xpCalcResult.getRemainingXp() / xpCalcResult.getNextLvXp()));
- }
-
- return new Dimension(100, fr.FONT_HEIGHT*2);
- }
-
- @Override
- public Dimension renderDummy() {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- fr.drawString(dungeonType.getFamiliarName(), 0,0, 0xFFFF5555);
- fr.drawString("99", fr.getStringWidth(dungeonType.getFamiliarName()+" "),0,0xFFFFFFFF);
- RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,1.0f);
- return new Dimension(100, fr.FONT_HEIGHT*2);
- }
- @Override
- public Dimension getDimension() {
- return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*2);
- }
-
- @Override
- public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
- DungeonSpecificData dungeonStatDungeonSpecificData = playerProfile.getDungeonStats().get(dungeonType);
- if (dungeonStatDungeonSpecificData == null) return;
- XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(dungeonStatDungeonSpecificData.getData().getExperience());
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
- GuiUtils.drawHoveringText(Arrays.asList("§bCurrent Lv§7: §e"+xpCalcResult.getLevel(),"§bExp§7: §e"+TextUtils.format((long)xpCalcResult.getRemainingXp()) + "§7/§e"+TextUtils.format((long)xpCalcResult.getNextLvXp()), "§bTotal Xp§7: §e"+ TextUtils.format((long)dungeonStatDungeonSpecificData.getData().getExperience())),mouseX, mouseY,
- scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererEditor.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererEditor.java
deleted file mode 100644
index c559775a..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererEditor.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.gui.MPanel;
-import kr.syeyoung.dungeonsguide.utils.RenderUtils;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.Gui;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraft.client.renderer.GlStateManager;
-import org.lwjgl.opengl.GL11;
-import org.lwjgl.opengl.GL14;
-
-import java.awt.*;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public class DataRendererEditor extends MPanel {
- private final FeatureViewPlayerOnJoin feature;
-
- public DataRendererEditor(FeatureViewPlayerOnJoin featureViewPlayerOnJoin) {
- this.feature = featureViewPlayerOnJoin;
- }
-
- @Override
- public void resize(int parentWidth, int parentHeight) {
- this.setBounds(new Rectangle(5,5,parentWidth-10, 260));
- }
-
- private String currentlySelected;
- private int selectedX;
- private int selectedY;
- private int lastX;
- private int lastY;
- private int scrollY;
- private final int baseWidth = 120;
- private final int hamburgerWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth("==");
-
- @Override
- public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {
- Gui.drawRect(0,0,getBounds().width, getBounds().height, RenderUtils.blendAlpha(0x141414, 0.12f));
-
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
-
-
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- fr.drawString("Available", (310 + baseWidth + hamburgerWidth -fr.getStringWidth("Available")) / 2, 4, 0xFFFFFFFF);
- fr.drawString("Current", (baseWidth + hamburgerWidth+10 -fr.getStringWidth("Current")) /2 , 4, 0xFFFFFFFF);
- Gui.drawRect(4,4 + fr.FONT_HEIGHT + 3,baseWidth + hamburgerWidth+6 + 1, 236+ fr.FONT_HEIGHT + 3, 0xFF222222);
- Gui.drawRect(5,5+ fr.FONT_HEIGHT + 3,baseWidth + hamburgerWidth + 5 + 1, 235+ fr.FONT_HEIGHT + 3, RenderUtils.blendAlpha(0x141414, 0.15f));
- Gui.drawRect(5 + hamburgerWidth,4+ fr.FONT_HEIGHT + 3,6 + hamburgerWidth, 236+ fr.FONT_HEIGHT + 3, 0xFF222222);
-
- Gui.drawRect(154,4 + fr.FONT_HEIGHT + 3,150 + baseWidth + hamburgerWidth + 6+1, 236+ fr.FONT_HEIGHT + 3, 0xFF222222);
- Gui.drawRect(155,5+ fr.FONT_HEIGHT + 3,150 + baseWidth + hamburgerWidth + 5+1, 235+ fr.FONT_HEIGHT + 3, RenderUtils.blendAlpha(0x141414, 0.15f));
- Gui.drawRect(155 + hamburgerWidth,4 + fr.FONT_HEIGHT + 3,156 + hamburgerWidth, 236+ fr.FONT_HEIGHT + 3, 0xFF222222);
-
- GlStateManager.pushMatrix();
- clip(scissor.x + 6+hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230);
- GlStateManager.translate(6+hamburgerWidth, 5+fr.FONT_HEIGHT+3, 0);
- int culmutativeY = 0;
- int relSelectedY = selectedY - (5+ fr.FONT_HEIGHT + 3);
- boolean drewit = false;
- for (String datarenderers : feature.>getParameter("datarenderers").getValue()) {
-
- if (0 <= selectedX && selectedX <= hamburgerWidth+11 && currentlySelected != null) {
- DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(currentlySelected);
- Dimension dim;
- if (dataRenderer == null) dim = new Dimension(0,fr.FONT_HEIGHT*2);
- else dim = dataRenderer.getDimension();
-
- if (culmutativeY + dim.height > relSelectedY && relSelectedY >= culmutativeY && !drewit) {
- clip(scissor.x + 6 + hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230);
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- if (dataRenderer == null) {
- fr.drawString("Couldn't find Datarenderer", 0,0, 0xFFFF0000);
- fr.drawString(currentlySelected, 0,fr.FONT_HEIGHT, 0xFFFF0000);
- dim = new Dimension(0, fr.FONT_HEIGHT * 2);
- } else {
- GlStateManager.pushMatrix();
- dim = dataRenderer.renderDummy();
- GlStateManager.popMatrix();
- }
- clip(scissor.x, scissor.y, scissor.width, scissor.height);
- GlStateManager.translate(-hamburgerWidth-1, 0, 0);
- Gui.drawRect(0,0, hamburgerWidth, dim.height-1, 0xFF777777);
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- fr.drawString("=",fr.getStringWidth("=")/2,(dim.height - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
- GlStateManager.translate(hamburgerWidth+1,dim.height,0);
- drewit = true;
- }
- }
-
- DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers);
- clip(scissor.x + 6 + hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230);
- Dimension dim;
-
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- if (dataRenderer == null) {
- fr.drawString("Couldn't find Datarenderer", 0,0, 0xFFFF0000);
- fr.drawString(datarenderers, 0,fr.FONT_HEIGHT, 0xFFFF0000);
- dim = new Dimension(0, fr.FONT_HEIGHT * 2);
- } else {
- GlStateManager.pushMatrix();
- dim = dataRenderer.renderDummy();
- GlStateManager.popMatrix();
- }
- clip(scissor.x, scissor.y, scissor.width, scissor.height);
- GlStateManager.translate(-hamburgerWidth-1, 0, 0);
- Gui.drawRect(0,0, hamburgerWidth, dim.height-1, 0xFFAAAAAA);
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- fr.drawString("=",fr.getStringWidth("=")/2,(dim.height - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
- GlStateManager.translate(hamburgerWidth+1,dim.height,0);
-
- culmutativeY += dim.height;
- }
-
- if (currentlySelected != null && new Rectangle(0,5+fr.FONT_HEIGHT + 3, hamburgerWidth+11, 232).contains(selectedX, selectedY) && !drewit) {
- DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(currentlySelected);
- Dimension dim;
- clip(scissor.x + 6 + hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230);
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- if (dataRenderer == null) {
- fr.drawString("Couldn't find Datarenderer", 0,0, 0xFFFF0000);
- fr.drawString(currentlySelected, 0,fr.FONT_HEIGHT, 0xFFFF0000);
- dim = new Dimension(0, fr.FONT_HEIGHT * 2);
- } else {
- GlStateManager.pushMatrix();
- dim = dataRenderer.renderDummy();
- GlStateManager.popMatrix();
- }
- clip(scissor.x, scissor.y, scissor.width, scissor.height);
- GlStateManager.translate(-hamburgerWidth-1, 0, 0);
- Gui.drawRect(0,0, hamburgerWidth, dim.height-1, 0xFF777777);
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- fr.drawString("=",fr.getStringWidth("=")/2,(dim.height - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
- GlStateManager.translate(hamburgerWidth+1,dim.height,0);
- }
- GlStateManager.popMatrix();
-
-
- GlStateManager.pushMatrix();
- GlStateManager.translate(156+hamburgerWidth, 5+fr.FONT_HEIGHT+3 - scrollY, 0);
-
- Set rest = new HashSet<>(DataRendererRegistry.getValidDataRenderer());
- rest.removeAll( feature.>getParameter("datarenderers").getValue());
- rest.remove(currentlySelected);
- for (String datarenderers : rest) {
- DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers);
- clip(scissor.x + 156 + hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230);
- Dimension dim;
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- if (dataRenderer == null) {
- fr.drawString("Couldn't find Datarenderer", 0,0, 0xFFFF0000);
- fr.drawString(datarenderers, 0,fr.FONT_HEIGHT, 0xFFFF0000);
- dim = new Dimension(0, fr.FONT_HEIGHT * 2);
- } else {
- GlStateManager.pushMatrix();
- dim = dataRenderer.renderDummy();
- GlStateManager.popMatrix();
- }
- clip(scissor.x + 155, scissor.y + 5+fr.FONT_HEIGHT+3, hamburgerWidth, 230);
- GlStateManager.translate(-hamburgerWidth-1, 0, 0);
- Gui.drawRect(0,0, hamburgerWidth, dim.height-1, 0xFFAAAAAA);
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- fr.drawString("=",fr.getStringWidth("=")/2,(dim.height - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
- GlStateManager.translate(hamburgerWidth+1,dim.height,0);
- }
- GlStateManager.popMatrix();
- clip(0,0,sr.getScaledWidth(), sr.getScaledHeight());
- {
- if (currentlySelected != null) {
- GlStateManager.pushMatrix();
- GlStateManager.translate(selectedX+hamburgerWidth+1, selectedY, 0);
- DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(currentlySelected);
- Dimension dim;
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- if (dataRenderer == null) {
- fr.drawString("Couldn't find Datarenderer", 0, 0, 0xFFFF0000);
- fr.drawString(currentlySelected, 0, fr.FONT_HEIGHT, 0xFFFF0000);
- dim = new Dimension(0, fr.FONT_HEIGHT * 2);
- } else {
- GlStateManager.pushMatrix();
- dim = dataRenderer.renderDummy();
- GlStateManager.popMatrix();
- }
- GlStateManager.translate(-hamburgerWidth-1, 0, 0);
- Gui.drawRect(0,0, hamburgerWidth, dim.height-1, 0xFFAAAAAA);
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- fr.drawString("=",fr.getStringWidth("=")/2,(dim.height - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
- GlStateManager.popMatrix();
- }
- }
- clip(scissor.x, scissor.y, scissor.width, scissor.height);
- }
-
- @Override
- public void mouseClicked(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int mouseButton) {
- super.mouseClicked(absMouseX, absMouseY, relMouseX, relMouseY, mouseButton);
- lastX = relMouseX;
- lastY = relMouseY;
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- int legitRelY = relMouseY - (5+fr.FONT_HEIGHT+3);
- if (new Rectangle(155,5+fr.FONT_HEIGHT + 3, hamburgerWidth, 230).contains(relMouseX, relMouseY)) {
- Set rest = new HashSet<>(DataRendererRegistry.getValidDataRenderer());
- rest.removeAll( feature.>getParameter("datarenderers").getValue());
- rest.remove(currentlySelected);
- int culmutativeY = -scrollY;
- for (String datarenderers : rest) {
- DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers);
- Dimension dim;
- if (dataRenderer == null) {
- dim = new Dimension(0, fr.FONT_HEIGHT * 2);
- } else {
- GlStateManager.pushMatrix();
- dim = dataRenderer.getDimension();
- GlStateManager.popMatrix();
- }
- culmutativeY += dim.height;
-
- if (legitRelY < culmutativeY) {
- currentlySelected = datarenderers;
- selectedX = 155;
- selectedY = culmutativeY - dim.height + 5+fr.FONT_HEIGHT + 3;
- break;
- }
- }
- }
- if (new Rectangle(5,5+fr.FONT_HEIGHT + 3, hamburgerWidth, 230).contains(relMouseX, relMouseY)) {
- List rest = feature.>getParameter("datarenderers").getValue();
- int culmutativeY = 0;
- for (String datarenderers : rest) {
- DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers);
- Dimension dim;
- if (dataRenderer == null) {
- dim = new Dimension(0, fr.FONT_HEIGHT * 2);
- } else {
- GlStateManager.pushMatrix();
- dim = dataRenderer.getDimension();
- GlStateManager.popMatrix();
- }
- culmutativeY += dim.height;
-
- if (legitRelY < culmutativeY) {
- currentlySelected = datarenderers;
- selectedX = 5;
- selectedY = culmutativeY - dim.height + 5+fr.FONT_HEIGHT + 3;
- rest.remove(datarenderers);
- break;
- }
- }
- }
- }
-
- @Override
- public void mouseClickMove(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int clickedMouseButton, long timeSinceLastClick) {
- super.mouseClickMove(absMouseX, absMouseY, relMouseX, relMouseY, clickedMouseButton, timeSinceLastClick);
- if (currentlySelected != null) {
- int dx = relMouseX - lastX;
- int dy = relMouseY - lastY;
- selectedX += dx;
- selectedY += dy;
- }
- lastX = relMouseX;
- lastY = relMouseY;
- }
-
- @Override
- public void mouseReleased(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int state) {
- super.mouseReleased(absMouseX, absMouseY, relMouseX, relMouseY, state);
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- int legitRelY = selectedY - (5+fr.FONT_HEIGHT+3);
- if (currentlySelected != null && new Rectangle(0,5+fr.FONT_HEIGHT + 3, hamburgerWidth+11, 232).contains(selectedX, selectedY)) {
- Set rest = new HashSet<>(DataRendererRegistry.getValidDataRenderer());
- int culmutativeY = 0;
- List asdasdkasd = feature.>getParameter("datarenderers").getValue();
- int index = asdasdkasd.size();
- for (int i = 0; i 0) scrollY -= 20;
- if (scrollY < 0) scrollY = 0;
-
-
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererFairySouls.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererFairySouls.java
deleted file mode 100644
index e2895967..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererFairySouls.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-
-import java.awt.*;
-
-public class DataRendererFairySouls implements DataRenderer {
- @Override
- public Dimension renderData(PlayerProfile playerProfile) {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- fr.drawString("§eFairy Souls §f"+playerProfile.getFairySouls(), 0,0,-1);
- return new Dimension(100, fr.FONT_HEIGHT);
- }
-
- @Override
- public Dimension renderDummy() {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- fr.drawString("§eFairy Souls §f300", 0,0,-1);
- return new Dimension(100, fr.FONT_HEIGHT);
- }
- @Override
- public Dimension getDimension() {
- return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT);
- }
-
- @Override
- public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererLilyWeight.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererLilyWeight.java
deleted file mode 100644
index fa9ecf65..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererLilyWeight.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile;
-import kr.syeyoung.dungeonsguide.utils.TextUtils;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraft.item.ItemStack;
-import net.minecraftforge.fml.client.config.GuiUtils;
-
-import java.awt.*;
-import java.util.Arrays;
-
-public class DataRendererLilyWeight implements DataRenderer {
- @Override
- public Dimension renderData(PlayerProfile playerProfile) {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- if (playerProfile.getLilyWeight() == null)
- fr.drawString("§eLily Weight §cAPI DISABLED", 0,0,-1);
- else
- fr.drawString("§eLily Weight §b"+String.format("%.3f", playerProfile.getLilyWeight().getTotal()), 0,0,-1);
- return new Dimension(100, fr.FONT_HEIGHT);
- }
-
- @Override
- public Dimension renderDummy() {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- fr.drawString("§eLily Weight §b300", 0,0,-1);
- return new Dimension(100, fr.FONT_HEIGHT);
- }
- @Override
- public Dimension getDimension() {
- return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT);
- }
-
- @Override
- public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
- PlayerProfile.LilyWeight lilyWeight= playerProfile.getLilyWeight();
- if (lilyWeight == null) return;
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
- GuiUtils.drawHoveringText(Arrays.asList(
- "§bDungeon Weights§7: §e"+ String.format("%.3f",lilyWeight.getCatacombs_base()+lilyWeight.getCatacombs_master()+lilyWeight.getCatacombs_exp()),
- " §bCatacomb Completion§7: §e"+String.format("%.3f",lilyWeight.getCatacombs_base()),
- " §bMaster Completion§7: §e"+String.format("%.3f", lilyWeight.getCatacombs_master()),
- " §bExperience§7: §e"+String.format("%.3f", lilyWeight.getCatacombs_exp()),
- "§bSkill Weights§7: §e"+ String.format("%.3f", lilyWeight.getSkill_base() + lilyWeight.getSkill_overflow()),
- " §bSkill Weight§7: §e"+String.format("%.3f", lilyWeight.getSkill_base()),
- " §bOverflow Weight§7: §e"+String.format("%.3f", lilyWeight.getSkill_overflow()),
- "§bSlayer Weight§7: §e"+String.format("%.3f", lilyWeight.getSlayer()),
- "§bTotal§7: §e"+String.format("%.3f", lilyWeight.getTotal())
- ),mouseX, mouseY,
- scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererRegistry.java
deleted file mode 100644
index 56e69feb..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererRegistry.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.DungeonClass;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.DungeonType;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.Skill;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-public class DataRendererRegistry {
- private static final Map dataRendererMap = new HashMap<>();
-
- public static DataRenderer getDataRenderer(String id) {
- return dataRendererMap.get(id);
- }
-
- public static Set getValidDataRenderer() {
- return dataRendererMap.keySet();
- }
-
- static {
- dataRendererMap.put("catalv", new DataRendererDungeonLv(DungeonType.CATACOMBS));
- for (DungeonClass value : DungeonClass.values()) {
- dataRendererMap.put("class_"+value.getJsonName()+"_lv", new DataRendererClassLv(value));
- }
- dataRendererMap.put("selected_class_lv", new DataRendererSelectedClassLv());
- for (Skill value : Skill.values()) {
- dataRendererMap.put("skill_"+value.getJsonName()+"_lv", new DataRendererSkillLv(value));
- }
- for (DungeonType value : DungeonType.values()) {
- for (Integer validFloor : value.getValidFloors()) {
- dataRendererMap.put("dungeon_"+value.getJsonName()+"_"+validFloor+"_stat", new DataRenderDungeonFloorStat(value, validFloor));
- }
- dataRendererMap.put("dungeon_"+value.getJsonName()+"_higheststat", new DataRenderDungeonHighestFloorStat(value));
- }
- dataRendererMap.put("fairysouls", new DataRendererFairySouls());
- dataRendererMap.put("secrets", new DataRendererSecrets());
-
- dataRendererMap.put("dummy", new DataRendererSetUrOwn());
-
- dataRendererMap.put("talismans", new DataRendererTalismans());
- dataRendererMap.put("weight", new DataRendererLilyWeight());
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSecrets.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSecrets.java
deleted file mode 100644
index 81f08c95..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSecrets.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-
-import java.awt.*;
-import java.util.stream.Collectors;
-
-public class DataRendererSecrets implements DataRenderer {
- @Override
- public Dimension renderData(PlayerProfile playerProfile) {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- double theint = playerProfile.getTotalSecrets()/ (double)playerProfile.getDungeonStats().values().stream().flatMap(s -> s.getData().getPlays().values().stream())
- .map(fs -> fs.getData().getWatcherKills()).reduce(0, Integer::sum);
- fr.drawString("§eSecrets §b"+playerProfile.getTotalSecrets()+" §7("+
- String.format("%.2f", theint)+"/run)", 0,0,-1);
- return new Dimension(100, fr.FONT_HEIGHT);
- }
-
- @Override
- public Dimension renderDummy() {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- fr.drawString("§eSecrets §b99999 §7(X/run)", 0,0,-1);
- return new Dimension(100, fr.FONT_HEIGHT);
- }
- @Override
- public Dimension getDimension() {
- return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT);
- }
-
- @Override
- public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSelectedClassLv.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSelectedClassLv.java
deleted file mode 100644
index 94bc3542..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSelectedClassLv.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.ClassSpecificData;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile;
-import kr.syeyoung.dungeonsguide.utils.RenderUtils;
-import kr.syeyoung.dungeonsguide.utils.TextUtils;
-import kr.syeyoung.dungeonsguide.utils.XPUtils;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraftforge.fml.client.config.GuiUtils;
-
-import java.awt.*;
-import java.util.Arrays;
-
-public class DataRendererSelectedClassLv implements DataRenderer {
- @Override
- public Dimension renderData(PlayerProfile playerProfile) {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- ClassSpecificData dungeonStatDungeonSpecificData = playerProfile.getPlayerClassData().get(playerProfile.getSelectedClass());
- if (dungeonStatDungeonSpecificData == null) {
- fr.drawString("Unknown Selected", 0,0, 0xFF55ffff);
- } else {
- XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(dungeonStatDungeonSpecificData.getData().getExperience());
- fr.drawString(playerProfile.getSelectedClass().getFamilarName(), 0,0, 0xFF55ffff);
- fr.drawString(xpCalcResult.getLevel()+"", fr.getStringWidth(playerProfile.getSelectedClass().getFamilarName()+" "),0,0xFFFFFFFF);
- fr.drawString("★", fr.getStringWidth(playerProfile.getSelectedClass().getFamilarName()+" "+xpCalcResult.getLevel()+" "),0,0xFFAAAAAA);
-
- RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,xpCalcResult.getRemainingXp() == 0 ? 1 : (float) (xpCalcResult.getRemainingXp() / xpCalcResult.getNextLvXp()));
- }
-
- return new Dimension(100, fr.FONT_HEIGHT*2);
- }
-
- @Override
- public Dimension renderDummy() {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- fr.drawString("SelectedClass", 0,0, 0xFF55ffff);
- fr.drawString("99", fr.getStringWidth("SelectedClass "),0,0xFFFFFFFF);
- fr.drawString("★", fr.getStringWidth("SelectedClass 99 "),0,0xFFAAAAAA);
- RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,1.0f);
- return new Dimension(100, fr.FONT_HEIGHT*2);
- }
- @Override
- public Dimension getDimension() {
- return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*2);
- }
-
- @Override
- public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
- ClassSpecificData dungeonStatDungeonSpecificData = playerProfile.getPlayerClassData().get(playerProfile.getSelectedClass());
- if (dungeonStatDungeonSpecificData == null) return;
- XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(dungeonStatDungeonSpecificData.getData().getExperience());
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
- GuiUtils.drawHoveringText(Arrays.asList("§bCurrent Lv§7: §e"+xpCalcResult.getLevel(),"§bExp§7: §e"+ TextUtils.format((long)xpCalcResult.getRemainingXp()) + "§7/§e"+TextUtils.format((long)xpCalcResult.getNextLvXp()), "§bTotal Xp§7: §e"+ TextUtils.format((long)dungeonStatDungeonSpecificData.getData().getExperience())),mouseX, mouseY,
- scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSetUrOwn.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSetUrOwn.java
deleted file mode 100644
index eff18d13..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSetUrOwn.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-
-import java.awt.*;
-
-public class DataRendererSetUrOwn implements DataRenderer {
- @Override
- public Dimension renderData(PlayerProfile playerProfile) {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- fr.drawString("§aCustomize at /dg", 0,0,-1);
- fr.drawString("§a-> Party Kicker", 0,fr.FONT_HEIGHT,-1);
- fr.drawString("§a-> View Player Stats", 0,fr.FONT_HEIGHT*2,-1);
- fr.drawString("§a-> Edit", 0,fr.FONT_HEIGHT*3,-1);
- return new Dimension(100, fr.FONT_HEIGHT*4);
- }
-
- @Override
- public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
-
- }
-
- @Override
- public Dimension renderDummy() {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- fr.drawString("§aCustomize at /dg", 0,0,-1);
- fr.drawString("§a-> Party Kicker", 0,fr.FONT_HEIGHT,-1);
- fr.drawString("§a-> View Player Stats", 0,fr.FONT_HEIGHT*2,-1);
- fr.drawString("§a-> Edit", 0,fr.FONT_HEIGHT*3,-1);
- return new Dimension(100, fr.FONT_HEIGHT*4);
- }
- @Override
- public Dimension getDimension() {
- return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*4);
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSkillLv.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSkillLv.java
deleted file mode 100644
index 58fbb782..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSkillLv.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.Skill;
-import kr.syeyoung.dungeonsguide.utils.RenderUtils;
-import kr.syeyoung.dungeonsguide.utils.TextUtils;
-import kr.syeyoung.dungeonsguide.utils.XPUtils;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraftforge.fml.client.config.GuiUtils;
-
-import java.awt.*;
-import java.util.Arrays;
-
-public class DataRendererSkillLv implements DataRenderer {
- private final Skill skill;
- public DataRendererSkillLv(Skill skill) {
- this.skill = skill;
- }
- @Override
- public Dimension renderData(PlayerProfile playerProfile) {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- Double xp = playerProfile.getSkillXp().get(skill);
- if (xp == null) {
- fr.drawString(skill.getFriendlyName(), 0,0, 0xFF55ffff);
- fr.drawString("§cSkill API Disabled", 0, fr.FONT_HEIGHT,0xFFFFFFFF);
- } else {
- XPUtils.XPCalcResult xpCalcResult = XPUtils.getSkillXp(skill, xp);
- fr.drawString(skill.getFriendlyName(), 0,0, 0xFF55ffff);
- fr.drawString(xpCalcResult.getLevel()+"", fr.getStringWidth(skill.getFriendlyName()+" "),0,0xFFFFFFFF);
-
- RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,xpCalcResult.getRemainingXp() == 0 ? 1 : (float) (xpCalcResult.getRemainingXp() / xpCalcResult.getNextLvXp()));
- }
-
- return new Dimension(100, fr.FONT_HEIGHT*2);
- }
-
- @Override
- public Dimension renderDummy() {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- fr.drawString(skill.getFriendlyName(), 0,0, 0xFF55ffff);
- fr.drawString("99", fr.getStringWidth(skill.getFriendlyName()+" "),0,0xFFFFFFFF);
- RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,1.0f);
- return new Dimension(100, fr.FONT_HEIGHT*2);
- }
- @Override
- public Dimension getDimension() {
- return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*2);
- }
-
- @Override
- public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
- Double xp = playerProfile.getSkillXp().get(skill);
- if (xp == null) return;
- XPUtils.XPCalcResult xpCalcResult = XPUtils.getSkillXp(skill, xp);
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
- GuiUtils.drawHoveringText(Arrays.asList("§bCurrent Lv§7: §e"+xpCalcResult.getLevel(),"§bExp§7: §e"+ TextUtils.format((long)xpCalcResult.getRemainingXp()) + "§7/§e"+TextUtils.format((long)xpCalcResult.getNextLvXp()), "§bTotal Xp§7: §e"+ TextUtils.format(xp.longValue())),mouseX, mouseY,
- scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererTalismans.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererTalismans.java
deleted file mode 100644
index d94ae506..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererTalismans.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraft.item.ItemStack;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.nbt.NBTTagList;
-import net.minecraftforge.fml.client.config.GuiUtils;
-
-import java.awt.*;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class DataRendererTalismans implements DataRenderer {
- @Override
- public Dimension renderData(PlayerProfile playerProfile) {
- boolean apiDisabled = playerProfile.getTalismans() == null || playerProfile.getInventory() == null;
- if (!playerProfile.getAdditionalProperties().containsKey("talismanCnt") && !apiDisabled) {
- int[] cnts = new int[Rarity.values().length];
- for (ItemStack talisman : playerProfile.getTalismans()) {
- if (talisman == null) continue;
- Rarity r = getRarity(talisman);
- if (r != null) cnts[r.ordinal()]++;
- }
- for (ItemStack itemStack : playerProfile.getInventory()) {
- if (itemStack == null) continue;
- Rarity r = getRarity(itemStack);
- if (r != null) cnts[r.ordinal()]++;
- }
- playerProfile.getAdditionalProperties().put("talismanCnt", cnts);
- }
- int[] rawData = (int[]) playerProfile.getAdditionalProperties().get("talismanCnt");
-
- String str = "";
- if (rawData != null)
- for (Rarity r : Rarity.values()) {
- str = r.color+rawData[r.idx] +" "+ str;
- }
-
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- if (apiDisabled)
- fr.drawString("§eTalis §cAPI DISABLED", 0,0,-1);
- else
- fr.drawString("§eTalis §f"+str, 0,0,-1);
- return new Dimension(100, fr.FONT_HEIGHT);
- }
-
- private Rarity getRarity(ItemStack itemStack) {
- NBTTagCompound display = itemStack.getTagCompound().getCompoundTag("display");
- if (display == null) return null;
- NBTTagList lore = display.getTagList("Lore", 8);
- if (lore == null) return null;
- for (int i = 0; i < lore.tagCount(); i++) {
- String line = lore.getStringTagAt(i);
- for (Rarity value : Rarity.values()) {
- if (line.startsWith(value.getColor()) && line.contains("CCESSORY")) return value;
- }
- }
- return null;
- }
-
- @Override
- public Dimension renderDummy() {
- String str = "";
- for (Rarity r : Rarity.values()) {
- str = r.color+(r.idx+5)*2+" "+str;
- }
-
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- fr.drawString("§eTalis §f"+str, 0,0,-1);
- return new Dimension(100, fr.FONT_HEIGHT);
- }
- @Override
- public Dimension getDimension() {
- return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT);
- }
-
- @Override
- public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
- int[] rawData = (int[]) playerProfile.getAdditionalProperties().get("talismanCnt");
- if (rawData == null) return;
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
- List list = new ArrayList<>();
-
- for (Rarity r : Rarity.values()) {
- list.add(r.getColor()+r.name()+"§7: §e"+rawData[r.idx]);
- }
- GuiUtils.drawHoveringText(list,mouseX, mouseY,
- scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
- }
-
-
- @AllArgsConstructor @Getter
- public static enum Rarity {
- COMMON("§f", 0), UNCOMMON("§a",1), RARE("§9",2), EPIC("§5",3), LEGENDARY("§6",4), MYTHIC("§d",5);
-
- private String color;
- private int idx;
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/FakePlayer.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/FakePlayer.java
new file mode 100644
index 00000000..ec8a29d9
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/FakePlayer.java
@@ -0,0 +1,101 @@
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
+
+import com.google.common.base.Objects;
+import com.mojang.authlib.GameProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.SkinFetcher;
+import kr.syeyoung.dungeonsguide.utils.TextUtils;
+import lombok.Getter;
+import lombok.Setter;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityOtherPlayerMP;
+import net.minecraft.client.resources.DefaultPlayerSkin;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.scoreboard.ScorePlayerTeam;
+import net.minecraft.scoreboard.Team;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.world.World;
+
+public class FakePlayer extends EntityOtherPlayerMP {
+ @Setter
+ @Getter
+ private PlayerProfile skyblockProfile;
+ private final SkinFetcher.SkinSet skinSet;
+ private final PlayerProfile.Armor armor;
+ @Getter
+ private final int profileNumber;
+
+ private FakePlayer(World w) {
+ super(w, null);
+ throw new UnsupportedOperationException("what");
+ }
+
+ public FakePlayer(GameProfile playerProfile, SkinFetcher.SkinSet skinSet, PlayerProfile skyblockProfile, int profileNumber) {
+ super(Minecraft.getMinecraft().theWorld, playerProfile);
+ this.profileNumber = profileNumber;
+ this.skyblockProfile = skyblockProfile;
+ this.skinSet = skinSet;
+ armor = skyblockProfile.getCurrentArmor();
+ this.inventory.armorInventory = skyblockProfile.getCurrentArmor().getArmorSlots();
+
+ int highestDungeonScore = Integer.MIN_VALUE;
+ if (skyblockProfile.getInventory() != null) {
+ ItemStack highestItem = null;
+ for (ItemStack itemStack : skyblockProfile.getInventory()) {
+ if (itemStack == null) continue;
+ NBTTagCompound display = itemStack.getTagCompound().getCompoundTag("display");
+ if (display == null) continue;
+ NBTTagList nbtTagList = display.getTagList("Lore", 8);
+ if (nbtTagList == null) continue;
+ for (int i = 0; i < nbtTagList.tagCount(); i++) {
+ String str = nbtTagList.getStringTagAt(i);
+ if (TextUtils.stripColor(str).startsWith("Gear")) {
+ int dungeonScore = Integer.parseInt(TextUtils.keepIntegerCharactersOnly(TextUtils.stripColor(str).split(" ")[2]));
+ if (dungeonScore > highestDungeonScore) {
+ highestItem = itemStack;
+ highestDungeonScore = dungeonScore;
+ }
+ }
+ }
+ }
+
+ this.inventory.mainInventory[0] = highestItem;
+ this.inventory.currentItem = 0;
+ }
+ }
+
+ public String getSkinType() {
+ return this.skinSet == null ? DefaultPlayerSkin.getSkinType(getGameProfile().getId()) : this.skinSet.getSkinType();
+ }
+
+ public ResourceLocation getLocationSkin() {
+ return Objects.firstNonNull(skinSet.getSkinLoc(), DefaultPlayerSkin.getDefaultSkin(getGameProfile().getId()));
+ }
+
+ public ResourceLocation getLocationCape() {
+ return skinSet.getCapeLoc();
+ }
+
+ @Override
+ public ItemStack[] getInventory() {
+ return this.inventory.armorInventory;
+ }
+
+ @Override
+ public boolean isInvisibleToPlayer(EntityPlayer player) {
+ return true;
+ }
+
+ @Override
+ public Team getTeam() {
+ return new ScorePlayerTeam(null, null) {
+ @Override
+ public EnumVisible getNameTagVisibility() {
+ return EnumVisible.NEVER;
+ }
+ };
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/FeatureViewPlayerOnJoin.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/FeatureViewPlayerOnJoin.java
deleted file mode 100644
index ceca0022..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/FeatureViewPlayerOnJoin.java
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
-
-import com.google.common.base.Supplier;
-import com.mojang.authlib.GameProfile;
-import io.github.moulberry.hychat.HyChat;
-import io.github.moulberry.hychat.chat.ChatManager;
-import io.github.moulberry.hychat.gui.GuiChatBox;
-import kr.syeyoung.dungeonsguide.DungeonsGuide;
-import kr.syeyoung.dungeonsguide.chat.ChatProcessor;
-import kr.syeyoung.dungeonsguide.chat.PartyManager;
-import kr.syeyoung.dungeonsguide.config.guiconfig.ConfigPanelCreator;
-import kr.syeyoung.dungeonsguide.config.guiconfig.MFeatureEdit;
-import kr.syeyoung.dungeonsguide.config.guiconfig.MParameterEdit;
-import kr.syeyoung.dungeonsguide.config.guiconfig.RootConfigPanel;
-import kr.syeyoung.dungeonsguide.cosmetics.ActiveCosmetic;
-import kr.syeyoung.dungeonsguide.cosmetics.CosmeticData;
-import kr.syeyoung.dungeonsguide.features.FeatureParameter;
-import kr.syeyoung.dungeonsguide.features.FeatureRegistry;
-import kr.syeyoung.dungeonsguide.features.SimpleFeature;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.*;
-import kr.syeyoung.dungeonsguide.features.listener.ChatListener;
-import kr.syeyoung.dungeonsguide.features.listener.GuiClickListener;
-import kr.syeyoung.dungeonsguide.features.listener.GuiPostRenderListener;
-import kr.syeyoung.dungeonsguide.gui.MPanel;
-import kr.syeyoung.dungeonsguide.utils.TextUtils;
-import lombok.Getter;
-import lombok.Setter;
-import lombok.SneakyThrows;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.entity.EntityOtherPlayerMP;
-import net.minecraft.client.gui.*;
-import net.minecraft.client.gui.inventory.GuiInventory;
-import net.minecraft.client.renderer.GlStateManager;
-import net.minecraft.client.renderer.RenderHelper;
-import net.minecraft.client.resources.DefaultPlayerSkin;
-import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.event.HoverEvent;
-import net.minecraft.item.ItemStack;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.nbt.NBTTagList;
-import net.minecraft.scoreboard.ScorePlayerTeam;
-import net.minecraft.scoreboard.Team;
-import net.minecraft.util.*;
-import net.minecraft.world.World;
-import net.minecraftforge.client.event.ClientChatReceivedEvent;
-import net.minecraftforge.client.event.GuiScreenEvent;
-import net.minecraftforge.fml.client.config.GuiUtils;
-import net.minecraftforge.fml.common.Loader;
-import org.lwjgl.input.Mouse;
-import org.lwjgl.opengl.GL11;
-import org.lwjgl.opengl.GL14;
-
-import java.awt.*;
-import java.util.*;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-public class FeatureViewPlayerOnJoin extends SimpleFeature implements GuiPostRenderListener, ChatListener, GuiClickListener {
-
- public FeatureViewPlayerOnJoin() {
- super("Party", "View player stats when join", "view player rendering when joining/someone joins the party", "partykicker.viewstats", true);
- this.parameters.put("datarenderers", new FeatureParameter>("datarenderers", "DataRenderers","Datarenderssdasd", new ArrayList<>(Arrays.asList(
- "catalv", "selected_class_lv", "dungeon_catacombs_higheststat", "dungeon_master_catacombs_higheststat", "skill_combat_lv", "skill_foraging_lv", "skill_mining_lv", "fairysouls", "dummy"
- )), "stringlist"));
- }
-
- private Rectangle popupRect;
- private String lastuid; // actually current uid
- private Future> profileFuture;
- private Future> gfFuture;
- private Future skinFuture;
- private FakePlayer fakePlayer;
- private boolean drawInv = false;
- @SneakyThrows
- @Override
- public void onGuiPostRender(GuiScreenEvent.DrawScreenEvent.Post rendered) {
- if (!(Minecraft.getMinecraft().currentScreen instanceof GuiChat)) {
- cancelRender();
- return;
- }
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
- IChatComponent ichatcomponent = getHoveredComponent(scaledResolution);
- String uid = null;
- if (ichatcomponent != null && ichatcomponent.getChatStyle().getChatHoverEvent() instanceof HoverEventRenderPlayer) {
- uid = ((HoverEventRenderPlayer) ichatcomponent.getChatStyle().getChatHoverEvent()).getUuid();
- }
- reqRender(uid);
- }
-
- public void cancelRender() {
- popupRect = null;
- profileFuture = null;
- lastuid = null;
- gfFuture = null;
- skinFuture= null;
- fakePlayer= null;
- drawInv = false;
- }
-
- public void reqRender(String uid) {
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
- int width = scaledResolution.getScaledWidth();
- int height = scaledResolution.getScaledHeight();
- int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
- int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
-
-
- if (!((popupRect != null && (popupRect.contains(mouseX, mouseY) || drawInv)) || uid != null && uid.equals(lastuid))) {
- cancelRender();
- }
-
- if (uid != null && !uid.equals(lastuid) && (popupRect==null || (!popupRect.contains(mouseX, mouseY) && !drawInv)) ) {
- cancelRender();
- lastuid = uid;
- }
- if (lastuid == null) return;
-
-
- if (popupRect == null) {
- popupRect = new Rectangle(mouseX, mouseY, 220, 220);
- if (popupRect.y + popupRect.height > scaledResolution.getScaledHeight()) {
- popupRect.y -= popupRect.y + popupRect.height - scaledResolution.getScaledHeight();
- }
- }
-
- if (profileFuture == null) {
- profileFuture = ApiFetchur.fetchMostRecentProfileAsync(lastuid, FeatureRegistry.PARTYKICKER_APIKEY.getAPIKey());
- }
-
- if (gfFuture == null) {
- gfFuture = ApiFetchur.getSkinGameProfileByUUIDAsync(lastuid);
- }
- boolean plsSetAPIKEY = false;
- if (skinFuture == null && gfFuture.isDone()) {
- try {
- skinFuture = SkinFetchur.getSkinSet(gfFuture.get().orElse(null));
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
- }
- }
-
- try {
- if (fakePlayer == null && skinFuture != null && profileFuture != null && skinFuture.isDone() && profileFuture.isDone() && profileFuture.get().isPresent()) {
- fakePlayer = new FakePlayer(gfFuture.get().orElse(null), skinFuture.get(), profileFuture.get().orElse(null));
- }
- } catch (InterruptedException | ExecutionException e) {
- plsSetAPIKEY = true;
- }
-
-
- try {
- render(popupRect, scaledResolution, mouseX, mouseY, plsSetAPIKEY ? null : (profileFuture.isDone() ? profileFuture.get() : null), plsSetAPIKEY);
- } catch (InterruptedException | ExecutionException e) {
- }
-
- }
-
- public static void clip(ScaledResolution resolution, int x, int y, int width, int height) {
- if (width < 0 || height < 0) return;
-
- int scale = resolution.getScaleFactor();
- GL11.glScissor((x ) * scale, Minecraft.getMinecraft().displayHeight - (y + height) * scale, (width) * scale, height * scale);
- }
- private void render(Rectangle popupRect, ScaledResolution scaledResolution, int mouseX, int mouseY, Optional playerProfile, boolean apiKeyPlsSet) {
-
- GlStateManager.pushMatrix();
- GlStateManager.translate(popupRect.x, popupRect.y, 0);
- Gui.drawRect(0,0, popupRect.width, popupRect.height, 0xFF23272a);
- Gui.drawRect(2,2, popupRect.width-2, popupRect.height-2, 0XFF2c2f33);
-
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- if (apiKeyPlsSet) {
- Minecraft.getMinecraft().fontRendererObj.drawString("Please set API KEY on /dg -> Party Kicker", 5,5, 0xFFFFFFFF);
- GlStateManager.popMatrix();
- return;
- }
- if (playerProfile == null) {
- Minecraft.getMinecraft().fontRendererObj.drawString("Fetching data...", 5,5, 0xFFFFFFFF);
- GlStateManager.popMatrix();
- return;
- }
- if (!playerProfile.isPresent()) {
- Minecraft.getMinecraft().fontRendererObj.drawString("User could not be found", 5,5, 0xFFFFFFFF);
- GlStateManager.popMatrix();
- return;
- }
- int relX = mouseX - popupRect.x;
- int relY = mouseY - popupRect.y;
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
-
-
- GL11.glEnable(GL11.GL_SCISSOR_TEST);
- clip(scaledResolution, popupRect.x, popupRect.y, popupRect.width, popupRect.height);
-
- Gui.drawRect(0,168, 90, 195, 0xFF23272a);
- Gui.drawRect(2,170, 88, 193, new Rectangle(2,170,86,23).contains(relX, relY) ? 0xFFff7777 : 0xFFFF3333);
-
- Gui.drawRect(0,193, 90, 220, 0xFF23272a);
- Gui.drawRect(2,195, 88, 218, new Rectangle(2,195,86,23).contains(relX, relY) ? 0xFF859DF0 : 0xFF7289da);
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- fr.drawString("Kick", (90 - fr.getStringWidth("Kick")) / 2,(364 - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
- fr.drawString("Invite", (90 - fr.getStringWidth("Invite")) / 2,(414 - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
-
- GlStateManager.pushMatrix();
-
- GlStateManager.translate(95, 5, 0);
- int culmutativeY = 5;
- DataRenderer dataRendererToHover = null;
- for (String datarenderers : this.>getParameter("datarenderers").getValue()) {
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers);
- Dimension dim;
- if (dataRenderer == null) {
- fr.drawString("Couldn't find Datarenderer", 0,0, 0xFFFF0000);
- fr.drawString(datarenderers, 0,fr.FONT_HEIGHT, 0xFFFF0000);
- dim = new Dimension(0, fr.FONT_HEIGHT * 2);
- } else {
- GlStateManager.pushMatrix();
- dim = dataRenderer.renderData(playerProfile.get());
- GlStateManager.popMatrix();
- }
- if (relX >= 95 && relX <= popupRect.width && relY >= culmutativeY && relY < culmutativeY+dim.height && dataRenderer != null) {
- dataRendererToHover = dataRenderer;
- }
- culmutativeY += dim.height;
- GlStateManager.translate(0,dim.height,0);
- }
-
- GlStateManager.popMatrix();
-
- Gui.drawRect(0,0, 90, 170, 0xFF23272a);
- Gui.drawRect(2,2, 88, 168, 0xFF444444);
- Gui.drawRect(80,159, 90, 170, 0xFF23272a);
- Gui.drawRect(82,161, 88, 168, 0xFF444444);
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- fr.drawString("§eI", 83,161,-1);
- GlStateManager.color(1, 1, 1, 1.0F);
- if (fakePlayer != null) {
- clip(scaledResolution, popupRect.x+2, popupRect.y+2, 86, 166);
- GuiInventory.drawEntityOnScreen(45, 150, 60, -(mouseX - popupRect.x - 75), 0, fakePlayer);
-
- String toDraw = fakePlayer.getName();
- List activeCosmetics = DungeonsGuide.getDungeonsGuide().getCosmeticsManager().getActiveCosmeticByPlayer().get(UUID.fromString(TextUtils.insertDashUUID(playerProfile.get().getMemberUID())));
- CosmeticData prefix = null, color = null;
- if (activeCosmetics != null) {
- for (ActiveCosmetic activeCosmetic : activeCosmetics) {
- CosmeticData cosmeticData = DungeonsGuide.getDungeonsGuide().getCosmeticsManager().getCosmeticDataMap().get(activeCosmetic.getCosmeticData());
- if (cosmeticData != null) {
- if (cosmeticData.getCosmeticType().equals("prefix")) prefix = cosmeticData;
- if (cosmeticData.getCosmeticType().equals("color")) color = cosmeticData;
- }
- }
- }
- toDraw = (color == null ? "§e" : color.getData().replace("&", "§"))+toDraw;
- if (prefix != null) toDraw = prefix.getData().replace("&", "§") + " "+toDraw;
-
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- fr.drawString(toDraw, (90 - fr.getStringWidth(toDraw)) / 2, 15, -1);
-
- ItemStack toHover = null;
- if (relX > 20 && relX < 70) {
- if (33<=relY && relY <= 66) {
- toHover = fakePlayer.getInventory()[3];
- } else if (66 <= relY && relY <= 108) {
- toHover = fakePlayer.getInventory()[2];
- } else if (108 <= relY && relY <= 130) {
- toHover = fakePlayer.getInventory()[1];
- } else if (130 <= relY && relY <= 154) {
- toHover = fakePlayer.getInventory()[0];
- }
- } else if (relX > 0 && relX <= 20) {
- if (80 <= relY && relY <= 120) {
- toHover = fakePlayer.inventory.mainInventory[fakePlayer.inventory.currentItem];
- }
- }
-
- if (toHover != null) {
- List list = toHover.getTooltip(Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().gameSettings.advancedItemTooltips);
- for (int i = 0; i < list.size(); ++i) {
- if (i == 0) {
- list.set(i, toHover.getRarity().rarityColor + list.get(i));
- } else {
- list.set(i, EnumChatFormatting.GRAY + list.get(i));
- }
- }
- FontRenderer font = toHover.getItem().getFontRenderer(toHover);
- GlStateManager.popMatrix();
- GL11.glDisable(GL11.GL_SCISSOR_TEST);
- FontRenderer theRenderer = (font == null ? fr : font);
- GuiUtils.drawHoveringText(list,mouseX, mouseY, scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, theRenderer);
- GL11.glEnable(GL11.GL_SCISSOR_TEST);
- GlStateManager.pushMatrix();
- GlStateManager.translate(popupRect.x, popupRect.y, 0);
- }
- clip(scaledResolution, popupRect.x, popupRect.y, popupRect.width, popupRect.height);
- } else {
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- fr.drawString("Loading", 5,35, 0xFFEFFF00);
- }
-
- GlStateManager.popMatrix();
- GL11.glDisable(GL11.GL_SCISSOR_TEST);
- if (dataRendererToHover != null && !drawInv) {
- dataRendererToHover.onHover(playerProfile.get(), mouseX, mouseY);
- }
- GL11.glEnable(GL11.GL_SCISSOR_TEST);
- GlStateManager.pushMatrix();
- GlStateManager.translate(popupRect.x, popupRect.y, 0);
-
- if (drawInv) {
- int startX = 81;
- int startY = 86;
- clip(scaledResolution, popupRect.x+startX-1, popupRect.y+startY-1, 164, 74);
- GlStateManager.translate(startX,startY,1);
- Gui.drawRect(-1,-1,163,73, 0xFF000000);
- GlStateManager.disableLighting();
- ItemStack toHover = null;
- int rx = relX - startX;
- int ry = relY - startY;
-
- if (playerProfile.get().getInventory() != null) {
- GlStateManager.disableRescaleNormal();
- RenderHelper.enableGUIStandardItemLighting();
- GlStateManager.disableLighting();
- for (int i = 0; i < playerProfile.get().getInventory().length; i++) {
- int x = (i%9) * 18;
- int y = (i/9) * 18;
- if (x <= rx && rx list = toHover.getTooltip(Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().gameSettings.advancedItemTooltips);
- for (int i = 0; i < list.size(); ++i) {
- if (i == 0) {
- list.set(i, toHover.getRarity().rarityColor + list.get(i));
- } else {
- list.set(i, EnumChatFormatting.GRAY + list.get(i));
- }
- }
- FontRenderer font = toHover.getItem().getFontRenderer(toHover);
- GlStateManager.popMatrix();
- GL11.glDisable(GL11.GL_SCISSOR_TEST);
- FontRenderer theRenderer = (font == null ? fr : font);
- GuiUtils.drawHoveringText(list,mouseX, mouseY, scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, theRenderer);
- GL11.glEnable(GL11.GL_SCISSOR_TEST);
- GlStateManager.pushMatrix();
- }
- } else {
- Gui.drawRect(0,0,162,72, 0xFF666666);
- fr.drawSplitString("Player has disabled Inventory API", 5,5, 142, -1);
- }
-
- }
- GL11.glDisable(GL11.GL_SCISSOR_TEST);
-
-
- GlStateManager.popMatrix(); // 33 66 108 130 154 // 5 75
- }
- @Override
- public void onMouseInput(GuiScreenEvent.MouseInputEvent.Pre mouseInputEvent) {
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
- int width = scaledResolution.getScaledWidth();
- int height = scaledResolution.getScaledHeight();
- int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
- int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
-
- if (Mouse.getEventButton() != -1 && Mouse.isButtonDown(Mouse.getEventButton()) && drawInv) drawInv = false;
- if (popupRect == null || !popupRect.contains(mouseX, mouseY)) return;
-
- mouseInputEvent.setCanceled(true);
-
- int relX = mouseX - popupRect.x;
- int relY = mouseY - popupRect.y;
-
-
- try {
- PlayerProfile playerProfile = profileFuture.isDone() ? profileFuture.get().orElse(null) : null;
- if (playerProfile == null) return;
- if (Mouse.getEventButton() != -1 && Mouse.isButtonDown(Mouse.getEventButton())) {
- if (new Rectangle(2, 195, 86, 23).contains(relX, relY)) {
- // invite
- ChatProcessor.INSTANCE.addToChatQueue("/p invite " + ApiFetchur.fetchNicknameAsync(playerProfile.getMemberUID()).get().orElse("-"), () -> {}, true);
- } else if (new Rectangle(2, 170, 86, 23).contains(relX, relY)) {
- // kick
- ChatProcessor.INSTANCE.addToChatQueue("/p kick " + ApiFetchur.fetchNicknameAsync(playerProfile.getMemberUID()).get().orElse("-"), () -> {}, true);
- } else if (new Rectangle(80,159,10,11).contains(relX, relY)) {
- drawInv = true;
- }
- }
-
- } catch (InterruptedException | ExecutionException e) {
- }
-
-
- }
-
- public IChatComponent getHoveredComponent(ScaledResolution scaledResolution) {
- IChatComponent ichatcomponent = null;
- if (Loader.isModLoaded("hychat")) {
- try {
- ChatManager chatManager = HyChat.getInstance().getChatManager();
- GuiChatBox guiChatBox = chatManager.getFocusedChat();
-
- int x = guiChatBox.getX(scaledResolution);
- int y = guiChatBox.getY(scaledResolution);
- ichatcomponent = guiChatBox.chatArray.getHoveredComponent(guiChatBox.getSelectedTab().getChatLines(), Mouse.getX(), Mouse.getY(), x, y);
- } catch (Throwable t) {}
- }
- if (ichatcomponent == null) {
- ichatcomponent = Minecraft.getMinecraft().ingameGUI.getChatGUI().getChatComponent(Mouse.getX(), Mouse.getY());
- }
- return ichatcomponent;
- }
-
- @Override
- public void onChat(ClientChatReceivedEvent clientChatReceivedEvent) {
- if (!isEnabled()) return;
- String str = clientChatReceivedEvent.message.getFormattedText();
- if (str.contains("§r§ejoined the dungeon group! (§r§b")) {
- String username = TextUtils.stripColor(str).split(" ")[3];
- if (username.equalsIgnoreCase(Minecraft.getMinecraft().getSession().getUsername())) {
- PartyManager.INSTANCE.requestPartyList((context) -> {
- if (context == null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §cBugged Dungeon Party "));
- } else {
-
- for (String member : context.getPartyRawMembers()) {
- ApiFetchur.fetchUUIDAsync(member)
- .thenAccept((a) -> {
- if (a == null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e"+member+"§f's Profile §cCouldn't fetch uuid"));
- } else {
- ApiFetchur.fetchMostRecentProfileAsync(a.get(), FeatureRegistry.PARTYKICKER_APIKEY.getAPIKey());
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e"+member+"§f's Profile ").appendSibling(new ChatComponentText("§7view").setChatStyle(new ChatStyle().setChatHoverEvent(new FeatureViewPlayerOnJoin.HoverEventRenderPlayer(a.orElse(null))))));
- }
- });
- }
- }
- });
- } else {
- ApiFetchur.fetchUUIDAsync(username)
- .thenAccept(a -> {
- if (a == null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e"+username+"§f's Profile §cCouldn't fetch uuid"));
- return;
- }
- ApiFetchur.fetchMostRecentProfileAsync(a.get(), FeatureRegistry.PARTYKICKER_APIKEY.getAPIKey());
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e"+username+"§f's Profile ").appendSibling(new ChatComponentText("§7view").setChatStyle(new ChatStyle().setChatHoverEvent(new FeatureViewPlayerOnJoin.HoverEventRenderPlayer(a.orElse(null))))));
- });
- }
- }
- }
-
-
- public static class HoverEventRenderPlayer extends HoverEvent {
- @Getter
- private final String uuid;
- public HoverEventRenderPlayer(String uuid) {
- super(Action.SHOW_TEXT, new ChatComponentText(""));
- this.uuid = uuid;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- if (!super.equals(o)) return false;
- HoverEventRenderPlayer that = (HoverEventRenderPlayer) o;
- return Objects.equals(uuid, that.uuid);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(super.hashCode(), uuid);
- }
-
- private IChatComponent cached;
-
- @Override
- public IChatComponent getValue() {
- if (cached == null)
- return cached = new ChatComponentText("").setChatStyle(new ChatStyle().setChatHoverEvent(new HoverEvent(Action.SHOW_TEXT, new ChatComponentText(uuid))));
- return cached;
- }
- }
-
- public static class FakePlayer extends EntityOtherPlayerMP {
- @Setter
- @Getter
- private PlayerProfile skyblockProfile;
- private final SkinFetchur.SkinSet skinSet;
- private final PlayerProfile.Armor armor;
- private FakePlayer(World w) {
- super(w, null);
- throw new UnsupportedOperationException("what");
- }
- public FakePlayer(GameProfile playerProfile, SkinFetchur.SkinSet skinSet, PlayerProfile skyblockProfile) {
- super(Minecraft.getMinecraft().theWorld, playerProfile);
- this.skyblockProfile = skyblockProfile;
- this.skinSet = skinSet;
- armor= skyblockProfile.getCurrentArmor();
- this.inventory.armorInventory = skyblockProfile.getCurrentArmor().getArmorSlots();
-
- int highestDungeonScore = Integer.MIN_VALUE;
- if (skyblockProfile.getInventory() != null) {
- ItemStack highestItem = null;
- for (ItemStack itemStack : skyblockProfile.getInventory()) {
- if (itemStack == null) continue;
- NBTTagCompound display = itemStack.getTagCompound().getCompoundTag("display");
- if (display == null) continue;
- NBTTagList nbtTagList = display.getTagList("Lore", 8);
- if (nbtTagList == null) continue;
- for (int i = 0; i < nbtTagList.tagCount(); i++) {
- String str = nbtTagList.getStringTagAt(i);
- if (TextUtils.stripColor(str).startsWith("Gear")) {
- int dungeonScore = Integer.parseInt(TextUtils.keepIntegerCharactersOnly(TextUtils.stripColor(str).split(" ")[2]));
- if (dungeonScore > highestDungeonScore) {
- highestItem = itemStack;
- highestDungeonScore = dungeonScore;
- }
- }
- }
- }
-
- this.inventory.mainInventory[0] = highestItem;
- this.inventory.currentItem = 0;
- }
- }
-
- public String getSkinType() {
- return this.skinSet == null ? DefaultPlayerSkin.getSkinType(getGameProfile().getId()) : this.skinSet.getSkinType();
- }
-
- public ResourceLocation getLocationSkin() {
- return com.google.common.base.Objects.firstNonNull(skinSet.getSkinLoc(), DefaultPlayerSkin.getDefaultSkin(getGameProfile().getId()));
- }
-
- public ResourceLocation getLocationCape() {
- return skinSet.getCapeLoc();
- }
-
- @Override
- public ItemStack[] getInventory() {
- return this.inventory.armorInventory;
- }
-
- @Override
- public boolean isInvisibleToPlayer(EntityPlayer player) {
- return true;
- }
-
- @Override
- public Team getTeam() {
- return new ScorePlayerTeam(null, null) {
- @Override
- public EnumVisible getNameTagVisibility() {
- return EnumVisible.NEVER;
- }
- };
- }
- }
-
-
-
- @Override
- public String getEditRoute(RootConfigPanel rootConfigPanel) {
- ConfigPanelCreator.map.put("base." + getKey() , new Supplier() {
- @Override
- public MPanel get() {
-
- MFeatureEdit featureEdit = new MFeatureEdit(FeatureViewPlayerOnJoin.this, rootConfigPanel);
- featureEdit.addParameterEdit("datarenderers", new DataRendererEditor(FeatureViewPlayerOnJoin.this));
- for (FeatureParameter parameter: getParameters()) {
- if (parameter.getKey().equals("datarenderers")) continue;
- featureEdit.addParameterEdit(parameter.getKey(), new MParameterEdit(FeatureViewPlayerOnJoin.this, parameter, rootConfigPanel));
- }
- return featureEdit;
- }
- });
- return "base." + getKey() ;
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/FeatureViewPlayerStatsOnJoin.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/FeatureViewPlayerStatsOnJoin.java
new file mode 100644
index 00000000..74beb42f
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/FeatureViewPlayerStatsOnJoin.java
@@ -0,0 +1,703 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
+
+import com.mojang.authlib.GameProfile;
+import io.github.moulberry.hychat.HyChat;
+import io.github.moulberry.hychat.chat.ChatManager;
+import io.github.moulberry.hychat.gui.GuiChatBox;
+import kr.syeyoung.dungeonsguide.DungeonsGuide;
+import kr.syeyoung.dungeonsguide.chat.ChatProcessor;
+import kr.syeyoung.dungeonsguide.chat.PartyContext;
+import kr.syeyoung.dungeonsguide.chat.PartyManager;
+import kr.syeyoung.dungeonsguide.config.guiconfig.ConfigPanelCreator;
+import kr.syeyoung.dungeonsguide.config.guiconfig.MFeatureEdit;
+import kr.syeyoung.dungeonsguide.config.guiconfig.MParameterEdit;
+import kr.syeyoung.dungeonsguide.config.guiconfig.RootConfigPanel;
+import kr.syeyoung.dungeonsguide.cosmetics.ActiveCosmetic;
+import kr.syeyoung.dungeonsguide.cosmetics.CosmeticData;
+import kr.syeyoung.dungeonsguide.features.FeatureParameter;
+import kr.syeyoung.dungeonsguide.features.FeatureRegistry;
+import kr.syeyoung.dungeonsguide.features.SimpleFeature;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.ApiFetcher;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.PlayerSkyblockData;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.SkinFetcher;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.DataRendererEditor;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.DataRendererRegistry;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.IDataRenderer;
+import kr.syeyoung.dungeonsguide.features.listener.ChatListener;
+import kr.syeyoung.dungeonsguide.features.listener.GuiClickListener;
+import kr.syeyoung.dungeonsguide.features.listener.GuiPostRenderListener;
+import kr.syeyoung.dungeonsguide.utils.TextUtils;
+import lombok.Getter;
+import lombok.Setter;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.GuiChat;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.gui.inventory.GuiInventory;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.RenderHelper;
+import net.minecraft.event.HoverEvent;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.ChatStyle;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.IChatComponent;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.fml.client.config.GuiUtils;
+import net.minecraftforge.fml.common.Loader;
+import org.lwjgl.input.Mouse;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL14;
+
+import java.awt.*;
+import java.util.List;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+public class FeatureViewPlayerStatsOnJoin extends SimpleFeature implements GuiPostRenderListener, ChatListener, GuiClickListener {
+
+ public FeatureViewPlayerStatsOnJoin() {
+ super("Party", "View player stats when join", "view player rendering when joining/someone joins the party", "partykicker.viewstats", true);
+
+
+ this.parameters.put("datarenderers", new FeatureParameter>("datarenderers", "DataRenderers", "Datarenderssdasd", new ArrayList<>(Arrays.asList(
+ "catalv", "selected_class_lv", "dungeon_catacombs_higheststat", "dungeon_master_catacombs_higheststat", "skill_combat_lv", "skill_foraging_lv", "skill_mining_lv", "fairysouls", "dummy"
+ )), "stringlist"));
+
+
+
+
+ }
+
+
+ ChangeProfileWidget profileButtonWidget = new ChangeProfileWidget();
+
+ static Minecraft mc = Minecraft.getMinecraft();
+ protected Rectangle popupRect;
+ private String lastuid; // actually current uid
+ private CompletableFuture> profileFuture;
+ private Future> gameProfileFuture;
+ private Future skinFuture;
+ private FakePlayer fakePlayer;
+ private boolean shouldDraw = false;
+
+
+ @Override
+ public void onGuiPostRender(GuiScreenEvent.DrawScreenEvent.Post rendered) {
+ if (!(mc.currentScreen instanceof GuiChat)) {
+ cancelRender();
+ return;
+ }
+
+ ScaledResolution scaledResolution = new ScaledResolution(mc);
+
+ IChatComponent ichatcomponent = getHoveredComponent(scaledResolution);
+ String uid = null;
+ if (ichatcomponent != null && ichatcomponent.getChatStyle().getChatHoverEvent() instanceof HoverEventRenderPlayer) {
+ uid = ((HoverEventRenderPlayer) ichatcomponent.getChatStyle().getChatHoverEvent()).getUuid();
+ }
+
+ int width = scaledResolution.getScaledWidth();
+ int height = scaledResolution.getScaledHeight();
+ int mouseX = Mouse.getX() * width / mc.displayWidth;
+ int mouseY = height - Mouse.getY() * height / mc.displayHeight - 1;
+
+ shouldCancelRendering(uid, mouseX, mouseY);
+
+ if (lastuid == null) return;
+
+
+ if (popupRect == null) {
+ popupRect = new Rectangle(mouseX, mouseY, 220, 220);
+ if (popupRect.y + popupRect.height > scaledResolution.getScaledHeight()) {
+ popupRect.y -= popupRect.y + popupRect.height - scaledResolution.getScaledHeight();
+ }
+ }
+
+ if (profileFuture == null) {
+ profileFuture = ApiFetcher.fetchMostRecentProfileAsync(lastuid, FeatureRegistry.PARTYKICKER_APIKEY.getAPIKey());
+ }
+
+ if (gameProfileFuture == null) {
+ gameProfileFuture = ApiFetcher.getSkinGameProfileByUUIDAsync(lastuid);
+ }
+ boolean plsSetAPIKEY = false;
+ if (skinFuture == null && gameProfileFuture.isDone()) {
+ try {
+ skinFuture = SkinFetcher.getSkinSet(gameProfileFuture.get().orElse(null));
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ try {
+ if (fakePlayer == null && skinFuture != null && profileFuture != null && skinFuture.isDone() && profileFuture.isDone() && profileFuture.get().isPresent()) {
+ if (profileButtonWidget.getCurrentrySelectedProfile(profileFuture.get().get()) != null) {
+ if (skinFuture.get() != null) {
+ profileButtonWidget.setCurrentyselectedprofile(profileFuture.get().get().getLastestprofileArrayIndex());
+ fakePlayer = new FakePlayer(gameProfileFuture.get().orElse(null), skinFuture.get(), profileButtonWidget.getCurrentrySelectedProfile(profileFuture.get().get()), profileButtonWidget.getCurrentyselectedprofile());
+ }
+ }
+ } else if (fakePlayer != null) {
+ if (fakePlayer.getProfileNumber() != profileButtonWidget.getCurrentyselectedprofile()) {
+ fakePlayer = new FakePlayer(gameProfileFuture.get().orElse(null), skinFuture.get(), profileButtonWidget.getCurrentrySelectedProfile(profileFuture.get().get()), profileButtonWidget.getCurrentyselectedprofile());
+ }
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ plsSetAPIKEY = true;
+ }
+
+
+ Optional playerProfile;
+ if (plsSetAPIKEY || !profileFuture.isDone()) {
+ playerProfile = null;
+ } else {
+ PlayerSkyblockData data = null;
+ try {
+ data = profileFuture.get().get();
+ } catch (InterruptedException | ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ PlayerProfile currentlySelectedProfile = profileButtonWidget.getCurrentrySelectedProfile(data);
+ playerProfile = Optional.ofNullable(currentlySelectedProfile);
+ }
+
+
+ draw(scaledResolution, mouseX, mouseY, plsSetAPIKEY, playerProfile);
+ }
+
+
+ private void draw(ScaledResolution scaledResolution, int mouseX, int mouseY, boolean plsSetAPIKEY, Optional playerProfile) {
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(popupRect.x, popupRect.y, 0);
+ int backroundGuiColor = 0xFF23272a;
+ Gui.drawRect(0, 0, popupRect.width, popupRect.height, backroundGuiColor);
+ Gui.drawRect(2, 2, popupRect.width - 2, popupRect.height - 2, 0XFF2c2f33);
+
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ if (plsSetAPIKEY) {
+ mc.fontRendererObj.drawString("Please set API KEY on /dg -> Party Kicker", 5, 5, 0xFFFFFFFF);
+ GlStateManager.popMatrix();
+ } else if (playerProfile == null) {
+ mc.fontRendererObj.drawString("Fetching data...", 5, 5, 0xFFFFFFFF);
+ GlStateManager.popMatrix();
+ } else if (!playerProfile.isPresent()) {
+ mc.fontRendererObj.drawString("User could not be found", 5, 5, 0xFFFFFFFF);
+ GlStateManager.popMatrix();
+ } else {
+ int relX = mouseX - popupRect.x;
+ int relY = mouseY - popupRect.y;
+ FontRenderer fr = mc.fontRendererObj;
+ GL11.glEnable(GL11.GL_SCISSOR_TEST);
+ clip(scaledResolution, popupRect.x, popupRect.y, popupRect.width, popupRect.height);
+
+ Gui.drawRect(0, 168, 90, 195, backroundGuiColor);
+ Gui.drawRect(2, 170, 88, 193, new Rectangle(2, 170, 86, 23).contains(relX, relY) ? 0xFFff7777 : 0xFFFF3333);
+
+ Gui.drawRect(0, 193, 90, 220, backroundGuiColor);
+ Gui.drawRect(2, 195, 88, 218, new Rectangle(2, 195, 86, 23).contains(relX, relY) ? 0xFF859DF0 : 0xFF7289da);
+
+
+
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ fr.drawString("Kick", (90 - fr.getStringWidth("Kick")) / 2, (364 - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
+ fr.drawString("Invite", (90 - fr.getStringWidth("Invite")) / 2, (414 - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
+
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(95, 5, 0);
+ int culmutativeY = 5;
+ IDataRenderer dataRendererToHover = null;
+ for (String datarenderers : this.>getParameter("datarenderers").getValue()) {
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers);
+ Dimension dim;
+ if (dataRenderer == null) {
+ fr.drawString("Couldn't find Datarenderer", 0, 0, 0xFFFF0000);
+ fr.drawString(datarenderers, 0, fr.FONT_HEIGHT, 0xFFFF0000);
+ dim = new Dimension(0, fr.FONT_HEIGHT * 2);
+ } else {
+ GlStateManager.pushMatrix();
+ dim = dataRenderer.renderData(playerProfile.get());
+ GlStateManager.popMatrix();
+ }
+ if (relX >= 95 && relX <= popupRect.width && relY >= culmutativeY && relY < culmutativeY + dim.height && dataRenderer != null) {
+ dataRendererToHover = dataRenderer;
+ }
+ culmutativeY += dim.height;
+ GlStateManager.translate(0, dim.height, 0);
+ }
+ GlStateManager.popMatrix();
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ Gui.drawRect(0, 0, 90, 170, backroundGuiColor);
+ Gui.drawRect(2, 2, 88, 168, 0xFF444444);
+
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+
+ profileButtonWidget.drawChangeProfileButton(relX, relY);
+
+
+ Gui.drawRect(78, 156, 90, 170, backroundGuiColor);
+ fr.drawString("§eI", 82, 159, -1);
+
+
+
+ GlStateManager.color(1, 1, 1, 1.0F);
+ if (fakePlayer != null) {
+ drawFakePlayer(scaledResolution, mouseX, mouseY, playerProfile, relX, relY, fr);
+ } else {
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ fr.drawString("Loading", 5, 35, 0xFFEFFF00);
+ }
+ GlStateManager.popMatrix();
+ GL11.glDisable(GL11.GL_SCISSOR_TEST);
+ if (dataRendererToHover != null && !shouldDraw) {
+ dataRendererToHover.onHover(playerProfile.get(), mouseX, mouseY);
+ }
+ GL11.glEnable(GL11.GL_SCISSOR_TEST);
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(popupRect.x, popupRect.y, 0);
+ if (shouldDraw) {
+ int startX = 81;
+ int startY = 86;
+ clip(scaledResolution, popupRect.x + startX - 1, popupRect.y + startY - 1, 164, 74);
+ GlStateManager.translate(startX, startY, 1);
+ Gui.drawRect(-1, -1, 163, 73, 0xFF000000);
+ GlStateManager.disableLighting();
+ ItemStack toHover = null;
+ int rx = relX - startX;
+ int ry = relY - startY;
+
+ if (playerProfile.get().getInventory() != null) {
+ GlStateManager.disableRescaleNormal();
+ RenderHelper.enableGUIStandardItemLighting();
+ GlStateManager.disableLighting();
+ for (int i = 0; i < playerProfile.get().getInventory().length; i++) {
+ int x = (i % 9) * 18;
+ int y = (i / 9) * 18;
+ if (x <= rx && rx < x + 18 && y <= ry && ry < y + 18) {
+ toHover = playerProfile.get().getInventory()[(i + 9) % 36];
+ }
+ Gui.drawRect(x, y, x + 18, y + 18, 0xFF000000);
+ Gui.drawRect(x + 1, y + 1, x + 17, y + 17, 0xFF666666);
+ GlStateManager.color(1, 1, 1, 1.0F);
+
+ mc.getRenderItem().renderItemAndEffectIntoGUI(playerProfile.get().getInventory()[(i + 9) % 36], (i % 9) * 18 + 1, (i / 9) * 18 + 1);
+ }
+
+ if (toHover != null) {
+ drawItemStackToolTip(scaledResolution, mouseX, mouseY, fr, toHover);
+ }
+ } else {
+ Gui.drawRect(0, 0, 162, 72, 0xFF666666);
+ fr.drawSplitString("Player has disabled Inventory API", 5, 5, 142, -1);
+ }
+
+ }
+ GL11.glDisable(GL11.GL_SCISSOR_TEST);
+ GlStateManager.popMatrix(); // 33 66 108 130 154 // 5 75
+ }
+
+
+ }
+
+ private void drawFakePlayer(ScaledResolution scaledResolution, int mouseX, int mouseY, Optional playerProfile, int relX, int relY, FontRenderer fr) {
+ clip(scaledResolution, popupRect.x + 2, popupRect.y + 2, 86, 166);
+ GuiInventory.drawEntityOnScreen(45, 150, 60, -(mouseX - popupRect.x - 75), 0, fakePlayer);
+
+ String toDraw = fakePlayer.getName();
+ List activeCosmetics = DungeonsGuide.getDungeonsGuide().getCosmeticsManager().getActiveCosmeticByPlayer().get(UUID.fromString(TextUtils.insertDashUUID(playerProfile.get().getMemberUID())));
+ CosmeticData prefix = null;
+ CosmeticData color = null;
+ if (activeCosmetics != null) {
+ for (ActiveCosmetic activeCosmetic : activeCosmetics) {
+ CosmeticData cosmeticData = DungeonsGuide.getDungeonsGuide().getCosmeticsManager().getCosmeticDataMap().get(activeCosmetic.getCosmeticData());
+ if (cosmeticData != null) {
+ if (cosmeticData.getCosmeticType().equals("prefix")) prefix = cosmeticData;
+ if (cosmeticData.getCosmeticType().equals("color")) color = cosmeticData;
+ }
+ }
+ }
+ toDraw = (color == null ? "§e" : color.getData().replace("&", "§")) + toDraw;
+ if (prefix != null) toDraw = prefix.getData().replace("&", "§") + " " + toDraw;
+
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+
+
+ String profileName = "on §6" + playerProfile.get().getProfileName();
+ fr.drawString(profileName, (90 - fr.getStringWidth(profileName)) / 2, 15, -1);
+
+
+ fr.drawString(toDraw, (90 - fr.getStringWidth(toDraw)) / 2, 10 - (fr.FONT_HEIGHT / 2), -1);
+
+ ItemStack toHover = null;
+ if (relX > 20 && relX < 70) {
+ if (33 <= relY && relY <= 66) {
+ toHover = fakePlayer.getInventory()[3];
+ } else if (66 <= relY && relY <= 108) {
+ toHover = fakePlayer.getInventory()[2];
+ } else if (108 <= relY && relY <= 130) {
+ toHover = fakePlayer.getInventory()[1];
+ } else if (130 <= relY && relY <= 154) {
+ toHover = fakePlayer.getInventory()[0];
+ }
+ } else if (relX > 0 && relX <= 20) {
+ if (80 <= relY && relY <= 120) {
+ toHover = fakePlayer.inventory.mainInventory[fakePlayer.inventory.currentItem];
+ }
+ }
+
+ if (toHover != null) {
+ drawItemStackToolTip(scaledResolution, mouseX, mouseY, fr, toHover);
+ GlStateManager.translate(popupRect.x, popupRect.y, 0);
+ }
+ clip(scaledResolution, popupRect.x, popupRect.y, popupRect.width, popupRect.height);
+ }
+
+ public void drawItemStackToolTip(ScaledResolution scaledResolution, int mouseX, int mouseY, FontRenderer fr, ItemStack toHover) {
+ List list = toHover.getTooltip(mc.thePlayer, mc.gameSettings.advancedItemTooltips);
+ for (int i = 0; i < list.size(); ++i) {
+ if (i == 0) {
+ list.set(i, toHover.getRarity().rarityColor + list.get(i));
+ } else {
+ list.set(i, EnumChatFormatting.GRAY + list.get(i));
+ }
+ }
+ FontRenderer font = toHover.getItem().getFontRenderer(toHover);
+ GlStateManager.popMatrix();
+ GL11.glDisable(GL11.GL_SCISSOR_TEST);
+ FontRenderer theRenderer = (font == null ? fr : font);
+ GuiUtils.drawHoveringText(list, mouseX, mouseY, scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, theRenderer);
+ GL11.glEnable(GL11.GL_SCISSOR_TEST);
+ GlStateManager.pushMatrix();
+ }
+
+
+ class ChangeProfileWidget {
+ public ChangeProfileWidget(){
+ fr = Minecraft.getMinecraft().fontRendererObj;
+ stringWidth = fr.getStringWidth(buttonText);
+ textx = ((83 - stringWidth) / 2);
+ texty = (324 - fr.FONT_HEIGHT) / 2;
+ blockWidth = stringWidth + 3;
+ blockHeight = fr.FONT_HEIGHT + 2;
+ }
+
+ FontRenderer fr;
+
+ @Getter @Setter
+ int currentyselectedprofile = 0;
+
+ String buttonText = "Switch Profile";
+
+ int stringWidth;
+ int textx;
+ int texty;
+
+ int blockWidth;
+ int blockHeight;
+
+ void drawChangeProfileButton(float relX, float relY){
+
+ boolean contains = isWithinButtonRec(relX, relY);
+
+ Gui.drawRect(textx - 5, texty - 1, textx + blockWidth, texty + blockHeight, contains ? 0xFFFFFFFF : 0xFF30afd3);
+
+ fr.drawString(buttonText, textx, texty + 2, contains ? 0x30afd3 : 0xFFFFFF);
+ }
+
+
+ Rectangle getButtonRec(){
+ return new Rectangle(textx - 5, texty - 1, blockWidth, blockHeight);
+ }
+
+ boolean isWithinButtonRec(float relX, float relY){
+ return getButtonRec().contains(relX, relY);
+ }
+
+ long clickDeBounce = 0;
+ void handleClickProfileButton(PlayerSkyblockData playerData){
+
+ if(System.currentTimeMillis() <= clickDeBounce){
+ return;
+ } else {
+ clickDeBounce = System.currentTimeMillis() + 200;
+ }
+
+ ScaledResolution scaledResolution = new ScaledResolution(mc);
+ int width = scaledResolution.getScaledWidth();
+ int height = scaledResolution.getScaledHeight();
+ int mouseX = Mouse.getX() * width / mc.displayWidth;
+ int mouseY = height - Mouse.getY() * height / mc.displayHeight - 1;
+
+ int relX = mouseX - popupRect.x;
+ int relY = mouseY - popupRect.y;
+
+ if (isWithinButtonRec(relX, relY)) {
+ if (profileButtonWidget.currentyselectedprofile + 1 >= playerData.getPlayerProfiles().length) {
+ profileButtonWidget.currentyselectedprofile = 0;
+ } else {
+ profileButtonWidget.currentyselectedprofile++;
+ }
+ }
+ }
+
+ PlayerProfile getCurrentrySelectedProfile(PlayerSkyblockData data) {
+ if (data == null) return null;
+ if (data.getPlayerProfiles() == null) return null;
+ if (data.getPlayerProfiles().length == 0) return null;
+ if (data.getPlayerProfiles().length < currentyselectedprofile) return null;
+ return data.getPlayerProfiles()[currentyselectedprofile];
+ }
+ }
+
+
+
+
+ private void shouldCancelRendering(String uid, int mouseX, int mouseY) {
+ if (!((popupRect != null && (popupRect.contains(mouseX, mouseY) || shouldDraw)) || uid != null && uid.equals(lastuid))) {
+ cancelRender();
+ }
+
+ if (uid != null && !uid.equals(lastuid) && (popupRect==null || (!popupRect.contains(mouseX, mouseY) && !shouldDraw)) ) {
+ cancelRender();
+ lastuid = uid;
+ }
+ }
+
+ public void cancelRender() {
+ popupRect = null;
+ profileFuture = null;
+ lastuid = null;
+ gameProfileFuture = null;
+ skinFuture = null;
+ fakePlayer = null;
+ shouldDraw = false;
+ }
+
+
+ public static void clip(ScaledResolution resolution, int x, int y, int width, int height) {
+ if (width < 0 || height < 0) return;
+
+ int scale = resolution.getScaleFactor();
+ GL11.glScissor((x) * scale, mc.displayHeight - (y + height) * scale, (width) * scale, height * scale);
+ }
+
+ @Override
+ public void onMouseInput(GuiScreenEvent.MouseInputEvent.Pre mouseInputEvent) {
+ ScaledResolution scaledResolution = new ScaledResolution(mc);
+ int width = scaledResolution.getScaledWidth();
+ int height = scaledResolution.getScaledHeight();
+ int mouseX = Mouse.getX() * width / mc.displayWidth;
+ int mouseY = height - Mouse.getY() * height / mc.displayHeight - 1;
+
+ if (Mouse.getEventButton() != -1 && Mouse.isButtonDown(Mouse.getEventButton()) && shouldDraw) shouldDraw = false;
+ if (popupRect == null || !popupRect.contains(mouseX, mouseY)) return;
+
+ mouseInputEvent.setCanceled(true);
+
+ int relX = mouseX - popupRect.x;
+ int relY = mouseY - popupRect.y;
+
+ try {
+ PlayerSkyblockData playerData;
+
+ if (profileFuture.isDone()) {
+ playerData = profileFuture.get().orElse(null);
+ } else {
+ return;
+ }
+
+ if (playerData == null) {
+ return;
+ }
+
+ if (Mouse.getEventButton() == -1 && !Mouse.isButtonDown(Mouse.getEventButton())) return;
+
+ if (new Rectangle(2, 195, 86, 23).contains(relX, relY)) {
+ // invite
+ ChatProcessor.INSTANCE.addToChatQueue("/p invite " + ApiFetcher.fetchNicknameAsync(profileButtonWidget.getCurrentrySelectedProfile(playerData).getMemberUID()).get().orElse("-"), () -> {
+ }, true);
+ }
+
+ else if (new Rectangle(2, 170, 86, 23).contains(relX, relY)) {
+ // kick
+ ChatProcessor.INSTANCE.addToChatQueue("/p kick " + ApiFetcher.fetchNicknameAsync(profileButtonWidget.getCurrentrySelectedProfile(playerData).getMemberUID()).get().orElse("-"), () -> {
+ }, true);
+ }
+
+
+
+ else if (new Rectangle(80, 159, 10, 11).contains(relX, relY)) {
+ shouldDraw = true;
+ }
+
+
+ this.profileButtonWidget.handleClickProfileButton(playerData);
+
+
+
+ } catch (InterruptedException | ExecutionException e) {
+ }
+
+
+ }
+
+
+
+ public IChatComponent getHoveredComponent(ScaledResolution scaledResolution) {
+ IChatComponent ichatcomponent = null;
+ if (Loader.isModLoaded("hychat")) {
+ try {
+ ChatManager chatManager = HyChat.getInstance().getChatManager();
+ GuiChatBox guiChatBox = chatManager.getFocusedChat();
+
+ int x = guiChatBox.getX(scaledResolution);
+ int y = guiChatBox.getY(scaledResolution);
+ ichatcomponent = guiChatBox.chatArray.getHoveredComponent(guiChatBox.getSelectedTab().getChatLines(), Mouse.getX(), Mouse.getY(), x, y);
+ } catch (Throwable t) {}
+ }
+ if (ichatcomponent == null) {
+ ichatcomponent = Minecraft.getMinecraft().ingameGUI.getChatGUI().getChatComponent(Mouse.getX(), Mouse.getY());
+ }
+ return ichatcomponent;
+
+// return Minecraft.getMinecraft().ingameGUI.getChatGUI().getChatComponent(Mouse.getX(), Mouse.getY());
+ }
+
+ @Override
+ public void onChat(ClientChatReceivedEvent event) {
+ if (!isEnabled()) return;
+ String str = event.message.getFormattedText();
+ if (str.contains("§r§ejoined the dungeon group! (§r§b")) {
+ String username = TextUtils.stripColor(str).split(" ")[3];
+ if (username.equalsIgnoreCase(mc.getSession().getUsername())) {
+ PartyManager.INSTANCE.requestPartyList(context -> {
+ if (context == null) {
+ mc.thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §cBugged Dungeon Party "));
+ } else {
+ processPartyMembers(context);
+ }
+ });
+ } else {
+ ApiFetcher.fetchUUIDAsync(username)
+ .thenAccept(a -> {
+ if (a == null) {
+ mc.thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e" + username + "§f's Profile §cCouldn't fetch uuid"));
+ return;
+ }
+ ApiFetcher.fetchMostRecentProfileAsync(a.get(), FeatureRegistry.PARTYKICKER_APIKEY.getAPIKey());
+ mc.thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e" + username + "§f's Profile ").appendSibling(new ChatComponentText("§7view").setChatStyle(new ChatStyle().setChatHoverEvent(new FeatureViewPlayerStatsOnJoin.HoverEventRenderPlayer(a.orElse(null))))));
+ });
+ }
+ }
+ }
+
+ public static void processPartyMembers(PartyContext context) {
+ for (String member : context.getPartyRawMembers()) {
+ ApiFetcher.fetchUUIDAsync(member)
+ .thenAccept(a -> {
+ if (a == null) {
+ mc.thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e" + member + "§f's Profile §cCouldn't fetch uuid"));
+ } else {
+ ApiFetcher.fetchMostRecentProfileAsync(a.get(), FeatureRegistry.PARTYKICKER_APIKEY.getAPIKey());
+ mc.thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e" + member + "§f's Profile ").appendSibling(new ChatComponentText("§7view").setChatStyle(new ChatStyle().setChatHoverEvent(new HoverEventRenderPlayer(a.orElse(null))))));
+ }
+ });
+ }
+ }
+
+
+ public static class HoverEventRenderPlayer extends HoverEvent {
+ @Getter
+ private final String uuid;
+
+ public HoverEventRenderPlayer(String uuid) {
+ super(Action.SHOW_TEXT, new ChatComponentText(""));
+ this.uuid = uuid;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ if (!super.equals(o)) return false;
+ HoverEventRenderPlayer that = (HoverEventRenderPlayer) o;
+ return Objects.equals(uuid, that.uuid);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), uuid);
+ }
+
+ private IChatComponent cached;
+
+ @Override
+ public IChatComponent getValue() {
+ if (cached == null) {
+ cached = new ChatComponentText("")
+ .setChatStyle(
+ new ChatStyle()
+ .setChatHoverEvent(
+ new HoverEvent(
+ Action.SHOW_TEXT,
+ new ChatComponentText(uuid)
+ )
+ )
+ );
+ return cached;
+ }
+ return cached;
+ }
+ }
+
+
+ @Override
+ public String getEditRoute(RootConfigPanel rootConfigPanel) {
+ ConfigPanelCreator.map.put("base." + getKey(), () -> {
+
+ MFeatureEdit featureEdit = new MFeatureEdit(FeatureViewPlayerStatsOnJoin.this, rootConfigPanel);
+ featureEdit.addParameterEdit("datarenderers", new DataRendererEditor(FeatureViewPlayerStatsOnJoin.this));
+ for (FeatureParameter parameter : getParameters()) {
+ if (parameter.getKey().equals("datarenderers")) continue;
+ featureEdit.addParameterEdit(parameter.getKey(), new MParameterEdit(FeatureViewPlayerStatsOnJoin.this, parameter, rootConfigPanel));
+ }
+ return featureEdit;
+ });
+ return "base." + getKey();
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/ApiFetcher.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/ApiFetcher.java
new file mode 100644
index 00000000..c11bc404
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/ApiFetcher.java
@@ -0,0 +1,387 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.mojang.authlib.GameProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfileParser;
+import kr.syeyoung.dungeonsguide.utils.TextUtils;
+import net.minecraft.client.Minecraft;
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class ApiFetcher {
+
+ private ApiFetcher(){}
+
+ private static final Gson gson = new Gson();
+
+ private static final Map> playerProfileCache = new ConcurrentHashMap<>();
+ private static final Map> nicknameToUID = new ConcurrentHashMap<>();
+ private static final Map> UIDtoNickname = new ConcurrentHashMap<>();
+ private static final Map> UIDtoGameProfile = new ConcurrentHashMap<>();
+
+ private static final ExecutorService ex = Executors.newFixedThreadPool(4);
+
+ private static final Set invalidKeys = new HashSet<>();
+
+ public static void purgeCache() {
+ playerProfileCache.clear();
+ nicknameToUID.clear();
+ UIDtoNickname.clear();
+ UIDtoGameProfile.clear();
+
+ completableFutureMap.clear();
+ completableFutureMap2.clear();
+ completableFutureMap3.clear();
+ completableFutureMap4.clear();
+ invalidKeys.clear();
+ PlayerProfileParser.constants = null;
+
+ ex.submit(PlayerProfileParser::getLilyWeightConstants);
+ }
+
+ static {
+ ex.submit(PlayerProfileParser::getLilyWeightConstants);
+ }
+
+ public static JsonObject getJson(String url) throws IOException {
+ URLConnection connection = new URL(url).openConnection();
+ connection.setConnectTimeout(10000);
+ connection.setReadTimeout(10000);
+ InputStreamReader inputStreamReader = new InputStreamReader(connection.getInputStream());
+ String serverres = IOUtils.toString(inputStreamReader);
+ return gson.fromJson(serverres, JsonObject.class);
+ }
+
+ public static JsonArray getJsonArr(String url) throws IOException {
+ URLConnection connection = new URL(url).openConnection();
+ connection.setConnectTimeout(10000);
+ connection.setReadTimeout(10000);
+ return gson.fromJson(new InputStreamReader(connection.getInputStream()), JsonArray.class);
+ }
+
+ private static final Map>> completableFutureMap4 = new ConcurrentHashMap<>();
+
+ public static CompletableFuture> getSkinGameProfileByUUIDAsync(String uid) {
+ if (UIDtoGameProfile.containsKey(uid)) {
+ CachedData cachedData = UIDtoGameProfile.get(uid);
+ if (cachedData.getExpire() > System.currentTimeMillis()) {
+ return CompletableFuture.completedFuture(Optional.ofNullable(cachedData.getData()));
+ }
+ UIDtoGameProfile.remove(uid);
+ }
+ if (completableFutureMap4.containsKey(uid)) return completableFutureMap4.get(uid);
+
+ CompletableFuture> completableFuture = new CompletableFuture<>();
+ fetchNicknameAsync(uid).thenAccept(nick -> {
+ if (!nick.isPresent()) {
+ completableFuture.complete(Optional.empty());
+ return;
+ }
+ ex.submit(() -> {
+ try {
+ Optional playerProfile = getSkinGameProfileByUUID(uid, nick.get());
+ UIDtoGameProfile.put(uid, new CachedData(System.currentTimeMillis() + 1000 * 60 * 30, playerProfile.orElse(null)));
+ completableFuture.complete(playerProfile);
+ completableFutureMap4.remove(uid);
+ return;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ completableFuture.complete(Optional.empty());
+ completableFutureMap4.remove(uid);
+ });
+ });
+ completableFutureMap4.put(uid, completableFuture);
+ return completableFuture;
+ }
+
+ public static Optional getSkinGameProfileByUUID(String uid, String nickname) throws IOException {
+ GameProfile gameProfile = new GameProfile(UUID.fromString(uid), nickname);
+ GameProfile newProf = Minecraft.getMinecraft().getSessionService().fillProfileProperties(gameProfile, true);
+ return newProf == gameProfile ? Optional.empty() : Optional.of(newProf);
+ }
+
+
+ private static final Map>> completableFutureMap = new ConcurrentHashMap<>();
+
+ public static CompletableFuture> fetchMostRecentProfileAsync(String uid, String apiKey) {
+ if (playerProfileCache.containsKey(uid)) {
+ CachedData cachedData = playerProfileCache.get(uid);
+ if (cachedData.getExpire() > System.currentTimeMillis()) {
+ return CompletableFuture.completedFuture(Optional.ofNullable(cachedData.getData()));
+ }
+ playerProfileCache.remove(uid);
+ }
+ if (completableFutureMap.containsKey(uid)) {
+ return completableFutureMap.get(uid);
+ }
+ if (invalidKeys.contains(apiKey)) {
+ CompletableFuture cf = new CompletableFuture();
+ cf.completeExceptionally(new IOException("403 for url"));
+ return cf;
+ }
+ CompletableFuture> completableFuture = new CompletableFuture<>();
+ ex.submit(() -> {
+ try {
+ Optional playerProfile = fetchPlayerProfiles(uid, apiKey);
+ playerProfileCache.put(uid, new CachedData<>(System.currentTimeMillis() + 1000 * 60 * 30, playerProfile.orElse(null)));
+ completableFuture.complete(playerProfile);
+ completableFutureMap.remove(uid);
+ } catch (IOException e) {
+ if (e.getMessage().contains("403 for URL")) {
+ completableFuture.completeExceptionally(e);
+ completableFutureMap.remove(uid);
+ invalidKeys.add(apiKey);
+ } else {
+ completableFuture.completeExceptionally(e);
+ completableFutureMap.remove(uid);
+ }
+ e.printStackTrace();
+ }
+ });
+ completableFutureMap.put(uid, completableFuture);
+ return completableFuture;
+ }
+
+ private static final Map>> completableFutureMap3 = new ConcurrentHashMap<>();
+
+ public static CompletableFuture> fetchNicknameAsync(String uid) {
+ if (UIDtoNickname.containsKey(uid)) {
+ CachedData cachedData = UIDtoNickname.get(uid);
+ if (cachedData.getExpire() > System.currentTimeMillis()) {
+ return CompletableFuture.completedFuture(Optional.ofNullable(cachedData.getData()));
+ }
+ UIDtoNickname.remove(uid);
+ }
+ if (completableFutureMap3.containsKey(uid)) return completableFutureMap3.get(uid);
+
+
+ CompletableFuture> completableFuture = new CompletableFuture<>();
+
+ ex.submit(() -> {
+ try {
+ Optional playerProfile = fetchNickname(uid);
+ UIDtoNickname.put(uid, new CachedData(System.currentTimeMillis() + 1000 * 60 * 60 * 12, playerProfile.orElse(null)));
+ if (playerProfile.isPresent())
+ nicknameToUID.put(playerProfile.orElse(null), new CachedData<>(System.currentTimeMillis() + 1000 * 60 * 60 * 12, uid));
+ completableFuture.complete(playerProfile);
+ completableFutureMap3.remove(uid);
+ return;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ completableFuture.complete(Optional.empty());
+ completableFutureMap3.remove(uid);
+ });
+ completableFutureMap3.put(uid, completableFuture);
+
+ return completableFuture;
+ }
+
+ private static final Map>> completableFutureMap2 = new ConcurrentHashMap<>();
+
+ public static CompletableFuture> fetchUUIDAsync(String nickname) {
+ if (nicknameToUID.containsKey(nickname)) {
+ CachedData cachedData = nicknameToUID.get(nickname);
+ if (cachedData.getExpire() > System.currentTimeMillis()) {
+ return CompletableFuture.completedFuture(Optional.ofNullable(cachedData.getData()));
+ }
+ nicknameToUID.remove(nickname);
+ }
+ if (completableFutureMap2.containsKey(nickname)) return completableFutureMap2.get(nickname);
+
+
+ CompletableFuture> completableFuture = new CompletableFuture<>();
+
+ ex.submit(() -> {
+ try {
+ Optional playerProfile = fetchUUID(nickname);
+ nicknameToUID.put(nickname, new CachedData(System.currentTimeMillis() + 1000 * 60 * 60 * 12, playerProfile.orElse(null)));
+ if (playerProfile.isPresent())
+ UIDtoNickname.put(playerProfile.orElse(null), new CachedData<>(System.currentTimeMillis() + 1000 * 60 * 60 * 12, nickname));
+
+ completableFuture.complete(playerProfile);
+ completableFutureMap2.remove(nickname);
+ return;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ completableFuture.complete(Optional.empty());
+ completableFutureMap2.remove(nickname);
+ });
+ completableFutureMap2.put(nickname, completableFuture);
+
+ return completableFuture;
+ }
+
+ public static Optional fetchUUID(String nickname) throws IOException {
+ JsonObject json = getJson("https://api.mojang.com/users/profiles/minecraft/" + nickname);
+ if (json.has("error")) return Optional.empty();
+ return Optional.of(TextUtils.insertDashUUID(json.get("id").getAsString()));
+ }
+
+ public static Optional fetchNickname(String uuid) throws IOException {
+ try {
+ JsonArray json = getJsonArr("https://api.mojang.com/user/profiles/" + uuid.replace("-", "") + "/names");
+ return Optional.of(json.get(json.size() - 1).getAsJsonObject().get("name").getAsString());
+ } catch (Exception e) {
+ return Optional.empty();
+ }
+ }
+
+
+ public static Optional getNumberOfSecretsFromAchievement(String uid, String apiKey) throws IOException {
+ JsonObject responce = getJson("https://api.hypixel.net/player?uuid=" + uid + "&key=" + apiKey);
+ if (responce.has("player")) {
+ JsonObject treasures = responce.getAsJsonObject("player");
+ if (treasures.has("achievements")) {
+ treasures = treasures.getAsJsonObject("achievements");
+ if (treasures.has("skyblock_treasure_hunter")) {
+ return Optional.of(treasures.get("skyblock_treasure_hunter").getAsInt());
+ }
+ }
+ }
+ return Optional.empty();
+ }
+
+
+ public static int getArrayIndex(Object[] arr,Object value) {
+ int k=0;
+ for(int i=0;i fetchPlayerProfiles(String uid, String apiKey) throws IOException {
+ System.out.println("Featching player profiles");
+ JsonObject json = getJson("https://api.hypixel.net/skyblock/profiles?uuid=" + uid + "&key=" + apiKey);
+ if (!json.get("success").getAsBoolean()) return Optional.empty();
+ System.out.println("Downloaded data from api");
+ JsonArray profiles = json.getAsJsonArray("profiles");
+ String dashTrimmed = uid.replace("-", "");
+
+
+ PlayerSkyblockData pp = new PlayerSkyblockData();
+ ArrayList playerProfiles = new ArrayList<>();
+ System.out.println("Saving and parsing data");
+ float lastSave = Long.MIN_VALUE;
+ PlayerProfile lastest = null;
+ for (JsonElement jsonElement : profiles) {
+ JsonObject semiProfile = jsonElement.getAsJsonObject();
+ if (!semiProfile.get("members").getAsJsonObject().has(dashTrimmed)) {
+ System.out.println("Profile does not appear to have the player???");
+ continue;
+ }
+
+ System.out.println("Parsing profile");
+ PlayerProfile e = PlayerProfileParser.parseProfile(semiProfile, dashTrimmed);
+
+ System.out.println("Finished Parsing Profile");
+
+
+ System.out.println("Getting nm of secrets from achivment");
+ getNumberOfSecretsFromAchievement(uid, apiKey).ifPresent(e::setTotalSecrets);
+ System.out.println("finished getting secrets from achivment");
+
+
+ System.out.println("Gettign last save");
+ JsonElement last_save = semiProfile.get("last_save");
+ if(last_save != null){
+ float lastSave2 = last_save.getAsLong();
+ if (lastSave2 > lastSave) {
+ lastest = e;
+ lastSave = lastSave2;
+ }
+ }
+ System.out.println("Finished getting last save");
+
+ playerProfiles.add(e);
+ }
+ System.out.println("THE AMMOUT OF PLAYER PROFILES: " + playerProfiles.size());
+ PlayerProfile[] p = new PlayerProfile[playerProfiles.size()];
+ pp.setLastestprofileArrayIndex(getArrayIndex(p, lastest));
+ pp.setPlayerProfiles(playerProfiles.toArray(p));
+ return Optional.of(pp);
+ }
+
+ public static Optional fetchMostRecentProfile(String uid, String apiKey) throws IOException {
+ JsonObject json = getJson("https://api.hypixel.net/skyblock/profiles?uuid=" + uid + "&key=" + apiKey);
+ if (!json.get("success").getAsBoolean()) return Optional.empty();
+ JsonArray profiles = json.getAsJsonArray("profiles");
+ String dashTrimmed = uid.replace("-", "");
+
+ JsonObject profile = null;
+ float lastSave = Long.MIN_VALUE;
+ for (JsonElement jsonElement : profiles) {
+ JsonObject semiProfile = jsonElement.getAsJsonObject();
+ if (!semiProfile.getAsJsonObject("members").has(dashTrimmed)) {
+ continue;
+ }
+ JsonElement last_save = semiProfile.get("last_save");
+
+ JsonElement cute_name = semiProfile.get("cute_name");
+ if (cute_name != null) {
+ System.out.println(cute_name.getAsString());
+ } else {
+ System.out.println("THIS SHOULD NOT HAPPEN");
+ }
+
+ if (last_save == null) {
+ return Optional.empty();
+ }
+ float lastSave2 = last_save.getAsLong();
+ if (lastSave2 > lastSave) {
+
+ profile = semiProfile;
+ lastSave = lastSave2;
+ }
+ }
+
+
+ if (profile == null) {
+ return Optional.empty();
+ }
+
+ PlayerProfile pp = PlayerProfileParser.parseProfile(profile, dashTrimmed);
+
+ getNumberOfSecretsFromAchievement(uid, apiKey).ifPresent(pp::setTotalSecrets);
+
+ return Optional.of(pp);
+ }
+
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/CachedData.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/CachedData.java
new file mode 100644
index 00000000..e3a98eaa
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/CachedData.java
@@ -0,0 +1,29 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class CachedData {
+ private final long expire;
+ private final T data;
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/PlayerSkyblockData.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/PlayerSkyblockData.java
new file mode 100644
index 00000000..72b28e61
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/PlayerSkyblockData.java
@@ -0,0 +1,10 @@
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import lombok.Data;
+
+@Data
+public class PlayerSkyblockData {
+ PlayerProfile[] playerProfiles;
+ int lastestprofileArrayIndex;
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/SkinFetcher.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/SkinFetcher.java
new file mode 100644
index 00000000..5d9afa4a
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/SkinFetcher.java
@@ -0,0 +1,90 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api;
+
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.minecraft.MinecraftProfileTexture;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.resources.DefaultPlayerSkin;
+import net.minecraft.client.resources.SkinManager;
+import net.minecraft.util.ResourceLocation;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class SkinFetcher {
+
+ private SkinFetcher(){}
+
+ private static final Map> skinSetMap = new ConcurrentHashMap<>();
+
+ private static final Map> currentReq = new HashMap<>();
+
+ public static CompletableFuture getSkinSet(GameProfile gameProfile) {
+ if (gameProfile == null) {
+ return CompletableFuture.completedFuture(new SkinSet(DefaultPlayerSkin.getDefaultSkinLegacy(), null, "default"));
+ }
+ if (skinSetMap.containsKey(gameProfile.getId().toString())) {
+ CachedData ss = skinSetMap.get(gameProfile.getId().toString());
+ if (ss.getExpire() > System.currentTimeMillis())
+ CompletableFuture.completedFuture(skinSetMap.get(gameProfile.getId().toString()).getData());
+ skinSetMap.remove(gameProfile.getId().toString());
+ }
+ if (currentReq.containsKey(gameProfile.getId().toString()))
+ return currentReq.get(gameProfile.getId().toString());
+
+ SkinSet skinSet = new SkinSet();
+ CompletableFuture skinSet2 = new CompletableFuture<>();
+ currentReq.put(gameProfile.getId().toString(), skinSet2);
+ Minecraft.getMinecraft().getSkinManager().loadProfileTextures(gameProfile, new SkinManager.SkinAvailableCallback() {
+ public void skinAvailable(MinecraftProfileTexture.Type p_180521_1_, ResourceLocation location, MinecraftProfileTexture profileTexture) {
+ switch (p_180521_1_) {
+ case SKIN:
+ skinSet.setSkinLoc(location);
+ skinSet.setSkinType(profileTexture.getMetadata("model"));
+ if (skinSet.getSkinType() == null) {
+ skinSet.setSkinType("default");
+ }
+ skinSet2.complete(skinSet);
+ skinSetMap.put(gameProfile.getId().toString(), new CachedData<>(System.currentTimeMillis() + 1000*60*60*3, skinSet));
+ currentReq.get(gameProfile.getId().toString());
+ break;
+ case CAPE:
+ skinSet.setCapeLoc(location);
+ }
+ }
+ }, true);
+
+ return skinSet2;
+ }
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class SkinSet {
+ private ResourceLocation skinLoc;
+ private ResourceLocation capeLoc;
+ private String skinType;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/PlayerProfile.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/PlayerProfile.java
new file mode 100644
index 00000000..95cd000f
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/PlayerProfile.java
@@ -0,0 +1,92 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.*;
+import lombok.Data;
+import net.minecraft.item.ItemStack;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class PlayerProfile {
+ private String profileUID;
+ private String memberUID;
+ private String profileName;
+
+ private long lastSave;
+
+ private int fairySouls;
+ private int fairyExchanges;
+
+ private Armor currentArmor;
+ private List wardrobe = new ArrayList<>();
+ private int selectedWardrobe = -1;
+
+ private ItemStack[] inventory;
+ private ItemStack[] enderchest;
+ private ItemStack[] talismans;
+
+ private int totalSecrets;
+
+ @Data
+ public static class Armor {
+ private final ItemStack[] armorSlots = new ItemStack[4];
+
+ public ItemStack getHelmet() { return armorSlots[3]; }
+ public ItemStack getChestPlate() { return armorSlots[2]; }
+ public ItemStack getLeggings() { return armorSlots[1]; }
+ public ItemStack getBoots() { return armorSlots[0]; }
+ }
+
+ private Map> dungeonStats = new HashMap<>();
+
+ private Map> playerClassData = new HashMap<>();
+ private DungeonClass selectedClass;
+ @Data
+ public static class PlayerClassData {
+ private double experience;
+ }
+
+ private Map skillXp;
+
+ private List pets = new ArrayList<>();
+
+
+ private Map additionalProperties = new HashMap<>();
+
+ private LilyWeight lilyWeight;
+
+ @Data
+ public static class LilyWeight {
+ private double skill_base;
+ private double skill_overflow;
+ private double catacombs_base;
+ private double catacombs_master;
+ private double catacombs_exp;
+ private double slayer;
+
+ public double getTotal() {
+ return skill_base + skill_overflow + catacombs_base + catacombs_exp + catacombs_master + slayer;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/PlayerProfileParser.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/PlayerProfileParser.java
new file mode 100644
index 00000000..b19e1e36
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/PlayerProfileParser.java
@@ -0,0 +1,449 @@
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.ApiFetcher;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.*;
+import kr.syeyoung.dungeonsguide.utils.XPUtils;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompressedStreamTools;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.function.BiFunction;
+import java.util.stream.Collectors;
+
+public class PlayerProfileParser {
+
+ public static volatile JsonObject constants;
+
+ public static JsonObject getLilyWeightConstants() {
+ if (constants != null) return constants;
+ try {
+ JsonObject jsonObject = ApiFetcher.getJson("https://raw.githubusercontent.com/Antonio32A/lilyweight/master/lib/constants.json");
+ constants = jsonObject;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return constants;
+ }
+
+ public static int getOrDefault(JsonObject jsonObject, String key, int value) {
+ if (jsonObject == null || !jsonObject.has(key) || jsonObject.get(key) instanceof JsonNull) return value;
+ return jsonObject.get(key).getAsInt();
+ }
+
+ public static long getOrDefault(JsonObject jsonObject, String key, long value) {
+ if (jsonObject == null || !jsonObject.has(key) || jsonObject.get(key) instanceof JsonNull) return value;
+ return jsonObject.get(key).getAsLong();
+ }
+
+ public static double getOrDefault(JsonObject jsonObject, String key, double value) {
+ if (jsonObject == null || !jsonObject.has(key) || jsonObject.get(key) instanceof JsonNull) return value;
+ return jsonObject.get(key).getAsDouble();
+ }
+
+ public static String getOrDefault(JsonObject jsonObject, String key, String value) {
+ if (jsonObject == null || !jsonObject.has(key) || jsonObject.get(key) instanceof JsonNull) return value;
+ return jsonObject.get(key).getAsString();
+ }
+
+ public static Double getOrDefaultNullable(JsonObject jsonObject, String key, Double value) {
+ if (jsonObject == null || !jsonObject.has(key) || jsonObject.get(key) instanceof JsonNull) return value;
+ return jsonObject.get(key).getAsDouble();
+ }
+
+ public static NBTTagCompound parseBase64NBT(String nbt) throws IOException {
+ return CompressedStreamTools.readCompressed(new ByteArrayInputStream(Base64.getDecoder().decode(nbt)));
+ }
+
+ public static ItemStack deserializeNBT(NBTTagCompound nbtTagCompound) {
+ if (nbtTagCompound.hasNoTags()) return null;
+ ItemStack itemStack = new ItemStack(Blocks.stone);
+ itemStack.deserializeNBT(nbtTagCompound);
+ return itemStack;
+ }
+
+ public static PlayerProfile parseProfile(JsonObject profile, String dashTrimmed) throws IOException {
+ PlayerProfile playerProfile = new PlayerProfile();
+ playerProfile.setProfileUID(getOrDefault(profile, "profile_id", ""));
+ playerProfile.setMemberUID(dashTrimmed);
+ playerProfile.setProfileName(getOrDefault(profile, "cute_name", ""));
+
+ JsonObject playerData = profile.getAsJsonObject("members").getAsJsonObject(dashTrimmed);
+ playerProfile.setLastSave(getOrDefault(playerData, "last_save", 0L));
+ playerProfile.setFairySouls(getOrDefault(playerData, "fairy_souls_collected", 0));
+ playerProfile.setFairyExchanges(getOrDefault(playerData, "fairy_exchanges", 0));
+
+ if (playerData.has("inv_armor")) {
+ playerProfile.setCurrentArmor(new PlayerProfile.Armor());
+ NBTTagCompound armor = parseBase64NBT(playerData.getAsJsonObject("inv_armor")
+ .get("data")
+ .getAsString());
+ NBTTagList array = armor.getTagList("i", 10);
+ for (int i = 0; i < 4; i++) {
+ NBTTagCompound item = array.getCompoundTagAt(i);
+ playerProfile.getCurrentArmor().getArmorSlots()[i] = deserializeNBT(item);
+ }
+ }
+
+ if (playerData.has("wardrobe_contents")) {
+ NBTTagCompound armor = parseBase64NBT(playerData.getAsJsonObject("wardrobe_contents").get("data").getAsString());
+ NBTTagList array = armor.getTagList("i", 10);
+ for (int i = 0; i < array.tagCount(); i++) {
+ if (i % 4 == 0) playerProfile.getWardrobe().add(new PlayerProfile.Armor());
+ NBTTagCompound item = array.getCompoundTagAt(i);
+ playerProfile.getWardrobe().get(i / 4).getArmorSlots()[i % 4] = deserializeNBT(item);
+ }
+
+ }
+ playerProfile.setSelectedWardrobe(getOrDefault(playerData, "wardrobe_equipped_slot", -1));
+
+ if (playerData.has("inv_contents")) {
+ NBTTagCompound armor = parseBase64NBT(playerData.getAsJsonObject("inv_contents").get("data").getAsString());
+ NBTTagList array = armor.getTagList("i", 10);
+ playerProfile.setInventory(new ItemStack[array.tagCount()]);
+ for (int i = 0; i < array.tagCount(); i++) {
+ NBTTagCompound item = array.getCompoundTagAt(i);
+ playerProfile.getInventory()[i] = deserializeNBT(item);
+ }
+ }
+ if (playerData.has("ender_chest_contents")) {
+ NBTTagCompound armor = parseBase64NBT(playerData.getAsJsonObject("ender_chest_contents").get("data").getAsString());
+ NBTTagList array = armor.getTagList("i", 10);
+ playerProfile.setEnderchest(new ItemStack[array.tagCount()]);
+ for (int i = 0; i < array.tagCount(); i++) {
+ NBTTagCompound item = array.getCompoundTagAt(i);
+ playerProfile.getEnderchest()[i] = deserializeNBT(item);
+ }
+ }
+ if (playerData.has("talisman_bag")) {
+ NBTTagCompound armor = parseBase64NBT(playerData.getAsJsonObject("talisman_bag").get("data").getAsString());
+ NBTTagList array = armor.getTagList("i", 10);
+ playerProfile.setTalismans(new ItemStack[array.tagCount()]);
+ for (int i = 0; i < array.tagCount(); i++) {
+ NBTTagCompound item = array.getCompoundTagAt(i);
+ playerProfile.getTalismans()[i] = deserializeNBT(item);
+ }
+ }
+
+ playerProfile.setSkillXp(new HashMap<>());
+ for (Skill value : Skill.values()) {
+ playerProfile.getSkillXp().put(value, getOrDefaultNullable(playerData, "experience_skill_" + value.getJsonName(), null));
+ }
+
+ if (playerData.has("pets")) {
+ for (JsonElement pets : playerData.getAsJsonArray("pets")) {
+ JsonObject pet = pets.getAsJsonObject();
+ Pet petObj = new Pet();
+ petObj.setActive(pet.get("active").getAsBoolean());
+ petObj.setExp(getOrDefault(pet, "exp", 0.0));
+ petObj.setHeldItem(getOrDefault(pet, "heldItem", null));
+ petObj.setSkin(getOrDefault(pet, "skin", null));
+ petObj.setType(getOrDefault(pet, "type", null));
+ petObj.setUuid(getOrDefault(pet, "uuid", null));
+
+ playerProfile.getPets().add(petObj);
+ }
+ }
+
+ if (playerData.has("dungeons") && playerData.getAsJsonObject("dungeons").has("dungeon_types")) {
+ JsonObject types = playerData.getAsJsonObject("dungeons")
+ .getAsJsonObject("dungeon_types");
+ for (DungeonType value : DungeonType.values()) {
+ DungeonStat dungeonStat = new DungeonStat();
+ DungeonSpecificData dungeonSpecificData = new DungeonSpecificData<>(value, dungeonStat);
+ playerProfile.getDungeonStats().put(value, dungeonSpecificData);
+
+ if (!types.has(value.getJsonName())) continue;
+
+ JsonObject dungeonObj = types.getAsJsonObject(value.getJsonName());
+
+ dungeonStat.setHighestCompleted(getOrDefault(dungeonObj, "highest_tier_completed", -1));
+
+ for (Integer validFloor : value.getValidFloors()) {
+ DungeonStat.PlayedFloor playedFloor = new DungeonStat.PlayedFloor();
+ playedFloor.setBestScore(getOrDefault(dungeonObj.getAsJsonObject("best_score"), "" + validFloor, 0));
+ playedFloor.setCompletions(getOrDefault(dungeonObj.getAsJsonObject("tier_completions"), "" + validFloor, 0));
+ playedFloor.setFastestTime(getOrDefault(dungeonObj.getAsJsonObject("fastest_time"), "" + validFloor, -1));
+ playedFloor.setFastestTimeS(getOrDefault(dungeonObj.getAsJsonObject("fastest_time_s"), "" + validFloor, -1));
+ playedFloor.setFastestTimeSPlus(getOrDefault(dungeonObj.getAsJsonObject("fastest_time_s_plus"), "" + validFloor, -1));
+ playedFloor.setMobsKilled(getOrDefault(dungeonObj.getAsJsonObject("mobs_killed"), "" + validFloor, 0));
+ playedFloor.setMostMobsKilled(getOrDefault(dungeonObj.getAsJsonObject("most_mobs_killed"), "" + validFloor, 0));
+ playedFloor.setMostHealing(getOrDefault(dungeonObj.getAsJsonObject("most_healing"), "" + validFloor, 0));
+ playedFloor.setTimes_played(getOrDefault(dungeonObj.getAsJsonObject("times_played"), "" + validFloor, 0));
+ playedFloor.setWatcherKills(getOrDefault(dungeonObj.getAsJsonObject("watcher_kills"), "" + validFloor, 0));
+
+ for (DungeonClass dungeonClass : DungeonClass.values()) {
+ DungeonStat.PlayedFloor.ClassStatistics classStatistics = new DungeonStat.PlayedFloor.ClassStatistics();
+ classStatistics.setMostDamage(getOrDefault(dungeonObj.getAsJsonObject("most_damage_" + dungeonClass.getJsonName()), "" + validFloor, 0));
+ ClassSpecificData classStatisticsClassSpecificData = new ClassSpecificData<>(dungeonClass, classStatistics);
+
+ playedFloor.getClassStatistics().put(dungeonClass, classStatisticsClassSpecificData);
+ }
+
+ FloorSpecificData playedFloorFloorSpecificData = new FloorSpecificData<>(validFloor, playedFloor);
+ dungeonStat.getPlays().put(validFloor, playedFloorFloorSpecificData);
+ }
+
+ dungeonStat.setExperience(getOrDefault(dungeonObj, "experience", 0));
+
+
+ }
+ }
+ if (playerData.has("dungeons") && playerData.getAsJsonObject("dungeons").has("player_classes")) {
+ JsonObject classes = playerData.getAsJsonObject("dungeons")
+ .getAsJsonObject("player_classes");
+ for (DungeonClass dungeonClass : DungeonClass.values()) {
+ PlayerProfile.PlayerClassData classStatistics = new PlayerProfile.PlayerClassData();
+ classStatistics.setExperience(getOrDefault(classes.getAsJsonObject(dungeonClass.getJsonName()), "experience", 0));
+ ClassSpecificData classStatisticsClassSpecificData = new ClassSpecificData<>(dungeonClass, classStatistics);
+
+ playerProfile.getPlayerClassData().put(dungeonClass, classStatisticsClassSpecificData);
+ }
+ }
+ if (playerData.has("dungeons")) {
+ String id = getOrDefault(playerData.getAsJsonObject("dungeons"), "selected_dungeon_class", null);
+ DungeonClass dungeonClass = DungeonClass.getClassByJsonName(id);
+ playerProfile.setSelectedClass(dungeonClass);
+ }
+ try {
+ calculateLilyWeight(playerProfile, playerData);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return playerProfile;
+ }
+
+ private static void calculateLilyWeight(PlayerProfile playerProfile, JsonObject playerData) throws ExecutionException, InterruptedException {
+ JsonObject constants = getLilyWeightConstants();
+ double[] slayerXP = new double[4];
+ if (playerData.has("slayer_bosses")) {
+ slayerXP[0] = getOrDefault(playerData.getAsJsonObject("slayer_bosses").getAsJsonObject("zombie"), "xp", 0);
+ slayerXP[1] = getOrDefault(playerData.getAsJsonObject("slayer_bosses").getAsJsonObject("spider"), "xp", 0);
+ slayerXP[2] = getOrDefault(playerData.getAsJsonObject("slayer_bosses").getAsJsonObject("wolf"), "xp", 0);
+ slayerXP[3] = getOrDefault(playerData.getAsJsonObject("slayer_bosses").getAsJsonObject("enderman"), "xp", 0);
+ }
+ double skillWeight = 0;
+ double overflowWeight = 0;
+ {
+ JsonObject srw = constants.getAsJsonObject("skillRatioWeight");
+ int skillMaxXP = constants.get("skillMaxXP").getAsInt();
+ JsonArray overflowMultiplier = constants.getAsJsonArray("skillOverflowMultipliers");
+ JsonArray skillFactor = constants.getAsJsonArray("skillFactors");
+
+ double skillAvg = playerProfile.getSkillXp().entrySet().stream()
+ .filter(a -> a.getValue() != null)
+ .filter(a -> srw.has(a.getKey().getJsonName()))
+ .map(a -> XPUtils.getSkillXp(a.getKey(), a.getValue()).getLevel()).collect(Collectors.averagingInt(a -> a));
+
+ double n = 12 * (skillAvg / 60) * (skillAvg / 60);
+ double r2 = Math.sqrt(2);
+
+ for (Map.Entry skillDoubleEntry : playerProfile.getSkillXp().entrySet()) {
+ String jsonName = skillDoubleEntry.getKey().getJsonName();
+ JsonArray temp_srw = srw.getAsJsonArray(jsonName);
+ if (temp_srw == null) continue;
+ int lv = XPUtils.getSkillXp(skillDoubleEntry.getKey(), skillDoubleEntry.getValue()).getLevel();
+ skillWeight += n * temp_srw.get(lv).getAsDouble()
+ * temp_srw.get(temp_srw.size() - 1).getAsDouble();
+ skillWeight += temp_srw.get(temp_srw.size() - 1).getAsDouble() * Math.pow(lv / 60.0, r2);
+ }
+
+ int cnt = 0;
+ for (Map.Entry skillNames : constants.getAsJsonObject("skillNames").entrySet()) {
+ Skill s = getSkillByLilyName(skillNames.getKey());
+ double factor = skillFactor.get(cnt).getAsDouble();
+ double effectiveOver;
+ Double xp = playerProfile.getSkillXp().get(s);
+ if (xp == null) continue;
+ xp -= skillMaxXP;
+ {
+ if (xp < skillMaxXP) effectiveOver = xp;
+ else {
+ double remainingXP = xp;
+ double z = 0;
+ for (int i = 0; i <= xp / skillMaxXP; i++) {
+ if (remainingXP >= skillMaxXP) {
+ remainingXP -= skillMaxXP;
+ z += Math.pow(factor, i);
+ }
+ }
+ effectiveOver = z * skillMaxXP;
+ }
+ }
+ double rating = effectiveOver / skillMaxXP;
+ double overflowMult = overflowMultiplier.get(cnt).getAsDouble();
+ double t = rating * overflowMult;
+ if (t > 0) overflowWeight += t;
+ cnt++;
+ }
+ }
+ double cataCompWeight, masterCompWeight;
+ {
+ JsonArray completionFactor = constants.getAsJsonArray("dungeonCompletionWorth");
+ JsonObject dungeonCompletionBuffs = constants.getAsJsonObject("dungeonCompletionBuffs");
+ double max1000 = 0;
+ double mMax1000 = 0;
+ for (int i = 0; i < completionFactor.size(); i++) {
+ if (i < 8) max1000 += completionFactor.get(i).getAsDouble();
+ else mMax1000 += completionFactor.get(i).getAsDouble();
+ }
+
+ max1000 *= 1000;
+ mMax1000 *= 1000;
+
+ double upperBound = 1500;
+ double score = 0;
+
+ DungeonStat dStat = playerProfile.getDungeonStats().get(DungeonType.CATACOMBS).getData();
+ for (FloorSpecificData value : dStat.getPlays().values()) {
+ int runs = value.getData().getCompletions();
+ int excess = 0;
+ if (runs > 1000) {
+ excess = runs - 1000;
+ runs = 1000;
+ }
+
+ double floorScore = runs * completionFactor.get(value.getFloor()).getAsDouble();
+ if (excess > 0)
+ floorScore *= Math.log10(excess / 1000.0 + 1) / Math.log10(7.5) + 1;
+ score += floorScore;
+ }
+ cataCompWeight = (score / max1000 * upperBound);
+
+ dStat = playerProfile.getDungeonStats().get(DungeonType.MASTER_CATACOMBS).getData();
+ for (FloorSpecificData value : dStat.getPlays().values()) {
+ if (dungeonCompletionBuffs.has(value.getFloor() + "")) {
+ double threshold = 20;
+ if (value.getData().getCompletions() >= threshold)
+ upperBound += dungeonCompletionBuffs.get(value.getFloor() + "").getAsDouble();
+ else
+ upperBound += dungeonCompletionBuffs.get(value.getFloor() + "").getAsDouble() * Math.pow(value.getData().getCompletions() / threshold, 1.840896416);
+ }
+ }
+ score = 0;
+ for (FloorSpecificData value : dStat.getPlays().values()) {
+ int runs = value.getData().getCompletions();
+ int excess = 0;
+ if (runs > 1000) {
+ excess = runs - 1000;
+ runs = 1000;
+ }
+
+ double floorScore = runs * completionFactor.get(value.getFloor() + 7).getAsDouble();
+ if (excess > 0)
+ floorScore *= Math.log10(excess / 1000.0 + 1) / Math.log10(5) + 1;
+ score += floorScore;
+ }
+
+ masterCompWeight = score / mMax1000 * upperBound;
+ }
+ double dungeonXPWeight = 0;
+ {
+ double dungeonOverall = constants.get("dungeonOverall").getAsDouble();
+ double dungeonMaxXP = constants.get("dungeonMaxXP").getAsDouble();
+
+ double cataXP = playerProfile.getDungeonStats().get(DungeonType.CATACOMBS).getData().getExperience();
+ XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(cataXP);
+ double level = xpCalcResult.getLevel();
+ if (xpCalcResult.getLevel() != 50) {
+ double progress = Math.floor(xpCalcResult.getRemainingXp() / xpCalcResult.getNextLvXp() * 1000) / 1000.0;
+ level += progress;
+ }
+
+ double n;
+ double tempLevel = 0;
+ if (cataXP < dungeonMaxXP)
+ n = 0.2 * Math.pow(level / 50.0, 2.967355422);
+ else {
+ double part = 142452410;
+ tempLevel = 50 + (cataXP - dungeonMaxXP) / part;
+ n = 0.2 * Math.pow(1 + ((tempLevel - 50) / 50), 2.967355422);
+ }
+ if (level != 0) {
+ if (cataXP < 569809640)
+ dungeonXPWeight = dungeonOverall * (Math.pow(1.18340401286164044, (level + 1)) - 1.05994990217254) * (1 + n);
+ else dungeonXPWeight = 4000 * (n / 0.15465244570598540);
+ } else dungeonXPWeight = 0;
+ }
+ double slayerWeight = 0;
+ {
+ JsonArray slayerDeprecationScaling = constants.getAsJsonArray("slayerDeprecationScaling");
+ BiFunction getSlayerWeight = (xp, type) -> {
+ double score = 0;
+ {
+ double d = xp / 100000;
+ if (xp >= 6416) {
+ double D = (d - Math.pow(3, (-5 / 2.0))) * (d + Math.pow(3, -5 / 2.0));
+ double u = Math.cbrt(3 * (d + Math.sqrt(D)));
+ double v = Math.cbrt(3 * (d - Math.sqrt(D)));
+ score = u + v - 1;
+ } else {
+ score = Math.sqrt(4 / 3.0) * Math.cos(Math.acos(d * Math.pow(3, 5 / 2.0)) / 3) - 1;
+ }
+ }
+ score = Math.floor(score);
+ double scaling = slayerDeprecationScaling.get(type).getAsDouble();
+ double effectiveXP = 0;
+ for (int i = 1; i <= score; i++)
+ effectiveXP += (i * i + i) * Math.pow(scaling, i);
+ effectiveXP = Math.round((1000000 * effectiveXP * (0.05 / scaling)) * 100) / 100.0;
+ double actualXP = ((score * score * score / 6) + (score * score / 2) + (score / 3)) * 100000;
+ double distance = xp - actualXP;
+ double effectiveDistance = distance * Math.pow(scaling, score);
+ return effectiveXP + effectiveDistance;
+ };
+
+ double zombie = getSlayerWeight.apply(slayerXP[0], 0);
+ double spider = getSlayerWeight.apply(slayerXP[1], 1);
+ double wolf = getSlayerWeight.apply(slayerXP[2], 2);
+ double enderman = getSlayerWeight.apply(slayerXP[3], 3);
+ double individual = zombie / 7000 + spider / 4800 + wolf / 2200 + enderman / 1000;
+ double extra = (slayerXP[0] + 1.6 * slayerXP[1] + 3.6 * slayerXP[2] + 10 * slayerXP[3]) / 900000;
+ slayerWeight = (individual + extra);
+ }
+
+ PlayerProfile.LilyWeight lilyWeight = new PlayerProfile.LilyWeight();
+ lilyWeight.setCatacombs_base(cataCompWeight);
+ lilyWeight.setCatacombs_master(masterCompWeight);
+ lilyWeight.setCatacombs_exp(dungeonXPWeight);
+ lilyWeight.setSkill_base(skillWeight);
+ lilyWeight.setSkill_overflow(overflowWeight);
+ lilyWeight.setSlayer(slayerWeight);
+
+ playerProfile.setLilyWeight(lilyWeight);
+ }
+
+ private static Skill getSkillByLilyName(String lilyName) {
+ switch (lilyName) {
+ case "experience_skill_enchanting":
+ return Skill.ENCHANTING;
+ case "experience_skill_taming":
+ return Skill.TAMING;
+ case "experience_skill_alchemy":
+ return Skill.ALCHEMY;
+ case "experience_skill_mining":
+ return Skill.MINING;
+ case "experience_skill_farming":
+ return Skill.FARMING;
+ case "experience_skill_foraging":
+ return Skill.FORAGING;
+ case "experience_skill_combat":
+ return Skill.COMBAT;
+ case "experience_skill_fishing":
+ return Skill.FISHING;
+ default:
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/ClassSpecificData.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/ClassSpecificData.java
new file mode 100644
index 00000000..3496f3a9
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/ClassSpecificData.java
@@ -0,0 +1,29 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+@Getter
+public class ClassSpecificData {
+ private final DungeonClass dungeonClass;
+ private final T data;
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonClass.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonClass.java
new file mode 100644
index 00000000..fc569b57
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonClass.java
@@ -0,0 +1,46 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum DungeonClass {
+ MAGE("mage", "Mage"), ARCHER("archer","Archer"), HEALER("healer", "Healer"), TANK("tank", "Tank"), BERSERK("berserk", "Berserk");
+
+
+ private final String jsonName;
+ private final String familarName;
+ private static final Map jsonNameToClazz = new HashMap<>();
+ static {
+ for (DungeonClass value : values()) {
+ jsonNameToClazz.put(value.getJsonName(), value);
+ }
+ }
+
+ public static DungeonClass getClassByJsonName(String name) {
+ return jsonNameToClazz.get(name);
+ }
+
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonSpecificData.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonSpecificData.java
new file mode 100644
index 00000000..05975767
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonSpecificData.java
@@ -0,0 +1,29 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public class DungeonSpecificData {
+ private final DungeonType type;
+ private final T data;
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonStat.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonStat.java
new file mode 100644
index 00000000..be42a509
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonStat.java
@@ -0,0 +1,54 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses;
+
+import lombok.Data;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Data
+public class DungeonStat {
+ private int highestCompleted;
+ private double experience;
+
+ private Map> plays = new HashMap<>();
+ @Data
+ public static class PlayedFloor {
+ private int times_played;
+ private int completions;
+ private int watcherKills;
+
+ private int fastestTime;
+ private int fastestTimeS;
+ private int fastestTimeSPlus;
+ private int bestScore;
+
+ private int mostMobsKilled;
+ private int mobsKilled;
+
+ private Map> classStatistics = new HashMap<>();
+ @Data
+ public static class ClassStatistics {
+ private double mostDamage;
+ }
+
+ private double mostHealing;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonType.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonType.java
new file mode 100644
index 00000000..a394214d
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonType.java
@@ -0,0 +1,39 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses;
+
+import com.google.common.collect.Sets;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Set;
+
+@Getter
+@AllArgsConstructor
+public enum DungeonType {
+ CATACOMBS("catacombs", "The Catacombs",
+ Sets.newHashSet(0,1,2,3,4,5,6,7)),
+ MASTER_CATACOMBS("master_catacombs", "MasterMode Catacombs", Sets.newHashSet(
+ 1,2,3,4,5,6
+ ));
+
+ private final String jsonName;
+ private final String familiarName;
+ private final Set validFloors ;
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/FloorSpecificData.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/FloorSpecificData.java
new file mode 100644
index 00000000..e31d5034
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/FloorSpecificData.java
@@ -0,0 +1,29 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public class FloorSpecificData {
+ private final int floor;
+ private final T data;
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/Pet.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/Pet.java
new file mode 100644
index 00000000..40f15e49
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/Pet.java
@@ -0,0 +1,31 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses;
+
+import lombok.Data;
+
+@Data
+public class Pet {
+ private String uuid;
+ private String type;
+ private double exp;
+ private boolean active;
+ private String heldItem;
+ private String skin;
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/Skill.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/Skill.java
new file mode 100644
index 00000000..4ccc1e2d
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/Skill.java
@@ -0,0 +1,31 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum Skill {
+ RUNECRAFTING("runecrafting", "Runecrafting"), COMBAT("combat", "Combat"), MINING("mining", "Mining"), ALCHEMY("alchemy", "Alchemy"), FARMING("farming", "Farming"), TAMING("taming", "Taming"), ENCHANTING("enchanting", "Enchanting"), FISHING("fishing", "Fishing"), FORAGING("foraging", "Foraging"), CARPENTRY("carpentry", "Carpentry");
+
+ private final String jsonName;
+ private final String friendlyName;
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/DataRendererEditor.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/DataRendererEditor.java
new file mode 100644
index 00000000..02ab6ea1
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/DataRendererEditor.java
@@ -0,0 +1,357 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.FeatureViewPlayerStatsOnJoin;
+import kr.syeyoung.dungeonsguide.gui.MPanel;
+import kr.syeyoung.dungeonsguide.utils.RenderUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.renderer.GlStateManager;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL14;
+
+import java.awt.*;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class DataRendererEditor extends MPanel {
+ private final FeatureViewPlayerStatsOnJoin feature;
+
+ public DataRendererEditor(FeatureViewPlayerStatsOnJoin featureViewPlayerStatsOnJoin) {
+ this.feature = featureViewPlayerStatsOnJoin;
+ }
+
+ @Override
+ public void resize(int parentWidth, int parentHeight) {
+ this.setBounds(new Rectangle(5,5,parentWidth-10, 260));
+ }
+
+ private String currentlySelected;
+ private int selectedX;
+ private int selectedY;
+ private int lastX;
+ private int lastY;
+ private int scrollY;
+ private final int baseWidth = 120;
+ private final int hamburgerWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth("==");
+
+ @Override
+ public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {
+ Gui.drawRect(0,0,getBounds().width, getBounds().height, RenderUtils.blendAlpha(0x141414, 0.12f));
+
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
+
+
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ fr.drawString("Available", (310 + baseWidth + hamburgerWidth -fr.getStringWidth("Available")) / 2, 4, 0xFFFFFFFF);
+ fr.drawString("Current", (baseWidth + hamburgerWidth+10 -fr.getStringWidth("Current")) /2 , 4, 0xFFFFFFFF);
+ Gui.drawRect(4,4 + fr.FONT_HEIGHT + 3,baseWidth + hamburgerWidth+6 + 1, 236+ fr.FONT_HEIGHT + 3, 0xFF222222);
+ Gui.drawRect(5,5+ fr.FONT_HEIGHT + 3,baseWidth + hamburgerWidth + 5 + 1, 235+ fr.FONT_HEIGHT + 3, RenderUtils.blendAlpha(0x141414, 0.15f));
+ Gui.drawRect(5 + hamburgerWidth,4+ fr.FONT_HEIGHT + 3,6 + hamburgerWidth, 236+ fr.FONT_HEIGHT + 3, 0xFF222222);
+
+ Gui.drawRect(154,4 + fr.FONT_HEIGHT + 3,150 + baseWidth + hamburgerWidth + 6+1, 236+ fr.FONT_HEIGHT + 3, 0xFF222222);
+ Gui.drawRect(155,5+ fr.FONT_HEIGHT + 3,150 + baseWidth + hamburgerWidth + 5+1, 235+ fr.FONT_HEIGHT + 3, RenderUtils.blendAlpha(0x141414, 0.15f));
+ Gui.drawRect(155 + hamburgerWidth,4 + fr.FONT_HEIGHT + 3,156 + hamburgerWidth, 236+ fr.FONT_HEIGHT + 3, 0xFF222222);
+
+ GlStateManager.pushMatrix();
+ clip(scissor.x + 6+hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230);
+ GlStateManager.translate(6+hamburgerWidth, 5+fr.FONT_HEIGHT+3, 0);
+ int culmutativeY = 0;
+ int relSelectedY = selectedY - (5+ fr.FONT_HEIGHT + 3);
+ boolean drewit = false;
+ for (String datarenderers : feature.>getParameter("datarenderers").getValue()) {
+
+ if (0 <= selectedX && selectedX <= hamburgerWidth+11 && currentlySelected != null) {
+ IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(currentlySelected);
+ Dimension dim;
+ if (dataRenderer == null) dim = new Dimension(0,fr.FONT_HEIGHT*2);
+ else dim = dataRenderer.getDimension();
+
+ if (culmutativeY + dim.height > relSelectedY && relSelectedY >= culmutativeY && !drewit) {
+ clip(scissor.x + 6 + hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230);
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ if (dataRenderer == null) {
+ fr.drawString("Couldn't find Datarenderer", 0,0, 0xFFFF0000);
+ fr.drawString(currentlySelected, 0,fr.FONT_HEIGHT, 0xFFFF0000);
+ dim = new Dimension(0, fr.FONT_HEIGHT * 2);
+ } else {
+ GlStateManager.pushMatrix();
+ dim = dataRenderer.renderDummy();
+ GlStateManager.popMatrix();
+ }
+ clip(scissor.x, scissor.y, scissor.width, scissor.height);
+ GlStateManager.translate(-hamburgerWidth-1, 0, 0);
+ Gui.drawRect(0,0, hamburgerWidth, dim.height-1, 0xFF777777);
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ fr.drawString("=",fr.getStringWidth("=")/2,(dim.height - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
+ GlStateManager.translate(hamburgerWidth+1,dim.height,0);
+ drewit = true;
+ }
+ }
+
+ IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers);
+ clip(scissor.x + 6 + hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230);
+ Dimension dim;
+
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ if (dataRenderer == null) {
+ fr.drawString("Couldn't find Datarenderer", 0,0, 0xFFFF0000);
+ fr.drawString(datarenderers, 0,fr.FONT_HEIGHT, 0xFFFF0000);
+ dim = new Dimension(0, fr.FONT_HEIGHT * 2);
+ } else {
+ GlStateManager.pushMatrix();
+ dim = dataRenderer.renderDummy();
+ GlStateManager.popMatrix();
+ }
+ clip(scissor.x, scissor.y, scissor.width, scissor.height);
+ GlStateManager.translate(-hamburgerWidth-1, 0, 0);
+ Gui.drawRect(0,0, hamburgerWidth, dim.height-1, 0xFFAAAAAA);
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ fr.drawString("=",fr.getStringWidth("=")/2,(dim.height - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
+ GlStateManager.translate(hamburgerWidth+1,dim.height,0);
+
+ culmutativeY += dim.height;
+ }
+
+ if (currentlySelected != null && new Rectangle(0,5+fr.FONT_HEIGHT + 3, hamburgerWidth+11, 232).contains(selectedX, selectedY) && !drewit) {
+ IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(currentlySelected);
+ Dimension dim;
+ clip(scissor.x + 6 + hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230);
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ if (dataRenderer == null) {
+ fr.drawString("Couldn't find Datarenderer", 0,0, 0xFFFF0000);
+ fr.drawString(currentlySelected, 0,fr.FONT_HEIGHT, 0xFFFF0000);
+ dim = new Dimension(0, fr.FONT_HEIGHT * 2);
+ } else {
+ GlStateManager.pushMatrix();
+ dim = dataRenderer.renderDummy();
+ GlStateManager.popMatrix();
+ }
+ clip(scissor.x, scissor.y, scissor.width, scissor.height);
+ GlStateManager.translate(-hamburgerWidth-1, 0, 0);
+ Gui.drawRect(0,0, hamburgerWidth, dim.height-1, 0xFF777777);
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ fr.drawString("=",fr.getStringWidth("=")/2,(dim.height - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
+ GlStateManager.translate(hamburgerWidth+1,dim.height,0);
+ }
+ GlStateManager.popMatrix();
+
+
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(156+hamburgerWidth, 5+fr.FONT_HEIGHT+3 - scrollY, 0);
+
+ Set rest = new HashSet<>(DataRendererRegistry.getValidDataRenderer());
+ rest.removeAll( feature.>getParameter("datarenderers").getValue());
+ rest.remove(currentlySelected);
+ for (String datarenderers : rest) {
+ IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers);
+ clip(scissor.x + 156 + hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230);
+ Dimension dim;
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ if (dataRenderer == null) {
+ fr.drawString("Couldn't find Datarenderer", 0,0, 0xFFFF0000);
+ fr.drawString(datarenderers, 0,fr.FONT_HEIGHT, 0xFFFF0000);
+ dim = new Dimension(0, fr.FONT_HEIGHT * 2);
+ } else {
+ GlStateManager.pushMatrix();
+ dim = dataRenderer.renderDummy();
+ GlStateManager.popMatrix();
+ }
+ clip(scissor.x + 155, scissor.y + 5+fr.FONT_HEIGHT+3, hamburgerWidth, 230);
+ GlStateManager.translate(-hamburgerWidth-1, 0, 0);
+ Gui.drawRect(0,0, hamburgerWidth, dim.height-1, 0xFFAAAAAA);
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ fr.drawString("=",fr.getStringWidth("=")/2,(dim.height - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
+ GlStateManager.translate(hamburgerWidth+1,dim.height,0);
+ }
+ GlStateManager.popMatrix();
+ clip(0,0,sr.getScaledWidth(), sr.getScaledHeight());
+ {
+ if (currentlySelected != null) {
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(selectedX+hamburgerWidth+1, selectedY, 0);
+ IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(currentlySelected);
+ Dimension dim;
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ if (dataRenderer == null) {
+ fr.drawString("Couldn't find Datarenderer", 0, 0, 0xFFFF0000);
+ fr.drawString(currentlySelected, 0, fr.FONT_HEIGHT, 0xFFFF0000);
+ dim = new Dimension(0, fr.FONT_HEIGHT * 2);
+ } else {
+ GlStateManager.pushMatrix();
+ dim = dataRenderer.renderDummy();
+ GlStateManager.popMatrix();
+ }
+ GlStateManager.translate(-hamburgerWidth-1, 0, 0);
+ Gui.drawRect(0,0, hamburgerWidth, dim.height-1, 0xFFAAAAAA);
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ fr.drawString("=",fr.getStringWidth("=")/2,(dim.height - fr.FONT_HEIGHT) / 2, 0xFFFFFFFF);
+ GlStateManager.popMatrix();
+ }
+ }
+ clip(scissor.x, scissor.y, scissor.width, scissor.height);
+ }
+
+ @Override
+ public void mouseClicked(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int mouseButton) {
+ super.mouseClicked(absMouseX, absMouseY, relMouseX, relMouseY, mouseButton);
+ lastX = relMouseX;
+ lastY = relMouseY;
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ int legitRelY = relMouseY - (5+fr.FONT_HEIGHT+3);
+ if (new Rectangle(155,5+fr.FONT_HEIGHT + 3, hamburgerWidth, 230).contains(relMouseX, relMouseY)) {
+ Set rest = new HashSet<>(DataRendererRegistry.getValidDataRenderer());
+ rest.removeAll( feature.>getParameter("datarenderers").getValue());
+ rest.remove(currentlySelected);
+ int culmutativeY = -scrollY;
+ for (String datarenderers : rest) {
+ IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers);
+ Dimension dim;
+ if (dataRenderer == null) {
+ dim = new Dimension(0, fr.FONT_HEIGHT * 2);
+ } else {
+ GlStateManager.pushMatrix();
+ dim = dataRenderer.getDimension();
+ GlStateManager.popMatrix();
+ }
+ culmutativeY += dim.height;
+
+ if (legitRelY < culmutativeY) {
+ currentlySelected = datarenderers;
+ selectedX = 155;
+ selectedY = culmutativeY - dim.height + 5+fr.FONT_HEIGHT + 3;
+ break;
+ }
+ }
+ }
+ if (new Rectangle(5,5+fr.FONT_HEIGHT + 3, hamburgerWidth, 230).contains(relMouseX, relMouseY)) {
+ List rest = feature.>getParameter("datarenderers").getValue();
+ int culmutativeY = 0;
+ for (String datarenderers : rest) {
+ IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers);
+ Dimension dim;
+ if (dataRenderer == null) {
+ dim = new Dimension(0, fr.FONT_HEIGHT * 2);
+ } else {
+ GlStateManager.pushMatrix();
+ dim = dataRenderer.getDimension();
+ GlStateManager.popMatrix();
+ }
+ culmutativeY += dim.height;
+
+ if (legitRelY < culmutativeY) {
+ currentlySelected = datarenderers;
+ selectedX = 5;
+ selectedY = culmutativeY - dim.height + 5+fr.FONT_HEIGHT + 3;
+ rest.remove(datarenderers);
+ break;
+ }
+ }
+ }
+ }
+
+ @Override
+ public void mouseClickMove(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int clickedMouseButton, long timeSinceLastClick) {
+ super.mouseClickMove(absMouseX, absMouseY, relMouseX, relMouseY, clickedMouseButton, timeSinceLastClick);
+ if (currentlySelected != null) {
+ int dx = relMouseX - lastX;
+ int dy = relMouseY - lastY;
+ selectedX += dx;
+ selectedY += dy;
+ }
+ lastX = relMouseX;
+ lastY = relMouseY;
+ }
+
+ @Override
+ public void mouseReleased(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int state) {
+ super.mouseReleased(absMouseX, absMouseY, relMouseX, relMouseY, state);
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ int legitRelY = selectedY - (5+fr.FONT_HEIGHT+3);
+ if (currentlySelected != null && new Rectangle(0,5+fr.FONT_HEIGHT + 3, hamburgerWidth+11, 232).contains(selectedX, selectedY)) {
+ Set rest = new HashSet<>(DataRendererRegistry.getValidDataRenderer());
+ int culmutativeY = 0;
+ List asdasdkasd = feature.>getParameter("datarenderers").getValue();
+ int index = asdasdkasd.size();
+ for (int i = 0; i 0) scrollY -= 20;
+ if (scrollY < 0) scrollY = 0;
+
+
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/DataRendererRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/DataRendererRegistry.java
new file mode 100644
index 00000000..b2187511
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/DataRendererRegistry.java
@@ -0,0 +1,64 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.DungeonClass;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.DungeonType;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.Skill;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl.*;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class DataRendererRegistry {
+ private static final Map dataRendererMap = new HashMap<>();
+
+ public static IDataRenderer getDataRenderer(String id) {
+ return dataRendererMap.get(id);
+ }
+
+ public static Set getValidDataRenderer() {
+ return dataRendererMap.keySet();
+ }
+
+ static {
+ dataRendererMap.put("catalv", new DataRendererDungeonLv(DungeonType.CATACOMBS));
+ for (DungeonClass value : DungeonClass.values()) {
+ dataRendererMap.put("class_"+value.getJsonName()+"_lv", new DataRendererClassLv(value));
+ }
+ dataRendererMap.put("selected_class_lv", new DataRendererSelectedClassLv());
+ for (Skill value : Skill.values()) {
+ dataRendererMap.put("skill_"+value.getJsonName()+"_lv", new DataRendererSkillLv(value));
+ }
+ for (DungeonType value : DungeonType.values()) {
+ for (Integer validFloor : value.getValidFloors()) {
+ dataRendererMap.put("dungeon_"+value.getJsonName()+"_"+validFloor+"_stat", new DataRenderDungeonFloorStat(value, validFloor));
+ }
+ dataRendererMap.put("dungeon_"+value.getJsonName()+"_higheststat", new DataRenderDungeonHighestFloorStat(value));
+ }
+ dataRendererMap.put("fairysouls", new DataRendererFairySouls());
+ dataRendererMap.put("secrets", new DataRendererSecrets());
+
+ dataRendererMap.put("dummy", new DataRendererSetUrOwn());
+
+ dataRendererMap.put("talismans", new DataRendererTalismans());
+ dataRendererMap.put("weight", new DataRendererLilyWeight());
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/IDataRenderer.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/IDataRenderer.java
new file mode 100644
index 00000000..3f2d0ad2
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/IDataRenderer.java
@@ -0,0 +1,33 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+
+import java.awt.*;
+
+public interface IDataRenderer {
+ Dimension renderData(PlayerProfile playerProfile);
+ void onHover(PlayerProfile playerProfile, int mouseX, int mouseY);
+
+
+ Dimension renderDummy();
+
+ Dimension getDimension();
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRenderDungeonFloorStat.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRenderDungeonFloorStat.java
new file mode 100644
index 00000000..f2cf4a38
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRenderDungeonFloorStat.java
@@ -0,0 +1,105 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.IDataRenderer;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.DungeonSpecificData;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.DungeonStat;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.DungeonType;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.FloorSpecificData;
+import kr.syeyoung.dungeonsguide.utils.TextUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraftforge.fml.client.config.GuiUtils;
+
+import java.awt.*;
+import java.util.Arrays;
+
+public class DataRenderDungeonFloorStat implements IDataRenderer {
+ private final DungeonType dungeonType;
+ private final int floor;
+ public DataRenderDungeonFloorStat(DungeonType dungeonType, int floor) {
+ this.dungeonType = dungeonType;
+ this.floor = floor;
+ }
+
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ String floorName = (dungeonType == DungeonType.CATACOMBS ? "F" : "M") + floor;
+
+ boolean flag = false;
+ DungeonSpecificData dungeonStatDungeonSpecificData = playerProfile.getDungeonStats().get(dungeonType);
+ if (dungeonStatDungeonSpecificData != null) {
+ FloorSpecificData playedFloorFloorSpecificData = dungeonStatDungeonSpecificData.getData().getPlays().get(floor);
+ if (playedFloorFloorSpecificData != null) {
+ flag = true;
+ fr.drawString("§b" + floorName + " §a" + playedFloorFloorSpecificData.getData().getBestScore() + " §f" + playedFloorFloorSpecificData.getData().getCompletions() + "§7/§f" + playedFloorFloorSpecificData.getData().getWatcherKills() + "§7/§f" + playedFloorFloorSpecificData.getData().getTimes_played() + " §7(" + (int) (playedFloorFloorSpecificData.getData().getCompletions()*100 / (double) playedFloorFloorSpecificData.getData().getWatcherKills()) + "%)", 0, 0, -1);
+ fr.drawString("§6S+ §e" + (playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "§7N/A") + " §6S §e" + (playedFloorFloorSpecificData.getData().getFastestTimeS() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "§7N/A"), 0, fr.FONT_HEIGHT, -1);
+ }
+ }
+ if (!flag) {
+ fr.drawString("§cNo Stat for "+floorName, 0,0,-1);
+ }
+
+ return getDimension();
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ String floorName = (dungeonType == DungeonType.CATACOMBS ? "F" : "M") + floor;
+
+
+ fr.drawString("§b"+floorName+" §a305 §f10§7/§f35§7/§f50 §7("+(int)(1000.0/35.0)+"%)", 0,0,-1);
+ fr.drawString("§6S+ §e10m 53s §6S §e15m 13s", 0, fr.FONT_HEIGHT, -1);
+ return getDimension();
+ }
+
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*2);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+
+ DungeonSpecificData dungeonStatDungeonSpecificData = playerProfile.getDungeonStats().get(dungeonType);
+ if (dungeonStatDungeonSpecificData == null) return;
+ FloorSpecificData playedFloorFloorSpecificData = dungeonStatDungeonSpecificData.getData().getPlays().get(floor);
+ if (playedFloorFloorSpecificData == null) return;
+ String floorName = (dungeonType == DungeonType.CATACOMBS ? "F" : "M") + floor;
+
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ GuiUtils.drawHoveringText(Arrays.asList(
+ "§bFloor "+floorName,
+ "§bBest Score§7: §f"+playedFloorFloorSpecificData.getData().getBestScore(),
+ "§bTotal Completions§7: §f"+playedFloorFloorSpecificData.getData().getCompletions(),
+ "§bTotal Watcher kills§7: §f"+playedFloorFloorSpecificData.getData().getWatcherKills(),
+ "§bTotal Runs§7: §f"+playedFloorFloorSpecificData.getData().getTimes_played(),
+ "§bFastest S+§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "§7N/A"),
+ "§bFastest S§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeS() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "§7N/A"),
+ "§bFastest Run§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTime() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTime()) : "§7N/A"),
+ "§bMost Mobs Killed§7: §f"+playedFloorFloorSpecificData.getData().getMostMobsKilled(),
+ "§bTotal Mobs Killed§7: §f"+playedFloorFloorSpecificData.getData().getMobsKilled()
+ ), mouseX, mouseY, scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRenderDungeonHighestFloorStat.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRenderDungeonHighestFloorStat.java
new file mode 100644
index 00000000..8daba7eb
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRenderDungeonHighestFloorStat.java
@@ -0,0 +1,107 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.IDataRenderer;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.DungeonSpecificData;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.DungeonStat;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.DungeonType;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.FloorSpecificData;
+import kr.syeyoung.dungeonsguide.utils.TextUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraftforge.fml.client.config.GuiUtils;
+
+import java.awt.*;
+import java.util.Arrays;
+
+public class DataRenderDungeonHighestFloorStat implements IDataRenderer {
+ private final DungeonType dungeonType;
+ public DataRenderDungeonHighestFloorStat(DungeonType dungeonType) {
+ this.dungeonType = dungeonType;
+ }
+
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+
+ boolean flag = false;
+ DungeonSpecificData dungeonStatDungeonSpecificData = playerProfile.getDungeonStats().get(dungeonType);
+ if (dungeonStatDungeonSpecificData != null) {
+ if (dungeonStatDungeonSpecificData.getData().getHighestCompleted() != -1) {
+ FloorSpecificData playedFloorFloorSpecificData = dungeonStatDungeonSpecificData.getData().getPlays().get(dungeonStatDungeonSpecificData.getData().getHighestCompleted());
+ String floorName = (dungeonType == DungeonType.CATACOMBS ? "F" : "M") + dungeonStatDungeonSpecificData.getData().getHighestCompleted();
+ if (playedFloorFloorSpecificData != null) {
+ flag = true;
+ fr.drawString("§bH: " + floorName + " §a" + playedFloorFloorSpecificData.getData().getBestScore() + " §f" + playedFloorFloorSpecificData.getData().getCompletions() + "§7/§f" + playedFloorFloorSpecificData.getData().getWatcherKills() + "§7/§f" + playedFloorFloorSpecificData.getData().getTimes_played() + " §7(" + (int) (playedFloorFloorSpecificData.getData().getCompletions() *100/ (double) playedFloorFloorSpecificData.getData().getWatcherKills()) + "%)", 0, 0, -1);
+ fr.drawString("§6S+ §e" + (playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "§7N/A") + " §6S §e" + (playedFloorFloorSpecificData.getData().getFastestTimeS() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "§7N/A"), 0, fr.FONT_HEIGHT, -1);
+ }
+ }
+ }
+ if (!flag) {
+ fr.drawString("§cNo Highest Floor for ", 0,0,-1);
+ fr.drawString("§c"+dungeonType.getFamiliarName(), 0,fr.FONT_HEIGHT,-1);
+ }
+
+ return getDimension();
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ String floorName = (dungeonType == DungeonType.CATACOMBS ? "F" : "M") + "9";
+
+
+ fr.drawString("§bH: "+floorName+" §a305 §f10§7/§f35§7/§f50 §7("+(int)(1000.0/35.0)+"%)", 0,0,-1);
+ fr.drawString("§6S+ §e10m 53s §6S §e15m 13s", 0, fr.FONT_HEIGHT, -1);
+ return getDimension();
+ }
+
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*2);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+
+ DungeonSpecificData dungeonStatDungeonSpecificData = playerProfile.getDungeonStats().get(dungeonType);
+ if (dungeonStatDungeonSpecificData == null) return;
+ if (dungeonStatDungeonSpecificData.getData().getHighestCompleted() == -1) return;
+ FloorSpecificData playedFloorFloorSpecificData = dungeonStatDungeonSpecificData.getData().getPlays().get( dungeonStatDungeonSpecificData.getData().getHighestCompleted());
+ if (playedFloorFloorSpecificData == null) return;
+ String floorName = (dungeonType == DungeonType.CATACOMBS ? "F" : "M") + dungeonStatDungeonSpecificData.getData().getHighestCompleted();
+
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ GuiUtils.drawHoveringText(Arrays.asList(
+ "§bFloor "+floorName,
+ "§bBest Score§7: §f"+playedFloorFloorSpecificData.getData().getBestScore(),
+ "§bTotal Completions§7: §f"+playedFloorFloorSpecificData.getData().getCompletions(),
+ "§bTotal Watcher kills§7: §f"+playedFloorFloorSpecificData.getData().getWatcherKills(),
+ "§bTotal Runs§7: §f"+playedFloorFloorSpecificData.getData().getTimes_played(),
+ "§bFastest S+§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "§7N/A"),
+ "§bFastest S§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeS() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "§7N/A"),
+ "§bFastest Run§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTime() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTime()) : "§7N/A"),
+ "§bMost Mobs Killed§7: §f"+playedFloorFloorSpecificData.getData().getMostMobsKilled(),
+ "§bTotal Mobs Killed§7: §f"+playedFloorFloorSpecificData.getData().getMobsKilled()
+ ), mouseX, mouseY, scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererClassLv.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererClassLv.java
new file mode 100644
index 00000000..8a798eee
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererClassLv.java
@@ -0,0 +1,88 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.IDataRenderer;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.ClassSpecificData;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.DungeonClass;
+import kr.syeyoung.dungeonsguide.utils.RenderUtils;
+import kr.syeyoung.dungeonsguide.utils.TextUtils;
+import kr.syeyoung.dungeonsguide.utils.XPUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraftforge.fml.client.config.GuiUtils;
+
+import java.awt.*;
+import java.util.Arrays;
+
+public class DataRendererClassLv implements IDataRenderer {
+ private final DungeonClass dungeonClass;
+ public DataRendererClassLv(DungeonClass dungeonClass) {
+ this.dungeonClass = dungeonClass;
+ }
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ ClassSpecificData dungeonStatDungeonSpecificData = playerProfile.getPlayerClassData().get(dungeonClass);
+ boolean selected = playerProfile.getSelectedClass() == dungeonClass;
+ if (dungeonStatDungeonSpecificData == null) {
+ fr.drawString(dungeonClass.getFamilarName(), 0,0, 0xFF55ffff);
+ fr.drawString("Unknown", fr.getStringWidth(dungeonClass.getFamilarName()+" "),0,0xFFFFFFFF);
+ if (selected)
+ fr.drawString("★", fr.getStringWidth(dungeonClass.getFamilarName()+" Unknown "),0,0xFFAAAAAA);
+ } else {
+ XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(dungeonStatDungeonSpecificData.getData().getExperience());
+ fr.drawString(dungeonClass.getFamilarName(), 0,0, 0xFF55ffff);
+ fr.drawString(xpCalcResult.getLevel()+"", fr.getStringWidth(dungeonClass.getFamilarName()+" "),0,0xFFFFFFFF);
+ if (selected)
+ fr.drawString("★", fr.getStringWidth(dungeonClass.getFamilarName()+" "+xpCalcResult.getLevel()+" "),0,0xFFAAAAAA);
+
+ RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,xpCalcResult.getRemainingXp() == 0 ? 1 : (float) (xpCalcResult.getRemainingXp() / xpCalcResult.getNextLvXp()));
+ }
+
+ return new Dimension(100, fr.FONT_HEIGHT*2);
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString(dungeonClass.getFamilarName(), 0,0, 0xFF55ffff);
+ fr.drawString("99", fr.getStringWidth(dungeonClass.getFamilarName()+" "),0,0xFFFFFFFF);
+ fr.drawString("★", fr.getStringWidth(dungeonClass.getFamilarName()+" 99 "),0,0xFFAAAAAA);
+ RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,1.0f);
+ return new Dimension(100, fr.FONT_HEIGHT*2);
+ }
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*2);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+ ClassSpecificData dungeonStatDungeonSpecificData = playerProfile.getPlayerClassData().get(dungeonClass);
+ if (dungeonStatDungeonSpecificData == null) return;
+ XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(dungeonStatDungeonSpecificData.getData().getExperience());
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+
+ GuiUtils.drawHoveringText(Arrays.asList("§bCurrent Lv§7: §e"+xpCalcResult.getLevel(),"§bExp§7: §e"+ TextUtils.format((long)xpCalcResult.getRemainingXp()) + "§7/§e"+TextUtils.format((long)xpCalcResult.getNextLvXp()), "§bTotal Xp§7: §e"+ TextUtils.format((long)dungeonStatDungeonSpecificData.getData().getExperience())),mouseX, mouseY,
+ scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererDungeonLv.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererDungeonLv.java
new file mode 100644
index 00000000..5cc37fa6
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererDungeonLv.java
@@ -0,0 +1,82 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.DungeonSpecificData;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.DungeonStat;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.DungeonType;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.IDataRenderer;
+import kr.syeyoung.dungeonsguide.utils.RenderUtils;
+import kr.syeyoung.dungeonsguide.utils.TextUtils;
+import kr.syeyoung.dungeonsguide.utils.XPUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraftforge.fml.client.config.GuiUtils;
+
+import java.awt.*;
+import java.util.Arrays;
+
+public class DataRendererDungeonLv implements IDataRenderer {
+ private final DungeonType dungeonType;
+ public DataRendererDungeonLv(DungeonType dungeonType) {
+ this.dungeonType = dungeonType;
+ }
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ DungeonSpecificData dungeonStatDungeonSpecificData = playerProfile.getDungeonStats().get(dungeonType);
+ if (dungeonStatDungeonSpecificData == null) {
+ fr.drawString(dungeonType.getFamiliarName(), 0,0, 0xFFFF5555);
+ fr.drawString("Unknown", fr.getStringWidth(dungeonType.getFamiliarName()+" "),0,0xFFFFFFFF);
+ } else {
+ XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(dungeonStatDungeonSpecificData.getData().getExperience());
+ fr.drawString(dungeonType.getFamiliarName(), 0,0, 0xFFFF5555);
+ fr.drawString(xpCalcResult.getLevel()+"", fr.getStringWidth(dungeonType.getFamiliarName()+" "),0,0xFFFFFFFF);
+
+ RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,xpCalcResult.getRemainingXp() == 0 ? 1 : (float) (xpCalcResult.getRemainingXp() / xpCalcResult.getNextLvXp()));
+ }
+
+ return new Dimension(100, fr.FONT_HEIGHT*2);
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString(dungeonType.getFamiliarName(), 0,0, 0xFFFF5555);
+ fr.drawString("99", fr.getStringWidth(dungeonType.getFamiliarName()+" "),0,0xFFFFFFFF);
+ RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,1.0f);
+ return new Dimension(100, fr.FONT_HEIGHT*2);
+ }
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*2);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+ DungeonSpecificData dungeonStatDungeonSpecificData = playerProfile.getDungeonStats().get(dungeonType);
+ if (dungeonStatDungeonSpecificData == null) return;
+ XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(dungeonStatDungeonSpecificData.getData().getExperience());
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ GuiUtils.drawHoveringText(Arrays.asList("§bCurrent Lv§7: §e"+xpCalcResult.getLevel(),"§bExp§7: §e"+TextUtils.format((long)xpCalcResult.getRemainingXp()) + "§7/§e"+TextUtils.format((long)xpCalcResult.getNextLvXp()), "§bTotal Xp§7: §e"+ TextUtils.format((long)dungeonStatDungeonSpecificData.getData().getExperience())),mouseX, mouseY,
+ scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererFairySouls.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererFairySouls.java
new file mode 100644
index 00000000..5b8f4d8e
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererFairySouls.java
@@ -0,0 +1,50 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.IDataRenderer;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+
+import java.awt.*;
+
+public class DataRendererFairySouls implements IDataRenderer {
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("§eFairy Souls §f"+playerProfile.getFairySouls(), 0,0,-1);
+ return new Dimension(100, fr.FONT_HEIGHT);
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("§eFairy Souls §f300", 0,0,-1);
+ return new Dimension(100, fr.FONT_HEIGHT);
+ }
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererLilyWeight.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererLilyWeight.java
new file mode 100644
index 00000000..ef57f955
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererLilyWeight.java
@@ -0,0 +1,71 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.IDataRenderer;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraftforge.fml.client.config.GuiUtils;
+
+import java.awt.*;
+import java.util.Arrays;
+
+public class DataRendererLilyWeight implements IDataRenderer {
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ if (playerProfile.getLilyWeight() == null)
+ fr.drawString("§eLily Weight §cAPI DISABLED", 0,0,-1);
+ else
+ fr.drawString("§eLily Weight §b"+String.format("%.3f", playerProfile.getLilyWeight().getTotal()), 0,0,-1);
+ return new Dimension(100, fr.FONT_HEIGHT);
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("§eLily Weight §b300", 0,0,-1);
+ return new Dimension(100, fr.FONT_HEIGHT);
+ }
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+ PlayerProfile.LilyWeight lilyWeight= playerProfile.getLilyWeight();
+ if (lilyWeight == null) return;
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ GuiUtils.drawHoveringText(Arrays.asList(
+ "§bDungeon Weights§7: §e"+ String.format("%.3f",lilyWeight.getCatacombs_base()+lilyWeight.getCatacombs_master()+lilyWeight.getCatacombs_exp()),
+ " §bCatacomb Completion§7: §e"+String.format("%.3f",lilyWeight.getCatacombs_base()),
+ " §bMaster Completion§7: §e"+String.format("%.3f", lilyWeight.getCatacombs_master()),
+ " §bExperience§7: §e"+String.format("%.3f", lilyWeight.getCatacombs_exp()),
+ "§bSkill Weights§7: §e"+ String.format("%.3f", lilyWeight.getSkill_base() + lilyWeight.getSkill_overflow()),
+ " §bSkill Weight§7: §e"+String.format("%.3f", lilyWeight.getSkill_base()),
+ " §bOverflow Weight§7: §e"+String.format("%.3f", lilyWeight.getSkill_overflow()),
+ "§bSlayer Weight§7: §e"+String.format("%.3f", lilyWeight.getSlayer()),
+ "§bTotal§7: §e"+String.format("%.3f", lilyWeight.getTotal())
+ ),mouseX, mouseY,
+ scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSecrets.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSecrets.java
new file mode 100644
index 00000000..bacbc598
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSecrets.java
@@ -0,0 +1,53 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.IDataRenderer;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+
+import java.awt.*;
+
+public class DataRendererSecrets implements IDataRenderer {
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ double theint = playerProfile.getTotalSecrets()/ (double)playerProfile.getDungeonStats().values().stream().flatMap(s -> s.getData().getPlays().values().stream())
+ .map(fs -> fs.getData().getWatcherKills()).reduce(0, Integer::sum);
+ fr.drawString("§eSecrets §b"+playerProfile.getTotalSecrets()+" §7("+
+ String.format("%.2f", theint)+"/run)", 0,0,-1);
+ return new Dimension(100, fr.FONT_HEIGHT);
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("§eSecrets §b99999 §7(X/run)", 0,0,-1);
+ return new Dimension(100, fr.FONT_HEIGHT);
+ }
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSelectedClassLv.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSelectedClassLv.java
new file mode 100644
index 00000000..d8d3a292
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSelectedClassLv.java
@@ -0,0 +1,77 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.ClassSpecificData;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.IDataRenderer;
+import kr.syeyoung.dungeonsguide.utils.RenderUtils;
+import kr.syeyoung.dungeonsguide.utils.TextUtils;
+import kr.syeyoung.dungeonsguide.utils.XPUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraftforge.fml.client.config.GuiUtils;
+
+import java.awt.*;
+import java.util.Arrays;
+
+public class DataRendererSelectedClassLv implements IDataRenderer {
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ ClassSpecificData dungeonStatDungeonSpecificData = playerProfile.getPlayerClassData().get(playerProfile.getSelectedClass());
+ if (dungeonStatDungeonSpecificData == null) {
+ fr.drawString("Unknown Selected", 0,0, 0xFF55ffff);
+ } else {
+ XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(dungeonStatDungeonSpecificData.getData().getExperience());
+ fr.drawString(playerProfile.getSelectedClass().getFamilarName(), 0,0, 0xFF55ffff);
+ fr.drawString(xpCalcResult.getLevel()+"", fr.getStringWidth(playerProfile.getSelectedClass().getFamilarName()+" "),0,0xFFFFFFFF);
+ fr.drawString("★", fr.getStringWidth(playerProfile.getSelectedClass().getFamilarName()+" "+xpCalcResult.getLevel()+" "),0,0xFFAAAAAA);
+
+ RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,xpCalcResult.getRemainingXp() == 0 ? 1 : (float) (xpCalcResult.getRemainingXp() / xpCalcResult.getNextLvXp()));
+ }
+
+ return new Dimension(100, fr.FONT_HEIGHT*2);
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("SelectedClass", 0,0, 0xFF55ffff);
+ fr.drawString("99", fr.getStringWidth("SelectedClass "),0,0xFFFFFFFF);
+ fr.drawString("★", fr.getStringWidth("SelectedClass 99 "),0,0xFFAAAAAA);
+ RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,1.0f);
+ return new Dimension(100, fr.FONT_HEIGHT*2);
+ }
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*2);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+ ClassSpecificData dungeonStatDungeonSpecificData = playerProfile.getPlayerClassData().get(playerProfile.getSelectedClass());
+ if (dungeonStatDungeonSpecificData == null) return;
+ XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(dungeonStatDungeonSpecificData.getData().getExperience());
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ GuiUtils.drawHoveringText(Arrays.asList("§bCurrent Lv§7: §e"+xpCalcResult.getLevel(),"§bExp§7: §e"+ TextUtils.format((long)xpCalcResult.getRemainingXp()) + "§7/§e"+TextUtils.format((long)xpCalcResult.getNextLvXp()), "§bTotal Xp§7: §e"+ TextUtils.format((long)dungeonStatDungeonSpecificData.getData().getExperience())),mouseX, mouseY,
+ scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSetUrOwn.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSetUrOwn.java
new file mode 100644
index 00000000..3d5e94cc
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSetUrOwn.java
@@ -0,0 +1,57 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.IDataRenderer;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+
+import java.awt.*;
+
+public class DataRendererSetUrOwn implements IDataRenderer {
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("§aCustomize at /dg", 0,0,-1);
+ fr.drawString("§a-> Party Kicker", 0,fr.FONT_HEIGHT,-1);
+ fr.drawString("§a-> View Player Stats", 0,fr.FONT_HEIGHT*2,-1);
+ fr.drawString("§a-> Edit", 0,fr.FONT_HEIGHT*3,-1);
+ return new Dimension(100, fr.FONT_HEIGHT*4);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("§aCustomize at /dg", 0,0,-1);
+ fr.drawString("§a-> Party Kicker", 0,fr.FONT_HEIGHT,-1);
+ fr.drawString("§a-> View Player Stats", 0,fr.FONT_HEIGHT*2,-1);
+ fr.drawString("§a-> Edit", 0,fr.FONT_HEIGHT*3,-1);
+ return new Dimension(100, fr.FONT_HEIGHT*4);
+ }
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*4);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSkillLv.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSkillLv.java
new file mode 100644
index 00000000..ea83a74e
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSkillLv.java
@@ -0,0 +1,80 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.Skill;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.IDataRenderer;
+import kr.syeyoung.dungeonsguide.utils.RenderUtils;
+import kr.syeyoung.dungeonsguide.utils.TextUtils;
+import kr.syeyoung.dungeonsguide.utils.XPUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraftforge.fml.client.config.GuiUtils;
+
+import java.awt.*;
+import java.util.Arrays;
+
+public class DataRendererSkillLv implements IDataRenderer {
+ private final Skill skill;
+ public DataRendererSkillLv(Skill skill) {
+ this.skill = skill;
+ }
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ Double xp = playerProfile.getSkillXp().get(skill);
+ if (xp == null) {
+ fr.drawString(skill.getFriendlyName(), 0,0, 0xFF55ffff);
+ fr.drawString("§cSkill API Disabled", 0, fr.FONT_HEIGHT,0xFFFFFFFF);
+ } else {
+ XPUtils.XPCalcResult xpCalcResult = XPUtils.getSkillXp(skill, xp);
+ fr.drawString(skill.getFriendlyName(), 0,0, 0xFF55ffff);
+ fr.drawString(xpCalcResult.getLevel()+"", fr.getStringWidth(skill.getFriendlyName()+" "),0,0xFFFFFFFF);
+
+ RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,xpCalcResult.getRemainingXp() == 0 ? 1 : (float) (xpCalcResult.getRemainingXp() / xpCalcResult.getNextLvXp()));
+ }
+
+ return new Dimension(100, fr.FONT_HEIGHT*2);
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString(skill.getFriendlyName(), 0,0, 0xFF55ffff);
+ fr.drawString("99", fr.getStringWidth(skill.getFriendlyName()+" "),0,0xFFFFFFFF);
+ RenderUtils.renderBar(0, fr.FONT_HEIGHT, 100,1.0f);
+ return new Dimension(100, fr.FONT_HEIGHT*2);
+ }
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT*2);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+ Double xp = playerProfile.getSkillXp().get(skill);
+ if (xp == null) return;
+ XPUtils.XPCalcResult xpCalcResult = XPUtils.getSkillXp(skill, xp);
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ GuiUtils.drawHoveringText(Arrays.asList("§bCurrent Lv§7: §e"+xpCalcResult.getLevel(),"§bExp§7: §e"+ TextUtils.format((long)xpCalcResult.getRemainingXp()) + "§7/§e"+TextUtils.format((long)xpCalcResult.getNextLvXp()), "§bTotal Xp§7: §e"+ TextUtils.format(xp.longValue())),mouseX, mouseY,
+ scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererTalismans.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererTalismans.java
new file mode 100644
index 00000000..9630e2be
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererTalismans.java
@@ -0,0 +1,123 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.IDataRenderer;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraftforge.fml.client.config.GuiUtils;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DataRendererTalismans implements IDataRenderer {
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ boolean apiDisabled = playerProfile.getTalismans() == null || playerProfile.getInventory() == null;
+ if (!playerProfile.getAdditionalProperties().containsKey("talismanCnt") && !apiDisabled) {
+ int[] cnts = new int[Rarity.values().length];
+ for (ItemStack talisman : playerProfile.getTalismans()) {
+ if (talisman == null) continue;
+ Rarity r = getRarity(talisman);
+ if (r != null) cnts[r.ordinal()]++;
+ }
+ for (ItemStack itemStack : playerProfile.getInventory()) {
+ if (itemStack == null) continue;
+ Rarity r = getRarity(itemStack);
+ if (r != null) cnts[r.ordinal()]++;
+ }
+ playerProfile.getAdditionalProperties().put("talismanCnt", cnts);
+ }
+ int[] rawData = (int[]) playerProfile.getAdditionalProperties().get("talismanCnt");
+
+ String str = "";
+ if (rawData != null)
+ for (Rarity r : Rarity.values()) {
+ str = r.color+rawData[r.idx] +" "+ str;
+ }
+
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ if (apiDisabled)
+ fr.drawString("§eTalis §cAPI DISABLED", 0,0,-1);
+ else
+ fr.drawString("§eTalis §f"+str, 0,0,-1);
+ return new Dimension(100, fr.FONT_HEIGHT);
+ }
+
+ private Rarity getRarity(ItemStack itemStack) {
+ NBTTagCompound display = itemStack.getTagCompound().getCompoundTag("display");
+ if (display == null) return null;
+ NBTTagList lore = display.getTagList("Lore", 8);
+ if (lore == null) return null;
+ for (int i = 0; i < lore.tagCount(); i++) {
+ String line = lore.getStringTagAt(i);
+ for (Rarity value : Rarity.values()) {
+ if (line.startsWith(value.getColor()) && line.contains("CCESSORY")) return value;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ String str = "";
+ for (Rarity r : Rarity.values()) {
+ str = r.color+(r.idx+5)*2+" "+str;
+ }
+
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("§eTalis §f"+str, 0,0,-1);
+ return new Dimension(100, fr.FONT_HEIGHT);
+ }
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+ int[] rawData = (int[]) playerProfile.getAdditionalProperties().get("talismanCnt");
+ if (rawData == null) return;
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ List list = new ArrayList<>();
+
+ for (Rarity r : Rarity.values()) {
+ list.add(r.getColor()+r.name()+"§7: §e"+rawData[r.idx]);
+ }
+ GuiUtils.drawHoveringText(list,mouseX, mouseY,
+ scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
+ }
+
+
+ @AllArgsConstructor @Getter
+ public static enum Rarity {
+ COMMON("§f", 0), UNCOMMON("§a",1), RARE("§9",2), EPIC("§5",3), LEGENDARY("§6",4), MYTHIC("§d",5);
+
+ private String color;
+ private int idx;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/utils/XPUtils.java b/src/main/java/kr/syeyoung/dungeonsguide/utils/XPUtils.java
index 2738dcec..ebdd87ab 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/utils/XPUtils.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/utils/XPUtils.java
@@ -18,7 +18,7 @@
package kr.syeyoung.dungeonsguide.utils;
-import kr.syeyoung.dungeonsguide.features.impl.party.api.Skill;
+import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses.Skill;
import lombok.Data;
import java.util.Map;
--
cgit