diff options
author | Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> | 2023-07-22 14:48:12 +0800 |
---|---|---|
committer | Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> | 2023-08-18 18:05:15 +0800 |
commit | b80f6df13b8dfb97f1569f5802b66fc837480eef (patch) | |
tree | 3805f4ef04bbe988240862cfd528163047acb3bf /src/main/java/me/xmrvizzy/skyblocker/utils | |
parent | fc65ff5b469fb384d2df422a5a6d8437012a819b (diff) | |
download | Skyblocker-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')
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; + } +} |