", msg));
}
}
}
-
- @Comment("Adapted from ForgeHooks::newChatWithLinks")
- private 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;
- }
}
diff --git a/src/main/java/com/luna/synthesis/features/utilities/ContainerChat.java b/src/main/java/com/luna/synthesis/features/utilities/ContainerChat.java
index 11dce96..fe5ba0d 100644
--- a/src/main/java/com/luna/synthesis/features/utilities/ContainerChat.java
+++ b/src/main/java/com/luna/synthesis/features/utilities/ContainerChat.java
@@ -1,32 +1,22 @@
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.GuiContainerMixin;
-import com.luna.synthesis.utils.ChatLib;
+import com.luna.synthesis.mixins.accessors.GuiRepairAccessor;
import com.luna.synthesis.utils.MixinUtils;
-import lombok.Getter;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiChat;
+import net.minecraft.client.gui.GuiRepair;
import net.minecraft.client.gui.GuiScreen;
-import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.gui.inventory.GuiContainer;
-import net.minecraft.client.renderer.GlStateManager;
-import net.minecraft.client.renderer.RenderHelper;
+import net.minecraft.client.gui.inventory.GuiContainerCreative;
import net.minecraft.util.MathHelper;
import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
-import net.minecraftforge.fml.common.gameevent.TickEvent;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
-import java.security.Key;
-import java.util.ArrayList;
-import java.util.List;
-
public class ContainerChat {
private final Config config = Synthesis.getInstance().getConfig();
@@ -34,10 +24,11 @@ public class ContainerChat {
private String historyBuffer = "";
private int sentHistoryCursor = -1;
- @Comment("For chat transfer, don't think I can make it in mixin in a decent way")
+ // For chat transfer magic
@SubscribeEvent
public void onGuiOpen(GuiOpenEvent event) {
if (!config.utilitiesContainerChat) return;
+ sentHistoryCursor = Minecraft.getMinecraft().ingameGUI.getChatGUI().getSentMessages().size();
if (config.utilitiesReopenContainerChat && MixinUtils.inputField != null) {
if (event.gui == null) {
if (Minecraft.getMinecraft().currentScreen instanceof GuiContainer) {
@@ -51,14 +42,17 @@ public void onGuiOpen(GuiOpenEvent event) {
}
}
- @Comment("Originally in mixin, had to rewrite in events because sbe and cowlection would have bad bad compatibility issues.")
+ // Originally in mixin, had to rewrite because SBE and Cowlection would have bad compatibility issues.
+ // I also need to fix this working when SBE's search bar is focused, but I don't think I'll be able to do that.
@SubscribeEvent
public void onKeyTyped(GuiScreenEvent.KeyboardInputEvent event) {
if (!(event.gui instanceof GuiContainer)) return;
+ if (event.gui instanceof GuiContainerCreative) return;
if (!config.utilitiesContainerChat) return;
if (!Keyboard.getEventKeyState()) return;
int keyCode = Keyboard.getEventKey();
if (MixinUtils.inputField == null) return;
+ if (event.gui instanceof GuiRepair && ((GuiRepairAccessor) event.gui).getNameField().isFocused()) return;
if (event instanceof GuiScreenEvent.KeyboardInputEvent.Pre) {
if (MixinUtils.inputField.isFocused()) {
if (keyCode == 1) {
@@ -67,9 +61,18 @@ public void onKeyTyped(GuiScreenEvent.KeyboardInputEvent event) {
Keyboard.enableRepeatEvents(false);
Minecraft.getMinecraft().ingameGUI.getChatGUI().resetScroll();
}
- event.setCanceled(true);
+ if (keyCode != Minecraft.getMinecraft().gameSettings.keyBindScreenshot.getKeyCode()) {
+ event.setCanceled(true);
+ }
} else {
if (keyCode == Minecraft.getMinecraft().gameSettings.keyBindChat.getKeyCode()) {
+ if (config.utilitiesContainerControl && !GuiScreen.isCtrlKeyDown()) return;
+ if (!config.utilitiesContainerControl && GuiScreen.isCtrlKeyDown()) return;
+ MixinUtils.inputField.setFocused(true);
+ Keyboard.enableRepeatEvents(true);
+ return;
+ } else if (keyCode == Minecraft.getMinecraft().gameSettings.keyBindCommand.getKeyCode()) {
+ MixinUtils.inputField.setText("/");
MixinUtils.inputField.setFocused(true);
Keyboard.enableRepeatEvents(true);
return;
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..3fdaf0b
--- /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.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]+).*");
+ 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, g, b = 0F;
+ private Float currentCapacity = 0F;
+ private Float maxCapacity = 1F; //prevent ArithmeticExceptions
+ private int x, y = 0;
+ private String menuName = "";
+ private String hubName = "";
+ private List itemLore;
+ private List slots;
+
+ @SubscribeEvent
+ public void onGuiScreen(GuiScreenEvent.BackgroundDrawnEvent e) {
+ if (config.occupancyOverlay) {
+ if (Minecraft.getMinecraft().thePlayer != 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;
+ for (Slot s : slots) {
+
+ /* PREVENT CACHING */
+ currentCapacity = 0F;
+ maxCapacity = 1F; //prevent ArithmeticExceptions
+ x = y = 0;
+ 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(Minecraft.getMinecraft().thePlayer, 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 apparentlyIHaveToDoThisNowToPreventFalseNegativeSearches = StringUtils.stripControlCodes(line);
+ apparentlyIHaveToDoThisNowToPreventFalseNegativeSearches = apparentlyIHaveToDoThisNowToPreventFalseNegativeSearches.replace("Players: ", "");
+ Matcher playerCapacityMatcher = playerCapacity.matcher(apparentlyIHaveToDoThisNowToPreventFalseNegativeSearches);
+ 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 apparentlyJavaRegexNeverWorksConsistently = apparentlyIHaveToDoThisNowToPreventFalseNegativeSearches.replace("Players: ", "");
+ currentCapacity = Float.parseFloat(apparentlyJavaRegexNeverWorksConsistently.substring(0, apparentlyJavaRegexNeverWorksConsistently.indexOf("/") + 1).replace("/", ""));
+ maxCapacity = Float.parseFloat(apparentlyJavaRegexNeverWorksConsistently.substring(apparentlyJavaRegexNeverWorksConsistently.indexOf("/"), apparentlyJavaRegexNeverWorksConsistently.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 (config.occupancyOverlayFriendAndGuildHighlght && hasFriend && hasGuildmate) {
+ r = b = 255F;
+ g = 85F;
+ break;
+ } else if (config.occupancyOverlayFriendHighlght && hasFriend) {
+ r = g = 85F;
+ b = 255F;
+ break;
+ } else if (config.occupancyOverlayGuildHighlght && hasGuildmate) {
+ r = b = 0F;
+ g = 170F;
+ break;
+ }
+ 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 (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.occupancyOverlayAlreadyConnectedHighlght) {
+ r = 85F;
+ g = b = 255F;
+ }
+ alreadyConnected = true;
+ }
+ }
+ Color bgColor = new Color(((int)(r)), ((int)(g)), ((int)(b)));
+ System.out.println("[Synthesis] 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);
+ /**
+ * The next six lines of code were taken from Danker's Skyblock Mod under the GPL 3.0 license.
+ * https://github.com/bowser0000/SkyblockMod/blob/master/LICENSE
+ * @author bowser0000
+ */
+ //They are necessary to render the colors within the inventory menu.
+ x = (((new ScaledResolution(Minecraft.getMinecraft())).getScaledWidth() - 176) / 2) + s.xDisplayPosition;
+ y = (((new ScaledResolution(Minecraft.getMinecraft())).getScaledHeight() - 222) / 2) + s.yDisplayPosition;
+ if (slots.size() != 90) y += (6 - (slots.size() - 36) / 9) * 9;
+ GL11.glTranslated(0, 0, 1);
+ Gui.drawRect(x, y, x + 16, y + 16, bgColor.getRGB());
+ GL11.glTranslated(0, 0, -1);
+ }
+ }
+ }
+ return;
+ }
+ }
+ }
+ }
+}
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..a445d77 100644
--- a/src/main/java/com/luna/synthesis/features/utilities/SearchMode.java
+++ b/src/main/java/com/luna/synthesis/features/utilities/SearchMode.java
@@ -1,26 +1,24 @@
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 com.luna.synthesis.utils.Utils;
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;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
+import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
@@ -29,7 +27,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 +36,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 +92,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..2db8250
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/features/utilities/Share.java
@@ -0,0 +1,229 @@
+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 com.luna.synthesis.utils.MixinUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.GuiChat;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.client.gui.inventory.GuiContainer;
+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.Loader;
+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.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClients;
+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;
+
+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.contains(config.utilitiesShareText)) {
+ ItemStack item = Minecraft.getMinecraft().thePlayer.getHeldItem();
+ if (item == null) return;
+ event.setCanceled(true);
+
+ NBTTagCompound extraAttributes = item.getSubCompound("ExtraAttributes", false);
+ JsonArray loreArray = new JsonArray();
+ NBTTagList lore = item.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(item.getSubCompound("display", false).getString("Name")));
+ itemJson.add("lore", loreArray);
+ JsonObject extraObject = new JsonObject();
+ if (item.hasTagCompound()) {
+ if (item.getTagCompound().hasKey("display")) {
+ if (item.getTagCompound().getCompoundTag("display").hasKey("color")) {
+ extraObject.add("color", new JsonPrimitive(item.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(message.replace("[item]", share).replace("[share]", share));
+ }
+ } catch (IOException e) {
+ ChatLib.chat("Something went wrong trying to upload share. Check logs maybe?");
+ e.printStackTrace();
+ }
+ })).start();
+ }
+ }
+
+ @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);
+ }
+ }
+ }
+}
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/VisibleLinks.java b/src/main/java/com/luna/synthesis/features/utilities/VisibleLinks.java
index 1fba8aa..ffe03a5 100644
--- a/src/main/java/com/luna/synthesis/features/utilities/VisibleLinks.java
+++ b/src/main/java/com/luna/synthesis/features/utilities/VisibleLinks.java
@@ -13,6 +13,7 @@ public class VisibleLinks {
private final Config config = Synthesis.getInstance().getConfig();
+ // Low priority so it's compatible with bridge
@SubscribeEvent(priority = EventPriority.LOW)
public void onChatMessage(ClientChatReceivedEvent event) {
if (!config.utilitiesVisibleLinks) return;
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..6d7d62d
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/mixins/EntityPlayerSPMixin.java
@@ -0,0 +1,27 @@
+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 net.minecraft.client.gui.inventory.GuiContainer;
+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..dda23a1 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;
@@ -17,19 +18,13 @@
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 +48,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..3dd74bf 100644
--- a/src/main/java/com/luna/synthesis/mixins/GuiNewChatMixin.java
+++ b/src/main/java/com/luna/synthesis/mixins/GuiNewChatMixin.java
@@ -1,16 +1,13 @@
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 +15,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 +23,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 +64,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 +87,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 +106,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..93c52bc 100644
--- a/src/main/java/com/luna/synthesis/mixins/RenderItemMixin.java
+++ b/src/main/java/com/luna/synthesis/mixins/RenderItemMixin.java
@@ -1,6 +1,5 @@
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;
@@ -15,6 +14,7 @@
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.*;
@@ -28,7 +28,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());
@@ -84,6 +84,20 @@ public void renderItemOverlayIntoGUI(FontRenderer fr, ItemStack stack, int xPosi
}
}
}
+ 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")) {
+ drawStringAsStackSize(String.valueOf(3 - tag.getCompoundTag("ExtraAttributes").getInteger("wishing_compass_uses")), xPosition, yPosition);
+ } else {
+ if (config.utilitiesWishingCompassAlwaysUsesLeft) {
+ drawStringAsStackSize("3", xPosition, yPosition);
+ }
+ }
+ }
+ }
+ }
}
private void drawStringAsStackSize(String text, int xPosition, int yPosition) {
@@ -93,6 +107,5 @@ private void drawStringAsStackSize(String text, int xPosition, int yPosition) {
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("");
}
}
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..098e050 100644
--- a/src/main/java/com/luna/synthesis/mixins/accessors/GuiNewChatAccessor.java
+++ b/src/main/java/com/luna/synthesis/mixins/accessors/GuiNewChatAccessor.java
@@ -2,7 +2,9 @@
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.Shadow;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
@@ -14,4 +16,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..5120a58 100644
--- a/src/main/java/com/luna/synthesis/mixins/optifine/CapeUtilsMixin.java
+++ b/src/main/java/com/luna/synthesis/mixins/optifine/CapeUtilsMixin.java
@@ -16,22 +16,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..db73e83
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/mixins/skytils/ChatTabsMixin.java
@@ -0,0 +1,37 @@
+package com.luna.synthesis.mixins.skytils;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import com.luna.synthesis.utils.Utils;
+import net.minecraft.network.play.server.S02PacketChat;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.IChatComponent;
+import net.minecraft.util.StringUtils;
+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;
+import org.spongepowered.asm.mixin.injection.Redirect;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@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..d231a81 100644
--- a/src/main/java/com/luna/synthesis/utils/Utils.java
+++ b/src/main/java/com/luna/synthesis/utils/Utils.java
@@ -1,33 +1,178 @@
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": [],