Skip to content

Chat events refactor #1125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion src/main/java/de/hysky/skyblocker/events/ChatEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Environment(EnvType.CLIENT)
Expand All @@ -23,7 +24,7 @@ public class ChatEvents {

/**
* This will be called when a game message is received, cancelled or not.
* This method is called with the result of {@link Text#getString()} to avoid each listener having to call it.
* This method is called with the result of {@link Text#getString} and {@link Formatting#strip} to avoid each listener having to call it.
*
* @implNote Not fired when {@code overlay} is {@code true}. See {@link de.hysky.skyblocker.mixins.MessageHandlerMixin#skyblocker$monitorGameMessage(Text, boolean, CallbackInfo) the mixin} for more information.
*/
Expand All @@ -34,6 +35,31 @@ public class ChatEvents {
}
});

/**
* This will be called when a game message is received, cancelled or not.
*
* @implNote Not fired when {@code overlay} is {@code false}. See {@link de.hysky.skyblocker.mixins.MessageHandlerMixin#skyblocker$monitorGameMessage(Text, boolean, CallbackInfo) the mixin} for more information.
*/
@SuppressWarnings("JavadocReference")
public static final Event<ChatTextEvent> RECEIVE_OVERLAY_TEXT = EventFactory.createArrayBacked(ChatTextEvent.class, listeners -> message -> {
for (ChatTextEvent listener : listeners) {
listener.onMessage(message);
}
});

/**
* This will be called when a game message is received, cancelled or not.
* This method is called with the result of {@link Text#getString} and {@link Formatting#strip} to avoid each listener having to call it.
*
* @implNote Not fired when {@code overlay} is {@code false}. See {@link de.hysky.skyblocker.mixins.MessageHandlerMixin#skyblocker$monitorGameMessage(Text, boolean, CallbackInfo) the mixin} for more information.
*/
@SuppressWarnings("JavadocReference")
public static final Event<ChatStringEvent> RECEIVE_OVERLAY_STRING = EventFactory.createArrayBacked(ChatStringEvent.class, listeners -> message -> {
for (ChatStringEvent listener : listeners) {
listener.onMessage(message);
}
});

