diff options
author | kokoniara <70776766+kingstefan26@users.noreply.github.com> | 2022-10-07 14:50:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-07 21:50:22 +0900 |
commit | dd7a4209752715db544b2fef804da9762c532cdc (patch) | |
tree | 496c7bf318c8b047285aba0c5c695b2242e3a336 /src/main/java | |
parent | 95af42d0a671517bad21df43ba82e61cd64e5fba (diff) | |
download | Skyblock-Dungeons-Guide-dd7a4209752715db544b2fef804da9762c532cdc.tar.gz Skyblock-Dungeons-Guide-dd7a4209752715db544b2fef804da9762c532cdc.tar.bz2 Skyblock-Dungeons-Guide-dd7a4209752715db544b2fef804da9762c532cdc.zip |
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>
Diffstat (limited to 'src/main/java')
37 files changed, 1393 insertions, 1064 deletions
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/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/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 <https://www.gnu.org/licenses/>. - */ - -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<List<String>>("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<Optional<PlayerProfile>> profileFuture; - private Future<Optional<GameProfile>> gfFuture; - private Future<SkinFetchur.SkinSet> 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> 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.<List<String>>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<ActiveCosmetic> 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<String> 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<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); - - Minecraft.getMinecraft().getRenderItem().renderItemAndEffectIntoGUI(playerProfile.get().getInventory()[(i+9) % 36], (i%9) * 18+1,(i/9) * 18+1); - } - - if (toHover != null) { - List<String> 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<MPanel>() { - @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 <https://www.gnu.org/licenses/>. + */ + +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<List<String>>("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<Optional<PlayerSkyblockData>> profileFuture; + private Future<Optional<GameProfile>> gameProfileFuture; + private Future<SkinFetcher.SkinSet> 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> 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> 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.<List<String>>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> 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<ActiveCosmetic> 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<String> 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 <https://www.gnu.org/licenses/>. + */ + +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<String, CachedData<PlayerSkyblockData>> playerProfileCache = new ConcurrentHashMap<>(); + private static final Map<String, CachedData<String>> nicknameToUID = new ConcurrentHashMap<>(); + private static final Map<String, CachedData<String>> UIDtoNickname = new ConcurrentHashMap<>(); + private static final Map<String, CachedData<GameProfile>> UIDtoGameProfile = new ConcurrentHashMap<>(); + + private static final ExecutorService ex = Executors.newFixedThreadPool(4); + + private static final Set<String> 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<String, CompletableFuture<Optional<GameProfile>>> completableFutureMap4 = new ConcurrentHashMap<>(); + + public static CompletableFuture<Optional<GameProfile>> getSkinGameProfileByUUIDAsync(String uid) { + if (UIDtoGameProfile.containsKey(uid)) { + CachedData<GameProfile> 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<Optional<GameProfile>> completableFuture = new CompletableFuture<>(); + fetchNicknameAsync(uid).thenAccept(nick -> { + if (!nick.isPresent()) { + completableFuture.complete(Optional.empty()); + return; + } + ex.submit(() -> { + try { + Optional<GameProfile> playerProfile = getSkinGameProfileByUUID(uid, nick.get()); + UIDtoGameProfile.put(uid, new CachedData<GameProfile>(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<GameProfile> 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<String, CompletableFuture<Optional<PlayerSkyblockData>>> completableFutureMap = new ConcurrentHashMap<>(); + + public static CompletableFuture<Optional<PlayerSkyblockData>> fetchMostRecentProfileAsync(String uid, String apiKey) { + if (playerProfileCache.containsKey(uid)) { + CachedData<PlayerSkyblockData> 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<Optional<PlayerSkyblockData>> completableFuture = new CompletableFuture<>(); + ex.submit(() -> { + try { + Optional<PlayerSkyblockData> 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<String, CompletableFuture<Optional<String>>> completableFutureMap3 = new ConcurrentHashMap<>(); + + public static CompletableFuture<Optional<String>> fetchNicknameAsync(String uid) { + if (UIDtoNickname.containsKey(uid)) { + CachedData<String> 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<Optional<String>> completableFuture = new CompletableFuture<>(); + + ex.submit(() -> { + try { + Optional<String> playerProfile = fetchNickname(uid); + UIDtoNickname.put(uid, new CachedData<String>(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<String, CompletableFuture<Optional<String>>> completableFutureMap2 = new ConcurrentHashMap<>(); + + public static CompletableFuture<Optional<String>> fetchUUIDAsync(String nickname) { + if (nicknameToUID.containsKey(nickname)) { + CachedData<String> 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<Optional<String>> completableFuture = new CompletableFuture<>(); + + ex.submit(() -> { + try { + Optional<String> playerProfile = fetchUUID(nickname); + nicknameToUID.put(nickname, new CachedData<String>(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<String> 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<String> 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<Integer> 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<arr.length;i++){ + if(arr[i]==value){ + k=i; + break; + } + } + return k; + } + + public static Optional<PlayerSkyblockData> 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<PlayerProfile> 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<PlayerProfile> 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/api/CachedData.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/CachedData.java index 39b04088..e3a98eaa 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/CachedData.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/CachedData.java @@ -16,7 +16,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.api; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api; import lombok.AllArgsConstructor; import lombok.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/api/SkinFetchur.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/SkinFetcher.java index e2c08d58..5d9afa4a 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/SkinFetchur.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/SkinFetcher.java @@ -16,7 +16,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.api; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api; import com.mojang.authlib.GameProfile; import com.mojang.authlib.minecraft.MinecraftProfileTexture; @@ -30,11 +30,12 @@ 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 { +public class SkinFetcher { + + private SkinFetcher(){} private static final Map<String, CachedData<SkinSet>> skinSetMap = new ConcurrentHashMap<>(); 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/playerpreview/api/playerprofile/PlayerProfile.java index a9c1a272..95cd000f 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/PlayerProfile.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/PlayerProfile.java @@ -16,8 +16,9 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.api; +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; 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/playerpreview/api/playerprofile/PlayerProfileParser.java index 0d929697..b19e1e36 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ApiFetchur.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/PlayerProfileParser.java @@ -1,334 +1,67 @@ -/* - * 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 <https://www.gnu.org/licenses/>. - */ - -package kr.syeyoung.dungeonsguide.features.impl.party.api; - -import com.google.gson.*; -import com.mojang.authlib.GameProfile; -import kr.syeyoung.dungeonsguide.utils.TextUtils; +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.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.Base64; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; 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(); +public class PlayerProfileParser { - private static final Map<String, CachedData<PlayerProfile>> playerProfileCache = new ConcurrentHashMap<>(); - private static final Map<String, CachedData<String>> nicknameToUID = new ConcurrentHashMap<>(); - private static final Map<String, CachedData<String>> UIDtoNickname = new ConcurrentHashMap<>(); - private static final Map<String, CachedData<GameProfile>> UIDtoGameProfile = new ConcurrentHashMap<>(); + public static volatile JsonObject constants; - private static final ExecutorService ex = Executors.newFixedThreadPool(4); - - private static final Set<String> 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<String, CompletableFuture<Optional<GameProfile>>> completableFutureMap4 = new ConcurrentHashMap<>(); - public static CompletableFuture<Optional<GameProfile>> getSkinGameProfileByUUIDAsync(String uid) { - if (UIDtoGameProfile.containsKey(uid)) { - CachedData<GameProfile> 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<Optional<GameProfile>> completableFuture = new CompletableFuture<>(); - fetchNicknameAsync(uid).thenAccept(nick -> { - if (!nick.isPresent()) { - completableFuture.complete(Optional.empty()); - return; - } - ex.submit(() -> { - try { - Optional<GameProfile> playerProfile = getSkinGameProfileByUUID(uid,nick.get()); - UIDtoGameProfile.put(uid, new CachedData<GameProfile>(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<GameProfile> 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<String, CompletableFuture<Optional<PlayerProfile>>> completableFutureMap = new ConcurrentHashMap<>(); - public static CompletableFuture<Optional<PlayerProfile>> fetchMostRecentProfileAsync(String uid, String apiKey) { - if (playerProfileCache.containsKey(uid)) { - CachedData<PlayerProfile> 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<Optional<PlayerProfile>> completableFuture = new CompletableFuture<>(); - ex.submit(() -> { - try { - Optional<PlayerProfile> playerProfile = fetchMostRecentProfile(uid, apiKey); - playerProfileCache.put(uid, new CachedData<PlayerProfile>(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<String, CompletableFuture<Optional<String>>> completableFutureMap3 = new ConcurrentHashMap<>(); - public static CompletableFuture<Optional<String>> fetchNicknameAsync(String uid) { - if (UIDtoNickname.containsKey(uid)) { - CachedData<String> 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<Optional<String>> completableFuture = new CompletableFuture<>(); - - ex.submit(() -> { - try { - Optional<String> playerProfile = fetchNickname(uid); - UIDtoNickname.put(uid, new CachedData<String>(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<String, CompletableFuture<Optional<String>>> completableFutureMap2 = new ConcurrentHashMap<>(); - public static CompletableFuture<Optional<String>> fetchUUIDAsync(String nickname) { - if (nicknameToUID.containsKey(nickname)) { - CachedData<String> 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<Optional<String>> completableFuture = new CompletableFuture<>(); - - ex.submit(() -> { - try { - Optional<String> playerProfile = fetchUUID(nickname); - nicknameToUID.put(nickname, new CachedData<String>(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<String> 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<String> 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<PlayerProfile> 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<PlayerProfile> 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<PlayerProfile> 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()); - } - } + JsonObject jsonObject = ApiFetcher.getJson("https://raw.githubusercontent.com/Antonio32A/lilyweight/master/lib/constants.json"); + constants = jsonObject; + } catch (Exception e) { + throw new RuntimeException(e); } - - return Optional.of(pp); + 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))); } @@ -349,7 +82,7 @@ public class ApiFetchur { 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)); + playerProfile.setFairyExchanges(getOrDefault(playerData, "fairy_exchanges", 0)); if (playerData.has("inv_armor")) { playerProfile.setCurrentArmor(new PlayerProfile.Armor()); @@ -369,7 +102,7 @@ public class ApiFetchur { 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.getWardrobe().get(i / 4).getArmorSlots()[i % 4] = deserializeNBT(item); } } @@ -405,7 +138,7 @@ public class ApiFetchur { playerProfile.setSkillXp(new HashMap<>()); for (Skill value : Skill.values()) { - playerProfile.getSkillXp().put(value, getOrDefaultNullable(playerData, "experience_skill_"+value.getJsonName(), null)); + playerProfile.getSkillXp().put(value, getOrDefaultNullable(playerData, "experience_skill_" + value.getJsonName(), null)); } if (playerData.has("pets")) { @@ -439,20 +172,20 @@ public class ApiFetchur { 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)); + 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)); + classStatistics.setMostDamage(getOrDefault(dungeonObj.getAsJsonObject("most_damage_" + dungeonClass.getJsonName()), "" + validFloor, 0)); ClassSpecificData<DungeonStat.PlayedFloor.ClassStatistics> classStatisticsClassSpecificData = new ClassSpecificData<>(dungeonClass, classStatistics); playedFloor.getClassStatistics().put(dungeonClass, classStatisticsClassSpecificData); @@ -511,9 +244,9 @@ public class ApiFetchur { 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)); + .map(a -> XPUtils.getSkillXp(a.getKey(), a.getValue()).getLevel()).collect(Collectors.averagingInt(a -> a)); - double n = 12 * (skillAvg/60)*(skillAvg/60); + double n = 12 * (skillAvg / 60) * (skillAvg / 60); double r2 = Math.sqrt(2); for (Map.Entry<Skill, Double> skillDoubleEntry : playerProfile.getSkillXp().entrySet()) { @@ -522,8 +255,8 @@ public class ApiFetchur { 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); + * 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; @@ -532,13 +265,14 @@ public class ApiFetchur { double factor = skillFactor.get(cnt).getAsDouble(); double effectiveOver; Double xp = playerProfile.getSkillXp().get(s); - if (xp == null) continue; xp -= skillMaxXP; + 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++) { + for (int i = 0; i <= xp / skillMaxXP; i++) { if (remainingXP >= skillMaxXP) { remainingXP -= skillMaxXP; z += Math.pow(factor, i); @@ -568,13 +302,16 @@ public class ApiFetchur { max1000 *= 1000; mMax1000 *= 1000; - double upperBound = 1500; double score = 0; + double upperBound = 1500; + double score = 0; DungeonStat dStat = playerProfile.getDungeonStats().get(DungeonType.CATACOMBS).getData(); for (FloorSpecificData<DungeonStat.PlayedFloor> value : dStat.getPlays().values()) { int runs = value.getData().getCompletions(); - int excess = 0; if (runs > 1000) { - excess = runs - 1000; runs = 1000; + int excess = 0; + if (runs > 1000) { + excess = runs - 1000; + runs = 1000; } double floorScore = runs * completionFactor.get(value.getFloor()).getAsDouble(); @@ -586,20 +323,24 @@ public class ApiFetchur { dStat = playerProfile.getDungeonStats().get(DungeonType.MASTER_CATACOMBS).getData(); for (FloorSpecificData<DungeonStat.PlayedFloor> value : dStat.getPlays().values()) { - if (dungeonCompletionBuffs.has(value.getFloor()+"")) { + 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); + 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<DungeonStat.PlayedFloor> value : dStat.getPlays().values()) { int runs = value.getData().getCompletions(); - int excess = 0; if (runs > 1000) { - excess = runs - 1000; runs = 1000; + int excess = 0; + if (runs > 1000) { + excess = runs - 1000; + runs = 1000; } - double floorScore = runs * completionFactor.get(value.getFloor()+7).getAsDouble(); + 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; @@ -620,7 +361,8 @@ public class ApiFetchur { level += progress; } - double n; double tempLevel = 0; + double n; + double tempLevel = 0; if (cataXP < dungeonMaxXP) n = 0.2 * Math.pow(level / 50.0, 2.967355422); else { @@ -629,8 +371,9 @@ public class ApiFetchur { 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); + 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; @@ -655,7 +398,7 @@ public class ApiFetchur { 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 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; @@ -682,16 +425,25 @@ public class ApiFetchur { } 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; + 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/ClassSpecificData.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/ClassSpecificData.java index f977b46a..3496f3a9 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ClassSpecificData.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/ClassSpecificData.java @@ -16,7 +16,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.api; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses; import lombok.AllArgsConstructor; import lombok.Getter; 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/playerpreview/api/playerprofile/dataclasses/DungeonClass.java index bc0d15f2..fc569b57 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonClass.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonClass.java @@ -16,7 +16,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.api; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses; import lombok.AllArgsConstructor; import lombok.Getter; 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/playerpreview/api/playerprofile/dataclasses/DungeonSpecificData.java index a70b8ba0..05975767 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonSpecificData.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonSpecificData.java @@ -16,7 +16,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.api; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses; import lombok.AllArgsConstructor; import lombok.Getter; 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/playerpreview/api/playerprofile/dataclasses/DungeonStat.java index fb3be9ac..be42a509 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonStat.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonStat.java @@ -16,7 +16,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.api; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses; import lombok.Data; 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/playerpreview/api/playerprofile/dataclasses/DungeonType.java index 00ca208b..a394214d 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/DungeonType.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/DungeonType.java @@ -16,7 +16,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.api; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses; import com.google.common.collect.Sets; import lombok.AllArgsConstructor; 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/playerpreview/api/playerprofile/dataclasses/FloorSpecificData.java index 3f3c4f35..e31d5034 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/FloorSpecificData.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/FloorSpecificData.java @@ -16,7 +16,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.api; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses; import lombok.AllArgsConstructor; import lombok.Getter; 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/playerpreview/api/playerprofile/dataclasses/Pet.java index eb1427eb..40f15e49 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/Pet.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/Pet.java @@ -16,7 +16,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.api; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses; import lombok.Data; 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/playerpreview/api/playerprofile/dataclasses/Skill.java index 47900ef3..4ccc1e2d 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/Skill.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/api/playerprofile/dataclasses/Skill.java @@ -16,10 +16,9 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.api; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.dataclasses; import lombok.AllArgsConstructor; -import lombok.Data; import lombok.Getter; @Getter 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/datarenders/DataRendererEditor.java index c559775a..02ab6ea1 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererEditor.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/DataRendererEditor.java @@ -16,8 +16,9 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +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; @@ -34,10 +35,10 @@ import java.util.List; import java.util.Set; public class DataRendererEditor extends MPanel { - private final FeatureViewPlayerOnJoin feature; + private final FeatureViewPlayerStatsOnJoin feature; - public DataRendererEditor(FeatureViewPlayerOnJoin featureViewPlayerOnJoin) { - this.feature = featureViewPlayerOnJoin; + public DataRendererEditor(FeatureViewPlayerStatsOnJoin featureViewPlayerStatsOnJoin) { + this.feature = featureViewPlayerStatsOnJoin; } @Override @@ -84,7 +85,7 @@ public class DataRendererEditor extends MPanel { for (String datarenderers : feature.<List<String>>getParameter("datarenderers").getValue()) { if (0 <= selectedX && selectedX <= hamburgerWidth+11 && currentlySelected != null) { - DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(currentlySelected); + IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(currentlySelected); Dimension dim; if (dataRenderer == null) dim = new Dimension(0,fr.FONT_HEIGHT*2); else dim = dataRenderer.getDimension(); @@ -115,7 +116,7 @@ public class DataRendererEditor extends MPanel { } } - DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers); + IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers); clip(scissor.x + 6 + hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230); Dimension dim; @@ -144,7 +145,7 @@ public class DataRendererEditor extends MPanel { } if (currentlySelected != null && new Rectangle(0,5+fr.FONT_HEIGHT + 3, hamburgerWidth+11, 232).contains(selectedX, selectedY) && !drewit) { - DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(currentlySelected); + IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(currentlySelected); Dimension dim; clip(scissor.x + 6 + hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230); GlStateManager.enableBlend(); @@ -178,7 +179,7 @@ public class DataRendererEditor extends MPanel { rest.removeAll( feature.<List<String>>getParameter("datarenderers").getValue()); rest.remove(currentlySelected); for (String datarenderers : rest) { - DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers); + IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers); clip(scissor.x + 156 + hamburgerWidth, scissor.y + 5+fr.FONT_HEIGHT+3, baseWidth, 230); Dimension dim; GlStateManager.enableBlend(); @@ -208,7 +209,7 @@ public class DataRendererEditor extends MPanel { if (currentlySelected != null) { GlStateManager.pushMatrix(); GlStateManager.translate(selectedX+hamburgerWidth+1, selectedY, 0); - DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(currentlySelected); + 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); @@ -247,7 +248,7 @@ public class DataRendererEditor extends MPanel { rest.remove(currentlySelected); int culmutativeY = -scrollY; for (String datarenderers : rest) { - DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers); + IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers); Dimension dim; if (dataRenderer == null) { dim = new Dimension(0, fr.FONT_HEIGHT * 2); @@ -270,7 +271,7 @@ public class DataRendererEditor extends MPanel { List<String> rest = feature.<List<String>>getParameter("datarenderers").getValue(); int culmutativeY = 0; for (String datarenderers : rest) { - DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers); + IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers); Dimension dim; if (dataRenderer == null) { dim = new Dimension(0, fr.FONT_HEIGHT * 2); @@ -317,7 +318,7 @@ public class DataRendererEditor extends MPanel { int index = asdasdkasd.size(); for (int i = 0; i <asdasdkasd.size(); i++) { String datarenderers = asdasdkasd.get(i); - DataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers); + IDataRenderer dataRenderer = DataRendererRegistry.getDataRenderer(datarenderers); Dimension dim; if (dataRenderer == null) { dim = new Dimension(0, fr.FONT_HEIGHT * 2); 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/datarenders/DataRendererRegistry.java index 56e69feb..b2187511 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererRegistry.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/DataRendererRegistry.java @@ -16,20 +16,21 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders; -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 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<String, DataRenderer> dataRendererMap = new HashMap<>(); + private static final Map<String, IDataRenderer> dataRendererMap = new HashMap<>(); - public static DataRenderer getDataRenderer(String id) { + public static IDataRenderer getDataRenderer(String id) { return dataRendererMap.get(id); } 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/datarenders/IDataRenderer.java index df72647e..3f2d0ad2 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderer.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/IDataRenderer.java @@ -16,13 +16,13 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders; -import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile; +import kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.api.playerprofile.PlayerProfile; import java.awt.*; -public interface DataRenderer { +public interface IDataRenderer { Dimension renderData(PlayerProfile playerProfile); void onHover(PlayerProfile playerProfile, int mouseX, int mouseY); 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/datarenders/impl/DataRenderDungeonFloorStat.java index 627b1881..f2cf4a38 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonFloorStat.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRenderDungeonFloorStat.java @@ -16,9 +16,14 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl; -import kr.syeyoung.dungeonsguide.features.impl.party.api.*; +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; @@ -28,7 +33,7 @@ import net.minecraftforge.fml.client.config.GuiUtils; import java.awt.*; import java.util.Arrays; -public class DataRenderDungeonFloorStat implements DataRenderer { +public class DataRenderDungeonFloorStat implements IDataRenderer { private final DungeonType dungeonType; private final int floor; public DataRenderDungeonFloorStat(DungeonType dungeonType, int floor) { 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/datarenders/impl/DataRenderDungeonHighestFloorStat.java index d19fa2f1..8daba7eb 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonHighestFloorStat.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRenderDungeonHighestFloorStat.java @@ -16,9 +16,14 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl; -import kr.syeyoung.dungeonsguide.features.impl.party.api.*; +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; @@ -28,7 +33,7 @@ import net.minecraftforge.fml.client.config.GuiUtils; import java.awt.*; import java.util.Arrays; -public class DataRenderDungeonHighestFloorStat implements DataRenderer { +public class DataRenderDungeonHighestFloorStat implements IDataRenderer { private final DungeonType dungeonType; public DataRenderDungeonHighestFloorStat(DungeonType dungeonType) { this.dungeonType = dungeonType; 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/datarenders/impl/DataRendererClassLv.java index 3f47f373..8a798eee 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererClassLv.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererClassLv.java @@ -16,9 +16,12 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl; -import kr.syeyoung.dungeonsguide.features.impl.party.api.*; +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; @@ -30,7 +33,7 @@ import net.minecraftforge.fml.client.config.GuiUtils; import java.awt.*; import java.util.Arrays; -public class DataRendererClassLv implements DataRenderer { +public class DataRendererClassLv implements IDataRenderer { private final DungeonClass dungeonClass; public DataRendererClassLv(DungeonClass dungeonClass) { this.dungeonClass = dungeonClass; 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/datarenders/impl/DataRendererDungeonLv.java index 80a918ef..5cc37fa6 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererDungeonLv.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererDungeonLv.java @@ -16,12 +16,13 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl; -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.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; @@ -33,7 +34,7 @@ import net.minecraftforge.fml.client.config.GuiUtils; import java.awt.*; import java.util.Arrays; -public class DataRendererDungeonLv implements DataRenderer { +public class DataRendererDungeonLv implements IDataRenderer { private final DungeonType dungeonType; public DataRendererDungeonLv(DungeonType dungeonType) { this.dungeonType = dungeonType; 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/datarenders/impl/DataRendererFairySouls.java index e2895967..5b8f4d8e 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererFairySouls.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererFairySouls.java @@ -16,15 +16,16 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl; -import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile; +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 DataRenderer { +public class DataRendererFairySouls implements IDataRenderer { @Override public Dimension renderData(PlayerProfile playerProfile) { FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; 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/datarenders/impl/DataRendererLilyWeight.java index fa9ecf65..ef57f955 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererLilyWeight.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererLilyWeight.java @@ -16,20 +16,19 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl; -import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile; -import kr.syeyoung.dungeonsguide.utils.TextUtils; +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.minecraft.item.ItemStack; import net.minecraftforge.fml.client.config.GuiUtils; import java.awt.*; import java.util.Arrays; -public class DataRendererLilyWeight implements DataRenderer { +public class DataRendererLilyWeight implements IDataRenderer { @Override public Dimension renderData(PlayerProfile playerProfile) { FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; 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/datarenders/impl/DataRendererSecrets.java index 81f08c95..bacbc598 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSecrets.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSecrets.java @@ -16,16 +16,16 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl; -import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile; +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.*; -import java.util.stream.Collectors; -public class DataRendererSecrets implements DataRenderer { +public class DataRendererSecrets implements IDataRenderer { @Override public Dimension renderData(PlayerProfile playerProfile) { FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; 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/datarenders/impl/DataRendererSelectedClassLv.java index 94bc3542..d8d3a292 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSelectedClassLv.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSelectedClassLv.java @@ -16,10 +16,11 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl; -import kr.syeyoung.dungeonsguide.features.impl.party.api.ClassSpecificData; -import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile; +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; @@ -31,7 +32,7 @@ import net.minecraftforge.fml.client.config.GuiUtils; import java.awt.*; import java.util.Arrays; -public class DataRendererSelectedClassLv implements DataRenderer { +public class DataRendererSelectedClassLv implements IDataRenderer { @Override public Dimension renderData(PlayerProfile playerProfile) { FontRenderer fr = 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/datarenders/impl/DataRendererSetUrOwn.java index eff18d13..3d5e94cc 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSetUrOwn.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSetUrOwn.java @@ -16,15 +16,16 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl; -import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile; +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 DataRenderer { +public class DataRendererSetUrOwn implements IDataRenderer { @Override public Dimension renderData(PlayerProfile playerProfile) { FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; 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/datarenders/impl/DataRendererSkillLv.java index 58fbb782..ea83a74e 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererSkillLv.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererSkillLv.java @@ -16,10 +16,11 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl; -import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile; -import kr.syeyoung.dungeonsguide.features.impl.party.api.Skill; +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; @@ -31,7 +32,7 @@ import net.minecraftforge.fml.client.config.GuiUtils; import java.awt.*; import java.util.Arrays; -public class DataRendererSkillLv implements DataRenderer { +public class DataRendererSkillLv implements IDataRenderer { private final Skill skill; public DataRendererSkillLv(Skill skill) { this.skill = skill; 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/datarenders/impl/DataRendererTalismans.java index d94ae506..9630e2be 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererTalismans.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/datarenders/impl/DataRendererTalismans.java @@ -16,9 +16,10 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview; +package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview.datarenders.impl; -import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile; +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; @@ -31,10 +32,9 @@ 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 { +public class DataRendererTalismans implements IDataRenderer { @Override public Dimension renderData(PlayerProfile playerProfile) { boolean apiDisabled = playerProfile.getTalismans() == null || playerProfile.getInventory() == null; 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; |