0) ? linePrefix + (isInGuild ? guildInfo : "§2They do not appear to be in a guild.") : "")
+// + linePrefix + coinsString
+// + linePrefix + skillAvg + ((config.utilitiesCheckStatsLvlOfDetail > 0) ? ("§r | " + totalAndSlayerXp) : "")
+// + linePrefix + (isCata ? catacombsLvlString + ((config.utilitiesCheckStatsLvlOfDetail > 0) ? dClassesInfo : "") : "§4They have not explored the Catacombs yet.")
+// + ((isCata && config.utilitiesCheckStatsLvlOfDetail == 2) ? linePrefix + essenceString : "")
+// + linePrefix + weightString
+// + linePrefix + activityString
+// + (config.utilitiesCheckStatsLvlOfDetail == 2 ? linePrefix + fairySoulFraction + linePrefix + uuidFromJsonString + linePrefix + profileIdString : "")
+// );
+// if (displayName.equals("Technoblade") || uuidFromJson.contains("b876ec32e396476ba1158438d83c67d4")) {
+// Calendar c = Calendar.getInstance();
+// ChatLib.chat("Please donate to the Sarcoma Foundation of America (https://www.curesarcoma.org/technoblade-tribute/), or buy his memorial merchandise at https://technoblade.com.");
+// if (c.get(Calendar.YEAR) == 2022 && c.get(Calendar.MONTH) == 6) {
+// ChatLib.chat("Make sure you visit Technoblade's memorial at the main Hypixel lobby and speak to the Book Keeper NPC there as well.");
+// }
+// } else if (displayName.equals("SirDesco") || uuidFromJson.contains("e710ff36fe334c0e8401bda9d24fa121")) {
+// ChatLib.chat("Oh look, it's the Synthesis developer!");
+// }
+// if (uuidFromJson.equals(profileId) && config.utilitiesCheckStatsLvlOfDetail == 2) {
+// ChatLib.chat("You may notice that their Minecraft UUID and Skyblock profile ID are the same. Why? Listen, I didn't make the rules, and neither did SkyCrypt devs. Don't ask any of us.");
+// }
+// } catch (Exception e) {
+// if (http.getResponseCode() != 200) {
+// ChatLib.chat("Synthesis did not get an A-OK response from SkyCrypt. The response code Synthesis got instead was " + http.getResponseCode() + ". Aborting mission.");
+// System.out.println("Synthesis did not get an A-OK response from SkyCrypt. The response code Synthesis got instead was " + http.getResponseCode() + ". See below.");
+// } else {
+// ChatLib.chat("Synthesis got information from SkyCrypt, but couldn't successfully parse it. See logs.");
+// System.out.println("Synthesis got information from SkyCrypt, but couldn't successfully parse it. See below.");
+// }
+// e.printStackTrace();
+// return;
+// }
+// } catch (Exception e) {
+// ChatLib.chat("Synthesis ran into a problem checking " + theNameToCheck + "'s weight. See logs.");
+// System.out.println("Synthesis ran into a problem checking " + theNameToCheck + "'s weight. See below.");
+// e.printStackTrace();
+// }
+// }
+// }
diff --git a/src/main/java/com/luna/synthesis/features/utilities/HexatorumUtils.java b/src/main/java/com/luna/synthesis/features/utilities/HexatorumUtils.java
new file mode 100644
index 0000000..d374b72
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/features/utilities/HexatorumUtils.java
@@ -0,0 +1,189 @@
+package com.luna.synthesis.features.utilities;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import com.luna.synthesis.utils.ChatLib;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.lwjgl.opengl.GL11;
+
+public class HexatorumUtils {
+
+ private final Config config = Synthesis.getInstance().getConfig();
+ private final Pattern fractionRegex = Pattern.compile("(?
\\d+)\\/(?\\d+)");
+ private EntityPlayerSP mcgmtp = Minecraft.getMinecraft().thePlayer;
+ private List itemLore = new ArrayList();
+ private ArrayList floats = new ArrayList();
+ private List slots;
+ private String menuName = "";
+ private float r = 0F, g = 0F, floatForArrayList = 0F;
+
+ @SubscribeEvent
+ public void onHexUI(GuiScreenEvent.BackgroundDrawnEvent e) {
+ if (!(config.utilitiesHexatorumOverlay)) return;
+ if ((Minecraft.getMinecraft().thePlayer == null) || !(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) return;
+ menuName = StringUtils.stripControlCodes((((ContainerChest)((GuiChest)(Minecraft.getMinecraft().currentScreen)).inventorySlots).getLowerChestInventory().getDisplayName().getUnformattedText()));
+ if (!(menuName.equals("The Hex"))) return;
+ int aMagicNumber = (((new ScaledResolution(Minecraft.getMinecraft())).getScaledWidth() - 176) / 2);
+ int anotherMagicNumber = (((new ScaledResolution(Minecraft.getMinecraft())).getScaledHeight() - 222) / 2);
+ slots = ((GuiChest)(Minecraft.getMinecraft().currentScreen)).inventorySlots.inventorySlots;
+ for (Slot sl : slots) {
+ boolean colorThisSlot = false;
+ try {if (!(itemLore.isEmpty())) itemLore.clear();} catch (Exception ex) {}
+ if (!(floats.isEmpty())) floats.clear();
+ floatForArrayList = 0F;
+ if (sl.getStack() == null || !(sl.getStack().hasDisplayName())) continue;
+ ItemStack is = sl.getStack();
+ String dName = is.getDisplayName();
+ if (dName.contains("aEnchantments")) {
+ itemLore = is.getTooltip(mcgmtp, false);
+ for (String s : itemLore) {
+ if (s.contains("7Enchantments") && !(s.contains("and"))) {
+ s = StringUtils.stripControlCodes(s);
+ findFracInStrForFloatArrLst(s, false);
+ colorThisSlot = true;
+ }
+ }
+ }
+ if (dName.contains("aUltimate Enchantments")) {
+ itemLore = is.getTooltip(mcgmtp, false);
+ for (String s : itemLore) {
+ s = StringUtils.stripControlCodes(s);
+ if (fractionRegex.matcher(s).find()) {
+ findFracInStrForFloatArrLst(s, false);
+ colorThisSlot = true;
+ }
+ }
+ }
+ if (dName.contains("aReforges")) {
+ itemLore = is.getTooltip(mcgmtp, false);
+ for (String s : itemLore) {
+ s = StringUtils.stripControlCodes(s);
+ if (s.contains("Reforge")) {
+ containsCheckmark(s, false);
+ colorThisSlot = true;
+ }
+ }
+ }
+ if (dName.contains("aModifiers") || dName.contains("aBooks")) {
+ colorThisSlot = true;
+ itemLore = is.getTooltip(mcgmtp, false);
+ for (String s : itemLore) {
+ s = StringUtils.stripControlCodes(s);
+ containsCheckmark(s, true);
+ findFracInStrForFloatArrLst(s, true);
+ }
+ }
+ if (dName.contains("aItem Upgrades")) {
+ colorThisSlot = true;
+ itemLore = is.getTooltip(mcgmtp, false);
+ for (String s : itemLore) {
+ s = StringUtils.stripControlCodes(s);
+ containsCheckmark(s, true);
+ if (s.contains("Upgrade Level")) {
+ s = s.replaceAll(" ","").replace("§7Upgrade Level", "");
+ float currStars = 0F, maxStars = 10F;
+ if (s.contains("➎")) currStars = 10F;
+ else if (s.contains("➍")) currStars = 9F;
+ else if (s.contains("➌")) currStars = 8F;
+ else if (s.contains("➋")) currStars = 7F;
+ else if (s.contains("➊")) currStars = 6F;
+ String[] sa = s.split("§");
+ if (sa.length < 1) return;
+ else for (String str : sa) if (str.endsWith("✪")) currStars++;
+ floats.add(currStars / maxStars);
+ }
+ }
+ }
+ if (dName.contains("aGemstones")) {
+ colorThisSlot = true;
+ itemLore = is.getTooltip(mcgmtp, false);
+ String[] sa = {};
+ for (String s : itemLore) if (s.contains("7Gemstones")) sa = s.split(" ");
+ if (sa.length < 1) return;
+ float filledGemstones = 0, availableGemstones = 0F;
+ for (String sTwo : sa) {
+ if (sTwo.contains("[") && sTwo.contains("]")) {
+ availableGemstones++;
+ if (!(sTwo.contains("8"))) {
+ filledGemstones++;
+ }
+ }
+ }
+ compareFloats(filledGemstones, availableGemstones);
+ }
+ if (!colorThisSlot) continue;
+ if (!(floats.isEmpty())) {
+ for (float f : floats) {
+ if (f >= 1F) f = 1F;
+ floatForArrayList += f;
+ }
+ compareFloats(floatForArrayList, ((float)(floats.size())));
+ }
+ Color bgColor = new Color(((int)(r)), ((int)(g)), (0));
+ if (config.utilitiesHexatorumDebug) {ChatLib.chat(bgColor.toString() + " was selected for item named " + dName);}
+ GL11.glTranslated(0, 0, 1);
+ Gui.drawRect(((aMagicNumber) + sl.xDisplayPosition), ((slots.size() != 90) ? (((anotherMagicNumber) + sl.yDisplayPosition) + ((6 - (slots.size() - 36) / 9) * 9)) : ((anotherMagicNumber) + sl.yDisplayPosition)), (((aMagicNumber) + sl.xDisplayPosition) + 16), (((slots.size() != 90) ? (((anotherMagicNumber) + sl.yDisplayPosition) + ((6 - (slots.size() - 36) / 9) * 9)) : ((anotherMagicNumber) + sl.yDisplayPosition)) + 16), bgColor.getRGB());
+ GL11.glTranslated(0, 0, -1);
+ }
+ }
+
+ private void containsCheckmark(String s, boolean isArrayList) {
+ if (s.contains("✔")) {
+ if (isArrayList){floats.add(1F);}
+ else {g = 255F; r = 0F;}
+ } else if (s.contains("✖")) {
+ if (isArrayList){floats.add(0F);}
+ else {r = 255F; g = 0F;}
+ }
+ }
+
+ private void findFracInStrForFloatArrLst(String s, boolean isArrayList) {
+ if (!(fractionRegex.matcher(s).find())) return;
+ String[] sa = s.split(" ");
+ s = sa[sa.length - 1];
+ float numerator = Float.parseFloat(s.substring(0, s.indexOf("/") + 1).replace("/", ""));
+ float denominator = Float.parseFloat(s.substring(s.indexOf("/"), s.length()).replace("/", ""));
+ if (isArrayList) {
+ if (denominator <= numerator) floats.add(1F);
+ else floats.add((numerator / denominator));
+ } else compareFloats(numerator, denominator);
+ }
+
+ private void compareFloats(float f1, float f2) {
+ if (f1 >= f2) {
+ f1 = f2;
+ g = 255F;
+ r = 0F;
+ } else {
+ float tempFloat = (f1 / f2);
+ if (tempFloat == 0.5F) {
+ r = g = 255F;
+ } else {
+ if (tempFloat > 0.5F) {
+ r = 255 - (tempFloat * 255F);
+ g = 255F;
+ } else {
+ r = 255F;
+ g = (tempFloat * 255F);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/features/utilities/MasterModeSoulDetector.java b/src/main/java/com/luna/synthesis/features/utilities/MasterModeSoulDetector.java
new file mode 100644
index 0000000..dbee247
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/features/utilities/MasterModeSoulDetector.java
@@ -0,0 +1,82 @@
+package com.luna.synthesis.features.utilities;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.event.entity.player.ItemTooltipEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+import org.lwjgl.opengl.GL11;
+
+public class MasterModeSoulDetector {
+ private final Config config = Synthesis.getInstance().getConfig();
+ private int numSouls = 0;
+ private ArrayList whichOnesAreMasterSouls = new ArrayList();
+ private int r,g,b = 0;
+
+ @SubscribeEvent
+ public void onTooltip(ItemTooltipEvent e) {
+ if (!config.utilitiesMasterModeSoulDetection) return;
+ if (e.toolTip == null) return;
+ ItemStack itemStack = e.itemStack;
+ List tooltip = e.toolTip;
+ try {
+ for (String s : tooltip) {
+ if (s.contains("Absorbed Souls")) {
+ findSouls(itemStack);
+ int anchor = tooltip.indexOf(s);
+ for (int h = 0; h < numSouls; h++) if (whichOnesAreMasterSouls.get(h)) tooltip.set(h + 1 + anchor, tooltip.get(h + 1 + anchor) + " §d(from Master Mode)");
+ }
+ }
+ } catch (Exception e) {}
+ }
+
+ @SubscribeEvent
+ public void guiRender(GuiScreenEvent.BackgroundDrawnEvent e) {
+ if (!config.utilitiesMasterModeSoulDetection) return;
+ if (!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) return;
+ if ((!(StringUtils.stripControlCodes(((ContainerChest)(Minecraft.getMinecraft().thePlayer.openContainer)).getLowerChestInventory().getDisplayName().getUnformattedText()).contains("You"))) && (!(StringUtils.stripControlCodes(((ContainerChest)(Minecraft.getMinecraft().thePlayer.openContainer)).getLowerChestInventory().getDisplayName().getUnformattedText()).contains("Auctions:"))) && (!(StringUtils.stripControlCodes(((ContainerChest)(Minecraft.getMinecraft().thePlayer.openContainer)).getLowerChestInventory().getDisplayName().getUnformattedText()).contains("Auction View")))) return;
+ List slots = ((GuiChest)(e.gui)).inventorySlots.inventorySlots;
+ for (Slot s : slots) {
+ int numTrues = 0, numFalses = 0;
+ if (s.getStack() != null) {
+ findSouls(s.getStack());
+ for (boolean bool : whichOnesAreMasterSouls) if (bool) numTrues++; else numFalses++;
+ if (!(whichOnesAreMasterSouls.isEmpty()) && numFalses != whichOnesAreMasterSouls.size()) {
+ if ((numTrues == whichOnesAreMasterSouls.size())) {
+ r = b = 0;
+ g = 255;
+ } else {
+ r = g = 255;
+ b = 0;
+ }
+ Color bgColor = new Color(r, g, b);
+ GL11.glTranslated(0, 0, 1);
+ Gui.drawRect(((((new ScaledResolution(Minecraft.getMinecraft())).getScaledWidth() - 176) / 2) + s.xDisplayPosition), ((slots.size() != 90) ? (((((new ScaledResolution(Minecraft.getMinecraft())).getScaledHeight() - 222) / 2) + s.yDisplayPosition) + ((6 - (slots.size() - 36) / 9) * 9)) : ((((new ScaledResolution(Minecraft.getMinecraft())).getScaledHeight() - 222) / 2) + s.yDisplayPosition)), (((((new ScaledResolution(Minecraft.getMinecraft())).getScaledWidth() - 176) / 2) + s.xDisplayPosition) + 16), (((slots.size() != 90) ? (((((new ScaledResolution(Minecraft.getMinecraft())).getScaledHeight() - 222) / 2) + s.yDisplayPosition) + ((6 - (slots.size() - 36) / 9) * 9)) : ((((new ScaledResolution(Minecraft.getMinecraft())).getScaledHeight() - 222) / 2) + s.yDisplayPosition)) + 16),bgColor.getRGB());
+ GL11.glTranslated(0, 0, -1);
+ }
+ }
+ }
+ }
+
+ private void findSouls(ItemStack is) {
+ if (!config.utilitiesMasterModeSoulDetection) return;
+ if (!(whichOnesAreMasterSouls.isEmpty())) whichOnesAreMasterSouls.clear();
+ if ((!(is.hasTagCompound())) || (is.getSubCompound("ExtraAttributes", false) == null || (!(is.getSubCompound("ExtraAttributes", false).hasKey("necromancer_souls"))))) return;
+ NBTTagList tl = ((NBTTagList)((is.getSubCompound("ExtraAttributes", false)).getTag("necromancer_souls")));
+ if (tl.tagCount() == 0) return;
+ numSouls = tl.tagCount();
+ for (int i = 0; i < numSouls; i++) whichOnesAreMasterSouls.add(tl.get(i).toString().contains("MASTER_"));
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/features/utilities/OccupancyOverlay.java b/src/main/java/com/luna/synthesis/features/utilities/OccupancyOverlay.java
new file mode 100644
index 0000000..afe7398
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/features/utilities/OccupancyOverlay.java
@@ -0,0 +1,173 @@
+package com.luna.synthesis.features.utilities;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.Slot;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.awt.Color;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+import org.lwjgl.opengl.GL11;
+
+/**
+ *
+ * OccupancyOverlay
+ *
+ * A Java class by Erymanthus / RayDeeUx for the Hypixel Skyblock-specific
+ * Minecraft Forge 1.8.9 mod named "Synthesis".
+ *
+ * Ever wondered how full a lobby is? Ever wanted a visual indicator of that metric?
+ * Here you go!
+ *
+ * Originally a feature from SkyblockReinvented by theCudster,
+ * which adapted it from an earlier Hypixel Skyblock mod
+ * named "Nate's Secret Mod" by Nat3z.
+ *
+ * Except this time it doesn't just use the same two or three predefined colors!
+ *
+ * We truly are living in the future.
+ *
+ * @author Erymanthus(#5074) / [u/]RayDeeUx
+ */
+
+public class OccupancyOverlay {
+
+ private final Config config = Synthesis.getInstance().getConfig();
+ private final Pattern playerCapacity = Pattern.compile("(?[1-9][0-9]+)/(?[1-9]+).*");
+ private boolean hasFriend, hasGuildmate, alreadyConnected, couldNotConnect = false;
+ /* alreadyConnected and couldNotConnect are for debugging purposes in case
+ * i ever get back to refining the regex solution */
+ private float r = 0F, g = 0F, b = 0F;
+ private Float currentCapacity = 0F;
+ private Float maxCapacity = 1F; //prevent ArithmeticExceptions
+ private String menuName = "";
+ private String hubName = "";
+ private List itemLore;
+ private List slots;
+ private EntityPlayerSP mcgmtp = Minecraft.getMinecraft().thePlayer;
+
+ @SubscribeEvent
+ public void onGuiScreen(GuiScreenEvent.BackgroundDrawnEvent e) {
+ if (config.utilitiesOccupancyOverlay) {
+ if (mcgmtp != null && Minecraft.getMinecraft().currentScreen instanceof GuiChest) {
+ menuName = StringUtils.stripControlCodes((((ContainerChest)((GuiChest)(Minecraft.getMinecraft().currentScreen)).inventorySlots).getLowerChestInventory().getDisplayName().getUnformattedText()));
+ if (menuName.toLowerCase().contains("skyblock hub") || menuName.toLowerCase().contains("dungeon hub") || menuName.toLowerCase().startsWith("visit")) {
+ slots = ((GuiChest)(Minecraft.getMinecraft().currentScreen)).inventorySlots.inventorySlots;
+ int aMagicNumber = (((new ScaledResolution(Minecraft.getMinecraft())).getScaledWidth() - 176) / 2);
+ int anotherMagicNumber = (((new ScaledResolution(Minecraft.getMinecraft())).getScaledHeight() - 222) / 2);
+ for (Slot s : slots) {
+
+ /* PREVENT CACHING */
+ currentCapacity = 0F;
+ maxCapacity = 1F; //prevent ArithmeticExceptions
+ hubName = "";
+ currentCapacity = 0F;
+ maxCapacity = 1F;
+ hubName = "";
+ hasFriend = hasGuildmate = alreadyConnected = couldNotConnect = false;
+
+ if (s.getStack() != null && s.getStack().hasDisplayName() && !(s.getStack().getDisplayName().toLowerCase().contains(" skyblock hub")) && (s.getStack().getDisplayName().toLowerCase().contains("skyblock hub") || s.getStack().getDisplayName().toLowerCase().contains("dungeon hub") || s.getStack().getDisplayName().toLowerCase().contains("visit player "))) {
+ hubName = StringUtils.stripControlCodes(s.getStack().getDisplayName());
+ itemLore = s.getStack().getTooltip(mcgmtp, false);
+ if (itemLore != null) {
+ for (String line : itemLore) {
+ if (line != null && line.toLowerCase().contains("online friend")) {
+ hasFriend = true;
+ } else if (line != null && line.toLowerCase().contains("online guild")) {
+ hasGuildmate = true;
+ } else if (line != null && (line.toLowerCase().contains("players: "))) {
+ String avoidFalseNegatives = StringUtils.stripControlCodes(line);
+ avoidFalseNegatives = avoidFalseNegatives.replace("Players: ", "");
+ Matcher playerCapacityMatcher = playerCapacity.matcher(avoidFalseNegatives);
+ if (playerCapacityMatcher.find()) {
+ currentCapacity = Float.parseFloat(playerCapacityMatcher.group(1));
+ maxCapacity = Float.parseFloat(playerCapacityMatcher.group(2));
+ } else {
+ //"What the fu...?" - [MCU] Spider-Man, Spider-Man: No Way Home (2021)
+ System.out.println("[Synthesis — DEBUG] For some reason, Synthesis couldn't find the player capacity using regex. Here's the relevant info: Inside the menu named " + menuName + " at item slot " + s.getSlotIndex() + "'s item lore line `" + line + "` at itemLore.indexOf(line) " + itemLore.indexOf(line) + " with hubName " + hubName + ". hasFriend was " + hasFriend + ", hasGuildmate was " + hasGuildmate + ", couldNotConnect was " + couldNotConnect + ", and alreadyConnected was " + alreadyConnected + ". -Erymanthus#5074");
+ System.out.println("[Synthesis — DEBUG] Synthesis is now attempting a failsafe solution using Java's replace() and substring() methods. -Erymanthus#5074");
+ String regexIsFun = avoidFalseNegatives.replace("Players: ", "");
+ currentCapacity = Float.parseFloat(regexIsFun.substring(0, regexIsFun.indexOf("/") + 1).replace("/", ""));
+ maxCapacity = Float.parseFloat(regexIsFun.substring(regexIsFun.indexOf("/"), regexIsFun.length()).replace("/", ""));
+ //So why does Java regex never work 100% of the time? Beats me, but the user shouldn't be punished for it!
+ }
+ if (currentCapacity >= maxCapacity) {
+ currentCapacity = maxCapacity; //prevent java.awt.Color crashes
+ r = 255F;
+ g = b = 0F;
+ break;
+ } else {
+ //"You know what's cooler than magic? Math!" - [MCU] Spider-Man, Spider-Man: No Way Home (2021)
+ if (currentCapacity / maxCapacity == .5F) {
+ r = g = 255F;
+ b = 0F;
+ } else if (currentCapacity / maxCapacity > .5F) {
+ r = 255F;
+ g = 255 - ((currentCapacity / maxCapacity) * 255F);
+ b = 0F;
+ } else {
+ r = ((currentCapacity / maxCapacity) * 255F);
+ g = 255F;
+ b = 0F;
+ }
+ //Instead of predefined RGB values, why not factor current occupancy in to make some degree of yellow?
+ /*Disclaimer: usually not that noticable with skyblock hub selector npc because all hubs are usually close
+ to full, try dungeon hub selector npc for better effect. i swear the code works as intended*/
+ }
+ } else if (config.utilitiesOccupancyOverlayFriendAndGuildHighlght && hasFriend && hasGuildmate) {
+ r = b = 255F;
+ g = 85F;
+ } else if (config.utilitiesOccupancyOverlayFriendHighlght && hasFriend) {
+ r = g = 85F;
+ b = 255F;
+ } else if (config.utilitiesOccupancyOverlayGuildHighlght && hasGuildmate) {
+ r = b = 0F;
+ g = 170F;
+ } else if (line != null && (line.toLowerCase().contains("full") || line.toLowerCase().contains("offline") || line.toLowerCase().contains("doesn't support guests yet") || line.toLowerCase().contains("island disallows guests"))) {
+ r = 255;
+ g = b = 0F;
+ couldNotConnect = true;
+ } else if (line != null && (line.toLowerCase().contains("already "))) {
+ if (config.utilitiesOccupancyOverlayAlreadyConnectedHighlght) {
+ r = 85F;
+ g = b = 255F;
+ }
+ alreadyConnected = true;
+ }
+ }
+ Color bgColor = new Color(((int)(r)), ((int)(g)), ((int)(b)));
+ System.out.println("[Synthesis — DEBUG] Inside the menu named " + menuName + ", the color " + bgColor + " was selected for the hub named " + hubName + " because it was at a capacity of " + currentCapacity + " / " + maxCapacity + " (" + ((currentCapacity/maxCapacity)*100) + "% full) and hasFriend was " + hasFriend + ", hasGuildmate was " + hasGuildmate + ", couldNotConnect was " + couldNotConnect + ", and alreadyConnected was " + alreadyConnected);
+ GL11.glTranslated(0, 0, 1);
+ Gui.drawRect(
+ ((aMagicNumber) + s.xDisplayPosition),
+ ((slots.size() != 90) ?
+ (((anotherMagicNumber) + s.yDisplayPosition) +
+ ((6 - (slots.size() - 36) / 9) * 9)) :
+ ((anotherMagicNumber) + s.yDisplayPosition)),
+ (((aMagicNumber) + s.xDisplayPosition) + 16),
+ (((slots.size() != 90) ?
+ (((anotherMagicNumber) + s.yDisplayPosition) +
+ ((6 - (slots.size() - 36) / 9) * 9)) :
+ ((anotherMagicNumber) + s.yDisplayPosition)) + 16),
+ bgColor.getRGB());
+ GL11.glTranslated(0, 0, -1);
+ }
+ }
+ }
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/features/utilities/PreventDeleteReset.java b/src/main/java/com/luna/synthesis/features/utilities/PreventDeleteReset.java
new file mode 100644
index 0000000..dc98a48
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/features/utilities/PreventDeleteReset.java
@@ -0,0 +1,161 @@
+package com.luna.synthesis.features.utilities;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import com.luna.synthesis.utils.ChatLib;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.client.gui.inventory.GuiContainer;
+import net.minecraft.inventory.Slot;
+import net.minecraft.inventory.ContainerChest;
+
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.List;
+
+import org.lwjgl.input.Mouse;
+
+public class PreventDeleteReset {
+ private final Config config = Synthesis.getInstance().getConfig();
+
+ @SubscribeEvent
+ public void onMouseClick(GuiScreenEvent.MouseInputEvent.Pre e) {
+ boolean isBarry = false, isDiaz = false, isDante = false, isSpecialSus = false;
+ if (!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) return;
+ if (!Mouse.getEventButtonState()) return;
+
+ if (e.gui instanceof GuiContainer) {
+ GuiContainer guiContainer = (GuiContainer) e.gui;
+ if ((Mouse.getEventButton() > -1)) {
+ Slot slot = guiContainer.getSlotUnderMouse();
+
+ if (slot == null) return;
+ if (!slot.getHasStack()) return;
+
+ List itemLore = slot.getStack().getTooltip(Minecraft.getMinecraft().thePlayer, false);
+
+ if ((StringUtils.stripControlCodes(((ContainerChest)(Minecraft.getMinecraft().thePlayer.openContainer)).getLowerChestInventory().getDisplayName().getUnformattedText()).contains("Auction"))) {
+ for (String string : itemLore) {
+ if (string.contains("7Seller: Unknown")) {
+ preventThatClick(e, "buying an auctioned item from an unknown seller", "");
+ break;
+ }
+ }
+ }
+
+ if (config.utilitiesPreventHOTMReset &&
+ (slot.getStack().getDisplayName().toLowerCase()
+ .contains("reset heart of the mountain"))) {
+ preventThatClick(e, "resetting", "HOTM tree");
+ }
+
+ if (config.utilitiesPreventProfileDeletion &&
+ slot.getStack().getDisplayName().toLowerCase()
+ .contains("delete profile")) {
+ preventThatClick(e, "deleting", "Skyblock profile");
+ }
+
+ if (slot.getStack().getDisplayName().toLowerCase()
+ .contains("confirm")) {
+ for (String string : itemLore) {
+ if (string.contains("portal") && config.utilitiesPreventPortalDestruction) {
+ preventThatClick(e, "destroying one of", "island's \"Warp to\" portals");
+ break;
+ }
+ }
+ }
+
+ if (!(StringUtils.stripControlCodes(
+ ((ContainerChest)(Minecraft.getMinecraft().thePlayer.openContainer))
+ .getLowerChestInventory().getDisplayName().getUnformattedText())
+ .contains("Election, Year "))
+ &&
+ !(StringUtils.stripControlCodes(
+ ((ContainerChest)(Minecraft.getMinecraft().thePlayer.openContainer))
+ .getLowerChestInventory().getDisplayName().getUnformattedText())
+ .equals("Election"))) return;
+
+ if (config.utilitiesPreventVotingBarry &&
+ slot.getStack().getDisplayName().toLowerCase()
+ .endsWith("barry") && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("mayor")))) {
+ preventThatClick(e, "voting Barry as", "Skyblock mayor");
+ isBarry = true;
+ }
+
+ if (config.utilitiesPreventVotingDiaz &&
+ slot.getStack().getDisplayName().toLowerCase()
+ .endsWith("diaz") && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("mayor")))) {
+ preventThatClick(e, "voting Diaz as", "Skyblock mayor");
+ isDiaz = true;
+ }
+
+ if ((config.utilitiesPreventVotingDante || config.utilitiesPreventVotingSusSpecialMayors) &&
+ slot.getStack().getDisplayName().toLowerCase()
+ .endsWith("dante") && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("mayor")))) {
+ preventThatClick(e, "voting Dante as", "Skyblock mayor");
+ isDante = true;
+ }
+
+ if ((config.utilitiesPreventVotingSusSpecialMayors) &&
+ slot.getStack().getDisplayName().toLowerCase()
+ .contains("\u00a7d")) {
+ if ((!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("mayor"))) && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("derpy"))) && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("jerry"))) && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("aatrox"))) && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("barry"))) && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("cole"))) && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("diana"))) && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("diaz"))) && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("foxy"))) && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("marina"))) && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("paul"))) && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("scorpius"))) && (!(slot.getStack().getDisplayName().toLowerCase()
+ .contains("technoblade")))) {
+ preventThatClick(e, "voting an unknown special mayor as", "Skyblock mayor");
+ isSpecialSus = true;
+ }
+ }
+
+ if (config.utilitiesPreventVotingXPerkMayors != 1) {
+ String colorCode = slot.getStack().getDisplayName().substring(0, 2);
+ int numPerks = 0;
+ for (String s : itemLore) {
+ s = s.replaceAll("§5§o", "");
+ if (s.startsWith(colorCode) &&
+ !(s.contains("You voted for this candidate!")) &&
+ !(s.contains("Leading in votes!")) &&
+ !(s.contains("Click to vote for ")) &&
+ !(s.startsWith(colorCode + "§"))) {
+ numPerks++;
+ }
+ }
+ if (isBarry || isDiaz || isDante || isSpecialSus) return;
+ if (numPerks < config.utilitiesPreventVotingXPerkMayors) {
+ preventThatClick(e, "voting for " + (StringUtils.stripControlCodes(slot.getStack().getDisplayName())) + " as", "Skyblock mayor because they only have " + numPerks + " perk" + ((numPerks != 1) ? "s" : ""));
+ }
+ }
+ }
+ }
+ }
+
+ private void preventThatClick(GuiScreenEvent.MouseInputEvent.Pre e, String action, String type) {
+ e.setCanceled(true);
+ Minecraft.getMinecraft().thePlayer.playSound("note.bass", 1, ((float)(0.5)));
+ if (type == "" && action == "buying an auctioned item from an unknown seller") {ChatLib.chat("Synthesis has prevented you from buying an auctioned item from an unknown seller, as doing so could cause a loss in coins. There is no config option to disable this."); return;}
+ ChatLib.chat(
+ "Synthesis has prevented you from " + action + " your " + type + ". " +
+ ((action.equals("voting Dante as")) ?
+ "Why would you vote for that dictator again?" :
+ "Check your configs if you actually wanted to do this."
+ )
+ );
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/features/utilities/SearchMode.java b/src/main/java/com/luna/synthesis/features/utilities/SearchMode.java
index fc9bcf3..4ae2407 100644
--- a/src/main/java/com/luna/synthesis/features/utilities/SearchMode.java
+++ b/src/main/java/com/luna/synthesis/features/utilities/SearchMode.java
@@ -1,20 +1,16 @@
package com.luna.synthesis.features.utilities;
-import com.luna.synthesis.Comment;
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
import com.luna.synthesis.mixins.accessors.GuiNewChatAccessor;
-import com.luna.synthesis.utils.ChatLib;
import com.luna.synthesis.utils.MixinUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ChatLine;
import net.minecraft.client.gui.GuiChat;
-import net.minecraft.client.gui.GuiUtilRenderComponents;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
-import net.minecraft.util.IChatComponent;
import net.minecraft.util.MathHelper;
import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -29,7 +25,6 @@ public class SearchMode {
public static boolean isSearchMode = false;
private final Config config = Synthesis.getInstance().getConfig();
- @Comment("Ctrl is 29, f is 33")
@SubscribeEvent
public void onKeyTyped(GuiScreenEvent.KeyboardInputEvent.Pre event) {
if (!(event.gui instanceof GuiChat || (event.gui instanceof GuiContainer && config.utilitiesContainerChat && MixinUtils.inputField != null && MixinUtils.inputField.isFocused()))) return;
@@ -39,33 +34,40 @@ public void onKeyTyped(GuiScreenEvent.KeyboardInputEvent.Pre event) {
if (Keyboard.getEventKey() == 33 && Keyboard.isKeyDown(29)) {
isSearchMode = !isSearchMode;
if (isSearchMode) {
- Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(new ChatComponentText(EnumChatFormatting.YELLOW + "" + EnumChatFormatting.BOLD + "SEARCH MODE ON"), "synthesis".hashCode());
+ ((GuiNewChatAccessor) Minecraft.getMinecraft().ingameGUI.getChatGUI()).invokeSetChatLine(new ChatComponentText(EnumChatFormatting.YELLOW + "" + EnumChatFormatting.BOLD + "SEARCH MODE ON"), "synthesissearchmode".hashCode(), Minecraft.getMinecraft().ingameGUI.getUpdateCounter(), true);
} else {
- Minecraft.getMinecraft().ingameGUI.getChatGUI().deleteChatLine("synthesis".hashCode());
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().deleteChatLine("synthesissearchmode".hashCode());
}
event.setCanceled(true);
if (!isSearchMode) {
Minecraft.getMinecraft().ingameGUI.getChatGUI().refreshChat();
}
} else if (Keyboard.getEventKey() == 1) {
- if (isSearchMode) isSearchMode = false;
- Minecraft.getMinecraft().ingameGUI.getChatGUI().deleteChatLine("synthesis".hashCode());
- Minecraft.getMinecraft().ingameGUI.getChatGUI().refreshChat();
+ if (isSearchMode) {
+ isSearchMode = false;
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().deleteChatLine("synthesissearchmode".hashCode());
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().refreshChat();
+ }
} else if (Keyboard.getEventKey() == 28 && isSearchMode) {
if (!config.utilitiesChatSearchKeyRefresh) {
Minecraft.getMinecraft().ingameGUI.getChatGUI().refreshChat();
+ if (((GuiNewChatAccessor) Minecraft.getMinecraft().ingameGUI.getChatGUI()).getDrawnChatLines().size() == 0) {
+ ((GuiNewChatAccessor) Minecraft.getMinecraft().ingameGUI.getChatGUI()).invokeSetChatLine(new ChatComponentText(EnumChatFormatting.YELLOW + "" + EnumChatFormatting.BOLD + "SEARCH MODE ON"), "synthesissearchmode".hashCode(), Minecraft.getMinecraft().ingameGUI.getUpdateCounter(), true);
+ }
}
event.setCanceled(true);
}
}
- @Comment("Keyboard::getKeyEventState is always false inside a GuiContainer??")
@SubscribeEvent
public void onKeyTypedPost(GuiScreenEvent.KeyboardInputEvent.Post event) {
if (!(event.gui instanceof GuiChat || (event.gui instanceof GuiContainer && config.utilitiesContainerChat && MixinUtils.inputField != null && MixinUtils.inputField.isFocused()))) return;
if (!Keyboard.getEventKeyState() && event.gui instanceof GuiChat) return;
if (config.utilitiesChatSearchKeyRefresh && isSearchMode) {
Minecraft.getMinecraft().ingameGUI.getChatGUI().refreshChat();
+ if (((GuiNewChatAccessor) Minecraft.getMinecraft().ingameGUI.getChatGUI()).getDrawnChatLines().size() == 0) {
+ ((GuiNewChatAccessor) Minecraft.getMinecraft().ingameGUI.getChatGUI()).invokeSetChatLine(new ChatComponentText(EnumChatFormatting.YELLOW + "" + EnumChatFormatting.BOLD + "SEARCH MODE ON"), "synthesissearchmode".hashCode(), Minecraft.getMinecraft().ingameGUI.getUpdateCounter(), true);
+ }
}
}
@@ -88,7 +90,7 @@ public void onMouseClicked(GuiScreenEvent.MouseInputEvent.Pre event) {
}
}
isSearchMode = false;
- Minecraft.getMinecraft().ingameGUI.getChatGUI().deleteChatLine("synthesis".hashCode());
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().deleteChatLine("synthesissearchmode".hashCode());
Minecraft.getMinecraft().ingameGUI.getChatGUI().refreshChat();
Minecraft.getMinecraft().ingameGUI.getChatGUI().resetScroll();
chatLines = ((GuiNewChatAccessor) Minecraft.getMinecraft().ingameGUI.getChatGUI()).getDrawnChatLines();
diff --git a/src/main/java/com/luna/synthesis/features/utilities/Share.java b/src/main/java/com/luna/synthesis/features/utilities/Share.java
new file mode 100644
index 0000000..b5c928c
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/features/utilities/Share.java
@@ -0,0 +1,248 @@
+package com.luna.synthesis.features.utilities;
+
+import com.google.gson.*;
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import com.luna.synthesis.events.MessageSentEvent;
+import com.luna.synthesis.utils.ChatLib;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.GuiChat;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.event.ClickEvent;
+import net.minecraft.event.HoverEvent;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.IChatComponent;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.apache.commons.io.IOUtils;
+import org.lwjgl.input.Mouse;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+//event.setCanceled(true) abused because NO ONE should get muted over using this and going to appeals = going to limbo
+
+public class Share {
+
+ private final Pattern shareRegexPattern = Pattern.compile("\\{SynthesisShare:([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})}", Pattern.CASE_INSENSITIVE);
+ private final Config config = Synthesis.getInstance().getConfig();
+
+ @SubscribeEvent
+ public void onMessageSent(MessageSentEvent event) {
+ String message = event.message;
+ if (message.endsWith(config.utilitiesShareText)) {
+ event.setCanceled(true);
+ doTheMagic(Minecraft.getMinecraft().thePlayer.getHeldItem(), message, config.utilitiesShareText);
+ }
+ /**
+ *
+ * Suggestion #29 by AstroFuture#0932
+ * suggested this before but it disappeared randomly,
+ * in addition to [item], have [helmet], [chestplate],
+ * [leggings] and [boots] to make it easier to show armour
+ * pieces without having to take them off and hold them
+ * which is a pain especially when you have armour pieces
+ * slot bound via neu
+ *
+ */
+ else if (message.endsWith(config.utilitiesShareHelmetText)) {
+ event.setCanceled(true);
+ doTheMagic(Minecraft.getMinecraft().thePlayer.getEquipmentInSlot(4), message, config.utilitiesShareHelmetText);
+ } else if (message.endsWith(config.utilitiesShareChestplateText)) {
+ event.setCanceled(true);
+ doTheMagic(Minecraft.getMinecraft().thePlayer.getEquipmentInSlot(3), message, config.utilitiesShareChestplateText);
+ } else if (message.endsWith(config.utilitiesShareLeggingsText)) {
+ event.setCanceled(true);
+ doTheMagic(Minecraft.getMinecraft().thePlayer.getEquipmentInSlot(2), message, config.utilitiesShareLeggingsText);
+ } else if (message.endsWith(config.utilitiesShareBootsText)) {
+ event.setCanceled(true);
+ doTheMagic(Minecraft.getMinecraft().thePlayer.getEquipmentInSlot(1), message, config.utilitiesShareBootsText);
+ }
+ }
+
+ @SubscribeEvent
+ public void onChatReceived(ClientChatReceivedEvent event) {
+ if (event.type == 0 || event.type == 1) {
+ String msg = StringUtils.stripControlCodes(event.message.getUnformattedText());
+ if (!msg.contains("{SynthesisShare:") || !msg.contains("}")) return;
+
+ Matcher matcher = shareRegexPattern.matcher(msg);
+ event.setCanceled(true);
+
+ (new Thread(() -> {
+ ArrayList shares = new ArrayList<>();
+ while (matcher.find()) {
+ String shareId = matcher.group(1);
+
+ try {
+ URL url = new URL("https://synthesis-share.antonio32a.com/share/" + shareId);
+ HttpURLConnection http = (HttpURLConnection) url.openConnection();
+ http.setDoOutput(true);
+ http.setDoInput(true);
+ http.setRequestProperty("User-Agent", "SynthesisMod");
+ http.setRequestProperty("Accept", "application/json");
+ http.setRequestProperty("Method", "GET");
+ http.connect();
+ try (InputStream instream = http.getInputStream()) {
+ if (http.getResponseCode() != 200) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(event.message);
+ return;
+ }
+ JsonParser parser = new JsonParser();
+ JsonObject shareJson = parser.parse(new String(IOUtils.toByteArray(instream), StandardCharsets.UTF_8)).getAsJsonObject();
+ if (!shareJson.get("success").getAsBoolean()) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(event.message);
+ return;
+ }
+
+ JsonObject shareItem = shareJson.get("share").getAsJsonObject().get("item").getAsJsonObject();
+ String itemName = shareItem.get("name").getAsString();
+ JsonArray itemLore = shareItem.get("lore").getAsJsonArray();
+ boolean isItemVerified = shareJson.get("share").getAsJsonObject().get("verified").getAsBoolean();
+
+ IChatComponent verifiedComponent = new ChatComponentText((isItemVerified ? EnumChatFormatting.GREEN + "✔ " : EnumChatFormatting.RED + "✖ "));
+ verifiedComponent.getChatStyle().setChatHoverEvent(new HoverEvent(
+ HoverEvent.Action.SHOW_TEXT,
+ new ChatComponentText((isItemVerified ? EnumChatFormatting.GREEN + "This item is verified!\nIt exists in the API." : EnumChatFormatting.RED + "This item is not verified!\nAPI is off or the item may not exist."))
+ ));
+
+ AtomicReference s = new AtomicReference<>("");
+ if (shareItem.has("extra")) {
+ if (shareItem.get("extra").getAsJsonObject().has("color")) {
+ s.set(EnumChatFormatting.GRAY + "Color: #" + Integer.toHexString(shareItem.get("extra").getAsJsonObject().get("color").getAsInt()).toUpperCase() + "\n");
+ }
+ }
+ itemLore.iterator().forEachRemaining(jsonElement -> s.set(s.get() + jsonElement.getAsString() + "\n"));
+ String shareLore = itemName + "\n" + s.get();
+
+ IChatComponent shareComponent = new ChatComponentText(EnumChatFormatting.LIGHT_PURPLE
+ + "[Synthesis " + itemName + EnumChatFormatting.LIGHT_PURPLE + "]");
+ shareComponent.getChatStyle().setChatHoverEvent(new HoverEvent(
+ HoverEvent.Action.SHOW_TEXT,
+ new ChatComponentText(shareLore.substring(0, shareLore.length() - 1))
+ )).setChatClickEvent(new ClickEvent(
+ ClickEvent.Action.RUN_COMMAND,
+ "/ctcc https://synthesis-share.antonio32a.com/share/" + shareId + "?embed"
+ ));
+ verifiedComponent.appendSibling(shareComponent);
+ shares.add(verifiedComponent);
+ }
+ } catch (IOException | JsonParseException e) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(event.message);
+ e.printStackTrace();
+ }
+ }
+
+ IChatComponent toSend = new ChatComponentText("");
+ ListIterator it = Arrays.asList(event.message.getFormattedText().split(shareRegexPattern.pattern())).listIterator();
+ while (it.hasNext()) {
+ String s = it.next();
+ toSend.appendSibling(new ChatComponentText(s));
+ if (it.hasNext()) {
+ toSend.appendSibling(shares.get(it.nextIndex() - 1));
+ }
+ }
+
+ Minecraft.getMinecraft().thePlayer.addChatMessage(toSend);
+ })).start();
+
+ }
+ }
+
+ @SubscribeEvent
+ public void onScroll(GuiScreenEvent.MouseInputEvent.Pre event) {
+ if (!config.utilitiesShareScroll) return;
+ if (!GuiScreen.isCtrlKeyDown()) return;
+ if (!(event.gui instanceof GuiChat)) return;
+ int i = Mouse.getEventDWheel();
+ if (i != 0) {
+ IChatComponent comp = Minecraft.getMinecraft().ingameGUI.getChatGUI().getChatComponent(Mouse.getX(), Mouse.getY());
+ if (comp != null && comp.getChatStyle().getChatHoverEvent() != null && comp.getChatStyle().getChatHoverEvent().getAction() == HoverEvent.Action.SHOW_TEXT) {
+ event.setCanceled(true);
+ }
+ }
+ }
+
+ private void doTheMagic(ItemStack itemParam, String messageParam, String whateverWasMatchedParam) {
+ if (itemParam == null || messageParam == null || whateverWasMatchedParam == null) {return;}
+ NBTTagCompound extraAttributes = itemParam.getSubCompound("ExtraAttributes", false);
+ JsonArray loreArray = new JsonArray();
+ NBTTagList lore = itemParam.getSubCompound("display", false).getTagList("Lore", 8);
+ for (int i = 0; i < lore.tagCount(); i++) {
+ loreArray.add(new JsonPrimitive(lore.getStringTagAt(i)));
+ }
+
+ JsonObject itemJson = new JsonObject();
+ itemJson.add("name", new JsonPrimitive(itemParam.getSubCompound("display", false).getString("Name")));
+ itemJson.add("lore", loreArray);
+ JsonObject extraObject = new JsonObject();
+ if (itemParam.hasTagCompound()) {
+ if (itemParam.getTagCompound().hasKey("display")) {
+ if (itemParam.getTagCompound().getCompoundTag("display").hasKey("color")) {
+ extraObject.add("color", new JsonPrimitive(itemParam.getTagCompound().getCompoundTag("display").getInteger("color")));
+ }
+ }
+ }
+ if (extraAttributes != null && extraAttributes.hasKey("uuid")) {
+ itemJson.add("uuid", new JsonPrimitive(extraAttributes.getString("uuid")));
+ }
+
+ itemJson.add("extra", extraObject);
+
+ JsonObject body = new JsonObject();
+ body.add("owner", new JsonPrimitive(Minecraft.getMinecraft().getSession().getPlayerID()));
+ body.add("item", itemJson);
+
+ (new Thread(() -> {
+ try {
+ URL url = new URL("https://synthesis-share.antonio32a.com/share");
+ HttpURLConnection http = (HttpURLConnection) url.openConnection();
+ http.setDoOutput(true);
+ http.setDoInput(true);
+ http.setRequestProperty("Content-Type", "application/json");
+ http.setRequestProperty("User-Agent", "SynthesisMod");
+ http.setRequestProperty("Accept", "application/json");
+ http.setRequestProperty("Method", "POST");
+ http.connect();
+ try (OutputStream os = http.getOutputStream()) {
+ os.write(body.toString().getBytes(StandardCharsets.UTF_8));
+ os.close();
+ if (http.getResponseCode() != 200) {
+ ChatLib.chat("Something went wrong trying to upload share. Check logs maybe?");
+ return;
+ }
+ JsonParser parser = new JsonParser();
+ JsonObject shareJson = parser.parse(IOUtils.toString(http.getInputStream())).getAsJsonObject();
+ if (!shareJson.get("success").getAsBoolean()) {
+ ChatLib.chat("Share was not successful. Reason: " + shareJson.get("error").getAsString());
+ return;
+ }
+
+ String shareId = shareJson.get("share").getAsJsonObject().get("id").getAsString();
+ String share = "{SynthesisShare:" + shareId + "}";
+ //Can't write event.message because this is a thread
+ Minecraft.getMinecraft().thePlayer.sendChatMessage(messageParam.replace(whateverWasMatchedParam, share));
+ ChatLib.chat(messageParam.replace(whateverWasMatchedParam, share));
+ }
+ } catch (IOException e) {
+ ChatLib.chat("Something went wrong trying to upload share. Check logs maybe?");
+ e.printStackTrace();
+ }
+ })).start();
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/features/utilities/ShareParser.java b/src/main/java/com/luna/synthesis/features/utilities/ShareParser.java
deleted file mode 100644
index d2d87f1..0000000
--- a/src/main/java/com/luna/synthesis/features/utilities/ShareParser.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package com.luna.synthesis.features.utilities;
-
-import com.google.gson.JsonArray;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonParser;
-import com.luna.synthesis.utils.ChatLib;
-import net.minecraft.client.Minecraft;
-import net.minecraft.event.HoverEvent;
-import net.minecraft.util.ChatComponentText;
-import net.minecraft.util.EnumChatFormatting;
-import net.minecraft.util.IChatComponent;
-import net.minecraft.util.StringUtils;
-import net.minecraftforge.client.event.ClientChatReceivedEvent;
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class ShareParser {
-
- private final Pattern shareRegex = Pattern.compile("\\{SynthesisShare:([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})}", Pattern.CASE_INSENSITIVE);
-
- @SubscribeEvent
- public void onChatReceived(ClientChatReceivedEvent event) {
- if (event.type == 0 || event.type == 1) {
- String msg = StringUtils.stripControlCodes(event.message.getUnformattedText());
- if (!msg.contains("{SynthesisShare:") || !msg.contains("}")) return;
- Matcher matcher = shareRegex.matcher(msg);
- if (matcher.find() && matcher.groupCount() == 1) {
- String shareId = matcher.group(1);
- String message = event.message.getFormattedText().split(": ")[0] + ": ";
- event.setCanceled(true);
- (new Thread(() -> {
- try {
- HttpClient httpclient = HttpClients.createDefault();
- HttpGet httpGet = new HttpGet("https://synthesis-share.antonio32a.workers.dev/share/" + shareId);
-
- HttpResponse response = httpclient.execute(httpGet);
- HttpEntity entity = response.getEntity();
-
- if (entity != null) {
- try (InputStream instream = entity.getContent()) {
- JsonParser parser = new JsonParser();
- JsonObject shareJson = parser.parse(new String(IOUtils.toByteArray(instream), StandardCharsets.UTF_8)).getAsJsonObject();
- if (!shareJson.get("success").getAsBoolean()) {
- ChatLib.chat("Share was not successful. Reason: " + shareJson.get("error").getAsString());
- return;
- }
- JsonObject shareItem = shareJson.get("share").getAsJsonObject().get("item").getAsJsonObject();
- String itemName = shareItem.get("name").getAsString();
- JsonArray itemLore = shareItem.get("lore").getAsJsonArray();
- boolean isItemVerified = shareJson.get("share").getAsJsonObject().get("verified").getAsBoolean();
- IChatComponent newComp = new ChatComponentText(EnumChatFormatting.LIGHT_PURPLE + "[Synthesis " + itemName + EnumChatFormatting.LIGHT_PURPLE + "]");
- AtomicReference s = new AtomicReference<>("");
- itemLore.iterator().forEachRemaining(jsonElement -> {
- s.set(s.get() + jsonElement.getAsString() + "\n");
- });
- newComp.getChatStyle().setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(s.get())));
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(message + (isItemVerified ? EnumChatFormatting.GREEN + "✔ " : EnumChatFormatting.RED + "✖ ")).appendSibling(newComp));
- } catch (JsonParseException e) {
- ChatLib.chat("Something went wrong trying to read share.");
- e.printStackTrace();
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- })).start();
- }
- }
- }
-}
diff --git a/src/main/java/com/luna/synthesis/features/utilities/TrophyFishingMoment.java b/src/main/java/com/luna/synthesis/features/utilities/TrophyFishingMoment.java
new file mode 100644
index 0000000..8753513
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/features/utilities/TrophyFishingMoment.java
@@ -0,0 +1,81 @@
+package com.luna.synthesis.features.utilities;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.Slot;
+import net.minecraft.util.StringUtils;
+
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.awt.Color;
+import java.util.List;
+
+import org.lwjgl.opengl.GL11;
+
+public class TrophyFishingMoment {
+
+ private final Config config = Synthesis.getInstance().getConfig();
+
+ private float r, g, b = 0F;
+ private String highestTrophyName = "";
+ private List itemLore;
+ private List slots;
+ private int slotIndex = 0;
+
+ @SubscribeEvent
+ public void onGuiScreen(GuiScreenEvent.BackgroundDrawnEvent e) {
+ if (!config.utilitiesTrophyFishingOverlay || Minecraft.getMinecraft().thePlayer == null || !(Minecraft.getMinecraft().currentScreen instanceof GuiChest) || !(StringUtils.stripControlCodes((((ContainerChest)((GuiChest)(Minecraft.getMinecraft().currentScreen)).inventorySlots).getLowerChestInventory().getDisplayName().getUnformattedText())).toLowerCase().contains("trophy fishing"))) return;
+
+ slots = ((GuiChest)(Minecraft.getMinecraft().currentScreen)).inventorySlots.inventorySlots;
+
+ for (Slot s : slots) {
+ highestTrophyName = "";
+ slotIndex = s.getSlotIndex();
+
+ if (slotIndex == 45) break;
+ if ((((slotIndex + 1) % 9) == 0) || (((slotIndex + 1) % 9) == 1) || (slotIndex < 8)) continue;
+
+ if (s.getStack() != null && s.getStack().hasDisplayName() && !(s.getStack().getDisplayName().isEmpty()) && (!(s.getStack().getDisplayName().contains("§c§k")))) {
+ itemLore = s.getStack().getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ for (String line : itemLore) {
+ if (line.contains("a\u2714")) {
+ highestTrophyName = StringUtils.stripControlCodes(line);
+ break;
+ }
+ }
+
+ if (highestTrophyName.contains("Diamond")) {
+ r = 85; b = g = 255;
+ } else if (highestTrophyName.contains("Gold")) {
+ r = 255; b = 0; g = 170;
+ } else if (highestTrophyName.contains("Silver")) {
+ r = b = g = 170;
+ } else if (highestTrophyName.contains("Bronze")) {
+ r = b = g = 85;
+ }
+ Color bgColor = new Color(((int)(r)), ((int)(g)), ((int)(b)));
+ GL11.glTranslated(0, 0, 1);
+ Gui.drawRect(
+ ((((new ScaledResolution(Minecraft.getMinecraft())).getScaledWidth() - 176) / 2) + s.xDisplayPosition),
+ ((slots.size() != 90) ?
+ (((((new ScaledResolution(Minecraft.getMinecraft())).getScaledHeight() - 222) / 2) + s.yDisplayPosition) +
+ ((6 - (slots.size() - 36) / 9) * 9)) :
+ ((((new ScaledResolution(Minecraft.getMinecraft())).getScaledHeight() - 222) / 2) + s.yDisplayPosition)),
+ (((((new ScaledResolution(Minecraft.getMinecraft())).getScaledWidth() - 176) / 2) + s.xDisplayPosition) + 16),
+ (((slots.size() != 90) ?
+ (((((new ScaledResolution(Minecraft.getMinecraft())).getScaledHeight() - 222) / 2) + s.yDisplayPosition) +
+ ((6 - (slots.size() - 36) / 9) * 9)) :
+ ((((new ScaledResolution(Minecraft.getMinecraft())).getScaledHeight() - 222) / 2) + s.yDisplayPosition)) + 16),
+ bgColor.getRGB());
+ GL11.glTranslated(0, 0, -1);
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/features/utilities/VisibleLinks.java b/src/main/java/com/luna/synthesis/features/utilities/VisibleLinks.java
index 1fba8aa..2cdb6da 100644
--- a/src/main/java/com/luna/synthesis/features/utilities/VisibleLinks.java
+++ b/src/main/java/com/luna/synthesis/features/utilities/VisibleLinks.java
@@ -1,5 +1,7 @@
package com.luna.synthesis.features.utilities;
+import java.util.regex.*;
+
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
import net.minecraft.event.ClickEvent;
@@ -13,9 +15,21 @@ public class VisibleLinks {
private final Config config = Synthesis.getInstance().getConfig();
+ private final Pattern domainPattern = Pattern.compile("((https?)://)?[-a-zA-Z0-9+&@#/%?=~_|!:,;]+\\.[-a-zA-Z0-9+&@#/%=~_|]");
+ //modified from the java regex of https://urlregex.com/
+ //it'll still falsely trigger on `...com` but fuck it
+
+ // Low priority so it's compatible with bridge
@SubscribeEvent(priority = EventPriority.LOW)
public void onChatMessage(ClientChatReceivedEvent event) {
if (!config.utilitiesVisibleLinks) return;
+ /**
+ * Suggestion #97 by Doppelclick#5993
+ * make it so that visible links must include top level domains:
+ * https://en.wikipedia.org/wiki/List_of_Internet_top-level_domains,
+ * as currently a simple ... can trigger the feature
+ */
+ if (!domainPattern.matcher(event.message.getUnformattedText()).find()) return;
if (event.type == 0 || event.type == 1) {
for (IChatComponent iChatComponent : event.message.getSiblings()) {
if (iChatComponent.getChatStyle().getChatClickEvent() != null) {
diff --git a/src/main/java/com/luna/synthesis/features/utilities/WishingCompass.java b/src/main/java/com/luna/synthesis/features/utilities/WishingCompass.java
index d52fe51..8fd02d2 100644
--- a/src/main/java/com/luna/synthesis/features/utilities/WishingCompass.java
+++ b/src/main/java/com/luna/synthesis/features/utilities/WishingCompass.java
@@ -1,6 +1,5 @@
package com.luna.synthesis.features.utilities;
-import com.luna.synthesis.Comment;
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
import com.luna.synthesis.events.packet.PacketReceivedEvent;
@@ -13,7 +12,6 @@
import net.minecraft.util.StringUtils;
import net.minecraft.util.Vec3;
import net.minecraftforge.client.ClientCommandHandler;
-import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -22,7 +20,7 @@ public class WishingCompass {
private final Config config = Synthesis.getInstance().getConfig();
private boolean awaiting = false;
- private long lastCompass = -1L;
+ private long lastItem = -1L;
private Vec3 pos1 = null;
private Vec3 pos2 = null;
private Vec3 vec1 = null;
@@ -54,7 +52,6 @@ public void onPacketReceived(PacketReceivedEvent event) {
}
}
- @Comment("Will eventually have something for checking the item's sb id instead of name but ehhhh")
@SubscribeEvent
public void onRightClick(PlayerInteractEvent event) {
if (!config.utilitiesWishingCompass) return;
@@ -62,13 +59,13 @@ public void onRightClick(PlayerInteractEvent event) {
ItemStack item = Minecraft.getMinecraft().thePlayer.getHeldItem();
if (item == null) return;
if (StringUtils.stripControlCodes(item.getDisplayName()).contains("Wishing Compass")) {
- if (config.utilitiesBlockWishingCompass && System.currentTimeMillis() - lastCompass < 4000) {
- ChatLib.chat("Last wishing compass hasn't disappeared yet, chill.");
+ if (config.utilitiesBlockWishingCompass && System.currentTimeMillis() - lastItem < 4000) {
+ ChatLib.chat("Last trail hasn't disappeared yet, chill.");
event.setCanceled(true);
return;
}
awaiting = true;
- lastCompass = System.currentTimeMillis();
+ lastItem = System.currentTimeMillis();
}
}
}
@@ -82,7 +79,9 @@ public void onWorldLoad(WorldEvent.Load event) {
awaiting = false;
}
- @Comment("All math credit in the mod (this included) goes to Lucy. Thank you Lucy!")
+ // All math in the mod is thanks to Lucy, this included, thank you, Lucy!
+ // If you don't understand something don't blame me, I just copied her notes.
+ // And no, you cannot expect me to do very simple math, I will simply ask the math genius when possible.
private void calculateIntercept() {
double a = pos1.xCoord;
double b = pos1.yCoord;
@@ -106,11 +105,11 @@ private void calculateIntercept() {
} else {
BlockPos solution = new BlockPos((a + t * i + h + s * l) / 2, (b + t * j + v + s * m) / 2, (c + t * k + w + s * n) / 2);
if (Math.abs(solution.getX() - 513) < 65 && Math.abs(solution.getZ() - 513) < 65) {
- ChatLib.chat("This compass points to the nucleus! You need to place crystals so the compass points somewhere else.");
+ ChatLib.chat("This compass points to the nucleus! You need to place crystals so the compass points somewhere else. It's also possible that the structure hasn't spawned.");
} else {
ChatLib.chat("Solution: (" + solution.getX() + ", " + solution.getY() + ", " + solution.getZ() + ")");
if (config.utilitiesWishingCompassWaypoint) {
- ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/sthw set WishingCompass " + solution.getX() + " " + solution.getY() + " " + solution.getZ());
+ ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/sthw set " + solution.getX() + " " + solution.getY() + " " + solution.getZ() + " WishingCompass");
}
}
}
diff --git a/src/main/java/com/luna/synthesis/managers/BackpackManager.java b/src/main/java/com/luna/synthesis/managers/BackpackManager.java
index 14fc2ca..67d736a 100644
--- a/src/main/java/com/luna/synthesis/managers/BackpackManager.java
+++ b/src/main/java/com/luna/synthesis/managers/BackpackManager.java
@@ -12,6 +12,7 @@ public class BackpackManager {
private JsonObject jsonObject;
private File file;
+ // Damn this is old and garbage lmao
public BackpackManager(File file) {
if (!file.exists()) {
try {
diff --git a/src/main/java/com/luna/synthesis/mixins/ContainerMixin.java b/src/main/java/com/luna/synthesis/mixins/ContainerMixin.java
new file mode 100644
index 0000000..b3f6c57
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/mixins/ContainerMixin.java
@@ -0,0 +1,80 @@
+package com.luna.synthesis.mixins;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import net.minecraft.client.Minecraft;
+import net.minecraft.inventory.Container;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagInt;
+import net.minecraft.nbt.NBTTagString;
+import net.minecraft.util.StringUtils;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyArg;
+
+@Mixin(Container.class)
+public class ContainerMixin {
+
+ private final Config config = Synthesis.getInstance().getConfig();
+
+ @ModifyArg(method = {"putStackInSlot", "putStacksInSlots"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/inventory/Slot;putStack(Lnet/minecraft/item/ItemStack;)V"))
+ public ItemStack overridePutStack(ItemStack in) {
+ if (!config.utilitiesSuperpairsIDs) return in;
+ if (Minecraft.getMinecraft().thePlayer.openContainer instanceof ContainerChest) {
+ ContainerChest containerChest = (ContainerChest) Minecraft.getMinecraft().thePlayer.openContainer;
+ String title = StringUtils.stripControlCodes(containerChest.getLowerChestInventory().getDisplayName().getUnformattedText());
+ if (!title.startsWith("Superpairs (")) return in;
+ if (in == null) return in;
+ String itemName = StringUtils.stripControlCodes(in.getDisplayName());
+ if (itemName.equals("Experiment the Fish")) return in;
+
+ if (!in.getTagCompound().hasKey("ExtraAttributes")) {
+ in.getTagCompound().setTag("ExtraAttributes", new NBTTagCompound());
+ }
+ NBTTagCompound ea = in.getTagCompound().getCompoundTag("ExtraAttributes");
+
+ if (itemName.startsWith("+")) {
+ if (itemName.endsWith(" Enchanting Exp")) {
+ ea.setTag("id", new NBTTagString("ENCHANTING_EXPERIENCE"));
+ } else if (itemName.endsWith(" XP")) {
+ ea.setTag("id", new NBTTagString("POWER_UP_EXPERIENCE"));
+ }
+ }
+
+ switch (itemName) {
+ case "Gained +3 Clicks":
+ ea.setTag("id", new NBTTagString("POWER_UP_EXTRA_CLICKS"));
+ break;
+ case "Instant Find":
+ ea.setTag("id", new NBTTagString("POWER_UP_INSTANT_FIND"));
+ break;
+ case "Titanic Experience Bottle":
+ ea.setTag("id", new NBTTagString("TITANIC_EXP_BOTTLE"));
+ break;
+ case "Grand Experience Bottle":
+ ea.setTag("id", new NBTTagString("GRAND_EXP_BOTTLE"));
+ break;
+ case "Experience Bottle":
+ ea.setTag("id", new NBTTagString("EXP_BOTTLE"));
+ break;
+ case "Enchanted Book":
+ ea.setTag("id", new NBTTagString("ENCHANTED_BOOK"));
+ ea.setTag("enchantments", new NBTTagCompound());
+ String enchant = StringUtils.stripControlCodes(in.getSubCompound("display", false).getTagList("Lore", 8).getStringTagAt(2));
+ String enchantName = "";
+ for (int i = 0; i < enchant.split(" ").length - 1; i++) {
+ enchantName += enchant.split(" ")[i];
+ if (i != enchant.split(" ").length - 2) {
+ enchantName += "_";
+ }
+ }
+ enchantName = enchantName.toLowerCase();
+ ea.getCompoundTag("enchantments").setTag(enchantName, new NBTTagInt(in.stackSize));
+ break;
+ }
+ }
+ return in;
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/mixins/EntityPlayerSPMixin.java b/src/main/java/com/luna/synthesis/mixins/EntityPlayerSPMixin.java
new file mode 100644
index 0000000..57678a6
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/mixins/EntityPlayerSPMixin.java
@@ -0,0 +1,26 @@
+package com.luna.synthesis.mixins;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.client.gui.GuiChat;
+import net.minecraft.client.gui.GuiScreen;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Redirect;
+
+@Mixin(EntityPlayerSP.class)
+public class EntityPlayerSPMixin {
+
+ private final Config config = Synthesis.getInstance().getConfig();
+
+ // It's possible (and very easy) to make portals never close any gui (since it closes it only clientside, server would not care)
+ // BUT I'm not sure if Hypixel would like that/there's any potential false bans SO only chat for now.
+ @Redirect(method = "onLivingUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiScreen;doesGuiPauseGame()Z"))
+ public boolean overrideDoesGuiPauseGame(GuiScreen gui) {
+ if (config.utilitiesPortalChat) {
+ return gui.doesGuiPauseGame() || gui instanceof GuiChat; //|| gui instanceof GuiContainer;
+ }
+ return gui.doesGuiPauseGame();
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/mixins/GuiContainerMixin.java b/src/main/java/com/luna/synthesis/mixins/GuiContainerMixin.java
index 01e04d5..4af719f 100644
--- a/src/main/java/com/luna/synthesis/mixins/GuiContainerMixin.java
+++ b/src/main/java/com/luna/synthesis/mixins/GuiContainerMixin.java
@@ -3,6 +3,7 @@
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
import com.luna.synthesis.utils.MixinUtils;
+import com.luna.synthesis.utils.ReflectionUtils;
import net.minecraft.client.gui.*;
import net.minecraft.client.gui.inventory.GuiContainer;
import org.spongepowered.asm.mixin.Mixin;
@@ -10,26 +11,17 @@
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import java.util.ArrayList;
-import java.util.List;
-
@Mixin(GuiContainer.class)
public class GuiContainerMixin extends GuiScreen {
private final Config config = Synthesis.getInstance().getConfig();
+ private final boolean patcherClearField = ReflectionUtils.getPatcherChatField();
private GuiTextField inputField;
- private int sentHistoryCursor = -1;
- private boolean playerNamesFound;
- private boolean waitingOnAutocomplete;
- private int autocompleteIndex;
- private final List foundPlayerNames = new ArrayList<>();
- private String historyBuffer = "";
@Inject(method = "initGui", at = @At("RETURN"))
public void initGui(CallbackInfo ci) {
if (config.utilitiesContainerChat) {
- this.sentHistoryCursor = this.mc.ingameGUI.getChatGUI().getSentMessages().size();
this.inputField = new GuiTextField(0, this.fontRendererObj, 4, this.height - 12, this.width - 4, 12);
this.inputField.setMaxStringLength(256);
this.inputField.setEnableBackgroundDrawing(false);
@@ -53,7 +45,9 @@ public void updateScreen(CallbackInfo ci) {
@Inject(method = "drawScreen", at = @At(value = "INVOKE", target = "net/minecraft/client/gui/GuiScreen.drawScreen(IIF)V"))
public void drawScreen(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) {
if (config.utilitiesContainerChat && this.inputField.isFocused()) {
- Gui.drawRect(2, this.height - 14, this.width - 2, this.height - 2, Integer.MIN_VALUE);
+ if (!patcherClearField) {
+ Gui.drawRect(2, this.height - 14, this.width - 2, this.height - 2, Integer.MIN_VALUE);
+ }
this.inputField.drawTextBox();
}
}
diff --git a/src/main/java/com/luna/synthesis/mixins/GuiNewChatMixin.java b/src/main/java/com/luna/synthesis/mixins/GuiNewChatMixin.java
index deb6a04..279b3d4 100644
--- a/src/main/java/com/luna/synthesis/mixins/GuiNewChatMixin.java
+++ b/src/main/java/com/luna/synthesis/mixins/GuiNewChatMixin.java
@@ -1,16 +1,12 @@
package com.luna.synthesis.mixins;
import com.google.common.collect.Lists;
-import com.luna.synthesis.Comment;
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
import com.luna.synthesis.features.utilities.SearchMode;
import com.luna.synthesis.mixins.accessors.GuiChatAccessor;
import com.luna.synthesis.mixins.accessors.GuiContainerAccessor;
-import com.luna.synthesis.utils.ChatLib;
import com.luna.synthesis.utils.MixinUtils;
-import com.luna.synthesis.utils.Utils;
-import com.sun.org.apache.bcel.internal.generic.GETFIELD;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*;
import net.minecraft.client.gui.inventory.GuiContainer;
@@ -18,6 +14,7 @@
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import net.minecraft.util.StringUtils;
+import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.*;
@@ -25,15 +22,16 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
-import java.util.ArrayList;
import java.util.List;
-import java.util.Locale;
@Mixin(GuiNewChat.class)
public abstract class GuiNewChatMixin {
private boolean needsRefresh = false;
- @Shadow private final List chatLines = Lists.newArrayList();
+ @Final @Shadow private final List chatLines = Lists.newArrayList();
+ @Final @Shadow private final List drawnChatLines = Lists.newArrayList();
+ @Shadow public abstract void deleteChatLine(int id);
+ @Shadow protected abstract void setChatLine(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly);
private final Config config = Synthesis.getInstance().getConfig();
@Inject(method = "clearChatMessages", at = @At(value = "INVOKE", target = "Ljava/util/List;clear()V", ordinal = 2), cancellable = true)
@@ -65,7 +63,7 @@ public void getChatOpen(CallbackInfoReturnable cir) {
}
}
- @Comment("Walmart solution to not having continue inside mixins. Kind of a cool mixin, prevents lag with a ton of chat lines when trying to search.")
+ // A way to "continue" in loops from inside a mixin. Kinda proud of this one ngl, fixes lag when searching for a lot of lines, mostly with Patcher's void chat.
@ModifyVariable(method = "refreshChat", at = @At(value = "INVOKE", target = "Ljava/util/List;get(I)Ljava/lang/Object;", shift = At.Shift.BEFORE), index = 1)
public int i(int in) {
GuiScreen gui = Minecraft.getMinecraft().currentScreen;
@@ -88,7 +86,7 @@ public int i(int in) {
return in;
}
- @Comment("And here's the failsafe to be able to 'continue' in the last iteration of the loop")
+ // This just here so it's possible to "continue" in the last iteration of the loop
@Inject(method = "refreshChat", at = @At(value = "INVOKE", target = "Ljava/util/List;get(I)Ljava/lang/Object;"), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
public void refreshChat(CallbackInfo ci, int i) {
if (i == -1) {
@@ -107,4 +105,49 @@ public void setChatLine(IChatComponent chatComponent, int chatLineId, int update
}
}
}
+
+ // The section below is used so the SEARCH MODE ON message always stays at the bottom of the chat
+
+ // Fix for refreshChat deleting messages with same id? For no reason either??
+ // If you're not using the mod, go to a hub and tab player's names so the message of potential players shows up
+ // Then, go to chat options and modify any setting, like opacity, doesn't matter if end value is the same, it just has to be changed
+ // THE MESSAGE WILL DISAPPEAR, FOR NO REASON EITHER, WHAT THE FWICK
+ @Redirect(method = "setChatLine", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiNewChat;deleteChatLine(I)V"))
+ public void deleteChatLine(GuiNewChat chat, int id, IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly) {
+ if (!displayOnly) {
+ this.deleteChatLine(id);
+ }
+ }
+
+ @ModifyArg(method = "setChatLine", at = @At(value = "INVOKE", target = "Ljava/util/List;add(ILjava/lang/Object;)V", ordinal = 0))
+ public int modifyIndex(int in, Object line) {
+ ChatLine cl = (ChatLine) line;
+ if (SearchMode.isSearchMode && !cl.getChatComponent().getFormattedText().contains(EnumChatFormatting.YELLOW + "" + EnumChatFormatting.BOLD + "SEARCH MODE ON")) {
+ if (this.drawnChatLines.size() == 0) {
+ this.deleteChatLine("synthesissearchmode".hashCode());
+ this.setChatLine(new ChatComponentText(EnumChatFormatting.YELLOW + "" + EnumChatFormatting.BOLD + "SEARCH MODE ON"), "synthesissearchmode".hashCode(), Minecraft.getMinecraft().ingameGUI.getUpdateCounter(), true);
+ }
+ return 1;
+ }
+ return in;
+ }
+
+ // For reforge message cleanup - There's probably a better way to do this, but I'm blind
+ // Also regexes wack, you know how it goes with me and regexes
+ @ModifyArg(method = "printChatMessage", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiNewChat;printChatMessageWithOptionalDeletion(Lnet/minecraft/util/IChatComponent;I)V"), index = 1)
+ public int overrideChatId(IChatComponent chatComponent, int in) {
+ if (config.cleanupChatOldReforgeMessages) {
+ String msg = StringUtils.stripControlCodes(chatComponent.getUnformattedText());
+ // Why must I be punished like this.
+ // What have I done to deserve this.
+ // Luna from the future (10 minutes after starting to code this): I should have done this with like 5 regexes holy shit this is annoying
+ // I have no clue what I did here, but I indeed regret it now, months after the fact, now that I have to change this.
+ if ((msg.startsWith("You reforged your ") && msg.contains(" into a ") && msg.endsWith("!")) ||
+ (msg.startsWith("You applied the ") && msg.contains(" reforge to your ") && msg.endsWith("!")) ||
+ (msg.startsWith("You selected the ") && msg.endsWith(" power for your Accessory Bag!"))) {
+ return "synthesisreforgemessagecleanup".hashCode();
+ }
+ }
+ return in;
+ }
}
diff --git a/src/main/java/com/luna/synthesis/mixins/GuiPlayerTabOverlayMixin.java b/src/main/java/com/luna/synthesis/mixins/GuiPlayerTabOverlayMixin.java
new file mode 100644
index 0000000..0e3433e
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/mixins/GuiPlayerTabOverlayMixin.java
@@ -0,0 +1,37 @@
+package com.luna.synthesis.mixins;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import net.minecraft.client.gui.GuiPlayerTabOverlay;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.IChatComponent;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyVariable;
+
+@Mixin(GuiPlayerTabOverlay.class)
+public class GuiPlayerTabOverlayMixin {
+
+ private final Config config = Synthesis.getInstance().getConfig();
+
+ // mhm tasty spaghetti
+
+ @ModifyVariable(method = "setFooter", at = @At("HEAD"), argsOnly = true)
+ public IChatComponent overrideFooter(IChatComponent in) {
+ if (config.cleanupTablistFooter) {
+ String s = in.getFormattedText()
+ .replace("\n§r§r§r§r§s§r\n§r§r§aRanks, Boosters & MORE! §r§c§lSTORE.HYPIXEL.NET§r", "")
+ .replace("§r§aRanks, Boosters & MORE! §r§c§lSTORE.HYPIXEL.NET§r", "");
+ return s.length() == 0 ? null : new ChatComponentText(s);
+ }
+ return in;
+ }
+
+ @ModifyVariable(method = "setHeader", at = @At("HEAD"), argsOnly = true)
+ public IChatComponent overrideHeader(IChatComponent in) {
+ if (config.cleanupTablistHeader) {
+ return null;
+ }
+ return in;
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/mixins/GuiScreenMixin.java b/src/main/java/com/luna/synthesis/mixins/GuiScreenMixin.java
new file mode 100644
index 0000000..d3f5566
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/mixins/GuiScreenMixin.java
@@ -0,0 +1,37 @@
+package com.luna.synthesis.mixins;
+
+import com.luna.synthesis.events.MessageSentEvent;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraftforge.common.MinecraftForge;
+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.ModifyVariable;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(GuiScreen.class)
+public class GuiScreenMixin {
+
+ private String newMessage = "";
+
+ @Inject(method = "sendChatMessage(Ljava/lang/String;)V", at = @At("HEAD"), cancellable = true)
+ public void onMessageSent(String message, CallbackInfo ci) {
+ MessageSentEvent event = new MessageSentEvent(message);
+ MinecraftForge.EVENT_BUS.post(event);
+
+ if (event.isCanceled()) {
+ ci.cancel();
+ } else if (!event.message.equals(message)) {
+ newMessage = event.message;
+ }
+ }
+
+ @ModifyVariable(method = "sendChatMessage(Ljava/lang/String;)V", at = @At("HEAD"))
+ public String overrideMessageSent(String msg) {
+ if (!newMessage.equals("")) {
+ msg = newMessage;
+ newMessage = "";
+ }
+ return msg;
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/mixins/RenderItemMixin.java b/src/main/java/com/luna/synthesis/mixins/RenderItemMixin.java
index 89aa212..c47135c 100644
--- a/src/main/java/com/luna/synthesis/mixins/RenderItemMixin.java
+++ b/src/main/java/com/luna/synthesis/mixins/RenderItemMixin.java
@@ -1,9 +1,9 @@
package com.luna.synthesis.mixins;
-import com.luna.synthesis.Comment;
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
import com.luna.synthesis.managers.BackpackManager;
+import com.luna.synthesis.utils.ChatLib;
import com.luna.synthesis.utils.MixinUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
@@ -11,16 +11,19 @@
import net.minecraft.client.renderer.ItemModelMesher;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.resources.model.IBakedModel;
+import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.ContainerChest;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.StringUtils;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Iterator;
+import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@Mixin(RenderItem.class)
@@ -28,7 +31,7 @@ public class RenderItemMixin {
private final Config config = Synthesis.getInstance().getConfig();
- @Comment("Might make these two mixins onto a forge event because they're very cool")
+ // Might make these two onto a forge event because they're very cool
@Redirect(method = "renderItemIntoGUI", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ItemModelMesher;getItemModel(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/client/resources/model/IBakedModel;"))
public IBakedModel iBakedModel(ItemModelMesher imm, ItemStack stack) {
String name = StringUtils.stripControlCodes(stack.getDisplayName());
@@ -45,6 +48,7 @@ public IBakedModel iBakedModel(ItemModelMesher imm, ItemStack stack) {
@Inject(method = "renderItemOverlayIntoGUI", at = @At(value = "JUMP", ordinal = 1, shift = At.Shift.BEFORE), cancellable = true)
public void renderItemOverlayIntoGUI(FontRenderer fr, ItemStack stack, int xPosition, int yPosition, String text, CallbackInfo ci) {
if (Minecraft.getMinecraft().thePlayer.openContainer instanceof ContainerChest) {
+ if (stack.getItem() == Item.getItemFromBlock(Blocks.glass_pane)) return;
ContainerChest containerChest = (ContainerChest) Minecraft.getMinecraft().thePlayer.openContainer;
String title = StringUtils.stripControlCodes(containerChest.getLowerChestInventory().getDisplayName().getUnformattedText());
if (config.utilitiesPerkLevelDisplay && title.equals("Heart of the Mountain")) {
@@ -59,13 +63,14 @@ public void renderItemOverlayIntoGUI(FontRenderer fr, ItemStack stack, int xPosi
level = level.split("/")[0];
}
if (level.equals("1")) return;
- drawStringAsStackSize(level, xPosition, yPosition);
+ drawAsStackSize(level, xPosition, yPosition);
ci.cancel();
}
} else if (config.utilitiesBestiaryGlance && (title.equals("Bestiary") || title.contains(" ➜ "))) {
- if (StringUtils.stripControlCodes(stack.getDisplayName()).startsWith("Bestiary Milestone ")) {
- String level = StringUtils.stripControlCodes(stack.getDisplayName()).replace("Bestiary Milestone ", "");
- drawStringAsStackSize(level, xPosition, yPosition);
+ String dName = stack.getDisplayName();
+ if (StringUtils.stripControlCodes(dName).startsWith("Bestiary Milestone ")) {
+ String level = StringUtils.stripControlCodes(dName).replace("Bestiary Milestone ", "");
+ drawAsStackSize(level, xPosition, yPosition);
ci.cancel();
} else if (stack == containerChest.getInventory().get(52)) {
ItemStack bestiary = containerChest.getInventory().get(51);
@@ -79,20 +84,248 @@ public void renderItemOverlayIntoGUI(FontRenderer fr, ItemStack stack, int xPosi
}
});
if (progress.get().equals("")) return;
- drawStringAsStackSize(progress.get(), xPosition, yPosition);
+ drawAsStackSize(progress.get(), xPosition, yPosition);
ci.cancel();
}
+ } else if (config.utilitiesShowCollectionStackSize && (title.contains(" Collection"))) {
+ String[] splitStr = StringUtils.stripControlCodes(stack.getDisplayName()).split(" ");
+ if (splitStr.length < 1) return;
+ String romanNumeral = splitStr[(splitStr.length - 1)];
+ if (!((romanNumeral.contains("I") || romanNumeral.contains("V") || romanNumeral.contains("X") || romanNumeral.contains("L") || romanNumeral.contains("C") || romanNumeral.contains("D") || romanNumeral.contains("M")))) return;
+ if ((stack.getDisplayName().contains(" Minion"))) return;
+ int finalResult = 0;
+ //BRUTEFORCE CONVERSION.
+ //I SURE AS FUCK GOT NO TIME TO WRITE THAT ROMAN TO ARABIC NUMERAL CONVERSION FUNCTION.
+ //S_A_D ISTG IF YOU SCREENSHOT THIS I WILL COMMIT COPIOUS AMOUNTS OF VIDEO GAME CRIMES -ERY
+ if (romanNumeral.equals("I")) finalResult = 1; else if (romanNumeral.equals("II")) finalResult = 2; else if (romanNumeral.equals("III")) finalResult = 3; else if (romanNumeral.equals("IV")) finalResult = 4; else if (romanNumeral.equals("V")) finalResult = 5; else if (romanNumeral.equals("VI")) finalResult = 6; else if (romanNumeral.equals("VII")) finalResult = 7; else if (romanNumeral.equals("VIII")) finalResult = 8; else if (romanNumeral.equals("IX")) finalResult = 9; else if (romanNumeral.equals("X")) finalResult = 10; else if (romanNumeral.equals("XI")) finalResult = 11; else if (romanNumeral.equals("XII")) finalResult = 12; else if (romanNumeral.equals("XIII")) finalResult = 13; else if (romanNumeral.equals("XIV")) finalResult = 14; else if (romanNumeral.equals("XV")) finalResult = 15; else if (romanNumeral.equals("XVI")) finalResult = 16; else if (romanNumeral.equals("XVII")) finalResult = 17; else if (romanNumeral.equals("XVIII")) finalResult = 18; else if (romanNumeral.equals("XIX")) finalResult = 19; else if (romanNumeral.equals("XX")) finalResult = 20; else return;
+ drawAsStackSize(finalResult, xPosition, yPosition);
+ ci.cancel();
+ } else if (config.utilitiesShowCraftedMinionsStackSize && title.contains("Crafted Minions")) {
+ if (!(stack.getItem() == Items.skull)) return;
+ if (!(stack.getDisplayName().endsWith(" Minion"))) return;
+ int numTiers = 0;
+ List itemLore = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ for (String s : itemLore) if (s.contains("a")) numTiers++; else if (s.contains("c")) break;
+ drawAsStackSize(numTiers, xPosition, yPosition);
+ ci.cancel();
+ } else if ((title.equals("Your Skills") || title.equals("Dungeoneering") || title.equals("Dungeon Classes"))) {
+ if (config.utilitiesShowSkillAverageStackSize != 0 && stack.getDisplayName().contains("Your Skill")) {
+ List itemLore = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ String skillAvg = "";
+ for (String s : itemLore) {
+ if ((StringUtils.stripControlCodes(s)).contains(" Skill Avg")) {
+ String[] temp = s.split(" ");
+ if (temp.length < 1) break; //prevent crash
+ skillAvg = StringUtils.stripControlCodes(temp[0]);
+ break;
+ }
+ }
+ if (skillAvg == "") return;
+ if (config.utilitiesShowSkillAverageStackSize == 1) drawAsStackSize(Math.round(Float.valueOf(skillAvg)), xPosition, yPosition);
+ else if (config.utilitiesShowSkillAverageStackSize == 2) drawAsStackSize(skillAvg, xPosition, yPosition);
+ ci.cancel();
+ } else if (config.utilitiesShowSkillStackSize) {
+ String[] splitStr = StringUtils.stripControlCodes(stack.getDisplayName()).split(" ");
+ if (splitStr.length < 2) return;
+ String skillNumeral = splitStr[(splitStr.length - 1)];
+ if (title.equals("Dungeon Classes")) skillNumeral = splitStr[1];
+ char c = skillNumeral.charAt(0);
+ if (c < '0' || c > '9') return; //HUGE SHOUTOUT TO Jonas K from StackOverflow for this: https://stackoverflow.com/a/237204
+ skillNumeral = skillNumeral.replace("[", "").replace("]", "").replace("(", "").replace(")", "");
+ drawAsStackSize(skillNumeral, xPosition, yPosition);
+ ci.cancel();
+ }
+ } else if (config.utilitiesShowDojoProgressStackSize && title.equals("Challenges")) {
+ if (!stack.getDisplayName().startsWith("§9Test of ") && !stack.getDisplayName().equals("§6Rank")) return;
+ List itemLore = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ String[] splitStr = {};
+ if (stack.getDisplayName().equals("§6Rank")) splitStr = itemLore.get(3).split(" ");
+ if (stack.getDisplayName().startsWith("§9Test of ")) splitStr = itemLore.get(1).split(" ");
+ if (splitStr.length < 2) return;
+ String result = splitStr[2];
+ if (stack.getDisplayName().equals("§6Rank")) result = result.substring(0, 3);
+ drawAsStackSize(result, xPosition, yPosition);
+ ci.cancel();
+ } else if (config.utilitiesShowCompletedQuestCountStackSize && title.equals("Quest Log")) {
+ if (!stack.getDisplayName().equals("§aCompleted Quests")) return;
+ List itemLore = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ String[] splitStr = StringUtils.stripControlCodes(itemLore.get(5)).split(" ");
+ if (splitStr.length < 1) return;
+ String result = splitStr[1];
+ drawAsStackSize(result, xPosition, yPosition);
+ ci.cancel();
+ } else if (config.utilitiesShowWardrobeSlotStackSize && title.startsWith("Wardrobe")) {
+ if (!stack.getDisplayName().startsWith("§7Slot ")) return;
+ String[] splitStr = StringUtils.stripControlCodes(stack.getDisplayName()).split(" ");
+ if (splitStr.length < 1) return;
+ String result = splitStr[1].replace(":", "");
+ drawAsStackSize(result, xPosition, yPosition);
+ ci.cancel();
+ } else if (title.startsWith("SkyBlock Menu")) {
+ if (!stack.getDisplayName().contains("Your Skill") && !stack.getDisplayName().equals("§aRecipe Book") && !stack.getDisplayName().equals("§aCollection") && !stack.getDisplayName().equals("§a§aActive Effects")) return;
+ if (config.utilitiesShowSkillAverageStackSize == 0 && config.utilitiesShowUnlockedRecipePercentStackSize == 0 && config.utilitiesShowUnlockedCollectionStackSize == 0) return;
+ String skillAvg = "";
+ List itemLore = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ if (stack.getDisplayName().contains("Your Skill") && config.utilitiesShowSkillAverageStackSize != 0) {
+ for (String s : itemLore) {
+ if ((StringUtils.stripControlCodes(s)).contains(" Skill Avg")) {
+ String[] temp = s.split(" ");
+ if (temp.length < 1) break; //prevent crash
+ skillAvg = StringUtils.stripControlCodes(temp[0]);
+ break;
+ }
+ }
+ if (skillAvg == "") return;
+ if (config.utilitiesShowSkillAverageStackSize == 1) drawAsStackSize(Math.round(Float.valueOf(skillAvg)), xPosition, yPosition);
+ else if (config.utilitiesShowSkillAverageStackSize == 2) drawAsStackSize(skillAvg, xPosition, yPosition);
+ ci.cancel();
+ } else if (stack.getDisplayName().equals("§aRecipe Book") && config.utilitiesShowUnlockedRecipePercentStackSize != 0) {
+ String[] splitStr = StringUtils.stripControlCodes(itemLore.get(6)).split(" ");
+ if (splitStr.length < 1) return;
+ String result = splitStr[3].replace("%", "");
+ if (config.utilitiesShowUnlockedRecipePercentStackSize == 1) drawAsStackSize(Math.round(Float.valueOf(result)), xPosition, yPosition);
+ else if (config.utilitiesShowUnlockedRecipePercentStackSize == 2) drawAsStackSize(result, xPosition, yPosition);
+ ci.cancel();
+ } else if (stack.getDisplayName().equals("§aCollection") && config.utilitiesShowUnlockedCollectionStackSize != 0) {
+ String[] splitStr = StringUtils.stripControlCodes(itemLore.get(7)).split(" ");
+ if (splitStr.length < 1) return;
+ String result = splitStr[2].replace("%", "");
+ char c = result.charAt(0);
+ if (c < '0' || c > '9') result = splitStr[3].replace("%", ""); //HUGE SHOUTOUT TO Jonas K from StackOverflow for this: https://stackoverflow.com/a/237204
+ result = result.replace("100", "§a✔");
+ if (config.utilitiesShowUnlockedCollectionStackSize == 1) {
+ try {
+ drawAsStackSize(Math.round(Float.valueOf(result)), xPosition, yPosition);
+ } catch (Exception why) {
+ drawAsStackSize(result, xPosition, yPosition);
+ }
+ }
+ else if (config.utilitiesShowUnlockedCollectionStackSize == 2) drawAsStackSize(result, xPosition, yPosition);
+ ci.cancel();
+ } else if (config.utilitiesShowActiveEffectsStackSize && stack.getDisplayName().equals("§a§aActive Effects")) {
+ String[] splitStr = StringUtils.stripControlCodes(itemLore.get(7)).split(" ");
+ if (splitStr.length < 1) return;
+ String result = splitStr[splitStr.length - 1].replace("%", "");
+ char c = result.charAt(0);
+ if (c < '0' || c > '9') return; //HUGE SHOUTOUT TO Jonas K from StackOverflow for this: https://stackoverflow.com/a/237204
+ drawAsStackSize(result, xPosition, yPosition);
+ ci.cancel();
+ }
+ } else if ((title.equals("Recipe Book") || title.endsWith(" Recipes"))) {
+ if (!stack.getDisplayName().startsWith("§a") || !stack.getDisplayName().endsWith(" Recipes")) return;
+ if (config.utilitiesShowUnlockedRecipePercentStackSize == 0 && config.utilitiesShowUnlockedSpecificRecipePercentStackSize == 0) return;
+ List itemLore = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ String[] splitStr = StringUtils.stripControlCodes(itemLore.get(4)).split(" ");
+ if (splitStr.length < 1) return;
+ String result = splitStr[2].replace("%", "");
+ char c = result.charAt(0);
+ if (c < '0' || c > '9') result = splitStr[3].replace("%", ""); //HUGE SHOUTOUT TO Jonas K from StackOverflow for this: https://stackoverflow.com/a/237204
+ result = result.replace("100", "§a✔");
+ if (config.utilitiesShowUnlockedSpecificRecipePercentStackSize == 1) {
+ try {
+ drawAsStackSize(Math.round(Float.valueOf(result)), xPosition, yPosition);
+ } catch (Exception why) {
+ drawAsStackSize(result, xPosition, yPosition);
+ }
+ } else if (config.utilitiesShowUnlockedSpecificRecipePercentStackSize == 2) drawAsStackSize(result, xPosition, yPosition);
+ ci.cancel();
+ } else if (title.equals("Collection")) {
+ if (!stack.getDisplayName().startsWith("§a") || !stack.getDisplayName().endsWith("Collection")) return;
+ if (config.utilitiesShowUnlockedCollectionStackSize == 0) return;
+ List itemLore = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ String[] splitStr = {};
+ if (stack.getDisplayName().equals("§aCollection")) splitStr = StringUtils.stripControlCodes(itemLore.get(7)).split(" ");
+ else splitStr = StringUtils.stripControlCodes(itemLore.get(3)).split(" ");
+ if (splitStr.length < 1) return;
+ String result = splitStr[2].replace("%", "");
+ char c = result.charAt(0);
+ if (c < '0' || c > '9') result = splitStr[3].replace("%", ""); //HUGE SHOUTOUT TO Jonas K from StackOverflow for this: https://stackoverflow.com/a/237204
+ result = result.replace("100", "§a✔");
+ if (config.utilitiesShowUnlockedCollectionStackSize == 1) {
+ try {
+ drawAsStackSize(Math.round(Float.valueOf(result)), xPosition, yPosition);
+ } catch (Exception why) {
+ drawAsStackSize(result, xPosition, yPosition);
+ }
+ } else if (config.utilitiesShowUnlockedCollectionStackSize == 2) drawAsStackSize(result, xPosition, yPosition);
+ } else if (title.contains("Museum") && config.utilitiesShowMuseumPercentagesStackSize != 0) {
+ if (!stack.getDisplayName().startsWith("§a") && !stack.getDisplayName().startsWith("§9")) return;
+ if (stack.getItem() == Items.sign || stack.getItem() == Items.name_tag) return;
+ List itemLore = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ String result = "";
+ if (stack.getDisplayName().equals("§9Museum")) result = StringUtils.stripControlCodes(itemLore.get(11)).split(" ")[2].replace("%", "");
+ if (stack.getDisplayName().equals("§aRarities") || stack.getDisplayName().equals("§aArmor Sets") || stack.getDisplayName().equals("§aWeapons")) result = StringUtils.stripControlCodes(itemLore.get(5)).split(" ")[2].replace("%", "");
+ if (stack.getDisplayName().equals("§aSpecial Items")) result = StringUtils.stripControlCodes(itemLore.get(13)).split(" ")[2].replace("%", "");
+ if (result == "") return;
+ char c = result.charAt(0);
+ if (c < '0' || c > '9') return; //HUGE SHOUTOUT TO Jonas K from StackOverflow for this: https://stackoverflow.com/a/237204
+ result = result.replace("100", "§a✔");
+ if (config.utilitiesShowMuseumPercentagesStackSize == 1) {
+ try {
+ drawAsStackSize(Math.round(Float.valueOf(result)), xPosition, yPosition);
+ } catch (Exception why) {
+ drawAsStackSize(result, xPosition, yPosition);
+ }
+ } else if (config.utilitiesShowMuseumPercentagesStackSize == 2) drawAsStackSize(result, xPosition, yPosition);
+ } else if (config.utilitiesShowBankTierStackSize && title.equals("Bank")) {
+ if (!stack.getDisplayName().equals("§6Bank Upgrades")) return;
+ if (stack.getItem() != Item.getItemFromBlock(Blocks.gold_block)) return;
+ List itemLore = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ String result = itemLore.get(4).split(" ")[2].substring(0, 3);
+ drawAsStackSize(result, xPosition, yPosition);
+ }
+ }
+ if (config.utilitiesWishingCompassUsesLeft) {
+ if (stack != null && stack.getDisplayName().contains("Wishing Compass")) {
+ NBTTagCompound tag = stack.getTagCompound();
+ if (tag.hasKey("ExtraAttributes")) {
+ if (tag.getCompoundTag("ExtraAttributes").hasKey("wishing_compass_uses")) {
+ drawAsStackSize((3 - tag.getCompoundTag("ExtraAttributes").getInteger("wishing_compass_uses")), xPosition, yPosition);
+ } else {
+ if (config.utilitiesWishingCompassAlwaysUsesLeft) {
+ drawAsStackSize(3, xPosition, yPosition);
+ }
+ }
+ }
+ }
+ }
+ if (config.utilitiesShowNYCakeStackSize) {
+ if (stack != null && stack.getDisplayName().contains("cNew Year Cake (Year") && stack.getDisplayName().contains(")")) {
+ NBTTagCompound tag = stack.getTagCompound();
+ if (tag.hasKey("ExtraAttributes") && tag.getCompoundTag("ExtraAttributes").hasKey("new_years_cake")) {
+ drawAsStackSize((tag.getCompoundTag("ExtraAttributes").getInteger("new_years_cake")), xPosition, yPosition);
+ }
+ }
+ }
+ if (config.utilitiesShowSpookyPieStackSize < 3 && config.utilitiesShowSpookyPieStackSize > 0) {
+ if (stack != null && stack.getDisplayName().contains("Spooky Pie")) {
+ NBTTagCompound tag = stack.getTagCompound();
+ if (tag.hasKey("ExtraAttributes")) {
+ List itemLore = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ for (String s : itemLore) {
+ if (s.contains("Obtained during the")) {
+ if (config.utilitiesShowSpookyPieStackSize == 2) {
+ drawAsStackSize((Integer.parseInt((tag.getCompoundTag("ExtraAttributes").getString("event").replace("spooky_festival_", ""))) + 1), xPosition, yPosition);
+ } else if (config.utilitiesShowSpookyPieStackSize == 1) {
+ drawAsStackSize((tag.getCompoundTag("ExtraAttributes").getInteger("new_years_cake") + 1), xPosition, yPosition);
+ }
+ }
+ }
+ }
}
}
}
- private void drawStringAsStackSize(String text, int xPosition, int yPosition) {
+ private void drawAsStackSize(String text, int xPosition, int yPosition) {
GlStateManager.disableLighting();
GlStateManager.disableDepth();
GlStateManager.disableBlend();
Minecraft.getMinecraft().fontRendererObj.drawStringWithShadow(text, (float)(xPosition + 19 - 2 - Minecraft.getMinecraft().fontRendererObj.getStringWidth(text)), (float)(yPosition + 6 + 3), 16777215);
GlStateManager.enableLighting();
GlStateManager.enableDepth();
- System.out.println("");
+ }
+
+ private void drawAsStackSize(int integer, int xPosition, int yPosition) {
+ drawAsStackSize(Integer.toString(integer), xPosition, yPosition);
}
}
diff --git a/src/main/java/com/luna/synthesis/mixins/accessors/GuiNewChatAccessor.java b/src/main/java/com/luna/synthesis/mixins/accessors/GuiNewChatAccessor.java
index c58cd68..457db4a 100644
--- a/src/main/java/com/luna/synthesis/mixins/accessors/GuiNewChatAccessor.java
+++ b/src/main/java/com/luna/synthesis/mixins/accessors/GuiNewChatAccessor.java
@@ -2,6 +2,7 @@
import net.minecraft.client.gui.ChatLine;
import net.minecraft.client.gui.GuiNewChat;
+import net.minecraft.util.IChatComponent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
@@ -14,4 +15,5 @@ public interface GuiNewChatAccessor {
@Accessor List getChatLines();
@Accessor List getDrawnChatLines();
@Accessor int getScrollPos();
+ @Invoker void invokeSetChatLine(IChatComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly);
}
diff --git a/src/main/java/com/luna/synthesis/mixins/accessors/GuiRepairAccessor.java b/src/main/java/com/luna/synthesis/mixins/accessors/GuiRepairAccessor.java
new file mode 100644
index 0000000..d746960
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/mixins/accessors/GuiRepairAccessor.java
@@ -0,0 +1,12 @@
+package com.luna.synthesis.mixins.accessors;
+
+import net.minecraft.client.gui.GuiRepair;
+import net.minecraft.client.gui.GuiTextField;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+@Mixin(GuiRepair.class)
+public interface GuiRepairAccessor {
+
+ @Accessor GuiTextField getNameField();
+}
diff --git a/src/main/java/com/luna/synthesis/mixins/neu/NEUEventListenerMixin.java b/src/main/java/com/luna/synthesis/mixins/neu/NEUEventListenerMixin.java
new file mode 100644
index 0000000..6d0a087
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/mixins/neu/NEUEventListenerMixin.java
@@ -0,0 +1,22 @@
+package com.luna.synthesis.mixins.neu;
+
+import com.luna.synthesis.utils.MixinUtils;
+import org.spongepowered.asm.mixin.Dynamic;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Pseudo;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyArg;
+
+@Pseudo
+@Mixin(targets = "io.github.moulberry.notenoughupdates.NEUEventListener", remap = false)
+public class NEUEventListenerMixin {
+
+ @Dynamic
+ @ModifyArg(method = "onTick", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;enableRepeatEvents(Z)V"))
+ public boolean overrideKeyEvents(boolean in) {
+ if (MixinUtils.inputField != null && MixinUtils.inputField.isFocused()) {
+ return true;
+ }
+ return in;
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/mixins/optifine/CapeUtilsMixin.java b/src/main/java/com/luna/synthesis/mixins/optifine/CapeUtilsMixin.java
index f032a75..2ffcae9 100644
--- a/src/main/java/com/luna/synthesis/mixins/optifine/CapeUtilsMixin.java
+++ b/src/main/java/com/luna/synthesis/mixins/optifine/CapeUtilsMixin.java
@@ -2,7 +2,6 @@
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
-import com.luna.synthesis.utils.ChatLib;
import net.minecraft.client.Minecraft;
import org.spongepowered.asm.mixin.Dynamic;
import org.spongepowered.asm.mixin.Mixin;
@@ -16,22 +15,25 @@ public class CapeUtilsMixin {
private static final Config config = Synthesis.getInstance().getConfig();
+ // I want to give people the ability to toggle anything in the mod they don't want.
+ // I don't know what would cause people to toggle them off.
+ // I wouldn't be mad, just disappointed.
@Dynamic
@ModifyVariable(method = "downloadCape(Lnet/minecraft/client/entity/AbstractClientPlayer;)V", at = @At("STORE"), name = "username")
private static String downloadCape(String in) {
- if (!config.utilitiesCapesCustomCape.equals("") && in.equals(Minecraft.getMinecraft().thePlayer.getName())) {
- return config.utilitiesCapesCustomCape;
+ if (!config.utilitiesOptifineCustomCape.equals("") && in.equals(Minecraft.getMinecraft().getSession().getUsername())) {
+ return config.utilitiesOptifineCustomCape;
}
- if (config.utilitiesCapesTransYeti && in.equals("Yeti ")) {
+ if (config.utilitiesOptifineTransYeti && in.equals("Yeti ")) {
return "Yeti";
}
- if (config.utilitiesCapesTransTerracotta && in.equals("Terracotta ")) {
+ if (config.utilitiesOptifineTransTerracotta && in.equals("Terracotta ")) {
return "Terracotta";
}
- if (config.utilitiesCapesNonBinaryBonzo && in.equals("Bonzo ")) {
+ if (config.utilitiesOptifineNonBinaryBonzo && in.equals("Bonzo ")) {
return "Bonzo";
}
- if (config.utilitiesCapesCandyCaneGrinch && in.equals("Grinch ")) {
+ if (config.utilitiesOptifineCandyCaneGrinch && in.equals("Grinch ")) {
return "Grinch";
}
return in;
diff --git a/src/main/java/com/luna/synthesis/mixins/optifine/PlayerItemsLayerMixin.java b/src/main/java/com/luna/synthesis/mixins/optifine/PlayerItemsLayerMixin.java
new file mode 100644
index 0000000..b9469b8
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/mixins/optifine/PlayerItemsLayerMixin.java
@@ -0,0 +1,25 @@
+package com.luna.synthesis.mixins.optifine;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import net.minecraft.entity.EntityLivingBase;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Pseudo;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Pseudo
+@Mixin(targets = "net.optifine.player.PlayerItemsLayer")
+public class PlayerItemsLayerMixin {
+
+ private final Config config = Synthesis.getInstance().getConfig();
+
+ // It's so great that I just made this almost after the santa hat is gone, but hey, here's to 2022 halloween if humanity hasn't collapsed by then.
+ @Inject(method = "renderEquippedItems(Lnet/minecraft/entity/EntityLivingBase;FF)V", at = @At("HEAD"), cancellable = true)
+ public void renderEquippedItems(EntityLivingBase entityLiving, float scale, float partialTicks, CallbackInfo ci) {
+ if (config.utilitiesOptifineHideHats) {
+ ci.cancel();
+ }
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/mixins/patcher/ChatHandlerMixin.java b/src/main/java/com/luna/synthesis/mixins/patcher/ChatHandlerMixin.java
index 32c3f9c..d9059b4 100644
--- a/src/main/java/com/luna/synthesis/mixins/patcher/ChatHandlerMixin.java
+++ b/src/main/java/com/luna/synthesis/mixins/patcher/ChatHandlerMixin.java
@@ -1,6 +1,5 @@
package com.luna.synthesis.mixins.patcher;
-import com.luna.synthesis.Comment;
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
import net.minecraft.client.gui.ChatLine;
@@ -18,7 +17,7 @@ public class ChatHandlerMixin {
private static final Config config = Synthesis.getInstance().getConfig();
- @Comment("ChatLine equals is bad. Calling GuiNewChat::refreshChat() creates a copy of the line, so equals doesn't actually work.")
+ // GuiNewChat::setChatLine breaks equals since ChatLine's is not overridden + the method creates a new chat line, this fixes that
@Dynamic
@Redirect(method = "deleteMessageByHash(I)Z", at = @At(value = "INVOKE", target = "Ljava/util/Set;contains(Ljava/lang/Object;)Z"), remap = false)
private static boolean contains(Set toRemove, Object obj) {
diff --git a/src/main/java/com/luna/synthesis/mixins/patcher/ImagePreviewerMixin.java b/src/main/java/com/luna/synthesis/mixins/patcher/ImagePreviewerMixin.java
index 45db960..c0954c4 100644
--- a/src/main/java/com/luna/synthesis/mixins/patcher/ImagePreviewerMixin.java
+++ b/src/main/java/com/luna/synthesis/mixins/patcher/ImagePreviewerMixin.java
@@ -1,6 +1,5 @@
package com.luna.synthesis.mixins.patcher;
-import com.luna.synthesis.Comment;
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
import gg.essential.api.utils.TrustedHostsUtil;
@@ -20,7 +19,7 @@ public class ImagePreviewerMixin {
private final Config config = Synthesis.getInstance().getConfig();
- @Comment("Most likely not the way to do it since TrustedHostsUtil::addTrustedHost exists BUT don't care")
+ // Probably not the way to do this since TrustedHostUtil::addTrustedHost exists BUT don't care.
@Dynamic
@Redirect(method = "handle(Ljava/lang/String;)V", at = @At(value = "INVOKE", target = "Lgg/essential/api/utils/TrustedHostsUtil;getTrustedHosts()Ljava/util/Set;"))
public Set equalsIgnoreCase(TrustedHostsUtil util) {
diff --git a/src/main/java/com/luna/synthesis/mixins/skytils/ChatTabsMixin.java b/src/main/java/com/luna/synthesis/mixins/skytils/ChatTabsMixin.java
new file mode 100644
index 0000000..d31ad61
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/mixins/skytils/ChatTabsMixin.java
@@ -0,0 +1,30 @@
+package com.luna.synthesis.mixins.skytils;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.IChatComponent;
+import org.spongepowered.asm.mixin.Dynamic;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Pseudo;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyVariable;
+
+@Pseudo
+@Mixin(targets = "skytils.skytilsmod.features.impl.handlers.ChatTabs", remap = false)
+public class ChatTabsMixin {
+
+ private final Config config = Synthesis.getInstance().getConfig();
+
+ // Hacky way to add bridge messages to guild, shrug
+ @Dynamic
+ @ModifyVariable(method = "shouldAllow", at = @At("HEAD"))
+ public IChatComponent overrideShouldAllow(IChatComponent in) {
+ if (config.utilitiesBridgeGuildChatTab) {
+ if (in.getFormattedText().startsWith(config.utilitiesBridgeMessageFormat.replaceAll("&", "§").split("<")[0])) {
+ return new ChatComponentText("§r§2Guild > " + in.getFormattedText());
+ }
+ }
+ return in;
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/utils/MixinUtils.java b/src/main/java/com/luna/synthesis/utils/MixinUtils.java
index 506c984..323564f 100644
--- a/src/main/java/com/luna/synthesis/utils/MixinUtils.java
+++ b/src/main/java/com/luna/synthesis/utils/MixinUtils.java
@@ -1,15 +1,12 @@
package com.luna.synthesis.utils;
-import com.luna.synthesis.Comment;
import com.luna.synthesis.mixins.accessors.ItemModelMesherAccessor;
-import lombok.Getter;
-import lombok.Setter;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.renderer.ItemModelMesher;
import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.item.Item;
-@Comment("This is a walmart solution. There's probably a better way to do what I'm trying to do.")
+// This is the absolute wrong way to do this BUT until I figure out something better, shrug
public class MixinUtils {
public static GuiTextField inputField;
diff --git a/src/main/java/com/luna/synthesis/utils/ReflectionUtils.java b/src/main/java/com/luna/synthesis/utils/ReflectionUtils.java
new file mode 100644
index 0000000..87e29db
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/utils/ReflectionUtils.java
@@ -0,0 +1,40 @@
+package com.luna.synthesis.utils;
+
+import net.minecraftforge.fml.common.Loader;
+
+import java.lang.reflect.Field;
+
+public class ReflectionUtils {
+
+ private static final String PATCHER_CONFIG_NAME = "club.sk1er.patcher.config.PatcherConfig";
+ private static Field patcherChatField = null;
+
+ public static void onInit() {
+ if (Loader.isModLoaded("patcher")) {
+ handlePatcherReflection();
+ }
+ }
+
+ private static void handlePatcherReflection() {
+ try {
+ Class> cls = Class.forName(PATCHER_CONFIG_NAME);
+ Field f = cls.getField("transparentChatInputField");
+ if (f.getType() == boolean.class) {
+ patcherChatField = f;
+ }
+ } catch (ReflectiveOperationException e) {
+ // Why is there not a logger
+ System.out.println("Unable to execute Patcher Reflection");
+ }
+ }
+
+ public static boolean getPatcherChatField(){
+ if (patcherChatField == null) return false;
+ try {
+ return patcherChatField.getBoolean(null);
+ } catch (ReflectiveOperationException ignored) {}
+ return false;
+ }
+
+
+}
diff --git a/src/main/java/com/luna/synthesis/utils/Utils.java b/src/main/java/com/luna/synthesis/utils/Utils.java
index 5978a37..7fe894b 100644
--- a/src/main/java/com/luna/synthesis/utils/Utils.java
+++ b/src/main/java/com/luna/synthesis/utils/Utils.java
@@ -1,33 +1,179 @@
package com.luna.synthesis.utils;
-import com.luna.synthesis.Comment;
-import com.luna.synthesis.mixins.GuiContainerMixin;
-import com.luna.synthesis.mixins.accessors.GuiNewChatAccessor;
-import com.luna.synthesis.mixins.accessors.ItemModelMesherAccessor;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.ChatLine;
-import net.minecraft.client.gui.GuiScreen;
-import net.minecraft.client.gui.GuiTextField;
-import net.minecraft.client.renderer.ItemModelMesher;
-import net.minecraft.client.resources.model.IBakedModel;
-import net.minecraft.item.Item;
-
-import java.util.List;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.WorldRenderer;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.event.ClickEvent;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.IChatComponent;
+import net.minecraft.util.MathHelper;
+
+import org.lwjgl.opengl.GL11;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.lwjgl.opengl.GL11.*;
public class Utils {
- @Comment("Copied and adapted from Patcher")
+ private static final Pattern linkPattern = Pattern.compile("((?:[a-z0-9]{2,}:\\/\\/)?(?:(?:[0-9]{1,3}\\.){3}[0-9]{1,3}|(?:[-\\w_\\.]{1,}\\.[a-z]{2,}?))(?::[0-9]{1,5})?.*?(?=[!\"\u00A7 \n]|$))", Pattern.CASE_INSENSITIVE);
+
+ // Copied and adapted from Patcher
public static boolean isDivider(String message) {
+ if (message == null) return false;
if (message.length() < 5) {
return false;
} else {
- for (int i = 0; i < message.length(); i++) {
- char c = message.charAt(i);
- if (c != '-' && c != '=' && c != '\u25AC') {
- return false;
+ // Dear god, forgive me, for I am tired.
+ if (message.equals("-------------- Guild: Message Of The Day --------------") || message.equals("---------- Guild: Message Of The Day (Preview) ----------")) {
+ return true;
+ } else {
+ for (int i = 0; i < message.length(); i++) {
+ char c = message.charAt(i);
+ if (c != '-' && c != '=' && c != '\u25AC') {
+ return false;
+ }
}
}
}
return true;
}
+
+ // Adapted from ForgeHooks::newChatWithLinks, may change linkPattern in the future
+ public static IChatComponent newChatWithLinks(String string) {
+ IChatComponent ichat = null;
+ Matcher matcher = linkPattern.matcher(string);
+ int lastEnd = 0;
+
+ while (matcher.find()) {
+ int start = matcher.start();
+ int end = matcher.end();
+
+ String part = string.substring(lastEnd, start);
+ if (part.length() > 0) {
+ if (ichat == null) {
+ ichat = new ChatComponentText(part);
+ } else {
+ ichat.appendText(part);
+ }
+ }
+ lastEnd = end;
+ String url = string.substring(start, end);
+ IChatComponent link = new ChatComponentText(url);
+
+ try {
+ if ((new URI(url)).getScheme() == null) {
+ url = "http://" + url;
+ }
+ } catch (URISyntaxException e) {
+ if (ichat == null) ichat = new ChatComponentText(url);
+ else ichat.appendText(url);
+ continue;
+ }
+
+ ClickEvent click = new ClickEvent(ClickEvent.Action.OPEN_URL, url);
+ link.getChatStyle().setChatClickEvent(click);
+ if (ichat == null) {
+ ichat = link;
+ } else {
+ ichat.appendSibling(link);
+ }
+ }
+
+ String end = string.substring(lastEnd);
+ if (ichat == null) {
+ ichat = new ChatComponentText(end);
+ } else if (end.length() > 0) {
+ ichat.appendText(string.substring(lastEnd));
+ }
+ return ichat;
+ }
+
+ public static void renderBeamSegment(double x, double y, double z, double partialTicks, double textureScale, double totalWorldTime, int yOffset, int height, float[] colors) {
+ double beamRadius = 0.2D;
+ double glowRadius = 0.25D;
+ int i = yOffset + height;
+ GL11.glTexParameteri(3553, 10242, 10497);
+ GL11.glTexParameteri(3553, 10243, 10497);
+ GlStateManager.disableLighting();
+ GlStateManager.disableCull();
+ GlStateManager.disableBlend();
+ GlStateManager.depthMask(true);
+ GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ZERO);
+ Tessellator tessellator = Tessellator.getInstance();
+ WorldRenderer worldRenderer = tessellator.getWorldRenderer();
+ double d0 = totalWorldTime + partialTicks;
+ double d1 = height < 0 ? d0 : -d0;
+ double d2 = MathHelper.func_181162_h(d1 * 0.2D - (double)MathHelper.floor_double(d1 * 0.1D));
+ float f = colors[0];
+ float f1 = colors[1];
+ float f2 = colors[2];
+ double d3 = d0 * 0.025D * -1.5D;
+ double d4 = 0.5D + Math.cos(d3 + 2.356194490192345D) * beamRadius;
+ double d5 = 0.5D + Math.sin(d3 + 2.356194490192345D) * beamRadius;
+ double d6 = 0.5D + Math.cos(d3 + (Math.PI / 4D)) * beamRadius;
+ double d7 = 0.5D + Math.sin(d3 + (Math.PI / 4D)) * beamRadius;
+ double d8 = 0.5D + Math.cos(d3 + 3.9269908169872414D) * beamRadius;
+ double d9 = 0.5D + Math.sin(d3 + 3.9269908169872414D) * beamRadius;
+ double d10 = 0.5D + Math.cos(d3 + 5.497787143782138D) * beamRadius;
+ double d11 = 0.5D + Math.sin(d3 + 5.497787143782138D) * beamRadius;
+ double d14 = -1.0D + d2;
+ double d15 = (double)height * textureScale * (0.5D / beamRadius) + d14;
+ worldRenderer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
+ worldRenderer.pos(x + d4, y + (double)i, z + d5).tex(1.0D, d15).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d4, y + (double)yOffset, z + d5).tex(1.0D, d14).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d6, y + (double)yOffset, z + d7).tex(0.0D, d14).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d6, y + (double)i, z + d7).tex(0.0D, d15).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d10, y + (double)i, z + d11).tex(1.0D, d15).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d10, y + (double)yOffset, z + d11).tex(1.0D, d14).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d8, y + (double)yOffset, z + d9).tex(0.0D, d14).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d8, y + (double)i, z + d9).tex(0.0D, d15).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d6, y + (double)i, z + d7).tex(1.0D, d15).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d6, y + (double)yOffset, z + d7).tex(1.0D, d14).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d10, y + (double)yOffset, z + d11).tex(0.0D, d14).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d10, y + (double)i, z + d11).tex(0.0D, d15).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d8, y + (double)i, z + d9).tex(1.0D, d15).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d8, y + (double)yOffset, z + d9).tex(1.0D, d14).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d4, y + (double)yOffset, z + d5).tex(0.0D, d14).color(f, f1, f2, 1.0F).endVertex();
+ worldRenderer.pos(x + d4, y + (double)i, z + d5).tex(0.0D, d15).color(f, f1, f2, 1.0F).endVertex();
+ tessellator.draw();
+ GlStateManager.enableBlend();
+ GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
+ GlStateManager.depthMask(false);
+ d3 = 0.5D - glowRadius;
+ d4 = 0.5D - glowRadius;
+ d5 = 0.5D + glowRadius;
+ d6 = 0.5D - glowRadius;
+ d7 = 0.5D - glowRadius;
+ d8 = 0.5D + glowRadius;
+ d9 = 0.5D + glowRadius;
+ d10 = 0.5D + glowRadius;
+ double d13 = -1.0D + d2;
+ d14 = (double)height * textureScale + d13;
+ worldRenderer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
+ worldRenderer.pos(x + d3, y + (double)i, z + d4).tex(1.0D, d14).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d3, y + (double)yOffset, z + d4).tex(1.0D, d13).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d5, y + (double)yOffset, z + d6).tex(0.0D, d13).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d5, y + (double)i, z + d6).tex(0.0D, d14).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d9, y + (double)i, z + d10).tex(1.0D, d14).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d9, y + (double)yOffset, z + d10).tex(1.0D, d13).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d7, y + (double)yOffset, z + d8).tex(0.0D, d13).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d7, y + (double)i, z + d8).tex(0.0D, d14).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d5, y + (double)i, z + d6).tex(1.0D, d14).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d5, y + (double)yOffset, z + d6).tex(1.0D, d13).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d9, y + (double)yOffset, z + d10).tex(0.0D, d13).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d9, y + (double)i, z + d10).tex(0.0D, d14).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d7, y + (double)i, z + d8).tex(1.0D, d14).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d7, y + (double)yOffset, z + d8).tex(1.0D, d13).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d3, y + (double)yOffset, z + d4).tex(0.0D, d13).color(f, f1, f2, 0.125F).endVertex();
+ worldRenderer.pos(x + d3, y + (double)i, z + d4).tex(0.0D, d14).color(f, f1, f2, 0.125F).endVertex();
+ tessellator.draw();
+ GlStateManager.enableLighting();
+ GlStateManager.enableTexture2D();
+ GlStateManager.depthMask(true);
+ }
}
diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info
index de19737..41f6dd3 100644
--- a/src/main/resources/mcmod.info
+++ b/src/main/resources/mcmod.info
@@ -3,12 +3,12 @@
"modid": "synthesis",
"name": "Synthesis",
"description": "Hypixel SkyBlock/general QoL mod.",
- "version": "Alpha-v3",
+ "version": "${version}",
"mcversion": "1.8.9",
"url": "",
"updateUrl": "",
"authorList": ["Luna, Desco"],
- "credits": "Heart DC or The CouncilTM or E for a lot of this mod's suggestions.",
+ "credits": "Heart DC, The CouncilTM, E and microwave guild for a lot of this mod's suggestions. Also Antonio32A for hosting the share service and making the entire backend.",
"logoFile": "",
"screenshots": [],
"dependencies": []
diff --git a/src/main/resources/synthesis.mixins.json b/src/main/resources/synthesis.mixins.json
index c2ae550..22a9d89 100644
--- a/src/main/resources/synthesis.mixins.json
+++ b/src/main/resources/synthesis.mixins.json
@@ -6,15 +6,23 @@
"accessors.GuiChatAccessor",
"accessors.GuiContainerAccessor",
"accessors.GuiNewChatAccessor",
+ "accessors.GuiRepairAccessor",
"accessors.ItemModelMesherAccessor",
"accessors.S2FPacketSetSlotAccessor",
+ "neu.NEUEventListenerMixin",
"optifine.CapeUtilsMixin",
+ "optifine.PlayerItemsLayerMixin",
"patcher.ChatHandlerMixin",
"patcher.ImagePreviewerMixin",
+ "skytils.ChatTabsMixin",
"BlockStainedGlassPaneMixin",
+ "ContainerMixin",
"EntityPlayerMixin",
+ "EntityPlayerSPMixin",
"GuiContainerMixin",
"GuiNewChatMixin",
+ "GuiPlayerTabOverlayMixin",
+ "GuiScreenMixin",
"RenderItemMixin"
],
"client": [],