aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/me/xmrvizzy/skyblocker/utils
diff options
context:
space:
mode:
authorKevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>2023-07-22 14:48:12 +0800
committerKevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>2023-08-18 18:05:15 +0800
commitb80f6df13b8dfb97f1569f5802b66fc837480eef (patch)
tree3805f4ef04bbe988240862cfd528163047acb3bf /src/main/java/me/xmrvizzy/skyblocker/utils
parentfc65ff5b469fb384d2df422a5a6d8437012a819b (diff)
downloadSkyblocker-b80f6df13b8dfb97f1569f5802b66fc837480eef.tar.gz
Skyblocker-b80f6df13b8dfb97f1569f5802b66fc837480eef.tar.bz2
Skyblocker-b80f6df13b8dfb97f1569f5802b66fc837480eef.zip
Refactor chat and discord packages
Diffstat (limited to 'src/main/java/me/xmrvizzy/skyblocker/utils')
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/chat/ChatFilterResult.java18
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/chat/ChatMessageListener.java88
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/chat/ChatPatternListener.java30
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/discord/DiscordRPCManager.java122
4 files changed, 258 insertions, 0 deletions
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/chat/ChatFilterResult.java b/src/main/java/me/xmrvizzy/skyblocker/utils/chat/ChatFilterResult.java
new file mode 100644
index 00000000..cd364eb5
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/chat/ChatFilterResult.java
@@ -0,0 +1,18 @@
+package me.xmrvizzy.skyblocker.utils.chat;
+
+import net.minecraft.client.resource.language.I18n;
+public enum ChatFilterResult {
+ // Skip this one / no action
+ PASS,
+ // Filter
+ FILTER,
+ // Move to action bar
+ ACTION_BAR;
+ // Skip remaining checks, don't filter
+ // null
+
+ @Override
+ public String toString() {
+ return I18n.translate("text.autoconfig.skyblocker.option.messages.chatFilterResult." + name());
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/chat/ChatMessageListener.java b/src/main/java/me/xmrvizzy/skyblocker/utils/chat/ChatMessageListener.java
new file mode 100644
index 00000000..7bb75947
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/chat/ChatMessageListener.java
@@ -0,0 +1,88 @@
+package me.xmrvizzy.skyblocker.utils.chat;
+
+import me.xmrvizzy.skyblocker.skyblock.barn.HungryHiker;
+import me.xmrvizzy.skyblocker.skyblock.barn.TreasureHunter;
+import me.xmrvizzy.skyblocker.skyblock.dungeon.Reparty;
+import me.xmrvizzy.skyblocker.skyblock.dungeon.ThreeWeirdos;
+import me.xmrvizzy.skyblocker.skyblock.dungeon.Trivia;
+import me.xmrvizzy.skyblocker.skyblock.dwarven.Fetchur;
+import me.xmrvizzy.skyblocker.skyblock.dwarven.Puzzler;
+import me.xmrvizzy.skyblocker.skyblock.filters.*;
+import me.xmrvizzy.skyblocker.utils.Utils;
+import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
+import net.fabricmc.fabric.api.event.Event;
+import net.fabricmc.fabric.api.event.EventFactory;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.text.Text;
+
+@FunctionalInterface
+public interface ChatMessageListener {
+ /**
+ * An event called when a game message is received. Register your listeners in {@link ChatMessageListener#init()}.
+ */
+ Event<ChatMessageListener> EVENT = EventFactory.createArrayBacked(ChatMessageListener.class,
+ (listeners) -> (message, asString) -> {
+ for (ChatMessageListener listener : listeners) {
+ ChatFilterResult result = listener.onMessage(message, asString);
+ if (result != ChatFilterResult.PASS) return result;
+ }
+ return ChatFilterResult.PASS;
+ });
+
+ /**
+ * Registers {@link ChatMessageListener}s to {@link ChatMessageListener#EVENT} and registers {@link ChatMessageListener#EVENT} to {@link ClientReceiveMessageEvents#ALLOW_GAME}
+ */
+ static void init() {
+ ChatMessageListener[] listeners = new ChatMessageListener[]{
+ // Features
+ new Fetchur(),
+ new Puzzler(),
+ new Reparty(),
+ new ThreeWeirdos(),
+ new Trivia(),
+ new TreasureHunter(),
+ new HungryHiker(),
+ // Filters
+ new AbilityFilter(),
+ new AdFilter(),
+ new AoteFilter(),
+ new ComboFilter(),
+ new HealFilter(),
+ new ImplosionFilter(),
+ new MoltenWaveFilter(),
+ new TeleportPadFilter(),
+ new AutopetFilter(),
+ new ShowOffFilter()
+ };
+ // Register all listeners to EVENT
+ for (ChatMessageListener listener : listeners) {
+ EVENT.register(listener);
+ }
+ // Register EVENT to ClientReceiveMessageEvents.ALLOW_GAME from fabric api
+ ClientReceiveMessageEvents.ALLOW_GAME.register((message, overlay) -> {
+ if (!Utils.isOnSkyblock()) {
+ return true;
+ }
+ ChatFilterResult result = EVENT.invoker().onMessage(message, message.getString());
+ switch (result) {
+ case ACTION_BAR -> {
+ if (overlay) {
+ return true;
+ }
+ ClientPlayerEntity player = MinecraftClient.getInstance().player;
+ if (player != null) {
+ player.sendMessage(message, true);
+ return false;
+ }
+ }
+ case FILTER -> {
+ return false;
+ }
+ }
+ return true;
+ });
+ }
+
+ ChatFilterResult onMessage(Text message, String asString);
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/chat/ChatPatternListener.java b/src/main/java/me/xmrvizzy/skyblocker/utils/chat/ChatPatternListener.java
new file mode 100644
index 00000000..3b363a85
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/chat/ChatPatternListener.java
@@ -0,0 +1,30 @@
+package me.xmrvizzy.skyblocker.utils.chat;
+
+import net.minecraft.text.Text;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public abstract class ChatPatternListener implements ChatMessageListener {
+ protected static final String NUMBER = "-?[0-9]{1,3}(?>,[0-9]{3})*(?:\\.[1-9])?";
+ public final Pattern pattern;
+
+ public ChatPatternListener(String pattern) {
+ this.pattern = Pattern.compile(pattern);
+ }
+
+ @Override
+ public final ChatFilterResult onMessage(Text message, String asString) {
+ ChatFilterResult state = state();
+ if (state == ChatFilterResult.PASS) return ChatFilterResult.PASS;
+ Matcher m = pattern.matcher(asString);
+ if (m.matches() && onMatch(message, m)) {
+ return state;
+ }
+ return ChatFilterResult.PASS;
+ }
+
+ protected abstract ChatFilterResult state();
+
+ protected abstract boolean onMatch(Text message, Matcher matcher);
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/discord/DiscordRPCManager.java b/src/main/java/me/xmrvizzy/skyblocker/utils/discord/DiscordRPCManager.java
new file mode 100644
index 00000000..58408944
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/discord/DiscordRPCManager.java
@@ -0,0 +1,122 @@
+package me.xmrvizzy.skyblocker.utils.discord;
+
+
+import me.shedaniel.autoconfig.AutoConfig;
+import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
+import me.xmrvizzy.skyblocker.utils.SkyblockEvents;
+import me.xmrvizzy.skyblocker.utils.Utils;
+import meteordevelopment.discordipc.DiscordIPC;
+import meteordevelopment.discordipc.RichPresence;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.DecimalFormat;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Manages the discord rich presence. Automatically connects to discord and displays a customizable activity when playing Skyblock.
+ */
+public class DiscordRPCManager {
+ public static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###,###.##");
+ public static final Logger LOGGER = LoggerFactory.getLogger("Skyblocker Discord RPC");
+ /**
+ * The update task used to avoid multiple update tasks running simultaneously.
+ */
+ public static CompletableFuture<Void> updateTask;
+ public static long startTimeStamp;
+ public static int cycleCount;
+
+ public static void init() {
+ SkyblockEvents.LEAVE.register(DiscordRPCManager::initAndUpdatePresence);
+ SkyblockEvents.JOIN.register(() -> {
+ startTimeStamp = System.currentTimeMillis();
+ initAndUpdatePresence(true);
+ });
+ }
+
+ /**
+ * Checks the {@link SkyblockerConfig.RichPresence#customMessage custom message}, updates {@link #cycleCount} if enabled, and updates rich presence.
+ */
+ public static void updateDataAndPresence() {
+ // If the custom message is empty, discord will keep the last message, this is can serve as a default if the user doesn't want a custom message
+ if (SkyblockerConfig.get().richPresence.customMessage.isEmpty()) {
+ SkyblockerConfig.get().richPresence.customMessage = "Playing Skyblock";
+ AutoConfig.getConfigHolder(SkyblockerConfig.class).save();
+ }
+ if (SkyblockerConfig.get().richPresence.cycleMode) cycleCount = (cycleCount + 1) % 3;
+ initAndUpdatePresence();
+ }
+
+ /**
+ * @see #initAndUpdatePresence(boolean)
+ */
+ private static void initAndUpdatePresence() {
+ initAndUpdatePresence(false);
+ }
+
+ /**
+ * Updates discord presence asynchronously.
+ * <p>
+ * When the {@link #updateTask previous update} does not exist or {@link CompletableFuture#isDone() has completed}:
+ * <p>
+ * Connects to discord if {@link SkyblockerConfig.RichPresence#enableRichPresence rich presence is enabled},
+ * the player {@link Utils#isOnSkyblock() is on Skyblock}, and {@link DiscordIPC#isConnected() discord is not already connected}.
+ * Updates the presence if {@link SkyblockerConfig.RichPresence#enableRichPresence rich presence is enabled}
+ * and the player {@link Utils#isOnSkyblock() is on Skyblock}.
+ * Stops the connection if {@link SkyblockerConfig.RichPresence#enableRichPresence rich presence is disabled}
+ * or the player {@link Utils#isOnSkyblock() is not on Skyblock} and {@link DiscordIPC#isConnected() discord is connected}.
+ * Saves the update task in {@link #updateTask}
+ *
+ * @param initialization whether this is the first time the presence is being updates. If {@code true}, a message will be logged
+ * if {@link SkyblockerConfig.RichPresence#enableRichPresence rich presence is disabled}.
+ */
+ private static void initAndUpdatePresence(boolean initialization) {
+ if (updateTask == null || updateTask.isDone()) {
+ updateTask = CompletableFuture.runAsync(() -> {
+ if (SkyblockerConfig.get().richPresence.enableRichPresence && Utils.isOnSkyblock()) {
+ if (!DiscordIPC.isConnected()) {
+ if (DiscordIPC.start(934607927837356052L, null)) {
+ LOGGER.info("Discord RPC started successfully");
+ } else {
+ LOGGER.error("Discord RPC failed to start");
+ return;
+ }
+ }
+ DiscordIPC.setActivity(buildPresence());
+ } else if (DiscordIPC.isConnected()) {
+ DiscordIPC.stop();
+ LOGGER.info("Discord RPC stopped");
+ } else if (initialization) {
+ LOGGER.info("Discord RPC is currently disabled");
+ }
+ });
+ }
+ }
+
+ public static RichPresence buildPresence() {
+ RichPresence presence = new RichPresence();
+ presence.setLargeImage("skyblocker-default", null);
+ presence.setStart(startTimeStamp);
+ presence.setDetails(SkyblockerConfig.get().richPresence.customMessage);
+ presence.setState(getInfo());
+ return presence;
+ }
+
+ public static String getInfo() {
+ String info = null;
+ if (!SkyblockerConfig.get().richPresence.cycleMode) {
+ switch (SkyblockerConfig.get().richPresence.info) {
+ case BITS -> info = "Bits: " + DECIMAL_FORMAT.format(Utils.getBits());
+ case PURSE -> info = "Purse: " + DECIMAL_FORMAT.format(Utils.getPurse());
+ case LOCATION -> info = Utils.getLocation();
+ }
+ } else if (SkyblockerConfig.get().richPresence.cycleMode) {
+ switch (cycleCount) {
+ case 0 -> info = "Bits: " + DECIMAL_FORMAT.format(Utils.getBits());
+ case 1 -> info = "Purse: " + DECIMAL_FORMAT.format(Utils.getPurse());
+ case 2 -> info = Utils.getLocation();
+ }
+ }
+ return info;
+ }
+}