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