diff --git a/src/main/java/me/alpha432/oyvey/ducks/render/IChatComponent.java b/src/main/java/me/alpha432/oyvey/ducks/render/IChatComponent.java new file mode 100644 index 0000000..282475e --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/ducks/render/IChatComponent.java @@ -0,0 +1,9 @@ +package me.alpha432.oyvey.ducks.render; + +import net.minecraft.client.GuiMessage; +import net.minecraft.network.chat.MessageSignature; + +public interface IChatComponent { + void oyvey$addMessage(GuiMessage message); + void oyvey$removeMessage(MessageSignature signature); +} \ No newline at end of file diff --git a/src/main/java/me/alpha432/oyvey/features/commands/Command.java b/src/main/java/me/alpha432/oyvey/features/commands/Command.java index c1cad6a..2e271a5 100644 --- a/src/main/java/me/alpha432/oyvey/features/commands/Command.java +++ b/src/main/java/me/alpha432/oyvey/features/commands/Command.java @@ -9,6 +9,7 @@ import me.alpha432.oyvey.util.TextUtil; import me.alpha432.oyvey.util.player.ChatUtil; import static com.mojang.brigadier.Command.SINGLE_SUCCESS; +import static me.alpha432.oyvey.features.commands.MessageIdentifiers.*; public abstract class Command extends Feature { public static final int NO_OP = -1; @@ -25,7 +26,7 @@ public abstract class Command extends Feature { public abstract void createArgumentBuilder(LiteralArgumentBuilder builder); protected int success(String message, Object... format) { - sendMessage(message, format); + sendMessage(message, SUCCESS, format); return NO_OP; } @@ -34,7 +35,7 @@ public abstract class Command extends Feature { } protected int fail(String message, Object... format) { - sendMessage("{red} " + message, format); + sendMessage("{red} " + message, FAIL, format); return NO_OP; } @@ -58,11 +59,14 @@ public abstract class Command extends Feature { return true; } - public static void sendMessage(String message, Object... format) { - if (message == null) { - return; - } - ChatUtil.sendMessage(TextUtil.text(message, format)); + public static void sendMessage(String message, String identifier) { + if (message == null) return; + ChatUtil.sendMessage(TextUtil.text(message), identifier); + } + + public static void sendMessage(String message, String identifier, Object... format) { + if (message == null) return; + ChatUtil.sendMessage(TextUtil.text(message, format), identifier); } public static LiteralArgumentBuilder literal(String literal) { @@ -72,4 +76,4 @@ public abstract class Command extends Feature { public static RequiredArgumentBuilder argument(String name, ArgumentType type) { return RequiredArgumentBuilder.argument(name, type); } -} +} \ No newline at end of file diff --git a/src/main/java/me/alpha432/oyvey/features/commands/MessageIdentifiers.java b/src/main/java/me/alpha432/oyvey/features/commands/MessageIdentifiers.java new file mode 100644 index 0000000..0e072e4 --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/features/commands/MessageIdentifiers.java @@ -0,0 +1,7 @@ +package me.alpha432.oyvey.features.commands; + +public class MessageIdentifiers { + public static final String GENERAL = "general"; + public static final String SUCCESS = "success"; + public static final String FAIL = "fail"; +} \ No newline at end of file diff --git a/src/main/java/me/alpha432/oyvey/features/commands/impl/BindCommand.java b/src/main/java/me/alpha432/oyvey/features/commands/impl/BindCommand.java index 3d94686..aa5fe73 100644 --- a/src/main/java/me/alpha432/oyvey/features/commands/impl/BindCommand.java +++ b/src/main/java/me/alpha432/oyvey/features/commands/impl/BindCommand.java @@ -40,7 +40,7 @@ public class BindCommand extends Command { if (event.getKey() == GLFW_KEY_ESCAPE) { module = null; - sendMessage("Operation canceled."); + sendMessage("Operation canceled.", "fail"); return; } diff --git a/src/main/java/me/alpha432/oyvey/features/commands/impl/HelpCommand.java b/src/main/java/me/alpha432/oyvey/features/commands/impl/HelpCommand.java index 3ce8ac4..42376f9 100644 --- a/src/main/java/me/alpha432/oyvey/features/commands/impl/HelpCommand.java +++ b/src/main/java/me/alpha432/oyvey/features/commands/impl/HelpCommand.java @@ -66,7 +66,7 @@ public class HelpCommand extends Command { List paginated = commands.subList((pageIndex - 1) * ITEMS_PER_PAGE, Math.min(commands.size(), pageIndex * ITEMS_PER_PAGE)); - sendMessage("Commands (%s):", commands.size()); + sendMessage("Commands (%s):", "general", commands.size()); for (Command command : paginated) { StringJoiner joiner = new StringJoiner(", "); @@ -74,7 +74,7 @@ public class HelpCommand extends Command { joiner.add(alias); } - sendMessage("{dark_gray} %s: {reset}\n %s", + sendMessage("{dark_gray} %s: {reset}\n %s", "general", joiner, command.getDescription()); } diff --git a/src/main/java/me/alpha432/oyvey/features/modules/Module.java b/src/main/java/me/alpha432/oyvey/features/modules/Module.java index 69b6c1c..86c5942 100644 --- a/src/main/java/me/alpha432/oyvey/features/modules/Module.java +++ b/src/main/java/me/alpha432/oyvey/features/modules/Module.java @@ -88,11 +88,11 @@ public class Module extends Feature implements Jsonable, Toggleable { Module module = OyVey.moduleManager.getModuleByDisplayName(name); Module originalModule = OyVey.moduleManager.getModuleByName(name); if (module == null && originalModule == null) { - Command.sendMessage(this.getDisplayName() + ", name: " + this.getName() + ", has been renamed to: " + name); + Command.sendMessage(this.getDisplayName() + ", name: " + this.getName() + ", has been renamed to: " + name, "general"); this.displayName.setValue(name); return; } - Command.sendMessage("{red} A module of this name already exists."); + Command.sendMessage("{red} A module of this name already exists.", "general"); } @Override diff --git a/src/main/java/me/alpha432/oyvey/features/modules/client/NotificationsModule.java b/src/main/java/me/alpha432/oyvey/features/modules/client/NotificationsModule.java index 0352afe..cda421a 100644 --- a/src/main/java/me/alpha432/oyvey/features/modules/client/NotificationsModule.java +++ b/src/main/java/me/alpha432/oyvey/features/modules/client/NotificationsModule.java @@ -28,6 +28,6 @@ public class NotificationsModule extends Module { ChatUtil.sendMessage(TextUtil.text(MODULE_FORMAT, event.getFeature().getName(), moduleState ? "{green}" : "{red}", - moduleState ? "on" : "off")); + moduleState ? "on" : "off"), event.getFeature().getName()); } } diff --git a/src/main/java/me/alpha432/oyvey/manager/CommandManager.java b/src/main/java/me/alpha432/oyvey/manager/CommandManager.java index 569f1c1..a1906b1 100644 --- a/src/main/java/me/alpha432/oyvey/manager/CommandManager.java +++ b/src/main/java/me/alpha432/oyvey/manager/CommandManager.java @@ -17,6 +17,7 @@ import java.util.*; import static com.mojang.brigadier.Command.SINGLE_SUCCESS; import static me.alpha432.oyvey.features.commands.Command.SINGLE_FAILURE; +import static me.alpha432.oyvey.features.commands.MessageIdentifiers.GENERAL; public class CommandManager extends Feature implements Jsonable { private static final Logger LOGGER = LogManager.getLogger("Commands"); @@ -45,16 +46,16 @@ public class CommandManager extends Feature implements Jsonable { public void onChatSent(String message) { try { - int result = dispatcher.execute(message.substring( - commandPrefix.length()).trim(), this); + int result = dispatcher.execute(message.substring(commandPrefix.length()).trim(), this); + if (result == SINGLE_SUCCESS) { - Command.sendMessage("{green} Command executed successfully"); + Command.sendMessage("{green} Command executed successfully", GENERAL); } else if (result == SINGLE_FAILURE) { - Command.sendMessage("{red} Failed to execute command"); + Command.sendMessage("{red} Failed to execute command", GENERAL); } } catch (CommandSyntaxException e) { LOGGER.error("Failed to execute command", e); - Command.sendMessage("{red} %s", e.getMessage()); + Command.sendMessage("{red} %s", GENERAL, e.getMessage()); } } @@ -101,10 +102,10 @@ public class CommandManager extends Feature implements Jsonable { @Override public void fromJson(JsonElement element) { - if (element == null || !element.isJsonObject()) { - return; - } + if (element == null || !element.isJsonObject()) return; + JsonObject object = element.getAsJsonObject(); + if (object.has("prefix")) { setCommandPrefix(object.get("prefix").getAsString()); } @@ -114,4 +115,4 @@ public class CommandManager extends Feature implements Jsonable { public String getFileName() { return "commands.json"; } -} +} \ No newline at end of file diff --git a/src/main/java/me/alpha432/oyvey/mixin/render/MixinChatComponent.java b/src/main/java/me/alpha432/oyvey/mixin/render/MixinChatComponent.java new file mode 100644 index 0000000..579013f --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/mixin/render/MixinChatComponent.java @@ -0,0 +1,32 @@ +package me.alpha432.oyvey.mixin.render; + +import me.alpha432.oyvey.ducks.render.IChatComponent; +import net.minecraft.client.GuiMessage; +import net.minecraft.client.gui.components.ChatComponent; +import net.minecraft.network.chat.MessageSignature; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.List; + +@Mixin(ChatComponent.class) +public abstract class MixinChatComponent implements IChatComponent { + @Shadow + private List allMessages; + + @Shadow + private void refreshTrimmedMessages() {} + + @Override + public void oyvey$addMessage(GuiMessage message) { + this.allMessages.addFirst(message); + this.refreshTrimmedMessages(); + } + + @Override + public void oyvey$removeMessage(MessageSignature signature) { + this.allMessages.removeIf(message -> signature.equals(message.signature())); + this.refreshTrimmedMessages(); + } +} \ No newline at end of file diff --git a/src/main/java/me/alpha432/oyvey/util/player/ChatUtil.java b/src/main/java/me/alpha432/oyvey/util/player/ChatUtil.java index 2faf4f0..01964f8 100644 --- a/src/main/java/me/alpha432/oyvey/util/player/ChatUtil.java +++ b/src/main/java/me/alpha432/oyvey/util/player/ChatUtil.java @@ -1,33 +1,51 @@ package me.alpha432.oyvey.util.player; import me.alpha432.oyvey.OyVey; +import me.alpha432.oyvey.ducks.render.IChatComponent; import me.alpha432.oyvey.features.commands.Command; import net.minecraft.ChatFormatting; +import net.minecraft.client.GuiMessage; +import net.minecraft.client.GuiMessageTag; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MessageSignature; import net.minecraft.network.chat.Style; +import java.nio.charset.StandardCharsets; + import static me.alpha432.oyvey.util.traits.Util.mc; public class ChatUtil { - public static void sendMessage(Component message) { - sendSilentMessage(Component.empty() + public static void sendMessage(Component message, String identifier) { + sendClientSideMessage(Component.empty() .setStyle(Style.EMPTY.withColor(ChatFormatting.GRAY)) .append("<") .append(getClientNameComponent()) .append(">") .append(" ") - .append(message)); + .append(message), identifier); } - public static void sendSilentMessage(Component message) { - if (Command.nullCheck()) { - return; - } - // TODO add silent support ig - mc.gui.getChat().addMessage(message); + public static void sendClientSideMessage(Component message, String identifier) { + if (Command.nullCheck()) return; + + IChatComponent chat = (IChatComponent) mc.gui.getChat(); + MessageSignature signature = new MessageSignature(get256Bytes(identifier)); + chat.oyvey$removeMessage(signature); + chat.oyvey$addMessage(new GuiMessage(mc.gui.getGuiTicks(), message, signature, getMessageTag())); } - + public static Component getClientNameComponent() { return Component.empty().withColor(OyVey.colorManager.getColorAsInt()).append("OyVey"); } + + private static GuiMessageTag getMessageTag() { + return new GuiMessageTag(OyVey.colorManager.getColorAsInt(), null, null, null); + } + + private static byte[] get256Bytes(String identifier) { + byte[] bytes = new byte[256]; + byte[] identifierBytes = identifier.getBytes(StandardCharsets.UTF_8); + System.arraycopy(identifierBytes, 0, bytes, 0, Math.min(bytes.length, identifierBytes.length)); + return bytes; + } } \ No newline at end of file diff --git a/src/main/resources/oyvey.mixins.json b/src/main/resources/oyvey.mixins.json index 5b20c43..fa007d6 100644 --- a/src/main/resources/oyvey.mixins.json +++ b/src/main/resources/oyvey.mixins.json @@ -11,6 +11,7 @@ "input.MixinKeyboard", "input.MixinMouse", "network.MixinClientPlayNetworkHandler", + "render.MixinChatComponent", "render.MixinLevelRenderer", "render.MixinRenderTickCounter", "render.MixinWorldRenderer",