diff options
author | syeyoung <cyong06@naver.com> | 2021-08-10 23:35:14 +0900 |
---|---|---|
committer | syeyoung <cyong06@naver.com> | 2021-08-10 23:35:14 +0900 |
commit | a48cb5c96e16fae589cb7d4f09146a17b3787924 (patch) | |
tree | f96af8b3c438357dad8ea6e0b223ce5351e82212 /src/main/java/kr/syeyoung/dungeonsguide/features | |
parent | 3f2a8ec601bdc43bbb2a48ef61e372e4c907ce8d (diff) | |
download | Skyblock-Dungeons-Guide-a48cb5c96e16fae589cb7d4f09146a17b3787924.tar.gz Skyblock-Dungeons-Guide-a48cb5c96e16fae589cb7d4f09146a17b3787924.tar.bz2 Skyblock-Dungeons-Guide-a48cb5c96e16fae589cb7d4f09146a17b3787924.zip |
Better Rich Presence
Diffstat (limited to 'src/main/java/kr/syeyoung/dungeonsguide/features')
7 files changed, 727 insertions, 1 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java index ee81ee2f..55e2753b 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java @@ -28,6 +28,8 @@ import kr.syeyoung.dungeonsguide.features.impl.boss.terminal.FeatureSimonSaysSol import kr.syeyoung.dungeonsguide.features.impl.boss.terminal.FeatureTerminalSolvers; import kr.syeyoung.dungeonsguide.features.impl.cosmetics.FeatureNicknameColor; import kr.syeyoung.dungeonsguide.features.impl.cosmetics.FeatureNicknamePrefix; +import kr.syeyoung.dungeonsguide.features.impl.discord.inviteViewer.PartyInviteViewer; +import kr.syeyoung.dungeonsguide.features.impl.discord.onlinealarm.PlayingDGAlarm; import kr.syeyoung.dungeonsguide.features.impl.dungeon.*; import kr.syeyoung.dungeonsguide.features.impl.etc.*; import kr.syeyoung.dungeonsguide.features.impl.etc.ability.FeatureAbilityCooldown; @@ -76,11 +78,15 @@ public class FeatureRegistry { public static final FeatureRoomDebugInfo ADVANCED_DEBUG_ROOM = register(new FeatureRoomDebugInfo()); public static final FeatureDebuggableMap ADVANCED_DEBUGGABLE_MAP = register(new FeatureDebuggableMap()); public static final FeatureRoomCoordDisplay ADVANCED_COORDS = register(new FeatureRoomCoordDisplay()); - public static final SimpleFeature ADVANCED_RICHPRESENCE = register(new SimpleFeature("Misc", "Discord RPC", "Discord rich presence with ASK-TO-JOIN Support!\n\nSimply type /dg asktojoin or /dg atj to toggle whether ask-to-join would be presented as option on discord!", "advanced.richpresence", true) { + + public static final SimpleFeature DISCORD_RICHPRESENCE = register(new SimpleFeature("Discord", "Discord RPC", "Enable Discord rich presence", "advanced.richpresence", true) { { parameters.put("disablenotskyblock", new FeatureParameter<Boolean>("disablenotskyblock", "Disable When not on Skyblock", "Disable When not on skyblock", false, "boolean")); } }); + public static final PartyInviteViewer DISCORD_ASKTOJOIN = register(new PartyInviteViewer()); + public static final PlayingDGAlarm DISCORD_ONLINEALARM = register(new PlayingDGAlarm()); + public static final SimpleFeature SOLVER_RIDDLE = register(new SimpleFeature("Solver.Any Floor", "Riddle", "Highlights the correct box after clicking on all 3 weirdos", "solver.riddle")); public static final SimpleFeature SOLVER_KAHOOT = register(new SimpleFeature("Solver.Floor 4+", "Quiz", "Highlights the correct solution for trivia puzzle", "solver.trivia")); diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/ImageTexture.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/ImageTexture.java new file mode 100644 index 00000000..62ee2913 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/ImageTexture.java @@ -0,0 +1,120 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021 cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.features.impl.discord.inviteViewer; + + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.ResourceLocation; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Iterator; + +@Data +public class ImageTexture { + private String url; + private BufferedImage image; + private DynamicTexture previewTexture; + private ResourceLocation resourceLocation; + + private int width; + private int height; + private int frames; + private int size; + + @Getter @Setter + private int lastFrame = 0; + + public void buildGLThings() { + previewTexture = new DynamicTexture(image); + resourceLocation = Minecraft.getMinecraft().getTextureManager().getDynamicTextureLocation("dgurl/"+url, previewTexture); + } + + public ImageTexture(String url) throws IOException { + this.url = url; + + URL urlObj = new URL(url); + HttpURLConnection huc = (HttpURLConnection) urlObj.openConnection(); + huc.addRequestProperty("User-Agent", "DungeonsGuideMod (dungeons.guide, 1.0)"); + ImageInputStream imageInputStream = ImageIO.createImageInputStream(huc.getInputStream()); + Iterator<ImageReader> readers = ImageIO.getImageReaders(imageInputStream); + if(!readers.hasNext()) throw new IOException("No image reader what" + url); + ImageReader reader = readers.next(); + reader.setInput(imageInputStream); + frames = reader.getNumImages(true); + BufferedImage dummyFrame = reader.read(0); + width = dummyFrame.getWidth(); height = dummyFrame.getHeight(); + + + image = new BufferedImage(width, height * frames, dummyFrame.getType()); + Graphics2D graphics2D = image.createGraphics(); + + for (int i = 0; i < frames; i++) { + BufferedImage bufferedImage = reader.read(i); + graphics2D.drawImage(bufferedImage, 0, i*height, null); + } + reader.dispose(); imageInputStream.close(); huc.disconnect(); + } + + public void drawFrame(int frame, int x, int y, int width, int height) { + if (getResourceLocation() == null) + buildGLThings(); + + TextureManager textureManager = Minecraft.getMinecraft().getTextureManager(); + textureManager.bindTexture(getResourceLocation()); + + GlStateManager.color(1, 1, 1, 1.0F); + + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldrenderer = tessellator.getWorldRenderer(); + worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX); + worldrenderer.pos((double)x, (double)(y + height), 0.0D) + .tex(0,((frame+1) * height)/ ((double)frames * height)).endVertex(); + worldrenderer.pos((double)(x + width), (double)(y + height), 0.0D) + .tex(1, ((frame+1) * height)/ ((double)frames * height)).endVertex(); + worldrenderer.pos((double)(x + width), (double)y, 0.0D) + .tex(1,(frame * height)/ ((double)frames * height)).endVertex(); + worldrenderer.pos((double)x, (double)y, 0.0D) + .tex(0, (frame * height) / ((double)frames * height)).endVertex(); + tessellator.draw(); + } + + public void drawFrameAndIncrement(int x, int y, int width, int height) { + drawFrame(lastFrame, x,y,width,height); + lastFrame++; + if (lastFrame >= frames) lastFrame = 0; + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/PartyInviteViewer.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/PartyInviteViewer.java new file mode 100644 index 00000000..6676eae2 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/PartyInviteViewer.java @@ -0,0 +1,318 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021 cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.features.impl.discord.inviteViewer; + +import kr.syeyoung.dungeonsguide.DungeonsGuide; +import kr.syeyoung.dungeonsguide.events.DiscordUserJoinRequestEvent; +import kr.syeyoung.dungeonsguide.features.SimpleFeature; +import kr.syeyoung.dungeonsguide.features.listener.*; +import kr.syeyoung.dungeonsguide.rpc.RichPresenceManager; +import kr.syeyoung.dungeonsguide.gamesdk.jna.enumuration.EDiscordActivityJoinRequestReply; +import kr.syeyoung.dungeonsguide.utils.TextUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraftforge.client.event.GuiScreenEvent; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL14; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.*; +import java.util.List; +import java.util.concurrent.*; + +public class PartyInviteViewer extends SimpleFeature implements GuiPostRenderListener, ScreenRenderListener, TickListener, GuiClickListener, DiscordUserJoinRequestListener { + 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"); + } + + @Override + public boolean isDisyllable() { + return false; + } + + @Override + public void onGuiPostRender(GuiScreenEvent.DrawScreenEvent.Post rendered) { + renderRequests(true); + } + + @Override + public void drawScreen(float partialTicks) { + try { + renderRequests(false); + } catch (Throwable t) { + t.printStackTrace(); + } + } + @Override + public void onTick() { + 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); + } catch (Throwable e) {e.printStackTrace();} + } + + + @Override + 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); + RichPresenceManager.INSTANCE.respond(joinRequest.getDiscordUser().id, EDiscordActivityJoinRequestReply.DiscordActivityJoinRequestReply_Yes); + return; + } + + if (joinRequest.getDenyRect().contains(mouseX, mouseY)) { + joinRequest.setReply(PartyJoinRequest.Reply.DENY); + joinRequest.setTtl(60); + RichPresenceManager.INSTANCE.respond(joinRequest.getDiscordUser().id, EDiscordActivityJoinRequestReply.DiscordActivityJoinRequestReply_No); + return; + } + + if (joinRequest.getIgnoreRect().contains(mouseX, mouseY)) { + joinRequest.setReply(PartyJoinRequest.Reply.IGNORE); + joinRequest.setTtl(60); + RichPresenceManager.INSTANCE.respond(joinRequest.getDiscordUser().id, EDiscordActivityJoinRequestReply.DiscordActivityJoinRequestReply_Ignore); + return; + } + } else { + if (joinRequest.getAcceptRect().contains(mouseX, mouseY)) { + joinRequest.setReply(PartyJoinRequest.Reply.ACCEPT); + joinRequest.setTtl(60); + RichPresenceManager.INSTANCE.accept(joinRequest.getDiscordUser().id); + 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); + 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/"+Long.toUnsignedString(partyJoinRequest.getDiscordUser().id.longValue())+"/"+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.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(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(); + } + + @Override + public void onDiscordUserJoinRequest(DiscordUserJoinRequestEvent event) { + PartyJoinRequest partyInvite = new PartyJoinRequest(); + partyInvite.setDiscordUser(event.getDiscordUser()); + partyInvite.setExpire(System.currentTimeMillis() + 30000L); + partyInvite.setInvite(event.isInvite()); + joinRequests.add(partyInvite); + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/PartyJoinRequest.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/PartyJoinRequest.java new file mode 100644 index 00000000..b95da68a --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/inviteViewer/PartyJoinRequest.java @@ -0,0 +1,60 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021 cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.features.impl.discord.inviteViewer; + +import kr.syeyoung.dungeonsguide.gamesdk.GameSDK; +import kr.syeyoung.dungeonsguide.gamesdk.jna.datastruct.DiscordUser; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; + +import java.awt.*; + +@Data +public class PartyJoinRequest { + private DiscordUser discordUser; + + public void setDiscordUser(DiscordUser discordUser) { + this.discordUser = discordUser; + username = GameSDK.readString(discordUser.username); + discriminator = GameSDK.readString(discordUser.discriminator); + avatar = GameSDK.readString(discordUser.avatar); + System.out.println(username+"/"+discriminator+"/"+avatar); + } + + 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/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/onlinealarm/PlayingDGAlarm.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/onlinealarm/PlayingDGAlarm.java new file mode 100644 index 00000000..d003b165 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/discord/onlinealarm/PlayingDGAlarm.java @@ -0,0 +1,171 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021 cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.features.impl.discord.onlinealarm; + +import kr.syeyoung.dungeonsguide.DungeonsGuide; +import kr.syeyoung.dungeonsguide.events.DiscordUserUpdateEvent; +import kr.syeyoung.dungeonsguide.features.FeatureRegistry; +import kr.syeyoung.dungeonsguide.features.SimpleFeature; +import kr.syeyoung.dungeonsguide.features.impl.discord.inviteViewer.ImageTexture; +import kr.syeyoung.dungeonsguide.features.listener.DiscordUserUpdateListener; +import kr.syeyoung.dungeonsguide.features.listener.ScreenRenderListener; +import kr.syeyoung.dungeonsguide.features.listener.TickListener; +import kr.syeyoung.dungeonsguide.gamesdk.jna.enumuration.EDiscordRelationshipType; +import kr.syeyoung.dungeonsguide.rpc.JDiscordActivity; +import kr.syeyoung.dungeonsguide.rpc.JDiscordRelation; +import kr.syeyoung.dungeonsguide.utils.TextUtils; +import lombok.AllArgsConstructor; +import lombok.Data; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.texture.TextureManager; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL14; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class PlayingDGAlarm extends SimpleFeature implements DiscordUserUpdateListener, ScreenRenderListener, TickListener { + 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"); + } + private List<PlayerOnline> notif = new CopyOnWriteArrayList<>(); + + @Override + public void onTick() { + 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); + } catch (Throwable e) {e.printStackTrace();} + } + + + + @Override + public void drawScreen(float partialTicks) { + 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(); + online.setEnd(System.currentTimeMillis()+600000); + 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/"+Long.toUnsignedString(online.getJDiscordRelation().getDiscordUser().getId())+"/"+online.getJDiscordRelation().getDiscordUser().getAvatar()+"."+(online.getJDiscordRelation().getDiscordUser().getAvatar().startsWith("a_") ? "gif":"png"); + 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().getUsername()+"", 0,0, 0xFFFFFFFF, true); + GlStateManager.popMatrix(); + + GlStateManager.pushMatrix(); + GlStateManager.translate(fr.getStringWidth(online.getJDiscordRelation().getDiscordUser().getUsername()+"") * 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; + } + + @Override + public void onDiscordUserUpdate(DiscordUserUpdateEvent event) { + JDiscordRelation prev = event.getPrev(), current = event.getCurrent(); + if (!isDisplayable(prev) && isDisplayable(current)) { + notif.add(new PlayerOnline(current, System.currentTimeMillis()+600000)); + } + } + + public boolean isDisplayable(JDiscordRelation jDiscordRelation) { + EDiscordRelationshipType relationshipType = jDiscordRelation.getDiscordRelationshipType(); + if (relationshipType == EDiscordRelationshipType.DiscordRelationshipType_Blocked) return false; + if (relationshipType == EDiscordRelationshipType.DiscordRelationshipType_None) return false; + if (relationshipType == EDiscordRelationshipType.DiscordRelationshipType_PendingIncoming) return false; + if (relationshipType == EDiscordRelationshipType.DiscordRelationshipType_PendingOutgoing) return false; + + JDiscordActivity jDiscordActivity = jDiscordRelation.getDiscordActivity(); + return jDiscordActivity.getApplicationId() == 816298079732498473L; + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/listener/DiscordUserJoinRequestListener.java b/src/main/java/kr/syeyoung/dungeonsguide/features/listener/DiscordUserJoinRequestListener.java new file mode 100644 index 00000000..d48331d5 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/listener/DiscordUserJoinRequestListener.java @@ -0,0 +1,26 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021 cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.features.listener; + +import kr.syeyoung.dungeonsguide.events.DiscordUserJoinRequestEvent; +import kr.syeyoung.dungeonsguide.events.DiscordUserUpdateEvent; + +public interface DiscordUserJoinRequestListener { + void onDiscordUserJoinRequest(DiscordUserJoinRequestEvent event); +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/listener/DiscordUserUpdateListener.java b/src/main/java/kr/syeyoung/dungeonsguide/features/listener/DiscordUserUpdateListener.java new file mode 100644 index 00000000..d376a21d --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/listener/DiscordUserUpdateListener.java @@ -0,0 +1,25 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021 cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.features.listener; + +import kr.syeyoung.dungeonsguide.events.DiscordUserUpdateEvent; + +public interface DiscordUserUpdateListener { + void onDiscordUserUpdate(DiscordUserUpdateEvent event); +} |