aboutsummaryrefslogtreecommitdiff
path: root/mod
diff options
context:
space:
mode:
authorsyeyoung <cyoung06@naver.com>2023-01-17 21:22:51 +0900
committersyeyoung <cyoung06@naver.com>2023-01-17 21:23:07 +0900
commit786be9ea22c86820c0f552a3b3a5f20b168f704b (patch)
tree0c3d675b083c3ceac0232a8ec70f41adae0600bf /mod
parent33ecb692b2b6d672ff231547a5fed4750034e490 (diff)
downloadSkyblock-Dungeons-Guide-786be9ea22c86820c0f552a3b3a5f20b168f704b.tar.gz
Skyblock-Dungeons-Guide-786be9ea22c86820c0f552a3b3a5f20b168f704b.tar.bz2
Skyblock-Dungeons-Guide-786be9ea22c86820c0f552a3b3a5f20b168f704b.zip
- Move online alarm to overlay manager
Signed-off-by: syeyoung <cyoung06@naver.com>
Diffstat (limited to 'mod')
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java4
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/DiscordIntegrationManager.java9
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/events/annotations/EventHandlerRegistry.java2
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/PartyInviteViewer.java280
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/PartyJoinRequest.java60
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/Reply.java30
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/TTL.java24
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/WidgetInvite.java75
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/WidgetJoinRequest.java80
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/WidgetPartyInviteViewer.java81
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/invteTooltip/MTooltipInviteElement.java27
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/PlayingDGAlarm.java116
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/WidgetOnline.java62
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/WidgetOnlinePeopleViewer.java72
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/DomElement.java3
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Clip.java2
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Column.java21
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/ConstrainedBox.java102
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Flexible.java9
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicHeight.java2
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicWidth.java2
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Line.java1
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Row.java21
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/SizedBox.java87
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Stack.java1
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java9
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/image/ImageTexture.java (renamed from mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/ImageTexture.java)13
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/image/URLImage.java16
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/OnlyChildrenRenderer.java1
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/Renderer.java4
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/RenderingContext.java5
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/SingleChildRenderer.java1
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/xml/DomElementRegistry.java6
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManager.java17
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManagerRootWidget.java2
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayWidget.java1
-rw-r--r--mod/src/main/resources/assets/dungeonsguide/gui/elements/size.gui23
-rw-r--r--mod/src/main/resources/assets/dungeonsguide/gui/features/discordOnline/discordOnline.gui52
-rw-r--r--mod/src/main/resources/assets/dungeonsguide/gui/features/discordOnline/discordOnlineList.gui22
-rw-r--r--mod/src/main/resources/assets/dungeonsguide/gui/features/discordParty/invite.gui85
-rw-r--r--mod/src/main/resources/assets/dungeonsguide/gui/features/discordParty/joinRequest.gui97
-rw-r--r--mod/src/main/resources/assets/dungeonsguide/gui/features/discordParty/partyInviteList.gui22
42 files changed, 957 insertions, 592 deletions
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java
index 36a0e955..394f95ca 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java
@@ -27,6 +27,7 @@ import kr.syeyoung.dungeonsguide.mod.discord.DiscordIntegrationManager;
import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
import kr.syeyoung.dungeonsguide.mod.features.impl.party.playerpreview.FeatureViewPlayerStatsOnJoin;
import kr.syeyoung.dungeonsguide.mod.features.impl.party.playerpreview.api.ApiFetcher;
+import kr.syeyoung.dungeonsguide.mod.guiv2.elements.image.ImageTexture;
import kr.syeyoung.dungeonsguide.mod.party.PartyManager;
import kr.syeyoung.dungeonsguide.mod.stomp.StompManager;
import kr.syeyoung.dungeonsguide.mod.stomp.StompPayload;
@@ -105,8 +106,7 @@ public class CommandDungeonsGuide extends CommandBase {
cosmeticsManager.requestCosmeticsList();
cosmeticsManager.requestActiveCosmetics();
StaticResourceCache.INSTANCE.purgeCache();
- FeatureRegistry.DISCORD_ASKTOJOIN.imageMap.clear();
- FeatureRegistry.DISCORD_ASKTOJOIN.futureMap.clear();
+ ImageTexture.imageMap.clear();
sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §fSuccessfully purged API Cache!"));
} else if (args[0].equals("pbroadcast")) {
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/DiscordIntegrationManager.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/DiscordIntegrationManager.java
index 196bdbd9..6771fc62 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/DiscordIntegrationManager.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/DiscordIntegrationManager.java
@@ -32,7 +32,7 @@ import kr.syeyoung.dungeonsguide.mod.events.impl.DiscordUserInvitedEvent;
import kr.syeyoung.dungeonsguide.mod.events.impl.DiscordUserJoinRequestEvent;
import kr.syeyoung.dungeonsguide.mod.events.impl.DiscordUserUpdateEvent;
import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
-import kr.syeyoung.dungeonsguide.mod.features.impl.discord.inviteViewer.PartyJoinRequest;
+import kr.syeyoung.dungeonsguide.mod.features.impl.discord.inviteViewer.Reply;
import kr.syeyoung.dungeonsguide.mod.party.PartyContext;
import kr.syeyoung.dungeonsguide.mod.party.PartyManager;
import lombok.Getter;
@@ -83,9 +83,9 @@ public class DiscordIntegrationManager implements IPCListener {
}
- public void respondToJoinRequest(String userId, PartyJoinRequest.Reply accept) {
+ public void respondToJoinRequest(String userId, Reply accept) {
JSONObject payload = null;
- if (accept == PartyJoinRequest.Reply.ACCEPT) {
+ if (accept == Reply.ACCEPT) {
payload = new JSONObject()
.put("cmd", "SEND_ACTIVITY_JOIN_INVITE")
.put("args", new JSONObject().put("user_id", userId));
@@ -125,6 +125,7 @@ public class DiscordIntegrationManager implements IPCListener {
ipcClient.subscribe("RELATIONSHIP_UPDATE", this::onRelationshipUpdate);
ipcClient.send(new JSONObject().put("cmd", "GET_RELATIONSHIPS"), new Callback(this::onRelationshipLoad));
ipcClient.setListener(this);
+ System.out.println("Connecting");
} catch (Throwable t) {
t.printStackTrace();
}
@@ -225,7 +226,7 @@ public class DiscordIntegrationManager implements IPCListener {
presence.setJoinSecret(PartyManager.INSTANCE.getAskToJoinSecret());
}
presence.setInstance(false);
- sendRichPresence(presence.build());
+// sendRichPresence(presence.build());
}
}
private void run() {
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/events/annotations/EventHandlerRegistry.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/events/annotations/EventHandlerRegistry.java
index fecfa2fc..1e5b3c70 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/events/annotations/EventHandlerRegistry.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/events/annotations/EventHandlerRegistry.java
@@ -112,7 +112,7 @@ public class EventHandlerRegistry {
private static Map<Class<? extends Event>, IEventListener> registeredHandlers = new HashMap<>();
- public static void registerActualListeners() {
+ public static synchronized void registerActualListeners() {
for (Class<? extends Event> aClass : targets.keySet()) {
if (registeredHandlers.containsKey(aClass)) continue;
try {
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/PartyInviteViewer.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/PartyInviteViewer.java
index e537c311..9e7cc18a 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/PartyInviteViewer.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/PartyInviteViewer.java
@@ -25,7 +25,13 @@ import kr.syeyoung.dungeonsguide.mod.events.annotations.DGEventHandler;
import kr.syeyoung.dungeonsguide.mod.events.impl.DGTickEvent;
import kr.syeyoung.dungeonsguide.mod.events.impl.DiscordUserInvitedEvent;
import kr.syeyoung.dungeonsguide.mod.events.impl.DiscordUserJoinRequestEvent;
+import kr.syeyoung.dungeonsguide.mod.features.FeatureParameter;
import kr.syeyoung.dungeonsguide.mod.features.SimpleFeature;
+import kr.syeyoung.dungeonsguide.mod.guiv2.elements.image.ImageTexture;
+import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Rect;
+import kr.syeyoung.dungeonsguide.mod.overlay.OverlayManager;
+import kr.syeyoung.dungeonsguide.mod.overlay.OverlayType;
+import kr.syeyoung.dungeonsguide.mod.overlay.OverlayWidget;
import kr.syeyoung.dungeonsguide.mod.utils.TextUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
@@ -45,10 +51,18 @@ import java.util.Map;
import java.util.concurrent.*;
public class PartyInviteViewer extends SimpleFeature {
+ private WidgetPartyInviteViewer partyInviteViewer;
+ private OverlayWidget widget;
public PartyInviteViewer() {
super("Discord", "Party Invite Viewer","Simply type /dg asktojoin or /dg atj to toggle whether ask-to-join would be presented as option on discord!\n\nRequires Discord RPC to be enabled", "discord.party_invite_viewer");
-
+ addParameter("ttl", new FeatureParameter<Integer>("ttl", "Request Duration", "The duration after which the requests will be dismissed automatically. The value is in seconds.", 15, "integer"));
+ widget = new OverlayWidget(
+ partyInviteViewer = new WidgetPartyInviteViewer(),
+ OverlayType.OVER_ANY,
+ () -> new Rect(0,0,Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight)
+ );
+ OverlayManager.getInstance().addOverlay(widget);
}
@Override
@@ -56,277 +70,21 @@ public class PartyInviteViewer extends SimpleFeature {
return false;
}
- @DGEventHandler
- public void onGuiPostRender(GuiScreenEvent.DrawScreenEvent.Post rendered) {
- renderRequests(true);
- }
-
- @DGEventHandler
- public void drawScreen(RenderGameOverlayEvent.Post postRender) {
-
- if (!(postRender.type == RenderGameOverlayEvent.ElementType.EXPERIENCE || postRender.type == RenderGameOverlayEvent.ElementType.JUMPBAR)) return;
-
- try {
- renderRequests(false);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
- @DGEventHandler
+ @DGEventHandler(triggerOutOfSkyblock = true)
public void onTick(DGTickEvent tickEvent) {
try {
- List<PartyJoinRequest> partyJoinRequestList = new ArrayList<>();
- boolean isOnHypixel = DungeonsGuide.getDungeonsGuide().getSkyblockStatus().isOnHypixel();
- for (PartyJoinRequest joinRequest:joinRequests) {
- if (joinRequest.getTtl() != -1) {
- joinRequest.setTtl(joinRequest.getTtl() - 1);
- if (joinRequest.getTtl() == 0 || !isOnHypixel) {
- partyJoinRequestList.add(joinRequest);
- }
- } else if (!isOnHypixel){
-// DiscordRPC.discordRespond(joinRequest.getDiscordUser().userId, DiscordRPC.DiscordReply.NO);
- partyJoinRequestList.add(joinRequest);
- } else if (joinRequest.getExpire() < System.currentTimeMillis()) {
- partyJoinRequestList.add(joinRequest);
- }
- }
- joinRequests.removeAll(partyJoinRequestList);
+ partyInviteViewer.tick();
} catch (Throwable e) {e.printStackTrace();}
}
-
- @DGEventHandler
- public void onMouseInput(GuiScreenEvent.MouseInputEvent.Pre mouseInputEvent) {
-
- int mouseX = Mouse.getX();
- int mouseY = Minecraft.getMinecraft().displayHeight - Mouse.getY() +3;
- for (PartyJoinRequest joinRequest:joinRequests) {
- if (joinRequest.getWholeRect() != null && joinRequest.getWholeRect().contains(mouseX, mouseY)) {
- mouseInputEvent.setCanceled(true);
-
- if (Mouse.getEventButton() == -1) return;
-
- if (joinRequest.getReply() != null) {
- joinRequests.remove(joinRequest);
- return;
- }
-
- if (!joinRequest.isInvite()) {
- if (joinRequest.getAcceptRect().contains(mouseX, mouseY)) {
- joinRequest.setReply(PartyJoinRequest.Reply.ACCEPT);
- joinRequest.setTtl(60);
- DiscordIntegrationManager.INSTANCE.respondToJoinRequest(joinRequest.getDiscordUser().getId(), PartyJoinRequest.Reply.ACCEPT);
- return;
- }
-
- if (joinRequest.getDenyRect().contains(mouseX, mouseY)) {
- joinRequest.setReply(PartyJoinRequest.Reply.DENY);
- joinRequest.setTtl(60);
- DiscordIntegrationManager.INSTANCE.respondToJoinRequest(joinRequest.getDiscordUser().getId(), PartyJoinRequest.Reply.DENY);
- return;
- }
-
- if (joinRequest.getIgnoreRect().contains(mouseX, mouseY)) {
- joinRequest.setReply(PartyJoinRequest.Reply.IGNORE);
- joinRequest.setTtl(60);
- DiscordIntegrationManager.INSTANCE.respondToJoinRequest(joinRequest.getDiscordUser().getId(), PartyJoinRequest.Reply.IGNORE);
- return;
- }
- } else {
- if (joinRequest.getAcceptRect().contains(mouseX, mouseY)) {
- joinRequest.setReply(PartyJoinRequest.Reply.ACCEPT);
- joinRequest.setTtl(60);
- DiscordIntegrationManager.INSTANCE.acceptInvite(joinRequest.getHandle());
- return;
- }
-
- if (joinRequest.getDenyRect().contains(mouseX, mouseY)) {
- joinRequest.setReply(PartyJoinRequest.Reply.DENY);
- joinRequest.setTtl(60);
- return;
- }
- }
-
- return;
- }
- }
- }
-
-
-
- public CopyOnWriteArrayList<PartyJoinRequest> joinRequests = new CopyOnWriteArrayList<>();
-
ExecutorService executorService = Executors.newFixedThreadPool(3, DungeonsGuide.THREAD_FACTORY);
- public Map<String, Future<ImageTexture>> futureMap = new HashMap<>();
- public Map<String, ImageTexture> imageMap = new HashMap<>();
-
- public Future<ImageTexture> loadImage(String url) {
- if (imageMap.containsKey(url)) return CompletableFuture.completedFuture(imageMap.get(url));
- if (futureMap.containsKey(url)) return futureMap.get(url);
- Future<ImageTexture> future = executorService.submit(() -> {
- try {
- ImageTexture imageTexture = new ImageTexture(url);
- imageMap.put(url, imageTexture);
- return imageTexture;
- } catch (Exception e) {
- throw e;
- }
- });
- futureMap.put(url,future);
- return future;
- }
-
-
- public void renderRequests(boolean hover) {
- try {
- GlStateManager.pushMatrix();
- ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
- GlStateManager.scale(1.0 / sr.getScaleFactor(), 1.0 / sr.getScaleFactor(), 1.0);
- int height = 90;
- int gap = 5;
- int x = 5;
- int y = 5;
- for (PartyJoinRequest partyJoinRequest : joinRequests) {
- renderRequest(partyJoinRequest, x, y, 350,height, hover);
- y += height + gap;
- }
- GlStateManager.popMatrix();
- GlStateManager.enableBlend();
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
-
-
- public void renderRequest(PartyJoinRequest partyJoinRequest, int x, int y, int width, int height, boolean hover) {
- ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
-
- int mouseX = Mouse.getX();
- int mouseY = Minecraft.getMinecraft().displayHeight - Mouse.getY() +3;
-
- partyJoinRequest.getWholeRect().setBounds(x,y,width,height);
-
-
- GlStateManager.pushMatrix();
- GlStateManager.translate(x,y,0);
-
- Gui.drawRect(0, 0,width,height, 0xFF23272a);
- Gui.drawRect(2, 2, width-2, height-2, 0XFF2c2f33);
- {
- String avatar = "https://cdn.discordapp.com/avatars/"+partyJoinRequest.getDiscordUser().getId()+"/"+partyJoinRequest.getAvatar()+"."+(partyJoinRequest.getAvatar().startsWith("a_") ? "gif":"png");
- Future<ImageTexture> loadedImageFuture = loadImage(avatar);
- ImageTexture loadedImage = null;
- if (loadedImageFuture.isDone()) {
- try {
- loadedImage = loadedImageFuture.get();
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
- }
- }
- if (loadedImage != null) {
- loadedImage.drawFrame( 7,7,height-14,height-14);
- } else {
- Gui.drawRect(7, 7, height - 7, height-7, 0xFF4E4E4E);
- }
- }
-
- 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);
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- GlStateManager.pushMatrix();
- GlStateManager.translate(height +3,7, 0);
-
- GlStateManager.pushMatrix();
- GlStateManager.scale(3.0,3.0,1.0);
- fr.drawString(partyJoinRequest.getUsername()+"", 0,0, 0xFFFFFFFF, true);
- GlStateManager.popMatrix();
-
- GlStateManager.pushMatrix();
- GlStateManager.translate(fr.getStringWidth(partyJoinRequest.getUsername()+"") * 3 + 1, (int)(fr.FONT_HEIGHT*1.5), 0);
- fr.drawString("#"+partyJoinRequest.getDiscriminator(), 0,0,0xFFaaaaaa, true);
- GlStateManager.popMatrix();
- GlStateManager.pushMatrix();
- GlStateManager.translate(0, fr.FONT_HEIGHT * 3 + 5, 0);
- GlStateManager.scale(1.0,1.0,1.0);
- if (partyJoinRequest.isInvite())
- fr.drawString("§ewants to you to join their party! ("+(TextUtils.formatTime(partyJoinRequest.getExpire() - System.currentTimeMillis()))+")", 0,0,0xFFFFFFFF,false);
- else
- fr.drawString("wants to join your party! ("+(TextUtils.formatTime(partyJoinRequest.getExpire() - System.currentTimeMillis()))+")", 0,0,0xFFFFFFFF,false);
- GlStateManager.popMatrix();
- GlStateManager.popMatrix();
- if (partyJoinRequest.getReply() == null) {
- GlStateManager.pushMatrix();
- GlStateManager.translate(height + 3, height - 32, 0);
- int widthForTheThing = (width - height) / 3;
- GlStateManager.pushMatrix();
- String text = "Accept";
- partyJoinRequest.getAcceptRect().setBounds(x + height + 3, y + height - 25, widthForTheThing - 10, 25);
- Gui.drawRect(0, 0, widthForTheThing - 10, 25, hover && partyJoinRequest.getAcceptRect().contains(mouseX, mouseY) ? 0xFF859DF0 : 0xFF7289da);
- GlStateManager.translate((widthForTheThing - 10 - fr.getStringWidth(text) * 2) / 2, 15 - fr.FONT_HEIGHT, 0);
-
- GlStateManager.scale(2.0f, 2.0f, 1.0f);
- 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(text, 0, 0, 0xFFFFFFFF);
- GlStateManager.popMatrix();
- GlStateManager.translate(widthForTheThing, 0, 0);
- partyJoinRequest.getDenyRect().setBounds(x + height + 3 + widthForTheThing, y + height - 25, widthForTheThing - 10, 25);
- Gui.drawRect(0, 0, widthForTheThing - 10, 25, hover && partyJoinRequest.getDenyRect().contains(mouseX, mouseY) ? 0xFFAEC0CB : 0xFF99aab5);
- GlStateManager.pushMatrix();
- text = "Deny";
- GlStateManager.translate((widthForTheThing - 10 - fr.getStringWidth(text) * 2) / 2, 15 - fr.FONT_HEIGHT, 0);
- GlStateManager.scale(2.0f, 2.0f, 1.0f);
- 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(text, 0, 0, 0xFFFFFFFF);
- GlStateManager.popMatrix();
- if (!partyJoinRequest.isInvite()) {
- GlStateManager.translate(widthForTheThing, 0, 0);
- partyJoinRequest.getIgnoreRect().setBounds(x + height + 3 + widthForTheThing + widthForTheThing, y + height - 25, widthForTheThing - 10, 25);
- Gui.drawRect(0, 0, widthForTheThing - 10, 25, hover && partyJoinRequest.getIgnoreRect().contains(mouseX, mouseY) ? 0xFFAEC0CB : 0xFF99aab5); // AEC0CB
-
- GlStateManager.pushMatrix();
- text = "Ignore";
- GlStateManager.translate((widthForTheThing - 10 - fr.getStringWidth(text) * 2) / 2, 15 - fr.FONT_HEIGHT, 0);
- GlStateManager.scale(2.0f, 2.0f, 1.0f);
- 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(text, 0, 0, 0xFFFFFFFF);
- GlStateManager.popMatrix();
- }
- GlStateManager.popMatrix();
- } else {
- GlStateManager.pushMatrix();
- GlStateManager.translate(height + 3, height - 28, 0);
- GlStateManager.scale(2.0f,2.0f,1.0f);
- 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(partyJoinRequest.getReply().getPast()+" the invite.",0,0,0xFFFFFFFF);
- GlStateManager.popMatrix();
- }
- GlStateManager.popMatrix();
- }
@DGEventHandler(triggerOutOfSkyblock = true)
public void onDiscordUserJoinRequest(DiscordUserJoinRequestEvent event) {
- PartyJoinRequest partyInvite = new PartyJoinRequest();
- partyInvite.setDiscordUser(event.getDiscordUser());
- partyInvite.setExpire(System.currentTimeMillis() + 30000L);
- partyInvite.setInvite(false);
- joinRequests.add(partyInvite);
+ partyInviteViewer.addJoinRequest(event);
}
@DGEventHandler(triggerOutOfSkyblock = true)
public void onDiscordUserJoinRequest(DiscordUserInvitedEvent event) {
- PartyJoinRequest partyInvite = new PartyJoinRequest();
- partyInvite.setDiscordUser(event.getDiscordUser());
- partyInvite.setHandle(event.getHandle());
- partyInvite.setExpire(System.currentTimeMillis() + 30000L);
- partyInvite.setInvite(true);
- joinRequests.add(partyInvite);
+ partyInviteViewer.addInvite(event);
}
}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/PartyJoinRequest.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/PartyJoinRequest.java
deleted file mode 100644
index 98d601b9..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/PartyJoinRequest.java
+++ /dev/null
@@ -1,60 +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.mod.features.impl.discord.inviteViewer;
-
-import com.jagrosh.discordipc.entities.User;
-import kr.syeyoung.dungeonsguide.mod.discord.InviteHandle;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.Getter;
-
-import java.awt.*;
-
-@Data
-public class PartyJoinRequest {
- private User discordUser;
- private InviteHandle handle;
-
- public void setDiscordUser(User discordUser) {
- this.discordUser = discordUser;
- username = discordUser.getName();
- discriminator = discordUser.getDiscriminator();
- avatar= discordUser.getEffectiveAvatarUrl();
- }
-
- private String username, discriminator, avatar;
- private long expire;
-
- private Rectangle wholeRect = new Rectangle();
- private Rectangle acceptRect = new Rectangle();
- private Rectangle denyRect = new Rectangle();
- private Rectangle ignoreRect = new Rectangle();
-
- private boolean isInvite;
- private int ttl = -1;
- private Reply reply;
-
- @AllArgsConstructor
- public enum Reply {
- ACCEPT("Accepted"), DENY("Denied"), IGNORE("Ignored");
-
- @Getter
- private final String past;
- }
-}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/Reply.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/Reply.java
new file mode 100644
index 00000000..c36c0f04
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/Reply.java
@@ -0,0 +1,30 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * 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.mod.features.impl.discord.inviteViewer;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+public enum Reply {
+ ACCEPT("Accepted"), DENY("Denied"), IGNORE("Ignored");
+
+ @Getter
+ private final String past;
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/TTL.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/TTL.java
new file mode 100644
index 00000000..8edc2dd6
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/TTL.java
@@ -0,0 +1,24 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * 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.mod.features.impl.discord.inviteViewer;
+
+public interface TTL {
+ long startedDisplaying();
+ long ttl();
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/WidgetInvite.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/WidgetInvite.java
new file mode 100644
index 00000000..ebad7821
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/WidgetInvite.java
@@ -0,0 +1,75 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * 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.mod.features.impl.discord.inviteViewer;
+
+import kr.syeyoung.dungeonsguide.mod.discord.DiscordIntegrationManager;
+import kr.syeyoung.dungeonsguide.mod.events.impl.DiscordUserInvitedEvent;
+import kr.syeyoung.dungeonsguide.mod.events.impl.DiscordUserJoinRequestEvent;
+import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
+import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedWidget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.On;
+import net.minecraft.util.ResourceLocation;
+
+public class WidgetInvite extends AnnotatedWidget implements TTL {
+
+ @Bind(variableName = "username")
+ public final BindableAttribute<String> username;
+ @Bind(variableName = "discriminator")
+ public final BindableAttribute<String> discriminator;
+ @Bind(variableName = "avatarUrl")
+ public final BindableAttribute<String> avatarURL;
+ private WidgetPartyInviteViewer inviteViewer;
+ private DiscordUserInvitedEvent event;
+ private long start;
+ public WidgetInvite(WidgetPartyInviteViewer parent, DiscordUserInvitedEvent invitedEvent) {
+ super(new ResourceLocation("dungeonsguide:gui/features/discordParty/invite.gui"));
+ this.inviteViewer = parent;
+ this.event = invitedEvent;
+ this.start = System.currentTimeMillis();
+ username = new BindableAttribute<>(String.class, invitedEvent.getDiscordUser().getName());
+ discriminator = new BindableAttribute<>(String.class, invitedEvent.getDiscordUser().getDiscriminator());
+ avatarURL = new BindableAttribute<>(String.class, invitedEvent.getDiscordUser().getEffectiveAvatarUrl());
+ }
+
+ public DiscordUserInvitedEvent getEvent() {
+ return event;
+ }
+
+ @On(functionName = "accept")
+ public void accept() {
+ inviteViewer.remove(this);
+ DiscordIntegrationManager.INSTANCE.acceptInvite(event.getHandle());
+ }
+ @On(functionName = "deny")
+ public void deny() {
+ inviteViewer.remove(this);
+ }
+
+ @Override
+ public long startedDisplaying() {
+ return 0;
+ }
+
+ @Override
+ public long ttl() {
+ return FeatureRegistry.DISCORD_ASKTOJOIN.<Integer>getParameter("ttl").getValue() * 1000;
+ }
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/WidgetJoinRequest.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/WidgetJoinRequest.java
new file mode 100644
index 00000000..7c51636b
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/WidgetJoinRequest.java
@@ -0,0 +1,80 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * 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.mod.features.impl.discord.inviteViewer;
+
+import kr.syeyoung.dungeonsguide.mod.discord.DiscordIntegrationManager;
+import kr.syeyoung.dungeonsguide.mod.events.impl.DiscordUserJoinRequestEvent;
+import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
+import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedWidget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.On;
+import net.minecraft.util.ResourceLocation;
+
+public class WidgetJoinRequest extends AnnotatedWidget implements TTL{
+
+ @Bind(variableName = "username")
+ public final BindableAttribute<String> username;
+ @Bind(variableName = "discriminator")
+ public final BindableAttribute<String> discriminator;
+ @Bind(variableName = "avatarUrl")
+ public final BindableAttribute<String> avatarURL;
+ private WidgetPartyInviteViewer inviteViewer;
+ private DiscordUserJoinRequestEvent event;
+ private long start;
+ public WidgetJoinRequest(WidgetPartyInviteViewer parent, DiscordUserJoinRequestEvent joinRequestEvent) {
+ super(new ResourceLocation("dungeonsguide:gui/features/discordParty/joinRequest.gui"));
+ this.inviteViewer = parent;
+ this.event = joinRequestEvent;
+ start = System.currentTimeMillis();
+ username = new BindableAttribute<>(String.class, joinRequestEvent.getDiscordUser().getName());
+ discriminator = new BindableAttribute<>(String.class, joinRequestEvent.getDiscordUser().getDiscriminator());
+ avatarURL = new BindableAttribute<>(String.class, joinRequestEvent.getDiscordUser().getEffectiveAvatarUrl());
+ }
+
+ public DiscordUserJoinRequestEvent getEvent() {
+ return event;
+ }
+
+ @On(functionName = "accept")
+ public void accept() {
+ inviteViewer.remove(this);
+ DiscordIntegrationManager.INSTANCE.respondToJoinRequest(event.getDiscordUser().getId(), Reply.ACCEPT);
+ }
+ @On(functionName = "deny")
+ public void deny() {
+ inviteViewer.remove(this);
+ DiscordIntegrationManager.INSTANCE.respondToJoinRequest(event.getDiscordUser().getId(), Reply.DENY);
+ }
+ @On(functionName = "ignore")
+ public void ignore() {
+ inviteViewer.remove(this);
+ DiscordIntegrationManager.INSTANCE.respondToJoinRequest(event.getDiscordUser().getId(), Reply.IGNORE);
+ }
+
+ @Override
+ public long startedDisplaying() {
+ return start;
+ }
+
+ @Override
+ public long ttl() {
+ return FeatureRegistry.DISCORD_ASKTOJOIN.<Integer>getParameter("ttl").getValue() * 1000;
+ }
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/WidgetPartyInviteViewer.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/WidgetPartyInviteViewer.java
new file mode 100644
index 00000000..969e7f94
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/WidgetPartyInviteViewer.java
@@ -0,0 +1,81 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * 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.mod.features.impl.discord.inviteViewer;
+
+import kr.syeyoung.dungeonsguide.mod.events.impl.DiscordUserInvitedEvent;
+import kr.syeyoung.dungeonsguide.mod.events.impl.DiscordUserJoinRequestEvent;
+import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement;
+import kr.syeyoung.dungeonsguide.mod.guiv2.Widget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.elements.Column;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedWidget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind;
+import net.minecraft.util.ResourceLocation;
+
+import java.util.*;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public class WidgetPartyInviteViewer extends AnnotatedWidget {
+ @Bind(variableName = "listApi")
+ public final BindableAttribute<Column> columnApi = new BindableAttribute<>(Column.class);
+
+ public WidgetPartyInviteViewer() {
+ super(new ResourceLocation("dungeonsguide:gui/features/discordParty/partyInviteList.gui"));
+ }
+
+ private final Set<String> joinReqUid = Collections.synchronizedSet( new HashSet<>());
+ private final Set<String> inviteUid = Collections.synchronizedSet( new HashSet<>());
+ private final List<Widget> widgetList = new CopyOnWriteArrayList<>();
+ public void addJoinRequest(DiscordUserJoinRequestEvent joinRequest) {
+ if (joinReqUid.contains(joinRequest.getDiscordUser().getId())) return;
+ joinReqUid.add(joinRequest.getDiscordUser().getId());
+ WidgetJoinRequest request;
+ columnApi.getValue().addWidget(request = new WidgetJoinRequest(this, joinRequest));
+ widgetList.add(request);
+ }
+
+ public void addInvite(DiscordUserInvitedEvent inviteEvent) {
+ if (inviteUid.contains(inviteEvent.getDiscordUser().getId())) return;
+ inviteUid.add(inviteEvent.getDiscordUser().getId());
+ WidgetInvite invite;
+ columnApi.getValue().addWidget(invite = new WidgetInvite(this, inviteEvent));
+ widgetList.add(invite);
+ }
+
+ public void remove(Widget widget) {
+ columnApi.getValue().removeWidget(widget);
+ widgetList.remove(widget);
+
+ if (widget instanceof WidgetJoinRequest)
+ joinReqUid.remove(((WidgetJoinRequest) widget).getEvent().getDiscordUser().getId());
+ if (widget instanceof WidgetInvite)
+ inviteUid.remove(((WidgetInvite) widget).getEvent().getDiscordUser().getId());
+ }
+
+ public void tick() {
+ List<Widget> toRemove = new ArrayList<>();
+ for (Widget widget : widgetList) {
+ TTL ttl = (TTL) widget;
+ if (ttl.startedDisplaying() + ttl.ttl() < System.currentTimeMillis()) {
+ toRemove.add(widget);
+ }
+ }
+ toRemove.forEach(this::remove);
+ }
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/invteTooltip/MTooltipInviteElement.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/invteTooltip/MTooltipInviteElement.java
index f895ad4d..7e0aec9e 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/invteTooltip/MTooltipInviteElement.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/invteTooltip/MTooltipInviteElement.java
@@ -21,7 +21,7 @@ package kr.syeyoung.dungeonsguide.mod.features.impl.discord.invteTooltip;
import kr.syeyoung.dungeonsguide.mod.discord.JDiscordRelation;
import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
-import kr.syeyoung.dungeonsguide.mod.features.impl.discord.inviteViewer.ImageTexture;
+import kr.syeyoung.dungeonsguide.mod.guiv2.elements.image.ImageTexture;
import kr.syeyoung.dungeonsguide.mod.gui.MPanel;
import kr.syeyoung.dungeonsguide.mod.gui.elements.MButton;
import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
@@ -38,6 +38,8 @@ import java.util.function.Consumer;
public class MTooltipInviteElement extends MPanel {
private JDiscordRelation relation;
private MButton invite;
+ private ImageTexture texture;
+
public MTooltipInviteElement(JDiscordRelation jDiscordRelation, boolean invited, Consumer<Long> inviteCallback) {
this.relation = jDiscordRelation;
this.invite = new MButton();
@@ -67,6 +69,12 @@ public class MTooltipInviteElement extends MPanel {
invite.setForeground(new Color(0xFF02EE67));
}
+ if (!jDiscordRelation.getDiscordUser().getEffectiveAvatarUrl().isEmpty()) {
+ ImageTexture.loadImage(jDiscordRelation.getDiscordUser().getEffectiveAvatarUrl(), (cback) -> {
+ this.texture = cback;
+ });
+ }
+
add(invite);
}
@@ -78,23 +86,12 @@ public class MTooltipInviteElement extends MPanel {
}
FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- if (!relation.getDiscordUser().getEffectiveAvatarUrl().isEmpty()){
- String avatar = relation.getDiscordUser().getEffectiveAvatarUrl();
- Future<ImageTexture> loadedImageFuture = FeatureRegistry.DISCORD_ASKTOJOIN.loadImage(avatar);
- ImageTexture loadedImage = null;
- if (loadedImageFuture.isDone()) {
- try {
- loadedImage = loadedImageFuture.get();
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
- }
- }
- if (loadedImage != null) {
- loadedImage.drawFrameAndIncrement( 3,3,bounds.height-6,bounds.height-6);
+ if (texture != null) {
+ texture.drawFrame( 3,3,bounds.height-6,bounds.height-6);
} else {
Gui.drawRect(3, 3, bounds.height - 6, bounds.height-6, 0xFF4E4E4E);
}
- }
+
fr.drawString(relation.getDiscordUser().getName()+"#"+relation.getDiscordUser().getDiscriminator(), bounds.height,(bounds.height-fr.FONT_HEIGHT)/2, -1);
}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/PlayingDGAlarm.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/PlayingDGAlarm.java
index ae799764..892cac52 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/PlayingDGAlarm.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/PlayingDGAlarm.java
@@ -26,7 +26,12 @@ import kr.syeyoung.dungeonsguide.mod.events.impl.DGTickEvent;
import kr.syeyoung.dungeonsguide.mod.events.impl.DiscordUserUpdateEvent;
import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
import kr.syeyoung.dungeonsguide.mod.features.SimpleFeature;
-import kr.syeyoung.dungeonsguide.mod.features.impl.discord.inviteViewer.ImageTexture;
+import kr.syeyoung.dungeonsguide.mod.features.impl.discord.inviteViewer.WidgetPartyInviteViewer;
+import kr.syeyoung.dungeonsguide.mod.guiv2.elements.image.ImageTexture;
+import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Rect;
+import kr.syeyoung.dungeonsguide.mod.overlay.OverlayManager;
+import kr.syeyoung.dungeonsguide.mod.overlay.OverlayType;
+import kr.syeyoung.dungeonsguide.mod.overlay.OverlayWidget;
import kr.syeyoung.dungeonsguide.mod.utils.TextUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -46,116 +51,31 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
public class PlayingDGAlarm extends SimpleFeature {
+ private WidgetOnlinePeopleViewer onlinePeopleViewer;
+ private OverlayWidget widget;
+
public PlayingDGAlarm() {
super("Discord", "Friend Online Notification","Notifies you in bottom when your discord friend has launched a Minecraft with DG!\n\nRequires the Friend's Discord RPC to be enabled", "discord.playingalarm");
+ widget = new OverlayWidget(
+ onlinePeopleViewer = new WidgetOnlinePeopleViewer(),
+ OverlayType.OVER_ANY,
+ () -> new Rect(0,0,Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight)
+ );
+ OverlayManager.getInstance().addOverlay(widget);
}
- private List<PlayerOnline> notif = new CopyOnWriteArrayList<>();
- @DGEventHandler
+ @DGEventHandler(triggerOutOfSkyblock = true)
public void onTick(DGTickEvent event) {
try {
- List<PlayerOnline> partyJoinRequestList = new ArrayList<>();
- boolean isOnHypixel = DungeonsGuide.getDungeonsGuide().getSkyblockStatus().isOnHypixel();
- for (PlayerOnline joinRequest:notif) {
- if (!isOnHypixel){
- partyJoinRequestList.add(joinRequest);
- } else if (joinRequest.getEnd() < System.currentTimeMillis()) {
- partyJoinRequestList.add(joinRequest);
- }
- }
- notif.removeAll(partyJoinRequestList);
+ onlinePeopleViewer.tick();
} catch (Throwable e) {e.printStackTrace();}
}
-
-
-
- @DGEventHandler
- public void drawScreen(RenderGameOverlayEvent.Post postRender) {
-
- if (!(postRender.type == RenderGameOverlayEvent.ElementType.EXPERIENCE || postRender.type == RenderGameOverlayEvent.ElementType.JUMPBAR)) return;
-
- try {
- GlStateManager.pushMatrix();
- GlStateManager.translate(0,0,100);
- ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
- GlStateManager.scale(1.0 / sr.getScaleFactor(), 1.0 / sr.getScaleFactor(), 1.0);
- int height = 90;
- int gap = 5;
- int x = Minecraft.getMinecraft().displayWidth-350-gap;
- int y = Minecraft.getMinecraft().displayHeight-(height+gap)*notif.size();
- for (PlayerOnline partyJoinRequest : notif) {
- renderRequest(partyJoinRequest, x, y, 350,height);
- y += height + gap;
- }
- GlStateManager.popMatrix();
- GlStateManager.enableBlend();
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
-
- public void renderRequest(PlayerOnline online, int x, int y, int width, int height) {
- GlStateManager.pushMatrix();
- GlStateManager.translate(x,y,0);
-
- Gui.drawRect(0, 0,width,height, 0xFF23272a);
- Gui.drawRect(2, 2, width-2, height-2, 0XFF2c2f33);
- {
- String avatar = online.jDiscordRelation.getDiscordUser().getEffectiveAvatarUrl();
- Future<ImageTexture> loadedImageFuture = FeatureRegistry.DISCORD_ASKTOJOIN.loadImage(avatar);
- ImageTexture loadedImage = null;
- if (loadedImageFuture.isDone()) {
- try {
- loadedImage = loadedImageFuture.get();
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
- }
- }
- if (loadedImage != null) {
- loadedImage.drawFrameAndIncrement( 7,7,height-14,height-14);
- } else {
- Gui.drawRect(7, 7, height - 7, height-7, 0xFF4E4E4E);
- }
- }
-
- 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);
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- GlStateManager.pushMatrix();
- GlStateManager.translate(height +3,7, 0);
-
- GlStateManager.pushMatrix();
- GlStateManager.scale(3.0,3.0,1.0);
- fr.drawString(online.getJDiscordRelation().getDiscordUser().getName()+"", 0,0, 0xFFFFFFFF, true);
- GlStateManager.popMatrix();
-
- GlStateManager.pushMatrix();
- GlStateManager.translate(fr.getStringWidth(online.getJDiscordRelation().getDiscordUser().getName()+"") * 3 + 1, (int)(fr.FONT_HEIGHT*1.5), 0);
- fr.drawString("#"+online.getJDiscordRelation().getDiscordUser().getDiscriminator(), 0,0,0xFFaaaaaa, true);
- GlStateManager.popMatrix();
- GlStateManager.pushMatrix();
- GlStateManager.translate(0, fr.FONT_HEIGHT * 3 + 5, 0);
- GlStateManager.scale(1.0,1.0,1.0);
- fr.drawString("Started Playing Skyblock! (Dismissed in "+(TextUtils.formatTime(online.getEnd() - System.currentTimeMillis()))+")", 0,0,0xFFFFFFFF,false);
- GlStateManager.popMatrix();
- GlStateManager.popMatrix();
- GlStateManager.popMatrix();
- }
-
-
- @Data @AllArgsConstructor
- public static class PlayerOnline {
- private JDiscordRelation jDiscordRelation;
- private long end;
- }
-
@DGEventHandler(triggerOutOfSkyblock = true)
public void onDiscordUserUpdate(DiscordUserUpdateEvent event) {
JDiscordRelation prev = event.getPrev(), current = event.getCurrent();
if (prev == null) return;
if (!isDisplayable(prev) && isDisplayable(current)) {
- notif.add(new PlayerOnline(current, System.currentTimeMillis()+3000));
+ onlinePeopleViewer.addUser(current);
}
}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/WidgetOnline.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/WidgetOnline.java
new file mode 100644
index 00000000..8cdd3d6f
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/WidgetOnline.java
@@ -0,0 +1,62 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * 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.mod.features.impl.discord.onlinealarm;
+
+import kr.syeyoung.dungeonsguide.mod.discord.JDiscordRelation;
+import kr.syeyoung.dungeonsguide.mod.features.impl.discord.inviteViewer.TTL;
+import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedWidget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind;
+import net.minecraft.util.ResourceLocation;
+
+public class WidgetOnline extends AnnotatedWidget implements TTL {
+
+ @Bind(variableName = "username")
+ public final BindableAttribute<String> username;
+ @Bind(variableName = "discriminator")
+ public final BindableAttribute<String> discriminator;
+ @Bind(variableName = "avatarUrl")
+ public final BindableAttribute<String> avatarURL;
+ private WidgetOnlinePeopleViewer viewer;
+ private JDiscordRelation relation;
+ private long start;
+ public WidgetOnline(WidgetOnlinePeopleViewer parent, JDiscordRelation relation) {
+ super(new ResourceLocation("dungeonsguide:gui/features/discordOnline/discordOnline.gui"));
+ this.viewer = parent;
+ this.relation = relation;
+ start = System.currentTimeMillis();
+ username = new BindableAttribute<>(String.class, relation.getDiscordUser().getName());
+ discriminator = new BindableAttribute<>(String.class, relation.getDiscordUser().getDiscriminator());
+ avatarURL = new BindableAttribute<>(String.class, relation.getDiscordUser().getEffectiveAvatarUrl());
+ }
+
+ public JDiscordRelation getRelation() {
+ return relation;
+ }
+
+ @Override
+ public long startedDisplaying() {
+ return start;
+ }
+
+ @Override
+ public long ttl() {
+ return 2000;
+ }
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/WidgetOnlinePeopleViewer.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/WidgetOnlinePeopleViewer.java
new file mode 100644
index 00000000..bf3ebe2c
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/onlinealarm/WidgetOnlinePeopleViewer.java
@@ -0,0 +1,72 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * 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.mod.features.impl.discord.onlinealarm;
+
+import kr.syeyoung.dungeonsguide.mod.discord.JDiscordRelation;
+import kr.syeyoung.dungeonsguide.mod.features.impl.discord.inviteViewer.TTL;
+import kr.syeyoung.dungeonsguide.mod.features.impl.discord.inviteViewer.WidgetJoinRequest;
+import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement;
+import kr.syeyoung.dungeonsguide.mod.guiv2.Widget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.elements.Column;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedWidget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind;
+import net.minecraft.util.ResourceLocation;
+
+import java.util.*;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public class WidgetOnlinePeopleViewer extends AnnotatedWidget {
+ @Bind(variableName = "listApi")
+ public final BindableAttribute<Column> columnApi = new BindableAttribute<>(Column.class);
+
+ public WidgetOnlinePeopleViewer() {
+ super(new ResourceLocation("dungeonsguide:gui/features/discordOnline/discordOnlineList.gui"));
+ }
+
+ private final Set<String> onlineUid = Collections.synchronizedSet( new HashSet<>());
+ private List<Widget> widgetList = new CopyOnWriteArrayList<>();
+ public void addUser(JDiscordRelation joinRequest) {
+ if (onlineUid.contains(joinRequest.getDiscordUser().getId())) return;
+ onlineUid.add(joinRequest.getDiscordUser().getId());
+ WidgetOnline online;
+ columnApi.getValue().addWidget(online = new WidgetOnline(this, joinRequest));
+ widgetList.add(online);
+ }
+
+
+ public void remove(Widget widget) {
+ columnApi.getValue().removeWidget(widget);
+ widgetList.remove(widget);
+
+ if (widget instanceof WidgetOnline)
+ onlineUid.remove(((WidgetOnline) widget).getRelation().getDiscordUser().getId());
+ }
+
+ public void tick() {
+ List<Widget> toRemove = new ArrayList<>();
+ for (Widget widget : widgetList) {
+ TTL ttl = (TTL) widget;
+ if (ttl.startedDisplaying() + ttl.ttl() < System.currentTimeMillis()) {
+ toRemove.add(widget);
+ }
+ }
+ toRemove.forEach(this::remove);
+ }
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/DomElement.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/DomElement.java
index d49589e3..8e1c847a 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/DomElement.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/DomElement.java
@@ -35,6 +35,7 @@ import lombok.Setter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
public class DomElement {
@Getter
@@ -51,7 +52,7 @@ public class DomElement {
@Setter
private DomElement parent;
@Getter
- private List<DomElement> children = new ArrayList<>();
+ private List<DomElement> children = new CopyOnWriteArrayList<>();
@Getter
Context context;
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Clip.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Clip.java
index 1eb52bf4..42ff1c7a 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Clip.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Clip.java
@@ -36,6 +36,8 @@ public class Clip extends AnnotatedExportOnlyWidget implements Renderer {
@Override
public void doRender(int absMouseX, int absMouseY, double relMouseX, double relMouseY, float partialTicks, RenderingContext context, DomElement buildContext) {
if (buildContext.getChildren().isEmpty()) return;
+ if (buildContext.getSize().getWidth() <= 0 || buildContext.getSize().getHeight() <= 0)
+ return;
context.pushClip(buildContext.getAbsBounds(), buildContext.getSize(), 0,0, buildContext.getSize().getWidth(), buildContext.getSize().getHeight());
DomElement value = buildContext.getChildren().get(0);
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Column.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Column.java
index b310e6cf..dc4155b1 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Column.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Column.java
@@ -97,7 +97,7 @@ public class Column extends AnnotatedExportOnlyWidget implements Layouter {
if (!(child.getWidget() instanceof Flexible)) {
Size requiredSize = child.getLayouter().layout(child, new ConstraintBox(
crossAxisAlignment == CrossAxisAlignment.STRETCH
- ? constraints.getMaxWidth() : 0, constraints.getMaxWidth(), 0, Integer.MAX_VALUE
+ ? constraints.getMaxWidth() : 0, constraints.getMaxWidth(), 0, Double.POSITIVE_INFINITY
));
saved.put(child, requiredSize);
width = Math.max(width, requiredSize.getWidth());
@@ -111,13 +111,13 @@ public class Column extends AnnotatedExportOnlyWidget implements Layouter {
int sumFlex = 0;
for (DomElement child : buildContext.getChildren()) {
if (child.getWidget() instanceof Flexible) {
- sumFlex += Math.min(1, ((Flexible) child.getWidget()).flex.getValue());
+ sumFlex += Math.max(1, ((Flexible) child.getWidget()).flex.getValue());
flexFound = true;
}
}
- if (flexFound && effheight == Integer.MAX_VALUE) throw new IllegalStateException("Max height can not be infinite with flex elements");
- else if (effheight == Integer.MAX_VALUE) effheight = height;
+ if (flexFound && effheight == Double.POSITIVE_INFINITY) throw new IllegalStateException("Max height can not be infinite with flex elements");
+ else if (effheight == Double.POSITIVE_INFINITY) effheight = height;
if (flexFound) {
double remainingHeight = effheight - height;
@@ -135,7 +135,7 @@ public class Column extends AnnotatedExportOnlyWidget implements Layouter {
}
}
}
- width = constraints.getMaxWidth() == Integer.MAX_VALUE ? width : constraints.getMaxWidth();
+ width = constraints.getMaxWidth() == Double.POSITIVE_INFINITY ? width : constraints.getMaxWidth();
@@ -198,10 +198,10 @@ public class Column extends AnnotatedExportOnlyWidget implements Layouter {
for (DomElement child : buildContext.getChildren()) {
if (child.getWidget() instanceof Flexible) {
flex += ((Flexible) child.getWidget()).flex.getValue();
- maxPer = Double.max(maxPer, child.getLayouter().getMaxIntrinsicHeight(buildContext, width) /
+ maxPer = Double.max(maxPer, child.getLayouter().getMaxIntrinsicHeight(child, width) /
((Flexible) child.getWidget()).flex.getValue());
} else {
- height += child.getLayouter().getMaxIntrinsicHeight(buildContext, width);
+ height += child.getLayouter().getMaxIntrinsicHeight(child, width);
}
}
return height + maxPer * flex;
@@ -214,8 +214,8 @@ public class Column extends AnnotatedExportOnlyWidget implements Layouter {
int sumFlex = 0;
for (DomElement child : buildContext.getChildren()) {
if (!(child.getWidget() instanceof Flexible)) {
- heightTaken += child.getLayouter().getMaxIntrinsicWidth(buildContext, Double.POSITIVE_INFINITY);
- maxWidth = Double.max(maxWidth, child.getLayouter().getMaxIntrinsicWidth(buildContext, 0));
+ heightTaken += child.getLayouter().getMaxIntrinsicHeight(child, 0);
+ maxWidth = Double.max(maxWidth, child.getLayouter().getMaxIntrinsicWidth(child, 0));
} else {
sumFlex += ((Flexible) child.getWidget()).flex.getValue();
}
@@ -223,9 +223,10 @@ public class Column extends AnnotatedExportOnlyWidget implements Layouter {
double leftOver = height - heightTaken;
if (sumFlex > 0) {
double per = leftOver / sumFlex;
+ if (height == 0) per = 0;
for (DomElement child : buildContext.getChildren()) {
if (child.getWidget() instanceof Flexible) {
- maxWidth = Double.max(maxWidth, child.getLayouter().getMaxIntrinsicWidth(buildContext, per * ((Flexible) child.getWidget()).flex.getValue()));
+ maxWidth = Double.max(maxWidth, child.getLayouter().getMaxIntrinsicWidth(child, per * ((Flexible) child.getWidget()).flex.getValue()));
}
}
}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/ConstrainedBox.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/ConstrainedBox.java
new file mode 100644
index 00000000..e26085c5
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/ConstrainedBox.java
@@ -0,0 +1,102 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2022 cyoung06 (syeyoung)
+ *
+ * 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.mod.guiv2.elements;
+
+import kr.syeyoung.dungeonsguide.mod.guiv2.*;
+import kr.syeyoung.dungeonsguide.mod.guiv2.layouter.Layouter;
+import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.ConstraintBox;
+import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Rect;
+import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Size;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedExportOnlyWidget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Export;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+public class ConstrainedBox extends AnnotatedExportOnlyWidget implements Layouter {
+
+ @Export(attributeName = "minWidth")
+ public final BindableAttribute<Double> minWidth = new BindableAttribute<>(Double.class, 0.0);
+ @Export(attributeName = "minHeight")
+ public final BindableAttribute<Double> minHeight = new BindableAttribute<>(Double.class, 0.0);
+ @Export(attributeName = "maxWidth")
+ public final BindableAttribute<Double> maxWidth = new BindableAttribute<>(Double.class, Double.POSITIVE_INFINITY);
+ @Export(attributeName = "maxHeight")
+ public final BindableAttribute<Double> maxHeight = new BindableAttribute<>(Double.class, Double.POSITIVE_INFINITY);
+
+
+ @Export(attributeName = "$")
+ public final BindableAttribute<Widget> child = new BindableAttribute<>(Widget.class);
+
+
+ @Override
+ public List<Widget> build(DomElement buildContext) {
+ return child.getValue() == null ? Collections.EMPTY_LIST : Collections.singletonList(child.getValue());
+ }
+
+ public ConstrainedBox() {
+ minWidth.addOnUpdate((a, b) -> getDomElement().requestRelayout());
+ minHeight.addOnUpdate((a, b) -> getDomElement().requestRelayout());
+ maxWidth.addOnUpdate((a, b) -> getDomElement().requestRelayout());
+ maxHeight.addOnUpdate((a, b) -> getDomElement().requestRelayout());
+ }
+
+ @Override
+ public Size layout(DomElement buildContext, ConstraintBox constraintBox) {
+
+ double minWidth = Layouter.clamp(this.minWidth.getValue(), constraintBox.getMinWidth(), constraintBox.getMaxWidth());
+ double minHeight = Layouter.clamp(this.minHeight.getValue(), constraintBox.getMinHeight(), constraintBox.getMaxHeight());
+
+ double maxWidth = Layouter.clamp(this.maxWidth.getValue(), constraintBox.getMinWidth(), constraintBox.getMaxWidth());
+ double maxHeight = Layouter.clamp(this.maxHeight.getValue(), constraintBox.getMinHeight(), constraintBox.getMaxHeight());
+
+ if (getDomElement().getChildren().isEmpty()) {
+ return new Size(maxWidth == Double.POSITIVE_INFINITY ? 0 : maxWidth,
+ maxHeight == Double.POSITIVE_INFINITY ? 0 : maxHeight);
+ }
+
+ DomElement child = getDomElement().getChildren().get(0);
+ Size dim = child.getLayouter().layout(child, new ConstraintBox(
+ minWidth, maxWidth, minHeight, maxHeight
+ )); // force size heh.
+ child.setRelativeBound(new Rect(0, 0, dim.getWidth(), dim.getHeight()));
+ return dim;
+ }
+
+ @Override
+ public boolean canCutRequest() {
+ return Objects.equals(minWidth.getValue(), maxWidth.getValue())
+ && Objects.equals(minHeight.getValue(), maxHeight.getValue());
+ }
+
+ @Override
+ public double getMaxIntrinsicHeight(DomElement buildContext, double width) {
+ DomElement child = buildContext.getChildren().get(0);
+ return Layouter.clamp(child.getLayouter().getMaxIntrinsicHeight(child, width),
+ minHeight.getValue() == Double.POSITIVE_INFINITY ? 0 : minHeight.getValue(), maxHeight.getValue());
+ }
+
+ @Override
+ public double getMaxIntrinsicWidth(DomElement buildContext, double height) {
+ DomElement child = buildContext.getChildren().get(0);
+ return Layouter.clamp(child.getLayouter().getMaxIntrinsicWidth(child, height),
+ minWidth.getValue() == Double.POSITIVE_INFINITY ? 0 : minWidth.getValue(), maxWidth.getValue());
+ }
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Flexible.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Flexible.java
index 09c1dcaf..4783b426 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Flexible.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Flexible.java
@@ -32,6 +32,7 @@ import kr.syeyoung.dungeonsguide.mod.guiv2.xml.data.WidgetList;
import java.awt.*;
import java.util.Collections;
import java.util.List;
+import java.util.Optional;
// yes it's that flexible from flutter
public class Flexible extends AnnotatedExportOnlyWidget implements Layouter {
@@ -50,8 +51,8 @@ public class Flexible extends AnnotatedExportOnlyWidget implements Layouter {
}
public Flexible() {
- flex.addOnUpdate((a,b) -> getDomElement().requestRelayout());
- fit.addOnUpdate((a,b) -> getDomElement().requestRelayout());
+ flex.addOnUpdate((a,b) -> Optional.ofNullable(getDomElement().getParent()).ifPresent(DomElement::requestRelayout));
+ fit.addOnUpdate((a,b) -> Optional.ofNullable(getDomElement().getParent()).ifPresent(DomElement::requestRelayout));
}
@Override
@@ -64,8 +65,8 @@ public class Flexible extends AnnotatedExportOnlyWidget implements Layouter {
FlexFit fit = this.fit.getValue();
ConstraintBox box =
fit == FlexFit.TIGHT ?
- new ConstraintBox(constraintBox.getMaxWidth() == Integer.MAX_VALUE ? 0 : constraintBox.getMaxWidth(), constraintBox.getMaxWidth()
- , constraintBox.getMaxHeight() == Integer.MAX_VALUE ? 0 : constraintBox.getMaxHeight(), constraintBox.getMaxHeight())
+ new ConstraintBox(constraintBox.getMaxWidth() == Double.POSITIVE_INFINITY ? 0 : constraintBox.getMaxWidth(), constraintBox.getMaxWidth()
+ , constraintBox.getMaxHeight() == Double.POSITIVE_INFINITY ? 0 : constraintBox.getMaxHeight(), constraintBox.getMaxHeight())
: ConstraintBox.loose(constraintBox.getMaxWidth(), constraintBox.getMaxHeight());
DomElement child = buildContext.getChildren().get(0);
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicHeight.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicHeight.java
index 484e46f7..f821de54 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicHeight.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicHeight.java
@@ -44,7 +44,7 @@ public class IntrinsicHeight extends AnnotatedExportOnlyWidget implements Layout
public Size layout(DomElement buildContext, ConstraintBox constraintBox) {
DomElement elem = buildContext.getChildren().get(0);
double height = elem.getLayouter().getMaxIntrinsicHeight(elem, constraintBox.getMaxWidth() == Double.POSITIVE_INFINITY ? 0 : constraintBox.getMaxWidth());
- Size size = elem.getLayouter().layout(buildContext, new ConstraintBox(
+ Size size = elem.getLayouter().layout(elem, new ConstraintBox(
constraintBox.getMinWidth(), constraintBox.getMaxWidth(), height, height
));
elem.setRelativeBound(new Rect(0,0,size.getWidth(), size.getHeight()));
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicWidth.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicWidth.java
index 9754ec1c..306d366b 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicWidth.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicWidth.java
@@ -44,7 +44,7 @@ public class IntrinsicWidth extends AnnotatedExportOnlyWidget implements Layoute
public Size layout(DomElement buildContext, ConstraintBox constraintBox) {
DomElement elem = buildContext.getChildren().get(0);
double width = elem.getLayouter().getMaxIntrinsicWidth(elem, constraintBox.getMaxHeight() == Double.POSITIVE_INFINITY ? 0 : constraintBox.getMaxHeight());
- Size size = elem.getLayouter().layout(buildContext, new ConstraintBox(
+ Size size = elem.getLayouter().layout(elem, new ConstraintBox(
width, width, constraintBox.getMinHeight(), constraintBox.getMaxHeight()
));
elem.setRelativeBound(new Rect(0,0,size.getWidth(), size.getHeight()));
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Line.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Line.java
index 5f0d0395..32bd97e0 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Line.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Line.java
@@ -123,6 +123,7 @@ public class Line extends AnnotatedExportOnlyWidget implements Layouter, Rendere
GL11.glVertex2d(w/2.0f, h);
}
GL11.glEnd();
+ GlStateManager.enableTexture2D();
if (pattern != null) {
GL11.glDisable(GL11.GL_LINE_STIPPLE);
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Row.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Row.java
index c3539f7c..9843418e 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Row.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Row.java
@@ -98,7 +98,7 @@ public class Row extends AnnotatedExportOnlyWidget implements Layouter {
for (DomElement child : buildContext.getChildren()) {
if (!(child.getWidget() instanceof Flexible)) {
Size requiredSize = child.getLayouter().layout(child, new ConstraintBox(
- 0, Integer.MAX_VALUE,
+ 0, Double.POSITIVE_INFINITY,
crossAxisAlignment == CrossAxisAlignment.STRETCH ? constraintBox.getMaxHeight() : 0, constraintBox.getMaxHeight()
));
saved.put(child, requiredSize);
@@ -112,13 +112,13 @@ public class Row extends AnnotatedExportOnlyWidget implements Layouter {
int sumFlex = 0;
for (DomElement child : buildContext.getChildren()) {
if (child.getWidget() instanceof Flexible) {
- sumFlex += Math.min(1, ((Flexible) child.getWidget()).flex.getValue());
+ sumFlex += Math.max(1, ((Flexible) child.getWidget()).flex.getValue());
flexFound =true;
}
}
- if (flexFound && effwidth == Integer.MAX_VALUE) throw new IllegalStateException("Max width can not be infinite with flex elements");
- else if (effwidth == Integer.MAX_VALUE) effwidth = width;
+ if (flexFound && effwidth == Double.POSITIVE_INFINITY) throw new IllegalStateException("Max width can not be infinite with flex elements");
+ else if (effwidth == Double.POSITIVE_INFINITY) effwidth = width;
if (flexFound) {
double remainingWidth = effwidth - width;
@@ -138,7 +138,7 @@ public class Row extends AnnotatedExportOnlyWidget implements Layouter {
}
- height = constraintBox.getMaxHeight() == Integer.MAX_VALUE ? height : constraintBox.getMaxHeight();
+ height = constraintBox.getMaxHeight() == Double.POSITIVE_INFINITY ? height : constraintBox.getMaxHeight();
@@ -202,8 +202,8 @@ public class Row extends AnnotatedExportOnlyWidget implements Layouter {
int sumFlex = 0;
for (DomElement child : buildContext.getChildren()) {
if (!(child.getWidget() instanceof Flexible)) {
- widthTaken += child.getLayouter().getMaxIntrinsicWidth(buildContext, Double.POSITIVE_INFINITY);
- maxHeight = Double.max(maxHeight, child.getLayouter().getMaxIntrinsicHeight(buildContext, 0));
+ widthTaken += child.getLayouter().getMaxIntrinsicWidth(child, 0);
+ maxHeight = Double.max(maxHeight, child.getLayouter().getMaxIntrinsicHeight(child, 0));
} else {
sumFlex += ((Flexible) child.getWidget()).flex.getValue();
}
@@ -211,9 +211,10 @@ public class Row extends AnnotatedExportOnlyWidget implements Layouter {
double leftOver = width - widthTaken;
if (sumFlex > 0) {
double per = leftOver / sumFlex;
+ if (width == 0) per = 0;
for (DomElement child : buildContext.getChildren()) {
if (child.getWidget() instanceof Flexible) {
- maxHeight = Double.max(maxHeight, child.getLayouter().getMaxIntrinsicHeight(buildContext, per * ((Flexible) child.getWidget()).flex.getValue()));
+ maxHeight = Double.max(maxHeight, child.getLayouter().getMaxIntrinsicHeight(child, per * ((Flexible) child.getWidget()).flex.getValue()));
}
}
}
@@ -228,10 +229,10 @@ public class Row extends AnnotatedExportOnlyWidget implements Layouter {
for (DomElement child : buildContext.getChildren()) {
if (child.getWidget() instanceof Flexible) {
flex += ((Flexible) child.getWidget()).flex.getValue();
- maxPer = Double.max(maxPer, child.getLayouter().getMaxIntrinsicWidth(buildContext, height) /
+ maxPer = Double.max(maxPer, child.getLayouter().getMaxIntrinsicWidth(child, height) /
((Flexible) child.getWidget()).flex.getValue());
} else {
- width += child.getLayouter().getMaxIntrinsicWidth(buildContext, height);
+ width += child.getLayouter().getMaxIntrinsicWidth(child, height);
}
}
return width + maxPer * flex;
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/SizedBox.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/SizedBox.java
deleted file mode 100644
index e06cd20e..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/SizedBox.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2022 cyoung06 (syeyoung)
- *
- * 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.mod.guiv2.elements;
-
-import kr.syeyoung.dungeonsguide.mod.guiv2.*;
-import kr.syeyoung.dungeonsguide.mod.guiv2.layouter.Layouter;
-import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.ConstraintBox;
-import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Rect;
-import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Size;
-import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.SingleChildRenderer;
-import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedExportOnlyWidget;
-import kr.syeyoung.dungeonsguide.mod.guiv2.xml.DomElementRegistry;
-import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Export;
-
-import java.awt.*;
-import java.util.Collections;
-import java.util.List;
-
-public class SizedBox extends AnnotatedExportOnlyWidget implements Layouter {
-
- @Export(attributeName = "width")
- public final BindableAttribute<Double> width = new BindableAttribute<>(Double.class, Double.POSITIVE_INFINITY);
- @Export(attributeName = "height")
- public final BindableAttribute<Double> height = new BindableAttribute<>(Double.class, Double.POSITIVE_INFINITY);
- @Export(attributeName = "$")
- public final BindableAttribute<Widget> child = new BindableAttribute<>(Widget.class);
-
-
- @Override
- public List<Widget> build(DomElement buildContext) {
- return child.getValue() == null ? Collections.EMPTY_LIST : Collections.singletonList(child.getValue());
- }
-
- public SizedBox() {
- width.addOnUpdate((a,b) -> getDomElement().requestRelayout());
- height.addOnUpdate((a,b) -> getDomElement().requestRelayout());
- }
-
- @Override
- public Size layout(DomElement buildContext, ConstraintBox constraintBox) {
-
- double width = Layouter.clamp(this.width.getValue(), constraintBox.getMinWidth(), constraintBox.getMaxWidth());
- double height = Layouter.clamp(this.height.getValue(), constraintBox.getMinHeight(), constraintBox.getMaxHeight());
-
- if (getDomElement().getChildren().isEmpty()) {
- return new Size(width, height);
- }
-
- DomElement child = getDomElement().getChildren().get(0);
- Size dim = child.getLayouter().layout(child, new ConstraintBox(
- width, width, height, height
- )); // force size heh.
- child.setRelativeBound(new Rect(0,0,dim.getWidth(),dim.getHeight()));
- return dim;
- }
-
- @Override
- public boolean canCutRequest() {
- return true;
- }
-
- @Override
- public double getMaxIntrinsicHeight(DomElement buildContext, double width) {
- return this.height.getValue();
- }
-
- @Override
- public double getMaxIntrinsicWidth(DomElement buildContext, double height) {
- return this.width.getValue();
- }
-}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Stack.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Stack.java
index e9f04d13..69060878 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Stack.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Stack.java
@@ -44,6 +44,7 @@ public class Stack extends AnnotatedExportOnlyWidget implements Renderer {
for (int i = buildContext.getChildren().size() - 1; i >= 0; i --) {
DomElement value = buildContext.getChildren().get(i);
Rect original = value.getRelativeBound();
+ if (original == null) return;
GlStateManager.pushMatrix();
GlStateManager.translate(original.getX(), original.getY(), 0);
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java
index 3c5b1a2d..ce12d105 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java
@@ -35,6 +35,7 @@ import net.minecraft.client.renderer.GlStateManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
public class Text extends AnnotatedExportOnlyWidget implements Layouter, Renderer {
@Export(attributeName = "text")
@@ -50,7 +51,7 @@ public class Text extends AnnotatedExportOnlyWidget implements Layouter, Rendere
final int width;
final String text;
}
- public List<WrappedTextData> wrappedTexts = new ArrayList();
+ public List<WrappedTextData> wrappedTexts = new CopyOnWriteArrayList<>();
@Export(attributeName = "font")
public final BindableAttribute<FontRenderer> fontRenderer =new BindableAttribute<>(FontRenderer.class, Minecraft.getMinecraft().fontRendererObj);
@@ -108,7 +109,7 @@ public class Text extends AnnotatedExportOnlyWidget implements Layouter, Rendere
@Override
public Size layout(DomElement buildContext, ConstraintBox constraintBox) {
- wrappedTexts.clear();
+ List<WrappedTextData> wrappedTexts = new ArrayList<>();
FontRenderer fr = fontRenderer.getValue();
String text = this.text.getValue();
@@ -205,7 +206,7 @@ public class Text extends AnnotatedExportOnlyWidget implements Layouter, Rendere
wrappedTexts.add(new WrappedTextData(currentWidth, currentLine.toString()));
}
-
+ this.wrappedTexts = wrappedTexts;
return new Size(hadToWrap ? constraintBox.getMaxWidth() :
Layouter.clamp(maxWidth2, constraintBox.getMinWidth(), constraintBox.getMaxWidth()),
@@ -221,6 +222,8 @@ public class Text extends AnnotatedExportOnlyWidget implements Layouter, Rendere
return max;
}
+ // TODO: incorporate line breaking into
+ // TODO: maybe turn into rich text?
@Override
public double getMaxIntrinsicHeight(DomElement buildContext, double width) {
return this.text.getValue().split("\n").length * (fr.FONT_HEIGHT * lineSpacing.getValue());
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/ImageTexture.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/image/ImageTexture.java
index df3b4043..0e794cc1 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/discord/inviteViewer/ImageTexture.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/image/ImageTexture.java
@@ -1,6 +1,6 @@
/*
* Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
+ * Copyright (C) 2023 cyoung06 (syeyoung)
*
* 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
@@ -16,13 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package kr.syeyoung.dungeonsguide.mod.features.impl.discord.inviteViewer;
+package kr.syeyoung.dungeonsguide.mod.guiv2.elements.image;
import kr.syeyoung.dungeonsguide.mod.DungeonsGuide;
import lombok.Data;
-import lombok.Getter;
-import lombok.Setter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
@@ -95,8 +93,11 @@ public class ImageTexture {
IIOMetadataNode graphicsControlExtensionNode = getNode(root, "GraphicControlExtension");
- delayTime = Integer.parseInt(graphicsControlExtensionNode.getAttribute("delayTime"));
-
+ try {
+ delayTime = Integer.parseInt(graphicsControlExtensionNode.getAttribute("delayTime"));
+ } catch (Exception e) {
+ delayTime = 1000;
+ }
image = new BufferedImage(width, height * frames, dummyFrame.getType());
Graphics2D graphics2D = image.createGraphics();
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/image/URLImage.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/image/URLImage.java
index 05996853..13bc2bae 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/image/URLImage.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/image/URLImage.java
@@ -18,35 +18,19 @@
package kr.syeyoung.dungeonsguide.mod.guiv2.elements.image;
-import kr.syeyoung.dungeonsguide.mod.DungeonsGuide;
-import kr.syeyoung.dungeonsguide.mod.features.impl.discord.inviteViewer.ImageTexture;
import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute;
import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement;
import kr.syeyoung.dungeonsguide.mod.guiv2.Widget;
-import kr.syeyoung.dungeonsguide.mod.guiv2.elements.Flexible;
import kr.syeyoung.dungeonsguide.mod.guiv2.layouter.Layouter;
import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.ConstraintBox;
-import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Rect;
import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Size;
import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.Renderer;
import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.RenderingContext;
import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedExportOnlyWidget;
import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Export;
-import net.minecraft.client.Minecraft;
-import net.minecraft.util.ResourceLocation;
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.function.Consumer;
public class URLImage extends AnnotatedExportOnlyWidget implements Renderer, Layouter {
@Export(attributeName="url")
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/OnlyChildrenRenderer.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/OnlyChildrenRenderer.java
index 42d7e35d..057eeafa 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/OnlyChildrenRenderer.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/OnlyChildrenRenderer.java
@@ -28,6 +28,7 @@ public class OnlyChildrenRenderer implements Renderer {
public void doRender(int absMouseX, int absMouseY, double relMouseX, double relMouseY, float partialTicks, RenderingContext renderingContext, DomElement buildContext) {
for (DomElement value : buildContext.getChildren()) {
Rect original = value.getRelativeBound();
+ if (original == null) continue;
GlStateManager.pushMatrix();
GlStateManager.translate(original.getX(), original.getY(), 0);
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/Renderer.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/Renderer.java
index 6f655916..2c715626 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/Renderer.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/Renderer.java
@@ -30,5 +30,7 @@ public interface Renderer {
* @param pos
* @return
*/
- default Position transformPoint(DomElement element, Position pos) {return new Position(pos.getX() - element.getRelativeBound().getX(), pos.getY() - element.getRelativeBound().getY());}
+ default Position transformPoint(DomElement element, Position pos) {
+ if (element.getRelativeBound() == null) return pos;
+ return new Position(pos.getX() - element.getRelativeBound().getX(), pos.getY() - element.getRelativeBound().getY());}
}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/RenderingContext.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/RenderingContext.java
index 7073e7be..efa46046 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/RenderingContext.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/RenderingContext.java
@@ -90,7 +90,10 @@ public class RenderingContext {
public Stack<Rectangle> clips = new Stack<>();
public void pushClip(Rect absBounds, Size size, double x, double y, double width, double height) {
- if (width < 0 || height < 0) throw new IllegalArgumentException("Clip width height less than 0");
+ if (width < 0 || height < 0) {
+ width = 0;
+ height = 0;
+ }
Rectangle previousClip;
if (clips.size() == 0)
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/SingleChildRenderer.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/SingleChildRenderer.java
index 48fbde81..11067f01 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/SingleChildRenderer.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/renderer/SingleChildRenderer.java
@@ -31,6 +31,7 @@ public class SingleChildRenderer implements Renderer {
DomElement value = buildContext.getChildren().get(0);
Rect original = value.getRelativeBound();
+ if (original == null) return;
GlStateManager.translate(original.getX(), original.getY(), 0);
double absXScale = buildContext.getAbsBounds().getWidth() / buildContext.getSize().getWidth();
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/xml/DomElementRegistry.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/xml/DomElementRegistry.java
index 6d446f32..1ac6c747 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/xml/DomElementRegistry.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/xml/DomElementRegistry.java
@@ -46,7 +46,6 @@ public class DomElementRegistry {
static {
register("stack", new ExportedWidgetConverter(Stack::new));
- register("size", new ExportedWidgetConverter(SizedBox::new));
register("scaler", new ExportedWidgetConverter(Scaler::new));
register("row", new ExportedWidgetConverter(Row::new));
register("padding", new ExportedWidgetConverter(Padding::new));
@@ -60,6 +59,7 @@ public class DomElementRegistry {
register("slot", new ExportedWidgetConverter(Slot::new));
register("clip", new ExportedWidgetConverter(Clip::new));
register("measure", new ExportedWidgetConverter(Measure::new));
+ register("ConstrainedBox", new ExportedWidgetConverter(ConstrainedBox::new));
register("UnconstrainedBox", new ExportedWidgetConverter(UnconstrainedBox::new));
register("absXY", new ExportedWidgetConverter(AbsXY::new));
register("Placeholder", new ExportedWidgetConverter(Placeholder::new));
@@ -73,12 +73,12 @@ public class DomElementRegistry {
register("IntrinsicWidth", new ExportedWidgetConverter(IntrinsicWidth::new));
register("IntrinsicHeight", new ExportedWidgetConverter(IntrinsicHeight::new));
register("TestView", new ExportedWidgetConverter(TestView::new));
-
+
register("ColorButton", new DelegatingWidgetConverter(new ResourceLocation("dungeonsguide:gui/elements/simpleButton.gui")));
register("SimpleHorizontalScrollBar", new DelegatingWidgetConverter(new ResourceLocation("dungeonsguide:gui/elements/simpleHorizontalScrollBar.gui")));
register("SimpleVerticalScrollBar", new DelegatingWidgetConverter(new ResourceLocation("dungeonsguide:gui/elements/simpleVerticalScrollBar.gui")));
register("SlowList", new DelegatingWidgetConverter(new ResourceLocation("dungeonsguide:gui/elements/slowlist.gui")));
-
+ register("size", new DelegatingWidgetConverter(new ResourceLocation("dungeonsguide:gui/elements/size.gui")));
register("ResourceImage", new DelegatingWidgetConverter(new ResourceLocation("dungeonsguide:gui/elements/ratioResourceImage.gui")));
register("UrlImage", new ExportedWidgetConverter(URLImage::new));
}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManager.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManager.java
index 8e38e2a0..4ce5f3aa 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManager.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManager.java
@@ -32,6 +32,7 @@ import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
@@ -90,11 +91,11 @@ public class OverlayManager {
@SubscribeEvent
public void renderGui(GuiScreenEvent.DrawScreenEvent.Post postRender) {
-// if (postRender.gui instanceof GuiChat)
-// view.getContext().CONTEXT.put(OVERLAY_TYPE_KEY, OverlayType.OVER_CHAT);
-// else
-// view.getContext().CONTEXT.put(OVERLAY_TYPE_KEY, OverlayType.OVER_ANY);
-// drawScreen(postRender.renderPartialTicks);
+ if (postRender.gui instanceof GuiChat)
+ view.getContext().CONTEXT.put(OVERLAY_TYPE_KEY, OverlayType.OVER_CHAT);
+ else
+ view.getContext().CONTEXT.put(OVERLAY_TYPE_KEY, OverlayType.OVER_ANY);
+ drawScreen(postRender.renderPartialTicks);
}
@@ -104,6 +105,7 @@ public class OverlayManager {
ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
GlStateManager.pushMatrix();
+ GlStateManager.translate(0,0,50);
GlStateManager.disableDepth();
GlStateManager.enableBlend();
GlStateManager.enableAlpha();
@@ -115,6 +117,7 @@ public class OverlayManager {
GlStateManager.alphaFunc(GL_GREATER, 0.1f);
GlStateManager.popMatrix();
GlStateManager.enableDepth();
+ GlStateManager.enableTexture2D();
GL11.glDisable(GL11.GL_SCISSOR_TEST);
}
@@ -195,7 +198,7 @@ public class OverlayManager {
private int lastX, lastY;
- @SubscribeEvent
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
public void handleMouseInput(GuiScreenEvent.MouseInputEvent.Pre mouseInputEvent) throws IOException {
try {
int i = Mouse.getEventX();
@@ -247,7 +250,7 @@ public class OverlayManager {
}
}
- @SubscribeEvent
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
public void handleKeyboardInput(GuiScreenEvent.KeyboardInputEvent.Pre keyboardInputEvent) throws IOException {
if (Keyboard.getEventKeyState()) {
if (Keyboard.isRepeatEvent())
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManagerRootWidget.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManagerRootWidget.java
index 9d27f0b9..83a8f739 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManagerRootWidget.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManagerRootWidget.java
@@ -38,6 +38,8 @@ public class OverlayManagerRootWidget extends Widget implements Layouter {
}
public void addOverlay(OverlayWidget overlayWidget) {
+ if (getDomElement().getChildren().contains(overlayWidget.getDomElement())) return;
+
DomElement domElement = overlayWidget.createDomElement(getDomElement());
getDomElement().addElement(domElement);
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayWidget.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayWidget.java
index 60d36f98..3ca0e3ba 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayWidget.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayWidget.java
@@ -55,6 +55,7 @@ public class OverlayWidget extends Widget implements Renderer, Layouter {
DomElement value = buildContext.getChildren().get(0);
Rect original = value.getRelativeBound();
+ if (original == null) return;
GlStateManager.translate(original.getX(), original.getY(), 0);
double absXScale = buildContext.getAbsBounds().getWidth() / buildContext.getSize().getWidth();
diff --git a/mod/src/main/resources/assets/dungeonsguide/gui/elements/size.gui b/mod/src/main/resources/assets/dungeonsguide/gui/elements/size.gui
new file mode 100644
index 00000000..6f326058
--- /dev/null
+++ b/mod/src/main/resources/assets/dungeonsguide/gui/elements/size.gui
@@ -0,0 +1,23 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ 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/>.
+ -->
+
+<wrapper width="+Infinity" height="+Infinity">
+ <ConstrainedBox bind:minWidth="width" bind:maxWidth="width" bind:minHeight="height" bind:maxHeight="height">
+ <slot bind:child="$"/>
+ </ConstrainedBox>
+</wrapper> \ No newline at end of file
diff --git a/mod/src/main/resources/assets/dungeonsguide/gui/features/discordOnline/discordOnline.gui b/mod/src/main/resources/assets/dungeonsguide/gui/features/discordOnline/discordOnline.gui
new file mode 100644
index 00000000..1b2bda6b
--- /dev/null
+++ b/mod/src/main/resources/assets/dungeonsguide/gui/features/discordOnline/discordOnline.gui
@@ -0,0 +1,52 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ 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/>.
+ -->
+
+ <padding left="5" right="5" top="2.5" bottom="2.5">
+ <border>
+ <line slot="left" dir="VERTICAL" thickness="1.0" color="#FF23272A"/>
+ <line slot="top" dir="HORIZONTAL" thickness="1.0" color="#FF23272A"/>
+ <line slot="bottom" dir="HORIZONTAL" thickness="1.0" color="#FF23272A"/>
+ <line slot="right" dir="VERTICAL" thickness="1.0" color="#FF23272A"/>
+ <bgcolor slot="content" backgroundColor="#FF2C2F33">
+ <padding left="3" right="3" top="3" bottom="3">
+ <IntrinsicHeight>
+ <IntrinsicWidth>
+ <row>
+ <UrlImage bind:url="avatarUrl"/>
+ <size width="5"></size>
+ <flexible>
+ <col crossAlign="START">
+ <row crossAlign="END">
+ <scaler scale="3.0">
+ <Text bind:text="username" color="#FFFFFFFF"/>
+ </scaler>
+ <Text text="#" color="#FFAAAAAA"/>
+ <Text bind:text="discriminator" color="#FFAAAAAA"/>
+ </row>
+ <size height="5"/>
+ <Text text="started playing with Dungeons Guide!" color="#FFFFFFFF"/>
+ <size height="5"/>
+ </col>
+ </flexible>
+ </row>
+ </IntrinsicWidth>
+ </IntrinsicHeight>
+ </padding>
+ </bgcolor>
+ </border>
+ </padding> \ No newline at end of file
diff --git a/mod/src/main/resources/assets/dungeonsguide/gui/features/discordOnline/discordOnlineList.gui b/mod/src/main/resources/assets/dungeonsguide/gui/features/discordOnline/discordOnlineList.gui
new file mode 100644
index 00000000..3ab3e7f8
--- /dev/null
+++ b/mod/src/main/resources/assets/dungeonsguide/gui/features/discordOnline/discordOnlineList.gui
@@ -0,0 +1,22 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ 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/>.
+ -->
+
+<align hAlign="END" vAlign="START">
+ <col mainAlign="START" crossAlign="END" bind:api="listApi">
+ </col>
+</align>
diff --git a/mod/src/main/resources/assets/dungeonsguide/gui/features/discordParty/invite.gui b/mod/src/main/resources/assets/dungeonsguide/gui/features/discordParty/invite.gui
new file mode 100644
index 00000000..f26c525a
--- /dev/null
+++ b/mod/src/main/resources/assets/dungeonsguide/gui/features/discordParty/invite.gui
@@ -0,0 +1,85 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ 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/>.
+ -->
+
+ <padding left="5" right="5" top="2.5" bottom="2.5">
+ <border>
+ <line slot="left" dir="VERTICAL" thickness="1.0" color="#FF23272A"/>
+ <line slot="top" dir="HORIZONTAL" thickness="1.0" color="#FF23272A"/>
+ <line slot="bottom" dir="HORIZONTAL" thickness="1.0" color="#FF23272A"/>
+ <line slot="right" dir="VERTICAL" thickness="1.0" color="#FF23272A"/>
+ <bgcolor slot="content" backgroundColor="#FF2C2F33">
+ <padding left="3" right="3" top="3" bottom="3">
+ <IntrinsicHeight>
+ <IntrinsicWidth>
+ <row>
+ <UrlImage bind:url="avatarUrl"/>
+ <size width="5"></size>
+ <flexible>
+ <col crossAlign="START">
+ <row crossAlign="END">
+ <scaler scale="3.0">
+ <Text bind:text="username" color="#FFFFFFFF"/>
+ </scaler>
+ <Text text="#" color="#FFAAAAAA"/>
+ <Text bind:text="discriminator" color="#FFAAAAAA"/>
+ </row>
+ <size height="5"/>
+ <Text text="§ewants you to join their party!" color="#FFFFFFFF"/>
+ <size height="5"/>
+ <size height="30">
+ <scaler scale="2.0">
+ <row crossAlign="START">
+ <flexible fit="TIGHT" flex="1">
+ <size/>
+ </flexible>
+ <flexible fit="TIGHT" flex="3">
+ <ColorButton on:click="accept"
+ backgroundColor="#FF7289DA" textColor="#FFFFFFFF"
+ hoveredBackgroundColor="#FF859DF0" hoveredTextColor="#FFFFFFFF"
+ disabledBackgroundColor="0" disabledTextColor="0"
+ pressedBackgroundColor="#FF9BB0FF" pressedTextColor="#FFFFFFFF"
+ text="ACCEPT"
+ />
+ </flexible>
+ <flexible fit="TIGHT" flex="1">
+ <size/>
+ </flexible>
+ <flexible fit="TIGHT" flex="3">
+ <ColorButton on:click="deny"
+ backgroundColor="#FF99AAB5" textColor="#FFFFFFFF"
+ hoveredBackgroundColor="#FFAEC0CB" hoveredTextColor="#FFFFFFFF"
+ disabledBackgroundColor="0" disabledTextColor="0"
+ pressedBackgroundColor="#FFCADDE8" pressedTextColor="#FFFFFFFF"
+ text="DENY"
+ />
+ </flexible>
+ <flexible fit="TIGHT" flex="1">
+ <size/>
+ </flexible>
+ </row>
+ </scaler>
+ </size>
+ </col>
+ </flexible>
+ </row>
+ </IntrinsicWidth>
+ </IntrinsicHeight>
+ </padding>
+ </bgcolor>
+ </border>
+ </padding> \ No newline at end of file
diff --git a/mod/src/main/resources/assets/dungeonsguide/gui/features/discordParty/joinRequest.gui b/mod/src/main/resources/assets/dungeonsguide/gui/features/discordParty/joinRequest.gui
new file mode 100644
index 00000000..7737d947
--- /dev/null
+++ b/mod/src/main/resources/assets/dungeonsguide/gui/features/discordParty/joinRequest.gui
@@ -0,0 +1,97 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ 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/>.
+ -->
+
+ <padding left="5" right="5" top="2.5" bottom="2.5">
+ <border>
+ <line slot="left" dir="VERTICAL" thickness="1.0" color="#FF23272A"/>
+ <line slot="top" dir="HORIZONTAL" thickness="1.0" color="#FF23272A"/>
+ <line slot="bottom" dir="HORIZONTAL" thickness="1.0" color="#FF23272A"/>
+ <line slot="right" dir="VERTICAL" thickness="1.0" color="#FF23272A"/>
+ <bgcolor slot="content" backgroundColor="#FF2C2F33">
+ <padding left="3" right="3" top="3" bottom="3">
+ <IntrinsicHeight>
+ <IntrinsicWidth>
+ <row>
+ <UrlImage bind:url="avatarUrl"/>
+ <size width="5"></size>
+ <flexible>
+ <col crossAlign="START">
+ <row crossAlign="END">
+ <scaler scale="3.0">
+ <Text bind:text="username" color="#FFFFFFFF"/>
+ </scaler>
+ <Text text="#" color="#FFAAAAAA"/>
+ <Text bind:text="discriminator" color="#FFAAAAAA"/>
+ </row>
+ <size height="5"/>
+ <Text text="wants to join your party!" color="#FFFFFFFF"/>
+ <size height="5"/>
+ <size height="30">
+ <scaler scale="2.0">
+ <row crossAlign="START">
+ <flexible fit="TIGHT" flex="1">
+ <size/>
+ </flexible>
+ <flexible fit="TIGHT" flex="3">
+ <ColorButton on:click="accept"
+ backgroundColor="#FF7289DA" textColor="#FFFFFFFF"
+ hoveredBackgroundColor="#FF859DF0" hoveredTextColor="#FFFFFFFF"
+ disabledBackgroundColor="0" disabledTextColor="0"
+ pressedBackgroundColor="#FF9BB0FF" pressedTextColor="#FFFFFFFF"
+ text="ACCEPT"
+ />
+ </flexible>
+ <flexible fit="TIGHT" flex="1">
+ <size/>
+ </flexible>
+ <flexible fit="TIGHT" flex="3">
+ <ColorButton on:click="deny"
+ backgroundColor="#FF99AAB5" textColor="#FFFFFFFF"
+ hoveredBackgroundColor="#FFAEC0CB" hoveredTextColor="#FFFFFFFF"
+ disabledBackgroundColor="0" disabledTextColor="0"
+ pressedBackgroundColor="#FFCADDE8" pressedTextColor="#FFFFFFFF"
+ text="DENY"
+ />
+ </flexible>
+ <flexible fit="TIGHT" flex="1">
+ <size/>
+ </flexible>
+ <flexible fit="TIGHT" flex="3">
+ <ColorButton on:click="ignore"
+ backgroundColor="#FF99AAB5" textColor="#FFFFFFFF"
+ hoveredBackgroundColor="#FFAEC0CB" hoveredTextColor="#FFFFFFFF"
+ disabledBackgroundColor="0" disabledTextColor="0"
+ pressedBackgroundColor="#FFCADDE8" pressedTextColor="#FFFFFFFF"
+ text="Ignore"
+ />
+ </flexible>
+ <flexible fit="TIGHT" flex="1">
+ <size/>
+ </flexible>
+ </row>
+ </scaler>
+ </size>
+ </col>
+ </flexible>
+ </row>
+ </IntrinsicWidth>
+ </IntrinsicHeight>
+ </padding>
+ </bgcolor>
+ </border>
+ </padding> \ No newline at end of file
diff --git a/mod/src/main/resources/assets/dungeonsguide/gui/features/discordParty/partyInviteList.gui b/mod/src/main/resources/assets/dungeonsguide/gui/features/discordParty/partyInviteList.gui
new file mode 100644
index 00000000..0d1d2590
--- /dev/null
+++ b/mod/src/main/resources/assets/dungeonsguide/gui/features/discordParty/partyInviteList.gui
@@ -0,0 +1,22 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ 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/>.
+ -->
+
+<align hAlign="START" vAlign="START">
+ <col mainAlign="START" crossAlign="START" bind:api="listApi">
+ </col>
+</align>