From 7510d292ca8e9e32df8efb6c204f5ece9a00d23a Mon Sep 17 00:00:00 2001
From: TacoMonkey <75862693+TacoMonkey11@users.noreply.github.com>
Date: Tue, 25 Jan 2022 16:31:16 -0500
Subject: Added rich presence and fishing ding

---
 build.gradle                                       |  7 +-
 .../java/me/xmrvizzy/skyblocker/SkyblockerMod.java |  8 ++-
 .../skyblocker/config/SkyblockerConfig.java        | 24 +++++++
 .../skyblocker/mixin/SoundManagerMixin.java        | 27 ++++++++
 .../java/me/xmrvizzy/skyblocker/utils/Discord.java | 74 ++++++++++++++++++++++
 .../java/me/xmrvizzy/skyblocker/utils/Utils.java   | 49 ++++++++++++++
 .../resources/assets/skyblocker/lang/en_us.json    | 10 ++-
 src/main/resources/skyblocker.mixins.json          |  9 +--
 8 files changed, 201 insertions(+), 7 deletions(-)
 create mode 100644 src/main/java/me/xmrvizzy/skyblocker/mixin/SoundManagerMixin.java
 create mode 100644 src/main/java/me/xmrvizzy/skyblocker/utils/Discord.java

diff --git a/build.gradle b/build.gradle
index a05703ab..16fe78a9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -29,6 +29,7 @@ repositories {
         url 'https://repo.maven.apache.org/maven2'
         name 'Maven Central'
     }
+	maven {url "https://jitpack.io"}
 
 }
 
@@ -53,7 +54,11 @@ dependencies {
 
 	// Fabric API. This is technically optional, but you probably want it anyway.
 	modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
-	
+
+	modImplementation("com.github.thatgravyboat:DiscordIPC:d813b27") {
+		exclude module: 'log4j'
+	}
+	include "com.github.thatgravyboat:DiscordIPC:d813b27"
 	// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
 	// You may need to force-disable transitiveness on them.
 }
diff --git a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
index 6c6a6d2a..fac4107a 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
@@ -1,7 +1,9 @@
 package me.xmrvizzy.skyblocker;
 
+import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
 import me.xmrvizzy.skyblocker.container.ContainerSolverManager;
 import me.xmrvizzy.skyblocker.skyblock.dungeon.DungeonBlaze;
+import me.xmrvizzy.skyblocker.utils.Discord;
 import me.xmrvizzy.skyblocker.utils.Utils;
 import net.minecraft.client.MinecraftClient;
 
@@ -35,7 +37,11 @@ public class SkyblockerMod {
         if (ticks % 20 == 0) {
             if (client.world != null && !client.isInSingleplayer())
                 Utils.sbChecker();
-
+            Discord.update();
+            if (Discord.connected){
+                if (SkyblockerConfig.get().general.richPresence.enableRichPresence) Discord.updatePresence(Discord.getInfo(), SkyblockerConfig.get().general.richPresence.customMessage);
+                if (!SkyblockerConfig.get().general.richPresence.enableRichPresence || !Utils.isSkyblock || client.world == null) Discord.stop();
+            }
             ticks = 0;
         }
     }
diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java
index 74cff226..a424ea14 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java
@@ -24,6 +24,10 @@ public class SkyblockerConfig implements ConfigData {
     @ConfigEntry.Gui.TransitiveObject
     public Messages messages = new Messages();
 
+    @ConfigEntry.Category("fishing")
+    @ConfigEntry.Gui.TransitiveObject
+    public Fishing fishing = new Fishing();
+
     public static class General {
         public String apiKey;
 
@@ -31,6 +35,10 @@ public class SkyblockerConfig implements ConfigData {
         @ConfigEntry.Gui.CollapsibleObject(startExpanded = true)
         public Bars bars = new Bars();
 
+        @ConfigEntry.Category("RichPresence")
+        @ConfigEntry.Gui.CollapsibleObject()
+        public RichPresence richPresence = new RichPresence();
+
         @ConfigEntry.Gui.Excluded
         public List<Integer> lockedSlots = new ArrayList<>();
     }
@@ -38,6 +46,13 @@ public class SkyblockerConfig implements ConfigData {
     public static class Bars {
         public boolean enableBars = true;
     }
+    public static class RichPresence {
+        @ConfigEntry.Gui.Tooltip()
+        public boolean enableRichPresence = true;
+        @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+        public Info info = Info.LOCATION;
+        public String customMessage;
+    }
 
     public static class Locations {
         @ConfigEntry.Category("dungeons")
@@ -80,6 +95,15 @@ public class SkyblockerConfig implements ConfigData {
         public boolean hideAds = false;
     }
 
+    public static class Fishing {
+        public boolean enableFishingDing = false;
+    }
+    public enum Info {
+        PIGGY,
+        BITS,
+        LOCATION
+    }
+
     public static void init() {
         AutoConfig.register(SkyblockerConfig.class, GsonConfigSerializer::new);
     }
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/SoundManagerMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/SoundManagerMixin.java
new file mode 100644
index 00000000..94380724
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/SoundManagerMixin.java
@@ -0,0 +1,27 @@
+package me.xmrvizzy.skyblocker.mixin;
+
+
+import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.sound.SoundInstance;
+import net.minecraft.client.sound.SoundManager;
+import net.minecraft.sound.SoundEvents;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(SoundManager.class)
+public class SoundManagerMixin {
+
+    private MinecraftClient client = MinecraftClient.getInstance();
+
+    @Inject(at = @At("HEAD"), method = "play(Lnet/minecraft/client/sound/SoundInstance;)V")
+    private void play(SoundInstance sound, CallbackInfo ci) {
+        if (sound.getId().toString().equals("minecraft:entity.player.splash")){
+            if (client.player.fishHook != null)
+                if (client.player.fishHook.isInOpenWater() && sound.getX() != client.player.getX() && sound.getY() != client.player.getY() && sound.getZ() != client.player.getZ() && SkyblockerConfig.get().fishing.enableFishingDing)
+                    client.player.playSound(SoundEvents.ENTITY_ARROW_HIT_PLAYER, 1, 1);
+        }
+    }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/Discord.java b/src/main/java/me/xmrvizzy/skyblocker/utils/Discord.java
new file mode 100644
index 00000000..e04f2bdd
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/Discord.java
@@ -0,0 +1,74 @@
+package me.xmrvizzy.skyblocker.utils;
+
+import com.jagrosh.discordipc.IPCClient;
+import com.jagrosh.discordipc.IPCListener;
+import com.jagrosh.discordipc.entities.RichPresence;
+import com.jagrosh.discordipc.entities.RichPresenceButton;
+import me.xmrvizzy.skyblocker.SkyblockerMod;
+import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.DecimalFormat;
+
+
+public class Discord {
+    public static Logger logger = LoggerFactory.getLogger(SkyblockerMod.NAMESPACE);
+    public static IPCClient ipcClient = new IPCClient(934607927837356052L);
+    public static boolean connected = false;
+    public static boolean warned = false;
+    public static DecimalFormat dFormat = new DecimalFormat("###,###.##");
+
+
+    public static void updatePresence(String state, String details){
+        logger.debug("updatePresence");
+        RichPresence.Builder builder = new RichPresence.Builder();
+        RichPresenceButton[] button = new RichPresenceButton[0];
+        builder.setState(state)
+                .setDetails(details)
+                .setButtons(button)
+                .setLargeImage("skyblocker-default");
+            ipcClient.sendRichPresence(builder.build());
+    }
+
+    public static String getInfo(){
+        String info = null;
+        if (SkyblockerConfig.get().general.richPresence.info == SkyblockerConfig.Info.BITS) info = "Bits: " + Utils.getBits();
+        if (SkyblockerConfig.get().general.richPresence.info == SkyblockerConfig.Info.PIGGY) info = "Purse: " + dFormat.format(Utils.getPurse());
+        if (SkyblockerConfig.get().general.richPresence.info == SkyblockerConfig.Info.LOCATION) info = "⏣ " + Utils.getLocation();
+        return info;
+    }
+
+    public static void stop(){
+        ipcClient.close();
+        ipcClient = null;
+        connected = false;
+    }
+
+    public static void update(){
+        if (Utils.isSkyblock && SkyblockerConfig.get().general.richPresence.enableRichPresence){
+
+            if (!connected){
+                try {
+                    ipcClient = new IPCClient(934607927837356052L);
+                    ipcClient.connect();
+                    connected = true;
+
+                } catch (Exception e) {
+                    if (!warned){
+                        if (e.getLocalizedMessage().equals("java.net.SocketException: Connection refused"))
+                            logger.warn("Discord client not running");
+                        warned = true;
+                    }
+            }
+        }
+
+        ipcClient.setListener(new IPCListener() {
+            @Override
+            public void onDisconnect(IPCClient client, Throwable t) {
+                IPCListener.super.onDisconnect(client, t);
+                connected = false;
+            }
+        });
+    }
+}}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java b/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java
index 87e5c846..93a28993 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java
@@ -2,6 +2,7 @@ package me.xmrvizzy.skyblocker.utils;
 
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
+import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
 import me.xmrvizzy.skyblocker.skyblock.item.PriceInfoTooltip;
 import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
 import net.minecraft.client.MinecraftClient;
@@ -33,6 +34,7 @@ public class Utils {
                     ItemTooltipCallback.EVENT.register(PriceInfoTooltip::onInjectTooltip);
                 }
                 isSkyblock = true;
+
             }
             else isSkyblock = false;
 
@@ -44,6 +46,53 @@ public class Utils {
         }
     }
 
+    public static String getLocation() {
+        String location = null;
+        List<String> sidebarLines = getSidebar();
+        try{
+            for (int i = 0; i < sidebarLines.size(); i++) {
+                if(sidebarLines.get(i).contains("⏣")) location = sidebarLines.get(i);
+            }
+            location = location.replace('⏣', ' ').strip();
+        } catch (IndexOutOfBoundsException e) {
+            e.printStackTrace();
+        }
+        return location;
+    }
+    public static double getPurse() {
+        String purseString = null;
+        double purse = 0;
+
+        List<String> sidebarLines = getSidebar();
+        try{
+            for (int i = 0; i < sidebarLines.size(); i++) {
+                if(sidebarLines.get(i).contains("Piggy:")) purseString = sidebarLines.get(i);
+                if(sidebarLines.get(i).contains("Purse:")) purseString = sidebarLines.get(i);
+            }
+            if (purseString != null) purse = Double.parseDouble(purseString.replaceAll("[^0-9.]", "").strip());
+            else purse = 0;
+
+        } catch (IndexOutOfBoundsException e) {
+            e.printStackTrace();
+        }
+        return purse;
+    }
+    public static int getBits() {
+        int bits = 0;
+        String bitsString = null;
+        List<String> sidebarLines = getSidebar();
+        try{
+            for (int i = 0; i < sidebarLines.size(); i++) {
+                if(sidebarLines.get(i).contains("Bits")) bitsString = sidebarLines.get(i);
+            }
+            bits = Integer.parseInt(bitsString.replaceAll("Bits:", "").strip());
+        } catch (IndexOutOfBoundsException e) {
+            e.printStackTrace();
+        }
+        return bits;
+    }
+
+
     public static List<String> getSidebar() {
         List<String> lines = new ArrayList<>();
         MinecraftClient client = MinecraftClient.getInstance();
diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json
index 680787e8..0ad63665 100644
--- a/src/main/resources/assets/skyblocker/lang/en_us.json
+++ b/src/main/resources/assets/skyblocker/lang/en_us.json
@@ -9,6 +9,11 @@
   "text.autoconfig.skyblocker.option.general.apiKey": "Hypixel API Key (WIP)",
   "text.autoconfig.skyblocker.option.general.bars": "Health, Mana, Defence & XP Bars",
   "text.autoconfig.skyblocker.option.general.bars.enableBars": "Enable Bars",
+  "text.autoconfig.skyblocker.option.general.richPresence": "Discord Rich Presence",
+  "text.autoconfig.skyblocker.option.general.richPresence.info": "Skyblock Info",
+  "text.autoconfig.skyblocker.option.general.richPresence.enableRichPresence": "Enabled",
+  "text.autoconfig.skyblocker.option.general.richPresence.customMessage": "Custom Message",
+
 
   "text.autoconfig.skyblocker.category.locations": "Locations",
   "text.autoconfig.skyblocker.option.locations.dungeons": "Dungeons",
@@ -32,5 +37,8 @@
   "text.autoconfig.skyblocker.option.messages.hideAOTE": "Hide AOTE Messages",
   "text.autoconfig.skyblocker.option.messages.hideImplosion": "Hide Implosion Message",
   "text.autoconfig.skyblocker.option.messages.hideMoltenWave": "Hide Molten Wave Message",
-  "text.autoconfig.skyblocker.option.messages.hideAds": "Hide Ads From Public Chat"
+  "text.autoconfig.skyblocker.option.messages.hideAds": "Hide Ads From Public Chat",
+
+  "text.autoconfig.skyblocker.category.fishing": "Fishing",
+  "text.autoconfig.skyblocker.option.fishing.enableFishingDing": "Enable Fishing Ding"
 }
\ No newline at end of file
diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json
index abc219fa..7fd36007 100644
--- a/src/main/resources/skyblocker.mixins.json
+++ b/src/main/resources/skyblocker.mixins.json
@@ -3,15 +3,16 @@
   "package": "me.xmrvizzy.skyblocker.mixin",
   "compatibilityLevel": "JAVA_17",
   "client": [
+    "AccessorWorldRenderer",
     "ChatHudListenerMixin",
     "ClientPlayerEntityMixin",
+    "GenericContainerScreenHandlerMixin",
+    "GenericContainerScreenMixin",
     "InGameHudMixin",
     "ItemRendererMixin",
+    "LeverBlockMixin",
     "MinecraftClientMixin",
-    "AccessorWorldRenderer",
-    "GenericContainerScreenMixin",
-    "GenericContainerScreenHandlerMixin",
-    "LeverBlockMixin"
+    "SoundManagerMixin"
   ],
   "injectors": {
     "defaultRequire": 1
-- 
cgit