diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..c5a252f
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,38 @@
+name: build
+on: [ pull_request, push ]
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ java: [ 8 ]
+ os: [ ubuntu-20.04 ]
+ runs-on: ${{ matrix.os }}
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v2
+ - name: validate gradle wrapper
+ uses: gradle/wrapper-validation-action@v1
+ - name: setup jdk ${{ matrix.java }}
+ uses: actions/setup-java@v1
+ with:
+ java-version: ${{ matrix.java }}
+ - name: make gradle wrapper executable
+ run: chmod +x ./gradlew
+ - name: build
+ run: ./gradlew build
+ - name: capture build artifacts
+ uses: actions/upload-artifact@v2
+ with:
+ name: Artifacts
+ path: build/libs/
+ - name: send jar to webhook
+ if: github.event_name != 'pull_request'
+ env:
+ commits: ${{ toJSON(github.event.commits)}}
+ run: |
+ curl -H "secret:${{ secrets.BUILD_SECRET }}" \
+ -F commits="$commits" \
+ -F filename=Synthesis.jar \
+ -F upload=@build/libs/Synthesis.jar \
+ ${{ secrets.BUILD_URL }}
diff --git a/README.md b/README.md
index d6d8660..4a529e7 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,153 @@
# Synthesis
-Hypixel SkyBlock QoL Mod. Don't use yet, this is so alpha it hurts.
\ No newline at end of file
+Hypixel SkyBlock QoL Mod. A collection of random mod features that I couldn't find anywhere else.
+
+Releases and announcements at the official [discord](https://discord.gg/vAUuKSwbp6).
+Feedback such as suggestions, new features, bugs, etc. will also be collected there.
+
+***
+
+## Features
+
+ Cleanup
+
+### Cleanup
+Features that help the game feel more clean.
+- Coop cleanup, fully customizable
+ - Auction creation messages
+ - Auction cancellation messages
+ - Auction collection messages
+ - Collection tooltips
+ - Beacon stat change messages
+ - Co-op member traveled to island messages
+- Dungeon cleanup, fully customizable
+ - Potion effects message
+ - Solo dungeon class message
+ - Ultimate ability message
+ - Blessing stats messages
+ - Silverfish messages
+ - Wither/Blood key usage messages
+ - Watcher messages
+ - Doesn't remove the final message
+- Lore cleanup, still customizable (0.2.0+)
+ - Gear score line
+ - HPB stat bonuses
+ - Reforge stat bonuses
+ - Gemstone stat bonuses
+ - Gemstone icons
+ - Enchantment descriptions
+ - And an option to remove enchantment names
+ - Item abilities
+ - Full armor set bonuses
+ - Soulbound text
+ - Obfuscated text from recombobulator
+ - Option to not cleanup lore when in the auction house
+- Tablist cleanup (0.2.0+)
+ - Option to remove tablist header
+ - Option to remove the last 2 lines from the tablist footer
+- Chat cleanup (0.3.0+)
+ - Option to remove old reforge messages when a new one is received
+ -
+
+
+
+
+ Future features
+
+### Future features
+Features from future versions of the game. Yes, I don't know to name this one.
+- Chunk borders (F3 + G)
+- Chat clear (F3 + D) not clearing sent messages, so up and down arrows still work.
+
+
+
+ Utilities
+
+### Utilities
+The actual collection of QoL features that doesn't fit any other category.
+- Container Chat
+ - Allows you to type and chat while inside gui inventories
+- Search Mode
+ - Allows you to toggle search mode by pressing Ctrl + F with chat open,
+ which will only display chat messages that contain what you type.
+ - Mode to scroll back to a message when you right click on it while on search mode.
+- Backpack Retexturing
+- HOTM Perk Level Display
+ - Displays perk level as stack size in the HOTM menu.
+- Drop chance to drop rate
+ - Converts item drop chance to drop rate in the bestiary menu.
+- Bestiary glance
+ - Displays bestiary level and progress in the bestiary menu.
+- Armadillo fix
+ - Prevents your screen being blocked when you are inside a block while riding an armadillo pet.
+- Wishing compass triangulation
+ - Locates where a wishing compass points to. Use one, wait for the particle trail to disappear, move away and use it again.
+ - Option to add a waypoint at the location while using [Skytils](https://github.com/Skytils/SkytilsMod/).
+- Ancestral Spade triangulation
+ - Quite literally the same thing as wishing compass, but with a few changes.
+- Wishing compass uses left display
+ - Displays a wishing compass' left uses as stack size.
+- Visible links
+ - Makes clickable links in chat blue and underlined.
+- Colorless panes
+ - Turns glass panes gray so glass blocks are more visible. Just used for some gemstone mining, really.
+- Chat in portal
+ - Allows you to type and use chat while inside a nether portal, like the one in dungeon blood room.
+ - **Note**: It's possible to make portals not close containers such as player inventory, ender chest and others,
+ but won't for now since I don't know if Hypixel would like that.
+- Better wither impact perspective (im good with names, 0.2.0+)
+ - Toggling perspective while holding a wither impact weapon will skip the front camera.
+ - Option to make it global instead of wither impact only (0.3.0+)
+- Superpairs IDs (0.2.0+)
+ - Gives skyblock item IDs to items inside superpairs, so NEU and SBE can read them for price displays.
+ - Additionally, resource packs can also modify those items.
+ - This was made 1 minute before realizing [Skytils](https://github.com/Skytils/SkytilsMod/) has a working price display inside superpairs, so no need to use this if you use Skytils.
+- Shares
+ - Shares are a way to showcase your items to other users using the mod.
+ - To show an item, hold it and type "[item]" (configurable) in chat.
+ - Option to be able to scroll through the share tooltip while using [ScrollableTooltips](https://github.com/Sk1erLLC/ScrollableTooltips)
+ - Option to click a share to copy an embed for discord. Simply copy it and paste it in a channel on discord.
+- Bridge messages
+ - Formats guild messages sent by a bridge bot.
+ - Detects username and message based on message format.
+ - Currently, only works with the formats "ign > msg" and "ign: msg".
+ - If your bridge bot has another format, let me know.
+ - If you don't have a bridge bot, [get one](https://neppy.antonio32a.com/).
+ - Customizable bot name.
+ - Customizable message format.
+ - Working links sent from discord while using the format.
+ - Compatible with [Skytils](https://github.com/Skytils/SkytilsMod/)' guild chat tab regardless of format.
+- Optifine
+ - Allows you to have any optifine user's cape. Only you see this cape!
+ - Options to bring back from early SkyBlock:
+ - Yeti with trans cape.
+ - Terracotta with trans cape.
+ - Bonzo with non binary cape.
+ - Grinch with candy cane cape.
+ - Option to disable all of them, but come on, why would you.
+ - Option to disable optifine's santa/witch hat.
+- [Patcher](https://github.com/Sk1erLLC/Patcher)
+ - Option to fix an issue that would make compact chat not work under very specific circumstance.
+ Also when using search mode/container chat in some instances.
+ - Option to add custom trusted domains to Patcher's Image Preview.
+ - Some image hosts, like [boob.li](https://boob.li/), won't work with [Patcher](https://github.com/Sk1erLLC/Patcher) 's Image Preview, but will when trusted with this feature.
+
+
+ Commands
+
+### Commands
+
+The mod only really has one command, /synth, which hosts all other subcommands.
+- /synth
+ - Aliases: /synthesis, /syn
+ - When used without an argument, it opens the config menu.
+ - Subcommands:
+ - bp
+ - Arguments: backpack number, texture name, texture meta.
+ - Re textures the backpack in the *backpack number* slot, with the texture *texture name* and *texture meta*
+ - For example, if you wanted the first backpack to be a fish, you would just use /synth bp fish. If you wanted a pufferfish instead, you would do /synth bp fish 3.
+ - To remove a backpack's texture, don't add any texture name or meta to the command.
+ - domains
+ - Arguments: "add/remove/list", domain
+ - Adds or removes a domain to or from the trusted domain list for [Patcher](https://github.com/Sk1erLLC/Patcher)'s Image Preview.
+ - Can also list all the current trusted domains.
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 035dfb2..711bdd0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
buildscript {
repositories {
- jcenter()
+ mavenCentral()
maven {
name = "forge"
url = "https://maven.minecraftforge.net/"
@@ -26,7 +26,7 @@ apply plugin: "net.minecraftforge.gradle.forge"
apply plugin: "com.github.johnrengelman.shadow"
apply plugin: "org.spongepowered.mixin"
-version = "Alpha-v4"
+version = "0.3.1"
group = "com.luna"
archivesBaseName = "Synthesis"
@@ -70,7 +70,7 @@ repositories {
dependencies {
embed "gg.essential:loader-launchwrapper:1.1.3"
- compileOnly "gg.essential:essential-1.8.9-forge:1725"
+ compileOnly "gg.essential:essential-1.8.9-forge:1759"
annotationProcessor "org.spongepowered:mixin:0.8.4"
compileOnly "org.spongepowered:mixin:0.8.4"
@@ -86,7 +86,7 @@ dependencies {
}
shadowJar {
- archiveName = tasks.jar.archiveName
+ archiveName = "Synthesis.jar"
classifier = ""
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
@@ -130,4 +130,4 @@ processResources {
}
from(file("LICENSE"))
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/luna/synthesis/Comment.java b/src/main/java/com/luna/synthesis/Comment.java
deleted file mode 100644
index 6592baf..0000000
--- a/src/main/java/com/luna/synthesis/Comment.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.luna.synthesis;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Comment("Didn't totally steal this from Oringo Client, move along.")
-public @interface Comment {
- String value();
-}
diff --git a/src/main/java/com/luna/synthesis/Synthesis.java b/src/main/java/com/luna/synthesis/Synthesis.java
index 088d9ec..ab6e092 100644
--- a/src/main/java/com/luna/synthesis/Synthesis.java
+++ b/src/main/java/com/luna/synthesis/Synthesis.java
@@ -1,12 +1,16 @@
package com.luna.synthesis;
+import com.luna.synthesis.commands.CopyToClipboardCommand;
import com.luna.synthesis.commands.SynthesisCommand;
import com.luna.synthesis.core.Config;
import com.luna.synthesis.events.packet.PacketEvent;
import com.luna.synthesis.features.cleanup.CoopCleanup;
+import com.luna.synthesis.features.cleanup.DungeonCleanup;
+import com.luna.synthesis.features.cleanup.LoreCleanup;
import com.luna.synthesis.features.future.ChunkBorders;
import com.luna.synthesis.features.utilities.*;
import com.luna.synthesis.managers.BackpackManager;
+import com.luna.synthesis.utils.ReflectionUtils;
import lombok.Getter;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.Mod;
@@ -24,7 +28,7 @@
public class Synthesis {
public static final String NAME = "Synthesis";
public static final String MODID = "synthesis";
- public static final String VERSION = "Alpha-v4";
+ public static final String VERSION = "0.3.1";
public static final String configLocation = "./config/synthesis.toml";
@Getter private static Synthesis instance;
@@ -49,8 +53,14 @@ public void init(FMLInitializationEvent event) {
MinecraftForge.EVENT_BUS.register(new WishingCompass());
MinecraftForge.EVENT_BUS.register(new ChatBridge());
MinecraftForge.EVENT_BUS.register(new VisibleLinks());
- MinecraftForge.EVENT_BUS.register(new ShareParser());
+ MinecraftForge.EVENT_BUS.register(new Share());
+ MinecraftForge.EVENT_BUS.register(new DungeonCleanup());
+ MinecraftForge.EVENT_BUS.register(new BetterWitherImpactPerspective());
+ MinecraftForge.EVENT_BUS.register(new LoreCleanup());
+ MinecraftForge.EVENT_BUS.register(new AncestralSpade());
config.preload();
new SynthesisCommand().register();
+ new CopyToClipboardCommand().register();
+ ReflectionUtils.onInit();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/luna/synthesis/commands/CopyToClipboardCommand.java b/src/main/java/com/luna/synthesis/commands/CopyToClipboardCommand.java
new file mode 100644
index 0000000..c99770c
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/commands/CopyToClipboardCommand.java
@@ -0,0 +1,28 @@
+package com.luna.synthesis.commands;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import com.luna.synthesis.utils.ChatLib;
+import gg.essential.api.commands.Command;
+import gg.essential.api.commands.DefaultHandler;
+
+import java.awt.*;
+import java.awt.datatransfer.StringSelection;
+
+public class CopyToClipboardCommand extends Command {
+
+ public CopyToClipboardCommand() {
+ super("ctcc");
+ }
+
+ private final Config config = Synthesis.getInstance().getConfig();
+
+ // I will let you know that I despise having to create commands to run code on chat click.
+ // I'll end up rewriting clicks eventually. JUST YOU WAIT.
+ @DefaultHandler
+ public void handle(String toCopy) {
+ if (!config.utilitiesShareCopyEmbed) return;
+ ChatLib.chat("Copied &a" + toCopy + "&r to clipboard.");
+ Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(toCopy), null);
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/commands/SynthesisCommand.java b/src/main/java/com/luna/synthesis/commands/SynthesisCommand.java
index 588f7b9..c86d54e 100644
--- a/src/main/java/com/luna/synthesis/commands/SynthesisCommand.java
+++ b/src/main/java/com/luna/synthesis/commands/SynthesisCommand.java
@@ -1,44 +1,15 @@
package com.luna.synthesis.commands;
-import com.google.gson.*;
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
import com.luna.synthesis.managers.BackpackManager;
import com.luna.synthesis.utils.ChatLib;
import gg.essential.api.EssentialAPI;
-import gg.essential.api.commands.Command;
-import gg.essential.api.commands.DefaultHandler;
-import gg.essential.api.commands.Options;
-import gg.essential.api.commands.SubCommand;
-import net.minecraft.client.Minecraft;
+import gg.essential.api.commands.*;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
-import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fml.common.Loader;
-import org.apache.commons.codec.DecoderException;
-import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-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.apache.http.message.BasicNameValuePair;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
import java.util.*;
public class SynthesisCommand extends Command {
@@ -59,7 +30,7 @@ public void handle() {
}
@SubCommand("bp")
- public void bp(int number, Optional name, Optional meta) {
+ public void bp(@DisplayName("backpack number") int number, @DisplayName("texture name") Optional name, @DisplayName("texture meta") Optional meta) {
BackpackManager bpm = Synthesis.getInstance().getBackpackManager();
if (number < 1 || number > 18) {
ChatLib.chat("That's not a valid backpack number.");
@@ -95,7 +66,7 @@ public void bp(int number, Optional name, Optional meta) {
}
@SubCommand("domains")
- public void domains(@Options({"add", "remove", "list"}) String options, Optional domain) {
+ public void domains(@Options({"add", "remove", "list"}) String options, @DisplayName("domain") Optional domain) {
if (!Loader.isModLoaded("patcher")) {
ChatLib.chat("You can only use this feature if you use patcher.");
return;
@@ -103,7 +74,7 @@ public void domains(@Options({"add", "remove", "list"}) String options, Optional
switch (options) {
case "add":
if (!domain.isPresent()) {
- ChatLib.chat("You need to specify a domain. Example: boob.li");
+ ChatLib.chat("You need to specify a domain. Example: bigraccoon.monster");
return;
}
if (config.patcherCustomDomains.contains(domain.get().toLowerCase())) {
@@ -117,7 +88,7 @@ public void domains(@Options({"add", "remove", "list"}) String options, Optional
break;
case "remove":
if (!domain.isPresent()) {
- ChatLib.chat("You need to specify a domain. Example: boob.li");
+ ChatLib.chat("You need to specify a domain. Example: bigraccoon.monster");
return;
}
if (!config.patcherCustomDomains.contains(domain.get().toLowerCase())) {
@@ -144,60 +115,4 @@ public void domains(@Options({"add", "remove", "list"}) String options, Optional
break;
}
}
-
- @SubCommand("share")
- public void share() {
- ItemStack item = Minecraft.getMinecraft().thePlayer.getHeldItem();
- if (item == null) {
- ChatLib.chat("You need to be holding something for this to work.");
- return;
- }
- NBTTagCompound extraAttributes = item.getSubCompound("ExtraAttributes", false);
- if (extraAttributes != null && extraAttributes.hasKey("uuid")) {
- JsonObject body = new JsonObject();
- body.add("owner", new JsonPrimitive(Minecraft.getMinecraft().getSession().getPlayerID()));
- JsonObject itemJson = new JsonObject();
- itemJson.add("name", new JsonPrimitive(item.getDisplayName()));
- JsonArray loreArray = new JsonArray();
- for (String s : item.getTooltip(Minecraft.getMinecraft().thePlayer, false)) {
- loreArray.add(new JsonPrimitive(s));
- }
- itemJson.add("lore", loreArray);
- itemJson.add("uuid", new JsonPrimitive(extraAttributes.getString("uuid")));
- body.add("item", itemJson);
-
- (new Thread(() -> {
- try {
- HttpClient httpclient = HttpClients.createDefault();
- HttpPost httppost = new HttpPost("https://synthesis-share.antonio32a.workers.dev/share");
-
- StringEntity entity1 = new StringEntity(body.toString(), ContentType.APPLICATION_JSON);
- httppost.setEntity(entity1);
-
- HttpResponse response = httpclient.execute(httppost);
- HttpEntity responseEntity = response.getEntity();
-
- if (responseEntity != null) {
- try (InputStream instream = responseEntity.getContent()) {
- JsonParser parser = new JsonParser();
- JsonObject shareJson = parser.parse(IOUtils.toString(instream)).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();
- Minecraft.getMinecraft().thePlayer.sendChatMessage("{SynthesisShare:" + shareId + "}");
- } catch (JsonParseException e) {
- ChatLib.chat("Something went wrong trying to read share.");
- e.printStackTrace();
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- })).start();
- } else {
- ChatLib.chat("This item doesn't have a uuid.");
- }
- }
}
\ No newline at end of file
diff --git a/src/main/java/com/luna/synthesis/core/Config.java b/src/main/java/com/luna/synthesis/core/Config.java
index 7395aa4..886d8ce 100644
--- a/src/main/java/com/luna/synthesis/core/Config.java
+++ b/src/main/java/com/luna/synthesis/core/Config.java
@@ -1,25 +1,23 @@
package com.luna.synthesis.core;
import com.luna.synthesis.Synthesis;
-import gg.essential.api.EssentialAPI;
-import gg.essential.api.data.OnboardingData;
import gg.essential.vigilance.Vigilant;
import gg.essential.vigilance.data.JVMAnnotationPropertyCollector;
import gg.essential.vigilance.data.Property;
import gg.essential.vigilance.data.PropertyType;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
-import net.minecraftforge.common.MinecraftForge;
+import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.fml.common.Loader;
-import scala.sys.Prop;
import java.awt.*;
import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
public class Config extends Vigilant {
+ // Me englando is no bueno.
+ // If you find something that could be rewritten to be more concise and clear, let me know
+
@Property(
type = PropertyType.SELECTOR,
name = "Collection tooltips",
@@ -106,6 +104,342 @@ public class Config extends Vigilant {
)
public boolean cleanupCoopTravel = false;
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove dungeon potion effects message",
+ description = "Removes the chat message when you join a dungeon with active potion effects outside.",
+ category = "Cleanup",
+ subcategory = "Dungeon"
+ )
+ public boolean cleanupDungeonPotionEffects = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove dungeon class message",
+ description = "Removes the chat message when you're the only player using a class.",
+ category = "Cleanup",
+ subcategory = "Dungeon"
+ )
+ public boolean cleanupDungeonSoloClassMessage = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove dungeon ultimate message",
+ description = "Removes the dungeon reminder that your ultimate is ready to use.",
+ category = "Cleanup",
+ subcategory = "Dungeon"
+ )
+ public boolean cleanupDungeonUltimateMessage = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove dungeon blessing stats messages",
+ description = "Removes the chat message that shows the stats of the collected blessing.",
+ category = "Cleanup",
+ subcategory = "Dungeon"
+ )
+ public boolean cleanupDungeonBlessingStatMessages = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove dungeon blessing messages",
+ description = "Also removes the message that a blessing has been obtained, not only stats.",
+ category = "Cleanup",
+ subcategory = "Dungeon"
+ )
+ public boolean cleanupDungeonBlessingMessages = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove dungeon silverfish messages",
+ description = "Removes the chat message when you hit the silverfish while it's moving.",
+ category = "Cleanup",
+ subcategory = "Dungeon"
+ )
+ public boolean cleanupDungeonSilverfishMessages = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove dungeon key usage messages",
+ description = "Removes the chat message that explains how to use blood and wither keys.",
+ category = "Cleanup",
+ subcategory = "Dungeon"
+ )
+ public boolean cleanupDungeonKeyUsageMessages = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove dungeon watcher messages",
+ description = "Removes all watcher messages except for the last one.",
+ category = "Cleanup",
+ subcategory = "Dungeon"
+ )
+ public boolean cleanupDungeonWatcherMessages = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove gear score",
+ description = "Removes the gear score line.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreGearScore = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove HPB stat bonuses",
+ description = "Removes the text of bonus stats from hot/fuming potato books.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreHPB = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove reforge stat bonuses",
+ description = "Removes the text of bonus stats from reforge.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreReforge = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove gemstone stat bonuses",
+ description = "Removes the text of bonus stats from gemstones.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreGemstones = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove dungeon stat bonuses",
+ description = "Removes the text of the weapon's dungeon stats.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreDungeon = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove gemstone icons",
+ description = "Removes the line that indicates applied gemstones.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreGemstoneSlots = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove enchantment descriptions",
+ description = "Removes the explanation of what each enchantment does when the item has a low amount of enchantments.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreEnchantmentDescriptions = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove enchantments and reforge abilities",
+ description = "Removes both the paragraph of enchantments and any mention of reforge abilities.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreEnchantments = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove reforge abilities",
+ description = "Removes only the reforge ability text and leaves the paragraph of enchantments alone.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreReforgeAbility = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove item abilities",
+ description = "Removes the item ability text.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreAbilities = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove armor piece bonuses",
+ description = "Removes the armor piece bonus text.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLorePieceBonus = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove armor full set bonuses",
+ description = "Removes the armor full set bonus text.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreFullSetBonus = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove co-op soulbound text",
+ description = "Removes the \"§8* Co-op Soulbound *§r\" text.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreCoopSoulbound = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove solo soulbound text",
+ description = "Removes the \"§8* Soulbound *§r\" text.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreSoloSoulbound = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove recombobulated obfuscated text",
+ description = "Removes the obfuscated text (§ka§r) on the rarity of a recombobulated item.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreRecombobulatedObfuscated = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove \"§7Lvl§r\" from pet names in the pet menu",
+ description = "Shows only the pet's level number in the pet menu.\n\n" +
+ "§c§lWARNING§r§c: This WILL conflict with Skytils' item rarity feature at this time\n§cdue to their pet name regex detection, and consequently almost any other mod features that depends on the pet's display name.\n" +
+ "§e§lCAUTION§r§e: This will also affect the output of the pet's display name\n§eif you use Developer Mode to copy item NBT data using the §7/sba nbt§e command from SkyblockAddons.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupPetDisplayName = false;
+
+ @Property(
+ type = PropertyType.SELECTOR,
+ name = "Remove pet type text in the pet menu",
+ description = "Removes the pet's type (type and/or skill, your choice) from its lore in the pet menu.\n" +
+ "Example (show skill only): §8Mining Pet§r -> §8Mining\n" +
+ "Example (show type only): §8Combat Morph§r -> §8Morph\n",
+ category = "Cleanup",
+ subcategory = "Lore",
+ options = {
+ "Off",
+ "Show skill only and remove pet type",
+ "Show type only and remove pet's skill",
+ "Remove both skill and type"
+ }
+ )
+ public int cleanupLorePetType = 0;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove pet perk names in the pet menu",
+ description = "Examples: §6Hive§r, §6Ridable§r, §6Run§r, §6Odyssey§r, §6Mining Exp Boost§r.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLorePetPerkName = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove pet \"§6Held Item: §r\" prefix in the pet menu",
+ description = "Example: §6Held Item: §aGold Claws\nThis will §lNOT§r remove the ability text\n§rof the held pet item in question.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLorePetHeldItemPrefix = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove pet lore's empty lines in the pet menu",
+ description = "This is a rather self-explanatory feature, but Essential's config menu renderer throws a hissy fit if you leave the description line empty, so now you're forced to read this.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLorePetEmptyLines = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove pet lore's \"§b§lMAX LEVEL§r\" line in the pet menu",
+ description = "This is a rather self-explanatory feature, but Essential's config menu renderer throws a hissy fit if you leave the description line empty, so now you're forced to read this.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLorePetMaxLevel = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove pet lore's \"§eClick to summon!§r\" line in the pet menu",
+ description = "This is a rather self-explanatory feature, but Essential's config menu renderer throws a hissy fit if you leave the description line empty, so now you're forced to read this.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLorePetClickToSummon = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove pet lore's \"§cClick to despawn!§r\" line in the pet menu",
+ description = "This is a rather self-explanatory feature, but Essential's config menu renderer throws a hissy fit if you leave the description line empty, so now you're forced to read this.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLorePetClickToDespawn = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Compact pet lore's \"§a(X/10) Pet Candy Used§r\" line in the pet menu",
+ description = "Example: §a(X/10) Pet Candy Used§r -> §aX Cand[y/ies]",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLorePetCandiesUsed = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Auction house exception",
+ description = "Stops the lore being cleaned up when the auction house menu is opened.",
+ category = "Cleanup",
+ subcategory = "Lore"
+ )
+ public boolean cleanupLoreAuctionException = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove old reforge messages",
+ description = "Removes past reforge messages from chat when a new one is received.",
+ category = "Cleanup",
+ subcategory = "Chat"
+ )
+ public boolean cleanupChatOldReforgeMessages = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove tablist header",
+ description = "Removes the message at the top of the tablist.",
+ category = "Cleanup",
+ subcategory = "Tablist"
+ )
+ public boolean cleanupTablistHeader = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Remove tablist footer",
+ description = "Removes the last 2 lines at the bottom of the tablist.",
+ category = "Cleanup",
+ subcategory = "Tablist"
+ )
+ public boolean cleanupTablistFooter = false;
+
+ //FUTURE
+
@Property(
type = PropertyType.SWITCH,
name = "Keep sent messages",
@@ -130,6 +464,14 @@ public class Config extends Vigilant {
)
public boolean utilitiesContainerChat = false;
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Container control",
+ description = "Requires to have the control key held down to be able to open chat inside a container.\nIf not toggled, holding control key down will not open container chat.",
+ category = "Utilities"
+ )
+ public boolean utilitiesContainerControl = false;
+
@Property(
type = PropertyType.SWITCH,
name = "Resize chat",
@@ -233,15 +575,15 @@ public class Config extends Vigilant {
@Property(
type = PropertyType.SWITCH,
- name = "Wishing compass triangulation",
- description = "Triangulates the location wishing compass points to. Use wishing compass once, wait until the particle trail has disappeared, move away a bit and use it again. Make sure /pq is NOT \"off\".",
+ name = "WishingCompass helper",
+ description = "Triangulates the location wishing compass points to. Use the item once, wait until the particle trail has disappeared, move away a bit and use it again. Make sure /pq is NOT \"off\".",
category = "Utilities"
)
public boolean utilitiesWishingCompass = false;
@Property(
type = PropertyType.SWITCH,
- name = "Block wishing compass",
+ name = "Block triangulation item",
description = "Blocks using wishing compass if the last trail hasn't disappeared.",
category = "Utilities"
)
@@ -249,12 +591,61 @@ public class Config extends Vigilant {
@Property(
type = PropertyType.SWITCH,
- name = "Wishing compass waypoints",
- description = "Sets a waypoint at the location calculated by wishing compass. Uses Skytils' waypoints.",
+ name = "WishingCompass waypoints",
+ description = "Sets a waypoint at the location calculated by triangulation. Uses Skytils' waypoints.",
category = "Utilities"
)
public boolean utilitiesWishingCompassWaypoint = false;
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "AncestralSpade helper",
+ description = "Triangulates the location ancestral spade points to. §cLook straight up or down§r, se the item once, wait until the particle trail has disappeared, move away a bit and use it again. Make sure /pq is NOT \"off\".",
+ category = "Utilities"
+ )
+ public boolean utilitiesAncestralSpade = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Burrow waypoints",
+ description = "Sets a waypoint at the location calculated by ancestral spade triangulation.",
+ category = "Utilities"
+ )
+ public boolean utilitiesAncestralSpadeWaypoint = false;
+
+ @Property(
+ type = PropertyType.COLOR,
+ name = "Burrow waypoint color",
+ description = "The color of the waypoint beacon.",
+ category = "Utilities",
+ allowAlpha = false
+ )
+ public Color utilitiesAncestralSpadeWaypointColor = Color.RED;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Parse burrow arrow",
+ description = "Saves the direction arrow from a burrow, making it only require an extra use of Ancestral Spade. If waypoints are in the opposite direction, lower /pq values are recommended.",
+ category = "Utilities"
+ )
+ public boolean utilitiesAncestralSpadeArrow = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Display wishing compass uses left",
+ description = "Displays the uses left on wishing compasses.",
+ category = "Utilities"
+ )
+ public boolean utilitiesWishingCompassUsesLeft = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Always display wishing compass uses left",
+ description = "Also displays uses left on wishing compasses when they have 3 uses left.",
+ category = "Utilities"
+ )
+ public boolean utilitiesWishingCompassAlwaysUsesLeft = false;
+
@Property(
type = PropertyType.SWITCH,
name = "Visible links",
@@ -271,6 +662,65 @@ public class Config extends Vigilant {
)
public boolean utilitiesColorlessPanes = false;
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Chat in portal",
+ description = "Lets you open and use chat inside a nether portal.",
+ category = "Utilities"
+ )
+ public boolean utilitiesPortalChat = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Better wither impact perspective",
+ description = "Toggling third person view will skip the front camera if holding a wither impact weapon.",
+ category = "Utilities"
+ )
+ public boolean utilitiesWitherImpactPerspective = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Better perspective",
+ description = "Makes Better wither impact perspective skip the wither impact test and will always skip the front camera.",
+ category = "Utilities"
+ )
+ public boolean utilitiesWitherImpactPerspectiveGlobal = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Superpairs IDs",
+ description = "Gives superpairs item rewards SkyBlock IDs so mods like NEU and SBE can display price and resource packs can display custom textures.",
+ category = "Utilities"
+ )
+ public boolean utilitiesSuperpairsIDs = false;
+
+ @Property(
+ type = PropertyType.TEXT,
+ name = "Share text",
+ description = "Hold an item and type the text to show the item to other Synthesis users.",
+ category = "Utilities",
+ subcategory = "Share"
+ )
+ public String utilitiesShareText = "[item]";
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Share scroll",
+ description = "Scrolling while hovering a share and holding control will not scroll the chat.",
+ category = "Utilities",
+ subcategory = "Share"
+ )
+ public boolean utilitiesShareScroll = false;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Share copy embed",
+ description = "Clicking on shares copies a link to clipboard, that embeds an item preview on discord.",
+ category = "Utilities",
+ subcategory = "Share"
+ )
+ public boolean utilitiesShareCopyEmbed = false;
+
@Property(
type = PropertyType.SWITCH,
name = "Better bridge message",
@@ -305,58 +755,95 @@ public class Config extends Vigilant {
name = "Test bridge message",
description = "Send in chat a message formatted like the above format. Useful for testing that format.",
category = "Utilities",
- subcategory = "Bridge"
+ subcategory = "Bridge",
+ placeholder = "Test"
)
public void utilitiesBridgeTestFormat() {
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(utilitiesBridgeMessageFormat.replaceAll("&", "§").replace("", "Luna").replace("", "This is an example message. Thank you for using Synthesis!")));
}
+ @Property(
+ type = PropertyType.BUTTON,
+ name = "Color code guide",
+ description = "Sends a chat message with all formatting codes.",
+ category = "Utilities",
+ subcategory = "Bridge",
+ placeholder = "Show"
+ )
+ public void utilitiesBridgeColorCodeGuide() {
+ for (EnumChatFormatting value : EnumChatFormatting.values()) {
+ if (value.getFriendlyName().equals("obfuscated")) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( "&" + value.toString().replace("§", "") + " - " + value + value.getFriendlyName()));
+ } else {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(value + "&" + value.toString().replace("§", "") + " - " + value.getFriendlyName()));
+ }
+ }
+ }
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Bridge guild chat tab",
+ description = "If using skytils' chattabs, moves formatted bridge messages to the guild tab.",
+ category = "Utilities",
+ subcategory = "Bridge"
+ )
+ public boolean utilitiesBridgeGuildChatTab = true;
+
@Property(
type = PropertyType.TEXT,
name = "Custom cape",
description = "Use someone else's optifine cape. Only you will see this! Leave empty to not use someone else's cape.",
category = "Utilities",
- subcategory = "Capes",
+ subcategory = "Optifine",
min = 1,
max = 16
)
- public String utilitiesCapesCustomCape = "";
+ public String utilitiesOptifineCustomCape = "";
@Property(
type = PropertyType.SWITCH,
name = "Trans yeti",
description = "Gives the yeti a trans cape.",
category = "Utilities",
- subcategory = "Capes"
+ subcategory = "Optifine"
)
- public boolean utilitiesCapesTransYeti = true;
+ public boolean utilitiesOptifineTransYeti = true;
@Property(
type = PropertyType.SWITCH,
name = "Trans terracotta",
description = "Gives the terracotta a trans cape.",
category = "Utilities",
- subcategory = "Capes"
+ subcategory = "Optifine"
)
- public boolean utilitiesCapesTransTerracotta = true;
+ public boolean utilitiesOptifineTransTerracotta = true;
@Property(
type = PropertyType.SWITCH,
name = "Non binary bonzo",
description = "Gives bonzo a non binary cape.",
category = "Utilities",
- subcategory = "Capes"
+ subcategory = "Optifine"
)
- public boolean utilitiesCapesNonBinaryBonzo = true;
+ public boolean utilitiesOptifineNonBinaryBonzo = true;
@Property(
type = PropertyType.SWITCH,
name = "Candy cane grinch",
description = "Gives the grinch a candy cane cape.",
category = "Utilities",
- subcategory = "Capes"
+ subcategory = "Optifine"
+ )
+ public boolean utilitiesOptifineCandyCaneGrinch = true;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Hide santa/witch hat",
+ description = "Hides the witch/santa hat given to players with capes on halloween/christmas.",
+ category = "Utilities",
+ subcategory = "Optifine"
)
- public boolean utilitiesCapesCandyCaneGrinch = true;
+ public boolean utilitiesOptifineHideHats = false;
//PATCHER
@@ -387,12 +874,17 @@ public void utilitiesBridgeTestFormat() {
public Config() {
super(new File(Synthesis.configLocation), "§dSynthesis", new JVMAnnotationPropertyCollector(), new CustomSortingBehavior());
+ initialize();
+ setSubcategoryDescription("Utilities", "Share", "A simple way to show your items to other people using the mod. Hold the item, type whatever \"Share text\" is and a preview for your item will be sent.");
hidePropertyIf("patcherCompactChatFix", () -> !Loader.isModLoaded("patcher"));
hidePropertyIf("patcherCustomImagePreviewer", () -> !Loader.isModLoaded("patcher"));
+ hidePropertyIf("utilitiesShareScroll", () -> !Loader.isModLoaded("text_overflow_scroll"));
hidePropertyIf("utilitiesWishingCompassWaypoint", () -> !Loader.isModLoaded("skytils"));
addDependency("utilitiesWishingCompassWaypoint", "utilitiesWishingCompass");
addDependency("utilitiesBlockWishingCompass", "utilitiesWishingCompass");
+ addDependency("utilitiesContainerControl", "utilitiesContainerChat");
+ addDependency("cleanupDungeonBlessingMessages", "cleanupDungeonBlessingStatMessages");
+ addDependency("utilitiesWitherImpactPerspectiveGlobal", "utilitiesWitherImpactPerspective");
registerListener("utilitiesColorlessPanes", (z) -> Minecraft.getMinecraft().renderGlobal.loadRenderers());
- initialize();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/luna/synthesis/events/MessageSentEvent.java b/src/main/java/com/luna/synthesis/events/MessageSentEvent.java
new file mode 100644
index 0000000..4f7e5d4
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/events/MessageSentEvent.java
@@ -0,0 +1,13 @@
+package com.luna.synthesis.events;
+
+import net.minecraftforge.fml.common.eventhandler.Cancelable;
+import net.minecraftforge.fml.common.eventhandler.Event;
+
+@Cancelable
+public class MessageSentEvent extends Event {
+ public String message;
+
+ public MessageSentEvent(String message) {
+ this.message = message;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/luna/synthesis/features/cleanup/CoopCleanup.java b/src/main/java/com/luna/synthesis/features/cleanup/CoopCleanup.java
index 61c9c44..b6722f9 100644
--- a/src/main/java/com/luna/synthesis/features/cleanup/CoopCleanup.java
+++ b/src/main/java/com/luna/synthesis/features/cleanup/CoopCleanup.java
@@ -1,6 +1,5 @@
package com.luna.synthesis.features.cleanup;
-import com.luna.synthesis.Comment;
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
import com.luna.synthesis.events.packet.PacketReceivedEvent;
@@ -11,6 +10,7 @@
import net.minecraft.network.play.server.S02PacketChat;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.IChatComponent;
import net.minecraftforge.client.event.ClientChatReceivedEvent;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -29,9 +29,10 @@ public class CoopCleanup {
private List messageQueue = new ArrayList<>();
private boolean isDividerBlock = false;
+ private IChatComponent theMessage = null;
private final AtomicReference price = new AtomicReference<>("");
- @Comment("Collection tooltips. I could have used regexes for other people's contributions but they are laggy and this is invoked a lot of times per second. If there is any problem with this I'll eventually swap to regex but for now, this is decent. Also no, that Minecraft.getMinecraft().getSession().getUsername() further down is not a session stealer.")
+ // I'm deeply terrified of regexes being called way too many times, as long as the message cannot be faked or give false positives, this will have to work.
@SubscribeEvent
public void onTooltip(ItemTooltipEvent event) {
if (config.cleanupCoopCollections == 0) return;
@@ -39,9 +40,8 @@ public void onTooltip(ItemTooltipEvent event) {
event.toolTip.removeIf(s -> EnumChatFormatting.getTextWithoutFormattingCodes(s).endsWith(": 0"));
} else if (config.cleanupCoopCollections == 2) {
Iterator iterator = event.toolTip.iterator();
- iterator.forEachRemaining(s -> {
- String actualLine = EnumChatFormatting.getTextWithoutFormattingCodes(s);
-
+ while (iterator.hasNext()) {
+ String actualLine = EnumChatFormatting.getTextWithoutFormattingCodes(iterator.next());
if (actualLine.equals("")) {
onContributions = false;
}
@@ -54,12 +54,12 @@ public void onTooltip(ItemTooltipEvent event) {
if (actualLine.startsWith("Co-op Contributions:")) {
onContributions = true;
}
- });
+ }
onContributions = false;
} else if (config.cleanupCoopCollections == 3) {
Iterator iterator = event.toolTip.iterator();
- iterator.forEachRemaining(s -> {
- String actualLine = EnumChatFormatting.getTextWithoutFormattingCodes(s);
+ while (iterator.hasNext()) {
+ String actualLine = EnumChatFormatting.getTextWithoutFormattingCodes(iterator.next());
if (actualLine.startsWith("Co-op Contributions:")) {
shouldRemove = true;
}
@@ -72,13 +72,12 @@ public void onTooltip(ItemTooltipEvent event) {
if (actualLine.equals("")) {
shouldRemove = false;
}
- });
+ }
shouldRemove = false;
}
}
- @Comment("Travel messages. Same thing as earlier, but as long as it works without regexes and people can't fake the message, I won't use regexes.")
- // &9&l» &aaliasalias &eis traveling to &aPrivate Island &e&lFOLLOW&r
+ // It is not necessary to check hover action because the " » " changes color depending on party/coop member, but I realised that when this was already done so whatever
@SubscribeEvent
public void onChatMessage(ClientChatReceivedEvent event) {
if (!config.cleanupCoopTravel) return;
@@ -106,13 +105,18 @@ public void onChatMessage(ClientChatReceivedEvent event) {
event.setCanceled(true);
}
}
- if (event.message.getUnformattedText().startsWith("BIN Auction started for ") && !price.get().equals("")) {
- event.message = new ChatComponentText(event.message.getFormattedText().replace("!", "") + EnumChatFormatting.YELLOW + " at " + EnumChatFormatting.GOLD + price.get() + " coins" + EnumChatFormatting.YELLOW + "!");
- price.set("");
+ if (event.message.getUnformattedText().startsWith("BIN Auction started for ")) {
+ if (!price.get().equals("")) {
+ event.message = new ChatComponentText(event.message.getFormattedText().replace("!", "") + EnumChatFormatting.YELLOW + " at " + EnumChatFormatting.GOLD + price.get() + " coins" + EnumChatFormatting.YELLOW + "!");
+ price.set("");
+ } else {
+ theMessage = event.message;
+ event.setCanceled(true);
+ }
}
}
- @Comment("Used as a way to detect bulk/block messages (that are surrounded by dividers, like coop messages).")
+ // Used as a way to detect bulk messages (the ones between dividers) and filter out potential messages that got caught between them.
@SubscribeEvent
public void onPacketReceived(PacketReceivedEvent event) {
if (event.getPacket() instanceof S02PacketChat) {
@@ -186,6 +190,11 @@ public void onPacketReceived(PacketReceivedEvent event) {
return false;
}).collect(Collectors.toList());
if (messageQueue.size() <= 2) messageQueue.clear();
+ if (theMessage != null && !price.get().equals("")) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(theMessage.getFormattedText().replace("!", "") + EnumChatFormatting.YELLOW + " at " + EnumChatFormatting.GOLD + price.get() + " coins" + EnumChatFormatting.YELLOW + "!"));
+ theMessage = null;
+ price.set("");
+ }
} else {
isDividerBlock = true;
messageQueue.add(packet.getChatComponent().getUnformattedText());
diff --git a/src/main/java/com/luna/synthesis/features/cleanup/DungeonCleanup.java b/src/main/java/com/luna/synthesis/features/cleanup/DungeonCleanup.java
new file mode 100644
index 0000000..40dad2a
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/features/cleanup/DungeonCleanup.java
@@ -0,0 +1,47 @@
+package com.luna.synthesis.features.cleanup;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class DungeonCleanup {
+
+ private final Config config = Synthesis.getInstance().getConfig();
+
+ @SubscribeEvent
+ public void onChatMessage(ClientChatReceivedEvent event) {
+ if (event.type != 0) return;
+ String msg = StringUtils.stripControlCodes(event.message.getUnformattedText());
+ if (!msg.contains(":")) {
+ if (config.cleanupDungeonPotionEffects && msg.equals("Your active Potion Effects have been paused and stored. They will be restored when you leave Dungeons! You are not allowed to use existing Potion Effects while in Dungeons.")) {
+ event.setCanceled(true);
+ }
+ if (config.cleanupDungeonSoloClassMessage) {
+ if (msg.startsWith("Your ") && msg.endsWith(" stats are doubled because you are the only player using this class!")) {
+ event.setCanceled(true);
+ } else if (msg.startsWith("[Healer] ") || msg.startsWith("[Berserk] ") || msg.startsWith("[Mage] ") || msg.startsWith("[Archer] ") || msg.startsWith("[Tank] ")) {
+ event.setCanceled(true);
+ }
+ }
+ if (config.cleanupDungeonUltimateMessage && msg.endsWith(" is ready to use! Press DROP to activate it!")) {
+ event.setCanceled(true);
+ }
+ if (config.cleanupDungeonBlessingStatMessages) {
+ if ((config.cleanupDungeonBlessingMessages && (msg.startsWith("A Blessing of ") || (msg.contains(" has obtained Blessing of ") && msg.endsWith("!")))) || msg.startsWith("DUNGEON BUFF! A Blessing of ") || msg.startsWith("DUNGEON BUFF! You found a Blessing of ") || msg.startsWith(" Grants you ") || msg.startsWith(" Granted you ")) {
+ event.setCanceled(true);
+ }
+ }
+ if (config.cleanupDungeonSilverfishMessages && msg.equals("You cannot hit the silverfish while it's moving!")) {
+ event.setCanceled(true);
+ }
+ if (config.cleanupDungeonKeyUsageMessages && (msg.equals("RIGHT CLICK on the BLOOD DOOR to open it. This key can only be used to open 1 door!") || msg.equals("RIGHT CLICK on a WITHER door to open it. This key can only be used to open 1 door!"))) {
+ event.setCanceled(true);
+ }
+ }
+ if (config.cleanupDungeonWatcherMessages && msg.startsWith("[BOSS] The Watcher: ") && !msg.equals("[BOSS] The Watcher: You have proven yourself. You may pass.")) {
+ event.setCanceled(true);
+ }
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/features/cleanup/LoreCleanup.java b/src/main/java/com/luna/synthesis/features/cleanup/LoreCleanup.java
new file mode 100644
index 0000000..1f9c9e8
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/features/cleanup/LoreCleanup.java
@@ -0,0 +1,192 @@
+package com.luna.synthesis.features.cleanup;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import net.minecraft.client.Minecraft;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.event.entity.player.ItemTooltipEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import net.minecraft.item.ItemSkull;
+
+import java.util.Iterator;
+
+public class LoreCleanup {
+
+ private final Config config = Synthesis.getInstance().getConfig();
+ // Some fucking tasty spaghetti
+
+ @SubscribeEvent(priority = EventPriority.LOW)
+ public void onItemTooltip(ItemTooltipEvent event) {
+ if (Minecraft.getMinecraft().thePlayer.openContainer instanceof ContainerChest) {
+ ContainerChest containerChest = (ContainerChest)Minecraft.getMinecraft().thePlayer.openContainer;
+ String title = StringUtils.stripControlCodes(containerChest.getLowerChestInventory().getDisplayName().getUnformattedText());
+ if (config.cleanupLoreAuctionException && (title.startsWith("Auctions") || title.endsWith("Auction View") || title.endsWith("'s Auctions"))) return;
+ }
+ ItemStack item = event.itemStack;
+ if (!item.hasTagCompound() || !item.getTagCompound().hasKey("ExtraAttributes") || !item.getTagCompound().getCompoundTag("ExtraAttributes").hasKey("id")) return;
+ Iterator iterator = event.toolTip.iterator();
+ int index = 0;
+ boolean inEnchantments = false;
+ boolean inAbility = false;
+ boolean petHoldingItem = false;
+ boolean inPetsMenuAndIsAPet = ((item.getItem() instanceof ItemSkull && Minecraft.getMinecraft().thePlayer.openContainer instanceof ContainerChest && StringUtils.stripControlCodes(((ContainerChest)(Minecraft.getMinecraft().thePlayer.openContainer)).getLowerChestInventory().getDisplayName().getUnformattedText()).endsWith("Pets")) && (item.getDisplayName().matches(".+\\[Lvl \\d+\\] (?§[0-9a-fk-or]).+") || item.getDisplayName().matches(".+\\[\\d+\\] (?§[0-9a-fk-or]).+")));
+ String previousLine = "";
+ while (iterator.hasNext()) {
+ // Thank you vanilla, very cool
+ String line = iterator.next().replace("§5§o", "");
+ // GEAR SCORE, GEMSTONE SLOTS, SOULBOUND, PET STUFF
+ if (config.cleanupPetDisplayName && inPetsMenuAndIsAPet && StringUtils.stripControlCodes(item.getDisplayName()).startsWith("[Lvl ") && StringUtils.stripControlCodes(item.getDisplayName()).contains("] ")){
+ item.setStackDisplayName(item.getDisplayName().replace("Lvl ", ""));
+ }
+ /* CONDITIONAL TO SKIP BASE CASE LINES, EDIT WITH CAUTION! -ERY */
+ else if (inPetsMenuAndIsAPet && (previousLine.startsWith("§6") && previousLine.contains("Held Item"))) {
+ //(inPetsMenuAndIsAPet && (previousLine.startsWith("§6") && previousLine.contains("Held Item")) || line.matches(".*§7[a-z].*") || line.matches(".*§[abcde569].*")) //PLAN: THERE IS NONE. HYPIXEL IS SO INCONSISTENT WITH THEIR LINE SPACING I'M SURPRISED ANY OF THE UNCOMMENTED CODE I WROTE EVEN WORKS. -ERY
+ previousLine = line;
+ } else if (config.cleanupLorePetType > 0 && config.cleanupLorePetType < 4 && inPetsMenuAndIsAPet && line.startsWith("§8") && (line.endsWith(" Pet") || line.endsWith(" Mount") || line.endsWith(" Morph") || line.endsWith(" gain XP") || line.contains("All Skills"))) {
+ previousLine = line;
+ if (config.cleanupLorePetType == 3 || line.contains("All Skills"))
+ iterator.remove();
+ else if (config.cleanupLorePetType == 2 && !line.contains("All Skills"))
+ event.toolTip.set(index, line.replace("Mining ", "").replace("Combat ", "").replace("Fishing ", "").replace("Farming ", "").replace("Foraging ", "").replace("Enchanting ", "").replace("Alchemy ", "").replace("Gabagool ", ""));
+ else if (config.cleanupLorePetType == 1)
+ event.toolTip.set(index, line.replace(" Pet", "").replace(" Mount", "").replace(" Morph", "").replace(", feed to gain XP", ""));
+ } else if (config.cleanupLorePetPerkName && inPetsMenuAndIsAPet && line.startsWith("§6") && !line.contains("Held Item")) {
+ previousLine = line;
+ iterator.remove();
+ }
+ /* PLAN: SOMEHOW DETECT THE BEGINNING OF A NEW PERK DESCRIPTION AND ADD A HYPHEN TO THE BEGINNING OF IT.
+ I ALREADY TRIED THE "inXYZ" CONDITIONAL STRATEGY AND IT WENT TERRIBLY WRONG BECAUSE, AGAIN, HYPIXEL
+ PET MENU LORE HAS NO STANDARD CONVENTION WHATSOEVER. -ERY
+
+ else if (config.cleanupLorePetPerkHyphens && inPetsMenuAndIsAPet && line.contains("§7§7") && !line.contains(":") && line.matches(".*§7§7[A-Z].*") && !previousLine.contains("Held Item")) {
+ event.toolTip.set(index, ("§e§r§7- " + line));
+ previousLine = line;
+ continue;
+ */
+ else if (config.cleanupLorePetHeldItemPrefix && inPetsMenuAndIsAPet && line.contains("Held Item")) {
+ previousLine = line;
+ event.toolTip.set(index, line.replace("Held Item: ", ""));
+ petHoldingItem = true;
+ } else if (config.cleanupLorePetMaxLevel && inPetsMenuAndIsAPet && line.contains("MAX LEVEL")) {
+ previousLine = line;
+ iterator.remove();
+ } else if (config.cleanupLorePetClickToSummon && inPetsMenuAndIsAPet && line.contains("Click to summon!")) {
+ previousLine = line;
+ iterator.remove();
+ } else if (config.cleanupLorePetClickToDespawn && inPetsMenuAndIsAPet && line.contains("Click to despawn!")) {
+ previousLine = line;
+ iterator.remove();
+ } else if (config.cleanupLorePetCandiesUsed && inPetsMenuAndIsAPet && line.contains("Pet Candy Used")) {
+ previousLine = line;
+ // begin the very hacky solution i wrote but it works on the pets that i own so im rolling with this unless anyone has better ideas -ery
+ int ifPetHeldItemEnabledOffset = 2;
+ if (!config.cleanupLorePetHeldItemPrefix)
+ if (!petHoldingItem)
+ ifPetHeldItemEnabledOffset = 0;
+ else
+ ifPetHeldItemEnabledOffset = 1;
+ else if (!petHoldingItem)
+ ifPetHeldItemEnabledOffset = 0;
+ // end hacky solution -ery
+ String pluralOrSingular = "Candies";
+ if (line.contains("1/") && !line.contains("10/"))
+ pluralOrSingular = "Candy";
+ event.toolTip.set(index + ifPetHeldItemEnabledOffset, line.replace("/10", "").replace("Pet Candy Used", pluralOrSingular).replace("(", "").replace(")", ""));
+ } else if (config.cleanupLorePetEmptyLines && inPetsMenuAndIsAPet && line.equals("")) {
+ previousLine = line;
+ iterator.remove();
+ }
+ /* PLAN: SOMEHOW REMOVE PROGRESS BAR WITHOUT EDGE CASES OF PROGRESS COUNT DUPLICATING ITSELF.
+ ATTEMPTED AND FAILED BECAUSE AAAAAAAAAAAAAAAAAA -ERY
+
+ else if (config.cleanupLorePetLevelProgressBar && inPetsMenuAndIsAPet && line.contains("--") && (line.contains("f-") || line.contains("2-"))) {
+ event.toolTip.set(index, line.replaceAll("-", ""));
+ previousLine = line;
+ // iterator.remove();
+ continue;
+ }
+ */
+ /* PLAN: SOMEHOW REMOVE TEXT PRECEDING PERCENTAGE PROGRESS.
+ ATTEMPTED AND FAILED BECAUSE AAAAAAAAAAAAAAAAAA -ERY
+
+ else if (config.cleanupLorePetLevelPercent && inPetsMenuAndIsAPet && line.contains("Progress to Level")) {
+ event.toolTip.set(index, line.replaceAll(".*Progress to Level [0-9]{1,3}.*", "% of next Lvl"));
+ // previousLine = line;
+ continue;
+ }
+ */
+ else if (StringUtils.stripControlCodes(line).startsWith("Gear Score: ") && config.cleanupLoreGearScore) {
+ iterator.remove();
+ } else if (StringUtils.stripControlCodes(line).startsWith(" [") && config.cleanupLoreGemstoneSlots) {
+ iterator.remove();
+ } else if ((line.contains("§8§l") && line.contains("*") && line.contains("8Co-op Soulbound")) && config.cleanupLoreCoopSoulbound) {
+ iterator.remove();
+ } else if ((line.contains("§8§l") && line.contains("*") && line.contains("8Soulbound")) && config.cleanupLoreSoloSoulbound) {
+ iterator.remove();
+ } else {
+ // STAT BONUSES, RECOMBOBULATED TEXT
+ if (line.contains(" ")) {
+ for (String s : line.split(" ")) {
+ String replacement = line.replace(s + " ", "").replace(s, "");
+ if (s.startsWith("§8(+") && config.cleanupLoreDungeon) {
+ event.toolTip.set(index, replacement);
+ line = replacement;
+ } else if (s.startsWith("§d(+") && config.cleanupLoreGemstones) {
+ event.toolTip.set(index, replacement);
+ line = replacement;
+ } else if (s.startsWith("§9(+") && config.cleanupLoreReforge) {
+ event.toolTip.set(index, replacement);
+ line = replacement;
+ } else if (s.startsWith("§e(+") && config.cleanupLoreHPB) {
+ event.toolTip.set(index, replacement);
+ line = replacement;
+ } else if (s.contains("§l§ka") && config.cleanupLoreRecombobulatedObfuscated) {
+ event.toolTip.set(index, replacement);
+ line = replacement;
+ }
+ }
+ }
+
+ // ENCHANTMENTS
+ if (!StringUtils.stripControlCodes(item.getDisplayName()).equals("Enchanted Book")) {
+ if (((line.startsWith("§9") || line.startsWith("§d§l")) && config.cleanupLoreEnchantmentDescriptions && !(inPetsMenuAndIsAPet && item.getItem() instanceof ItemSkull))) inEnchantments = true;
+ if (inEnchantments) {
+ if (!config.cleanupLoreEnchantments && (line.startsWith("§9") || line.startsWith("§d§l"))) {
+ index++;
+ continue;
+ }
+ if (StringUtils.stripControlCodes(line).equals("")) {
+ iterator.remove();
+ continue;
+ }
+ inEnchantments = false;
+ if (config.cleanupLoreEnchantments) {
+ iterator.remove();
+ continue;
+ }
+ }
+ }
+
+ // ABILITIES
+ if (!line.endsWith("RIGHT CLICK") && !line.endsWith("LEFT CLICK") && !line.equals("§aScroll Abilities:")) {
+ if (config.cleanupLoreReforgeAbility && line.startsWith("§9") && line.endsWith(" Bonus")) inAbility = true;
+ else if (config.cleanupLoreFullSetBonus && line.startsWith("§6Full Set Bonus: ")) inAbility = true;
+ else if (config.cleanupLorePieceBonus && line.startsWith("§6Piece Bonus: ")) inAbility = true;
+ } else if (config.cleanupLoreAbilities) {
+ inAbility = true;
+ }
+ if (inAbility) {
+ iterator.remove();
+ if (line.equals("")) inAbility = false;
+ } else {
+ index++;
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/features/future/ChunkBorders.java b/src/main/java/com/luna/synthesis/features/future/ChunkBorders.java
index 8be0e2b..088382b 100644
--- a/src/main/java/com/luna/synthesis/features/future/ChunkBorders.java
+++ b/src/main/java/com/luna/synthesis/features/future/ChunkBorders.java
@@ -1,6 +1,5 @@
package com.luna.synthesis.features.future;
-import com.luna.synthesis.Comment;
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
import net.minecraft.client.Minecraft;
@@ -20,7 +19,7 @@ public class ChunkBorders {
private final Config config = Synthesis.getInstance().getConfig();
private boolean isToggled = false;
- @Comment("Code directly taken from 1.12.2, translated to 1.8.9 and cleaned up a little.")
+ // Directly taken from 1.12.2, translated and adapted a bit.
@SubscribeEvent
public void onRenderWorld(RenderWorldLastEvent event) {
if (!config.futureChunkBorders) return;
@@ -114,7 +113,7 @@ public void onRenderWorld(RenderWorldLastEvent event) {
GlStateManager.enableTexture2D();
}
- @Comment("61 is F3, 34 is G")
+ // F3 + G, like in future versions of the game. Should this be configurable? Eh..
@SubscribeEvent
public void onKeyPress(InputEvent.KeyInputEvent event) {
if (!Keyboard.getEventKeyState()) return;
diff --git a/src/main/java/com/luna/synthesis/features/utilities/AncestralSpade.java b/src/main/java/com/luna/synthesis/features/utilities/AncestralSpade.java
new file mode 100644
index 0000000..e3d0979
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/features/utilities/AncestralSpade.java
@@ -0,0 +1,157 @@
+package com.luna.synthesis.features.utilities;
+
+import com.luna.synthesis.Synthesis;
+import com.luna.synthesis.core.Config;
+import com.luna.synthesis.events.packet.PacketReceivedEvent;
+import com.luna.synthesis.utils.ChatLib;
+import com.luna.synthesis.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.item.ItemStack;
+import net.minecraft.network.play.server.S2APacketParticles;
+import net.minecraft.util.*;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.client.event.RenderWorldLastEvent;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.awt.*;
+
+public class AncestralSpade {
+
+ private final Config config = Synthesis.getInstance().getConfig();
+ private final ResourceLocation beaconBeam = new ResourceLocation("textures/entity/beacon_beam.png");
+ private boolean awaiting = false;
+ private boolean awaitingForArrow = false;
+ private long lastSpoon = -1L;
+ private Vec3 pos1 = null;
+ private Vec3 pos2 = null;
+ private Vec3 vec1 = null;
+ private Vec3 vec2 = null;
+ private BlockPos solution = null;
+
+ @SubscribeEvent
+ public void onPacketReceived(PacketReceivedEvent event) {
+ if (!config.utilitiesAncestralSpade) return;
+ if (event.getPacket() instanceof S2APacketParticles) {
+ S2APacketParticles packet = (S2APacketParticles) event.getPacket();
+ if (packet.getParticleType() == EnumParticleTypes.FIREWORKS_SPARK && packet.getXOffset() == 0 && packet.getYOffset() == 0 && packet.getZOffset() == 0) {
+ if (packet.getParticleSpeed() == 0 && packet.getParticleCount() == 1) {
+ if (awaiting) {
+ if (pos1 == null) {
+ pos1 = new Vec3(packet.getXCoordinate(), packet.getYCoordinate(), packet.getZCoordinate());
+ awaiting = false;
+ } else if (pos2 == null) {
+ pos2 = new Vec3(packet.getXCoordinate(), packet.getYCoordinate(), packet.getZCoordinate());
+ awaiting = false;
+ }
+ } else {
+ if (vec1 == null && pos1 != null) {
+ vec1 = new Vec3(packet.getXCoordinate() - pos1.xCoord, packet.getYCoordinate() - pos1.yCoord, packet.getZCoordinate() - pos1.zCoord).normalize();
+ } else if (vec2 == null && pos2 != null) {
+ vec2 = new Vec3(packet.getXCoordinate() - pos2.xCoord, packet.getYCoordinate() - pos2.yCoord, packet.getZCoordinate() - pos2.zCoord).normalize();
+ calculateIntercept();
+ }
+ }
+ }
+ } else if (packet.getParticleType() == EnumParticleTypes.REDSTONE && packet.getParticleSpeed() == 1 && packet.getParticleCount() == 0) {
+ if (awaitingForArrow) {
+ if (pos1 == null) {
+ pos1 = new Vec3(packet.getXCoordinate(), packet.getYCoordinate(), packet.getZCoordinate());
+ } else if (vec1 == null) {
+ if (packet.getXCoordinate() - pos1.xCoord == 0 && packet.getZCoordinate() - pos1.zCoord == 0) return;
+ vec1 = new Vec3(packet.getXCoordinate() - pos1.xCoord, packet.getYCoordinate() - pos1.yCoord, packet.getZCoordinate() - pos1.zCoord).normalize();
+ awaitingForArrow = false;
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onRightClick(PlayerInteractEvent event) {
+ if (!config.utilitiesAncestralSpade) return;
+ if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_AIR || event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) {
+ ItemStack item = Minecraft.getMinecraft().thePlayer.getHeldItem();
+ if (item == null) return;
+ if (StringUtils.stripControlCodes(item.getDisplayName()).contains("Ancestral Spade")) {
+ if (System.currentTimeMillis() >= lastSpoon + 3000) {
+ if (Minecraft.getMinecraft().thePlayer.rotationPitch == 90 || Minecraft.getMinecraft().thePlayer.rotationPitch == -90) {
+ awaiting = true;
+ lastSpoon = System.currentTimeMillis();
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onClientTick(TickEvent.ClientTickEvent event) {
+ if (solution != null && Minecraft.getMinecraft().thePlayer != null) {
+ if (Math.pow(Minecraft.getMinecraft().thePlayer.posX - solution.getX(), 2) + Math.pow(Minecraft.getMinecraft().thePlayer.posZ - solution.getZ(), 2) <= 9) {
+ solution = null;
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onChatMessage(ClientChatReceivedEvent event) {
+ if (event.type == 2) return;
+ if (!config.utilitiesAncestralSpade || !config.utilitiesAncestralSpadeArrow) return;
+ String msg = StringUtils.stripControlCodes(event.message.getUnformattedText());
+ if (msg.startsWith("You dug out a Griffin Burrow!")) {
+ awaitingForArrow = true;
+ }
+ }
+
+ @SubscribeEvent
+ public void onRenderWorld(RenderWorldLastEvent event) {
+ if (config.utilitiesAncestralSpadeWaypoint && solution != null) {
+ double renderPosX = Minecraft.getMinecraft().getRenderManager().viewerPosX;
+ double renderPosY = Minecraft.getMinecraft().getRenderManager().viewerPosY;
+ double renderPosZ = Minecraft.getMinecraft().getRenderManager().viewerPosZ;
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(-renderPosX, -renderPosY, -renderPosZ);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(beaconBeam);
+ Utils.renderBeamSegment(solution.getX(), 0, solution.getZ(), event.partialTicks, 1.0, Minecraft.getMinecraft().theWorld.getTotalWorldTime(), 0, 256, config.utilitiesAncestralSpadeWaypointColor.getColorComponents(null));
+ GlStateManager.translate(renderPosX, renderPosY, renderPosZ);
+ GlStateManager.popMatrix();
+ }
+ }
+
+ @SubscribeEvent
+ public void onWorldLoad(WorldEvent.Load event) {
+ pos1 = null;
+ pos2 = null;
+ vec1 = null;
+ vec2 = null;
+ awaiting = false;
+ solution = null;
+ }
+
+ // 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 p1x = pos1.xCoord;
+ double p1z = pos1.zCoord;
+ double v1x = vec1.xCoord;
+ double v1z = vec1.zCoord;
+ //
+ double p2x = pos2.xCoord;
+ double p2z = pos2.zCoord;
+ double v2x = vec2.xCoord;
+ double v2z = vec2.zCoord;
+ double a = v1z / v1x * p1x - p1z;
+ double b = v2z / v2x * p2x - p2z;
+ double x = (a - b) / (v1z / v1x - v2z / v2x);
+ double z = v1z / v1x * x - a;
+
+ BlockPos solution = new BlockPos(x, 0, z);
+ ChatLib.chat("Solution: (" + solution.getX() + ", " + solution.getZ() + ")");
+ this.solution = solution;
+ pos1 = pos2 = vec1 = vec2 = null;
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/features/utilities/BestiaryDropRate.java b/src/main/java/com/luna/synthesis/features/utilities/BestiaryDropRate.java
index 7298394..cf62acd 100644
--- a/src/main/java/com/luna/synthesis/features/utilities/BestiaryDropRate.java
+++ b/src/main/java/com/luna/synthesis/features/utilities/BestiaryDropRate.java
@@ -30,11 +30,13 @@ public void onItemTooltip(ItemTooltipEvent event) {
it.forEachRemaining(s -> {
String line = StringUtils.stripControlCodes(s);
if (line.endsWith("%)")) {
- double number = Double.parseDouble(line.split("\\(")[1].replace("%)", ""));
- if (number < 100) {
- event.toolTip.set(i.get(), s.replaceAll("\\(§a[\\d.]+%§8\\)",
- EnumChatFormatting.DARK_GRAY + "(" + EnumChatFormatting.GREEN + "1/" + Math.floor(10000/number + 0.5) / 100 + EnumChatFormatting.DARK_GRAY + ")"));
- }
+ try {
+ double number = Double.parseDouble(line.split("\\(")[1].replace("%)", ""));
+ if (number < 100) {
+ event.toolTip.set(i.get(), s.replaceAll("\\(§a[\\d.]+%§8\\)",
+ EnumChatFormatting.DARK_GRAY + "(" + EnumChatFormatting.GREEN + "1/" + Math.floor(10000 / number + 0.5) / 100 + EnumChatFormatting.DARK_GRAY + ")"));
+ }
+ } catch (NumberFormatException ignored) {}
}
i.getAndIncrement();
});
diff --git a/src/main/java/com/luna/synthesis/features/utilities/BetterWitherImpactPerspective.java b/src/main/java/com/luna/synthesis/features/utilities/BetterWitherImpactPerspective.java
new file mode 100644
index 0000000..a322223
--- /dev/null
+++ b/src/main/java/com/luna/synthesis/features/utilities/BetterWitherImpactPerspective.java
@@ -0,0 +1,40 @@
+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.item.ItemStack;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.InputEvent;
+import org.lwjgl.input.Keyboard;
+
+public class BetterWitherImpactPerspective {
+
+ private final Config config = Synthesis.getInstance().getConfig();
+
+ // InputEvent has to be the absolute worst event in forge
+ @SubscribeEvent
+ public void onKey(InputEvent.KeyInputEvent event) {
+ if (!config.utilitiesWitherImpactPerspective) return;
+ if (!Keyboard.getEventKeyState()) return;
+ if (Keyboard.getEventKey() == Minecraft.getMinecraft().gameSettings.keyBindTogglePerspective.getKeyCode()) {
+ if (Minecraft.getMinecraft().gameSettings.thirdPersonView == 2) {
+ if (config.utilitiesWitherImpactPerspectiveGlobal) {
+ Minecraft.getMinecraft().gameSettings.thirdPersonView = 0;
+ } else {
+ ItemStack item = Minecraft.getMinecraft().thePlayer.getHeldItem();
+ if (item == null) return;
+ if (item.hasTagCompound()) {
+ if (item.getTagCompound().hasKey("ExtraAttributes")) {
+ if (item.getTagCompound().getCompoundTag("ExtraAttributes").hasKey("ability_scroll")) {
+ if (item.getTagCompound().getCompoundTag("ExtraAttributes").getTagList("ability_scroll", 8).tagCount() == 3) {
+ Minecraft.getMinecraft().gameSettings.thirdPersonView = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/luna/synthesis/features/utilities/ChatBridge.java b/src/main/java/com/luna/synthesis/features/utilities/ChatBridge.java
index 4262e99..5e3d249 100644
--- a/src/main/java/com/luna/synthesis/features/utilities/ChatBridge.java
+++ b/src/main/java/com/luna/synthesis/features/utilities/ChatBridge.java
@@ -1,16 +1,14 @@
package com.luna.synthesis.features.utilities;
-import com.luna.synthesis.Comment;
import com.luna.synthesis.Synthesis;
import com.luna.synthesis.core.Config;
-import net.minecraft.client.Minecraft;
+import com.luna.synthesis.utils.Utils;
import net.minecraft.event.ClickEvent;
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.common.ForgeHooks;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.net.URI;
@@ -21,11 +19,9 @@
public class ChatBridge {
private final Config config = Synthesis.getInstance().getConfig();
- private final Pattern msgPattern = Pattern.compile("^Guild > (?\\[[A-Z+]+] )?(?[a-zA-Z0-9_]{3,16})(? \\[.+])?: (?[^>: ]{1,32})(?( > |: ))(?.+)");
- private 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);
+ private final Pattern msgPattern = Pattern.compile("^Guild > (?\\[[A-Z+]+] )?(?[a-zA-Z0-9_]{3,16})(? \\[.+])?: (?.*)(?( >|:))(? .*)");
- @Comment("That second if is to not try to match that pattern on a message that will never be correct.")
- @SubscribeEvent
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
public void onClientChatMessage(ClientChatReceivedEvent event) {
if (!config.utilitiesBridge) return;
String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
@@ -36,58 +32,8 @@ public void onClientChatMessage(ClientChatReceivedEvent event) {
if (msgSender.equals(config.utilitiesBridgeBotName)) {
String ign = matcher.group(4);
String msg = matcher.group(7);
- event.message = newChatWithLinks(config.utilitiesBridgeMessageFormat.replaceAll("&", "§").replace("", ign).replace("", msg));
+ event.message = Utils.newChatWithLinks(config.utilitiesBridgeMessageFormat.replaceAll("&", "§").replace("", ign).replace("", 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/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": [],