@FunctionalInterface
public interface ChatTextEvent {
void onMessage(Text message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import de.hysky.skyblocker.events.ChatEvents;
import net.minecraft.client.network.message.MessageHandler;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
Expand All @@ -12,8 +13,13 @@
public class MessageHandlerMixin {
@Inject(method = "onGameMessage", at = @At("HEAD"))
private void skyblocker$monitorGameMessage(Text message, boolean overlay, CallbackInfo ci) {
if (overlay) return; //Can add overlay-specific events in the future or incorporate it into the existing events. For now, it's not necessary.
ChatEvents.RECEIVE_TEXT.invoker().onMessage(message);
ChatEvents.RECEIVE_STRING.invoker().onMessage(message.getString());
String stripped = Formatting.strip(message.getString());
if (overlay) {
ChatEvents.RECEIVE_OVERLAY_TEXT.invoker().onMessage(message);
ChatEvents.RECEIVE_OVERLAY_STRING.invoker().onMessage(stripped);
} else {
ChatEvents.RECEIVE_TEXT.invoker().onMessage(message);
ChatEvents.RECEIVE_STRING.invoker().onMessage(stripped);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package de.hysky.skyblocker.skyblock.accessories.newyearcakes;

import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.events.ChatEvents;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.render.gui.ColorHighlight;
import de.hysky.skyblocker.utils.container.SimpleContainerSolver;
import de.hysky.skyblocker.utils.render.gui.ColorHighlight;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -29,7 +28,7 @@ public class NewYearCakesHelper extends SimpleContainerSolver {

private NewYearCakesHelper() {
super("Auctions: \".*\"");
ClientReceiveMessageEvents.GAME.register(this::onChatMessage);
ChatEvents.RECEIVE_STRING.register(this::onChatMessage);
}

public static int getCakeYear(ItemStack stack) {
Expand Down Expand Up @@ -58,9 +57,9 @@ public boolean addCake(int year) {
return cakes.computeIfAbsent(Utils.getProfile(), _profile -> new IntOpenHashSet()).add(year);
}

private void onChatMessage(Text message, boolean overlay) {
private void onChatMessage(String message) {
if (isEnabled()) {
addCake(getCakeYear(NEW_YEAR_CAKE_PURCHASE, message.getString()));
addCake(getCakeYear(NEW_YEAR_CAKE_PURCHASE, message));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import com.mojang.brigadier.Command;
import de.hysky.skyblocker.annotations.Init;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.events.ChatEvents;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.scheduler.MessageScheduler;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.ClickEvent;
import net.minecraft.text.HoverEvent;
Expand Down Expand Up @@ -38,7 +38,7 @@ public static void init() {
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(
ClientCommandManager.literal("skyblocker").then(ClientCommandManager.literal("sharePosition").executes(context -> sharePlayerPosition(context.getSource())))
));
ClientReceiveMessageEvents.GAME.register(ChatPositionShare::onMessage);
ChatEvents.RECEIVE_STRING.register(ChatPositionShare::onMessage);
}

private static int sharePlayerPosition(FabricClientCommandSource source) {
Expand All @@ -47,10 +47,8 @@ private static int sharePlayerPosition(FabricClientCommandSource source) {
return Command.SINGLE_SUCCESS;
}

private static void onMessage(Text text, boolean overlay) {
private static void onMessage(String message) {
if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().uiAndVisuals.waypoints.enableWaypoints) {
String message = text.getString();

for (Pattern pattern : PATTERNS) {
Matcher matcher = pattern.matcher(message);
if (matcher.find()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

import de.hysky.skyblocker.annotations.Init;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.events.ChatEvents;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.scheduler.MessageScheduler;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.fabricmc.fabric.api.client.screen.v1.ScreenMouseEvents;
Expand All @@ -23,7 +23,7 @@ public class ConfirmationPromptHelper {

@Init
public static void init() {
ClientReceiveMessageEvents.GAME.register(ConfirmationPromptHelper::onMessage);
ChatEvents.RECEIVE_TEXT.register(ConfirmationPromptHelper::onMessage);
ScreenEvents.AFTER_INIT.register((_client, screen, _scaledWidth, _scaledHeight) -> {
//Don't check for the command being present in case the user opens the chat before the prompt is sent
if (Utils.isOnSkyblock() && screen instanceof ChatScreen && SkyblockerConfigManager.get().chat.confirmationPromptHelper) {
Expand All @@ -46,12 +46,12 @@ private static boolean hasCommand() {
return command != null && commandFoundAt + 60_000 > System.currentTimeMillis();
}

private static void onMessage(Text message, boolean overlay) {
if (Utils.isOnSkyblock() && !overlay && SkyblockerConfigManager.get().chat.confirmationPromptHelper && message.getString().contains("[YES]")) {
private static void onMessage(Text message) {
if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().chat.confirmationPromptHelper && message.getString().contains("[YES]")) {
Optional<String> confirmationCommand = message.visit((style, asString) -> {
ClickEvent event = style.getClickEvent();

//Check to see if its a yes and has the proper command
//Check to see if it's a yes and has the proper command
if (asString.equals("§a§l[YES]") && event != null && event.getAction() == ClickEvent.Action.RUN_COMMAND && event.getValue().startsWith("/chatprompt")) {
return Optional.of(event.getValue());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,28 @@

import de.hysky.skyblocker.annotations.Init;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.events.ChatEvents;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.scheduler.Scheduler;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SkyblockXpMessages {
private static final MinecraftClient CLIENT = MinecraftClient.getInstance();
private static final Pattern SKYBLOCK_XP_PATTERN = Pattern.compile("§b\\+\\d+ SkyBlock XP §7\\([^()]+§7\\)§b \\(\\d+\\/\\d+\\)");
private static final Pattern SKYBLOCK_XP_PATTERN = Pattern.compile("\\+\\d+ SkyBlock XP \\([^()]+\\) \\(\\d+/\\d+\\)");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we're losing information here by striping the formatting codes. There's a reason hypixel put them in so I think we should keep them too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think functionality should depend on formatting codes, as they might be just artifacts left from an older era and stuff would break once they migrate to text objects with styles.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I do agree with the above, in order to make the pet cache work with autopet it'd require that section symbols are present for parsing the rarity and whatnot so maybe it would be better to have a note saying to not rely on them unless absolutely necessary.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If some features have to use formatting codes, those specific usages could do Text#getString with the RECEIVE_TEXT event and do their own thing anyway.

private static final IntOpenHashSet RECENT_MESSAGES = new IntOpenHashSet();

@Init
public static void init() {
ClientReceiveMessageEvents.GAME.register(SkyblockXpMessages::onMessage);
ChatEvents.RECEIVE_OVERLAY_STRING.register(SkyblockXpMessages::onOverlayMessage);
}

private static void onMessage(Text text, boolean overlay) {
if (Utils.isOnSkyblock() && overlay && SkyblockerConfigManager.get().chat.skyblockXpMessages) {
String message = text.getString();
private static void onOverlayMessage(String message) {
if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().chat.skyblockXpMessages) {
Matcher matcher = SKYBLOCK_XP_PATTERN.matcher(message);

if (matcher.find()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
package de.hysky.skyblocker.skyblock.chat.filters;

import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.skyblock.dungeon.DungeonScore;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.chat.ChatFilterResult;
import de.hysky.skyblocker.utils.chat.ChatPatternListener;
import net.minecraft.text.Text;

import java.util.regex.Matcher;

public class MimicFilter extends ChatPatternListener {
public class MimicFilter extends SimpleChatFilter {
public MimicFilter() {
super(".*?(?:Mimic dead!?|Mimic Killed!|\\$SKYTILS-DUNGEON-SCORE-MIMIC\\$|\\Q" + SkyblockerConfigManager.get().dungeons.mimicMessage.mimicMessage + "\\E)$");
}
Expand All @@ -18,11 +12,4 @@ public MimicFilter() {
public ChatFilterResult state() {
return SkyblockerConfigManager.get().chat.hideMimicKill;
}

@Override
protected boolean onMatch(Text message, Matcher matcher) {
if (!Utils.isInDungeons() || !DungeonScore.isDungeonStarted() || !DungeonScore.isMimicOnCurrentFloor()) return false;
DungeonScore.onMimicKill(); //Only called when the message is cancelled | sent to action bar, complementing DungeonScore#checkMessageForMimic
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.annotations.Init;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.events.ChatEvents;
import de.hysky.skyblocker.events.SkyblockEvents;
import de.hysky.skyblocker.utils.*;
import de.hysky.skyblocker.utils.command.argumenttypes.EggTypeArgumentType;
Expand All @@ -15,7 +16,6 @@
import it.unimi.dsi.fastutil.objects.ObjectImmutableList;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
Expand Down Expand Up @@ -67,7 +67,7 @@ public static void init() {
}
});
SkyblockEvents.LOCATION_CHANGE.register(EggFinder::handleLocationChange);
ClientReceiveMessageEvents.GAME.register(EggFinder::onChatMessage);
ChatEvents.RECEIVE_STRING.register(EggFinder::onChatMessage);
WorldRenderEvents.AFTER_TRANSLUCENT.register(EggFinder::renderWaypoints);
ClientTickEvents.END_CLIENT_TICK.register(client -> {
if (!SkyblockerConfigManager.get().helpers.chocolateFactory.enableEggFinder || client.player == null) return;
Expand Down Expand Up @@ -147,9 +147,9 @@ private static void renderWaypoints(WorldRenderContext context) {
}
}

private static void onChatMessage(Text text, boolean overlay) {
if (overlay || !SkyblockerConfigManager.get().helpers.chocolateFactory.enableEggFinder) return;
Matcher matcher = eggFoundPattern.matcher(text.getString());
private static void onChatMessage(String message) {
if (!SkyblockerConfigManager.get().helpers.chocolateFactory.enableEggFinder) return;
Matcher matcher = eggFoundPattern.matcher(message);
if (matcher.find()) {
try {
EggType eggType = EggType.valueOf(matcher.group(1).toUpperCase());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package de.hysky.skyblocker.skyblock.chocolatefactory;

import com.mojang.brigadier.Message;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.annotations.Init;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.events.ChatEvents;
import de.hysky.skyblocker.events.SkyblockEvents;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.scheduler.Scheduler;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
Expand All @@ -34,11 +33,11 @@ private TimeTowerReminder() {
@Init
public static void init() {
SkyblockEvents.JOIN.register(TimeTowerReminder::checkTempFile);
ClientReceiveMessageEvents.GAME.register(TimeTowerReminder::checkIfTimeTower);
ChatEvents.RECEIVE_STRING.register(TimeTowerReminder::checkIfTimeTower);
}

public static void checkIfTimeTower(Message message, boolean overlay) {
if (!TIME_TOWER_PATTERN.matcher(message.getString()).matches() || scheduled) return;
public static void checkIfTimeTower(String message) {
if (!TIME_TOWER_PATTERN.matcher(message).matches() || scheduled) return;
Scheduler.INSTANCE.schedule(TimeTowerReminder::sendMessage, 60 * 60 * 20); // 1 hour
scheduled = true;
File tempFile = SkyblockerMod.CONFIG_DIR.resolve(TIME_TOWER_FILE).toFile();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import de.hysky.skyblocker.annotations.Init;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.events.ChatEvents;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.scheduler.Scheduler;
import it.unimi.dsi.fastutil.booleans.BooleanPredicate;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
Expand All @@ -19,9 +19,7 @@
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.packet.c2s.query.QueryPingC2SPacket;
import net.minecraft.network.packet.s2c.play.ParticleS2CPacket;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import net.minecraft.util.Util;
import net.minecraft.util.hit.EntityHitResult;
Expand Down Expand Up @@ -70,7 +68,7 @@ public static DojoChallenges from(String name) {

@Init
public static void init() {
ClientReceiveMessageEvents.GAME.register(DojoManager::onMessage);
ChatEvents.RECEIVE_STRING.register(DojoManager::onMessage);
WorldRenderEvents.AFTER_TRANSLUCENT.register(DojoManager::render);
ClientPlayConnectionEvents.JOIN.register((_handler, _sender, _client) -> reset());
ClientEntityEvents.ENTITY_LOAD.register(DojoManager::onEntitySpawn);
Expand All @@ -91,16 +89,13 @@ private static void reset() {
}

/**
* works out if the player is in dojo and if so what challenge based on chat messages
*
* @param text message
* @param overlay is overlay
* Works out if the player is in dojo and if so what challenge based on chat messages
*/
private static void onMessage(Text text, Boolean overlay) {
if (!Utils.isInCrimson() || overlay) {
private static void onMessage(String message) {
if (!Utils.isInCrimson()) {
return;
}
if (Objects.equals(Formatting.strip(text.getString()), START_MESSAGE)) {
if (Objects.equals(message, START_MESSAGE)) {
inArena = true;
//update the players ping
getPing();
Expand All @@ -109,7 +104,7 @@ private static void onMessage(Text text, Boolean overlay) {
if (!inArena) {
return;
}
if (text.getString().matches(CHALLENGE_FINISHED_REGEX)) {
if (message.matches(CHALLENGE_FINISHED_REGEX)) {
reset();
return;
}
Expand All @@ -118,7 +113,7 @@ private static void onMessage(Text text, Boolean overlay) {
if (currentChallenge != DojoChallenges.NONE) {
return;
}
Matcher nextChallenge = TEST_OF_PATTERN.matcher(text.getString());
Matcher nextChallenge = TEST_OF_PATTERN.matcher(message);
if (nextChallenge.matches()) {
currentChallenge = DojoChallenges.from(nextChallenge.group(1));
if (!currentChallenge.enabled.test(true)) {
Expand Down
Loading
Loading