diff --git a/build.gradle b/build.gradle index 272538c..4154acc 100644 --- a/build.gradle +++ b/build.gradle @@ -34,11 +34,8 @@ dependencies { modImplementation "fi.dy.masa.malilib:malilib-fabric-1.19.0:${project.malilib_version}" modCompileOnly "io.github.prospector:modmenu:1.16.8" - modImplementation "com.github.DarkKronicle:KommandLib:${project.kommandlib_version}" - implementation "com.github.DarkKronicle.Konstruct:addons:${project.konstruct_version}" implementation "com.github.DarkKronicle.Konstruct:core:${project.konstruct_version}" - include "com.github.DarkKronicle:KommandLib:${project.kommandlib_version}" implementation 'com.electronwill.night-config:toml:3.6.5' // Transitive diff --git a/gradle.properties b/gradle.properties index 68db2e1..061b8ee 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,15 +1,14 @@ org.gradle.jvmargs=-Xmx1G -minecraft_version=1.19 -yarn_mappings=1.19+build.4 +minecraft_version=1.19.1 +yarn_mappings=1.19.1+build.1 loader_version=0.14.8 -fabric_api_version=0.57.0+1.19 +fabric_api_version=0.58.5+1.19.1 -mod_version=1.5.4 +mod_version=1.5.5 maven_group=io.github.darkkronicle archives_base_name=AdvancedChatCore -kommandlib_version=1.0.0-build2 malilib_version=0.13.0 konstruct_version=2.0.3-build1 mxparser_version=4.4.2 diff --git a/src/main/java/io/github/darkkronicle/advancedchatcore/InitHandler.java b/src/main/java/io/github/darkkronicle/advancedchatcore/InitHandler.java index 085f7fd..cc47dc5 100644 --- a/src/main/java/io/github/darkkronicle/advancedchatcore/InitHandler.java +++ b/src/main/java/io/github/darkkronicle/advancedchatcore/InitHandler.java @@ -15,7 +15,6 @@ import fi.dy.masa.malilib.interfaces.IInitializationHandler; import fi.dy.masa.malilib.util.InfoUtils; import io.github.darkkronicle.advancedchatcore.chat.*; -import io.github.darkkronicle.advancedchatcore.config.CommandsHandler; import io.github.darkkronicle.advancedchatcore.config.ConfigStorage; import io.github.darkkronicle.advancedchatcore.config.gui.GuiConfig; import io.github.darkkronicle.advancedchatcore.config.gui.GuiConfigHandler; @@ -101,7 +100,6 @@ public void registerModHandlers() { "advancedchatcore.findtype.custom.profanity", "advancedchatcore.findtype.custom.info.profanity"); - CommandsHandler.getInstance().setup(); InputHandler.getInstance().addDisplayName("core_general", "advancedchatcore.config.tab.hotkeysgeneral"); InputHandler.getInstance().add("core_general", ConfigStorage.Hotkeys.OPEN_CHAT.config, (action, key) -> { if (MinecraftClient.getInstance().world == null) { diff --git a/src/main/java/io/github/darkkronicle/advancedchatcore/chat/AdvancedChatScreen.java b/src/main/java/io/github/darkkronicle/advancedchatcore/chat/AdvancedChatScreen.java index d2f9a7d..329b8f1 100644 --- a/src/main/java/io/github/darkkronicle/advancedchatcore/chat/AdvancedChatScreen.java +++ b/src/main/java/io/github/darkkronicle/advancedchatcore/chat/AdvancedChatScreen.java @@ -20,14 +20,17 @@ import io.github.darkkronicle.advancedchatcore.util.Color; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.function.Function; import io.github.darkkronicle.advancedchatcore.util.RowList; import lombok.Getter; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.hud.ChatHud; +import net.minecraft.client.gui.screen.ChatPreviewBackground; import net.minecraft.client.network.ChatPreviewer; import net.minecraft.client.network.ServerInfo; +import net.minecraft.client.option.ChatPreviewMode; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.option.ServerList; import net.minecraft.client.toast.SystemToast; @@ -41,7 +44,9 @@ import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; +import net.minecraft.util.Util; import net.minecraft.util.math.MathHelper; +import org.jetbrains.annotations.Nullable; public class AdvancedChatScreen extends GuiBase { @@ -68,13 +73,17 @@ public class AdvancedChatScreen extends GuiBase { private final RowList leftSideButtons = new RowList<>(); // TODO chat preview somewhere else - private static final Text CHAT_PREVIEW_WARNING_TOAST_TITLE = Text.translatable("chatPreview.warning.toast.title"); - private static final Text CHAT_PREVIEW_WARNING_TOAST_TEXT = Text.translatable("chatPreview.warning.toast"); - private static final Text CHAT_PREVIEW_PLACEHOLDER_TEXT = Text.translatable("chat.preview").formatted(Formatting.DARK_GRAY); + private static final Text CHAT_PREVIEW_INPUT_TEXT = Text.translatable("chat.previewInput", Text.translatable("key.keyboard.enter")); + @Getter private ChatPreviewer chatPreviewer; + @Getter + private boolean missingPreview; + + private final ChatPreviewBackground chatPreviewBackground = new ChatPreviewBackground(); + @Override protected void closeGui(boolean showParent) { if (ConfigStorage.ChatScreen.PERSISTENT_TEXT.config.getBooleanValue()) { @@ -193,12 +202,16 @@ protected MutableText getNarrationMessage() { setChatFromHistory(-startHistory - 1); } ServerInfo serverInfo = this.client.getCurrentServerEntry(); - if (serverInfo != null && this.client.options.getChatPreview().getValue()) { + if (serverInfo != null && this.client.options.getChatPreview().getValue() == ChatPreviewMode.LIVE) { ServerInfo.ChatPreview chatPreview = serverInfo.getChatPreview(); if (chatPreview != null && serverInfo.shouldPreviewChat() && chatPreview.showToast()) { ServerList.updateServerListEntry(serverInfo); } } + + if (client.options.getChatPreview().getValue() == ChatPreviewMode.CONFIRM) { + this.missingPreview = this.originalChatText.startsWith("/") && !this.client.player.hasSignedArgument(this.originalChatText.substring(1)); + } } public void resize(MinecraftClient client, int width, int height) { @@ -252,7 +265,7 @@ private void tryRequestCommandPreview(String chatText) { private boolean shouldPreviewChat() { if (this.client.player == null) { return false; - } else if (!this.client.options.getChatPreview().getValue()) { + } else if (this.client.options.getChatPreview().getValue() == ChatPreviewMode.OFF) { return false; } else { ServerInfo serverInfo = this.client.getCurrentServerEntry(); @@ -265,6 +278,12 @@ private void onChatFieldUpdate(String chatText) { for (AdvancedChatScreenSection section : sections) { section.onChatFieldUpdate(chatText, string); } + if (client.options.getChatPreview().getValue() == ChatPreviewMode.LIVE) { + this.updatePreviewer(string); + } else if (client.options.getChatPreview().getValue() == ChatPreviewMode.CONFIRM && !this.chatPreviewer.equalsLastPreviewed(string)) { + this.missingPreview = string.startsWith("/") && !this.client.player.hasSignedArgument(string.substring(1)); + this.chatPreviewer.tryRequest(""); + } } @Override @@ -295,7 +314,13 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (keyCode == KeyCodes.KEY_ENTER || keyCode == KeyCodes.KEY_KP_ENTER) { String string = this.chatField.getText().trim(); // Strip message and send - Text text = this.chatPreviewer.tryConsumeResponse(this.chatField.getText()); + if (this.client.options.getChatPreview().getValue() == ChatPreviewMode.CONFIRM && !this.missingPreview) { + if (!this.chatPreviewer.equalsLastPreviewed(string)) { + this.updatePreviewer(string); + return false; + } + } + Text text = getPreviewText(); MessageSender.getInstance().sendMessage(string, text); this.chatField.setText(""); last = ""; @@ -449,35 +474,69 @@ public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partia if (style != null && style.getHoverEvent() != null) { this.renderTextHoverEffect(matrixStack, style, mouseX, mouseY); } - if (this.chatPreviewer.shouldRenderPreview()) { - this.renderChatPreview(matrixStack); + ChatPreviewBackground.RenderData renderData = this.chatPreviewBackground.computeRenderData(Util.getMeasuringTimeMs(), this.getPreviewScreenText()); + if (renderData.preview() != null) { + this.renderChatPreview(matrixStack, renderData.preview(), renderData.alpha(), client.getProfileKeys().getSigner() != null); } } - public void renderChatPreview(MatrixStack matrices) { - int i = (int)(255.0 * (this.client.options.getChtOpacity().getValue() * 0.9F + 0.1F)); - int j = (int)(255.0 * this.client.options.getTextBackgroundOpacity().getValue()); - int k = this.getPreviewWidth(); - List list = this.getPreviewText(); - int l = this.getPreviewHeight(list); + @Nullable + protected Text getPreviewScreenText() { + String string = this.chatField.getText(); + if (string.isBlank()) { + return null; + } else { + Text text = this.getPreviewText(); + return client.options.getChatPreview().getValue() == ChatPreviewMode.CONFIRM && !this.missingPreview + ? (Text) Objects.requireNonNullElse( + text, this.chatPreviewer.equalsLastPreviewed(string) && !string.startsWith("/") ? Text.literal(string) : CHAT_PREVIEW_INPUT_TEXT + ) + : text; + } + } + + public void renderChatPreview(MatrixStack matrices, Text previewText, float alpha, boolean signable) { + int opacity = (int)(255.0 * (this.client.options.getChatOpacity().getValue() * 0.9F + 0.1F) * (double)alpha); + int j = (int)( + (double)(this.chatPreviewer.cannotConsumePreview() ? 127 : 255) * this.client.options.getTextBackgroundOpacity().getValue() * (double)alpha + ); + int width = this.getPreviewWidth(); + List list = this.wrapPreviewText(previewText); + int height = this.getPreviewHeight(list); + int topY = this.getPreviewTop(height); RenderSystem.enableBlend(); matrices.push(); - matrices.translate((double)this.getPreviewLeft(), (double)this.getPreviewTop(l), 0.0); - fill(matrices, 0, 0, k, l, j << 24); - matrices.translate(2.0, 2.0, 0.0); - - for(int m = 0; m < list.size(); ++m) { - OrderedText orderedText = list.get(m); - this.client.textRenderer.drawWithShadow(matrices, orderedText, 0.0F, (float)(m * 9), i << 24 | 16777215); + matrices.translate(this.getPreviewLeft(), topY, 0.0); + fill(matrices, 0, 0, width, height, j << 24); + if (opacity > 0) { + matrices.translate(2.0, 2.0, 0.0); + + for (int n = 0; n < list.size(); ++n) { + OrderedText orderedText = list.get(n); + int o = n * 9; + this.textRenderer.drawWithShadow(matrices, orderedText, 0.0F, (float)o, opacity << 24 | 16777215); + } } matrices.pop(); RenderSystem.disableBlend(); + if (signable && this.chatPreviewer.getPreviewText() != null) { + int n = this.chatPreviewer.cannotConsumePreview() ? 15118153 : 7844841; + int p = (int)(255.0F * alpha); + matrices.push(); + fill(matrices, 0, topY, 2, this.getPreviewBottom(), p << 24 | n); + matrices.pop(); + } + + } + + @Nullable + private Text getPreviewText() { + return Util.map(this.chatPreviewer.getPreviewText(), ChatPreviewer.Response::previewText); } - private List getPreviewText() { - Text text = this.chatPreviewer.getPreviewText(); - return text != null ? this.textRenderer.wrapLines(text, this.getPreviewWidth()) : List.of(CHAT_PREVIEW_PLACEHOLDER_TEXT.asOrderedText()); + private List wrapPreviewText(Text preview) { + return this.textRenderer.wrapLines(preview, this.getPreviewWidth()); } private int getPreviewWidth() { diff --git a/src/main/java/io/github/darkkronicle/advancedchatcore/chat/ChatHistoryProcessor.java b/src/main/java/io/github/darkkronicle/advancedchatcore/chat/ChatHistoryProcessor.java index 116e6e1..3ae01fd 100644 --- a/src/main/java/io/github/darkkronicle/advancedchatcore/chat/ChatHistoryProcessor.java +++ b/src/main/java/io/github/darkkronicle/advancedchatcore/chat/ChatHistoryProcessor.java @@ -18,6 +18,8 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.hud.MessageIndicator; +import net.minecraft.network.message.MessageSignatureData; import net.minecraft.text.Style; import net.minecraft.text.Text; import net.minecraft.text.TextColor; @@ -26,10 +28,10 @@ @Environment(EnvType.CLIENT) public class ChatHistoryProcessor implements IMessageProcessor { - private static boolean sendToHud(Text text) { + private static boolean sendToHud(Text text, @Nullable MessageSignatureData signature, MessageIndicator indicator) { if (AdvancedChatCore.FORWARD_TO_HUD) { ((MixinChatHudInvoker) MinecraftClient.getInstance().inGameHud.getChatHud()).invokeAddMessage( - text, 0, MinecraftClient.getInstance().inGameHud.getTicks(), false); + text, signature, MinecraftClient.getInstance().inGameHud.getTicks(), indicator, false); return true; } return false; @@ -37,6 +39,11 @@ private static boolean sendToHud(Text text) { @Override public boolean process(Text text, @Nullable Text unfiltered) { + return process(text, unfiltered, null, MessageIndicator.system()); + } + + @Override + public boolean process(Text text, @Nullable Text unfiltered, @Nullable MessageSignatureData signature, @Nullable MessageIndicator indicator) { if (unfiltered == null) { unfiltered = text; } @@ -75,7 +82,7 @@ public boolean process(Text text, @Nullable Text unfiltered) { .backgroundColor(new Color(0, 0, 0, 100)) .build(); if (ChatHistory.getInstance().add(line)) { - sendToHud(line.getDisplayText()); + sendToHud(line.getDisplayText(), line.getSignature(), line.getIndicator()); } return true; } diff --git a/src/main/java/io/github/darkkronicle/advancedchatcore/chat/ChatMessage.java b/src/main/java/io/github/darkkronicle/advancedchatcore/chat/ChatMessage.java index f013ba0..90b23c0 100644 --- a/src/main/java/io/github/darkkronicle/advancedchatcore/chat/ChatMessage.java +++ b/src/main/java/io/github/darkkronicle/advancedchatcore/chat/ChatMessage.java @@ -18,6 +18,8 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.hud.MessageIndicator; +import net.minecraft.network.message.MessageSignatureData; import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; @@ -56,6 +58,11 @@ public class ChatMessage { /** Split up lines for line breaks. */ protected List lines; + @Nullable + protected MessageSignatureData signature; + + protected MessageIndicator indicator; + /** * Set's the display text of the message and formats the line breaks. * @@ -83,7 +90,9 @@ public ChatMessage shallowClone(int width) { time, backgroundColor, width, - owner); + owner, + signature, + indicator); message.setStacks(getStacks()); return message; } @@ -119,7 +128,9 @@ protected ChatMessage( LocalTime time, Color backgroundColor, int width, - MessageOwner owner) { + MessageOwner owner, + @Nullable MessageSignatureData signature, + @Nullable MessageIndicator indicator) { this.creationTick = creationTick; this.displayText = displayText; this.id = id; @@ -129,6 +140,8 @@ protected ChatMessage( this.uuid = UUID.randomUUID(); this.owner = owner; this.originalText = originalText == null ? displayText : originalText; + this.signature = signature; + this.indicator = indicator == null ? MessageIndicator.system() : indicator; formatChildren(width); } diff --git a/src/main/java/io/github/darkkronicle/advancedchatcore/chat/DefaultChatSuggestor.java b/src/main/java/io/github/darkkronicle/advancedchatcore/chat/DefaultChatSuggestor.java index 6dd9350..e322cf9 100644 --- a/src/main/java/io/github/darkkronicle/advancedchatcore/chat/DefaultChatSuggestor.java +++ b/src/main/java/io/github/darkkronicle/advancedchatcore/chat/DefaultChatSuggestor.java @@ -11,14 +11,14 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.CommandSuggestor; +import net.minecraft.client.gui.screen.ChatInputSuggestor; import net.minecraft.client.util.math.MatrixStack; /** Handles the CommandSuggestor for the chat */ @Environment(EnvType.CLIENT) public class DefaultChatSuggestor extends AdvancedChatScreenSection { - private CommandSuggestor commandSuggestor; + private ChatInputSuggestor commandSuggestor; public DefaultChatSuggestor(AdvancedChatScreen screen) { super(screen); @@ -65,7 +65,7 @@ public void initGui() { MinecraftClient client = MinecraftClient.getInstance(); AdvancedChatScreen screen = getScreen(); this.commandSuggestor = - new CommandSuggestor( + new ChatInputSuggestor( client, screen, screen.chatField, diff --git a/src/main/java/io/github/darkkronicle/advancedchatcore/chat/MessageDispatcher.java b/src/main/java/io/github/darkkronicle/advancedchatcore/chat/MessageDispatcher.java index 18b3b65..ef98c3e 100644 --- a/src/main/java/io/github/darkkronicle/advancedchatcore/chat/MessageDispatcher.java +++ b/src/main/java/io/github/darkkronicle/advancedchatcore/chat/MessageDispatcher.java @@ -22,10 +22,13 @@ import java.util.Optional; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.gui.hud.MessageIndicator; +import net.minecraft.network.message.MessageSignatureData; import net.minecraft.text.ClickEvent; import net.minecraft.text.MutableText; import net.minecraft.text.Text; import org.apache.logging.log4j.LogManager; +import org.jetbrains.annotations.Nullable; /** * A class to handle chat events. @@ -105,17 +108,17 @@ private MessageDispatcher() { * * @param text Text that is received */ - public void handleText(Text text) { + public void handleText(Text text, @Nullable MessageSignatureData signature, @Nullable MessageIndicator indicator) { boolean previouslyBlank = text.getString().length() == 0; - text = preFilter(text); + text = preFilter(text, signature, indicator); if (text.getString().length() == 0 && !previouslyBlank) { // No more return; } - process(text); + process(text, signature, indicator); } - private Text preFilter(Text text) { + private Text preFilter(Text text, @Nullable MessageSignatureData signature, @Nullable MessageIndicator indicator) { for (IMessageFilter f : preFilters) { Optional t = f.filter(text); if (t.isPresent()) { @@ -125,7 +128,7 @@ private Text preFilter(Text text) { return text; } - private void process(Text text) { + private void process(Text text, @Nullable MessageSignatureData signature, @Nullable MessageIndicator indicator) { for (IMessageFilter f : processors) { f.filter(text); } diff --git a/src/main/java/io/github/darkkronicle/advancedchatcore/config/CommandsHandler.java b/src/main/java/io/github/darkkronicle/advancedchatcore/config/CommandsHandler.java deleted file mode 100644 index fad4d56..0000000 --- a/src/main/java/io/github/darkkronicle/advancedchatcore/config/CommandsHandler.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2022 DarkKronicle - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ -package io.github.darkkronicle.advancedchatcore.config; - -import com.mojang.brigadier.arguments.BoolArgumentType; -import com.mojang.brigadier.arguments.DoubleArgumentType; -import com.mojang.brigadier.arguments.IntegerArgumentType; -import com.mojang.brigadier.arguments.StringArgumentType; -import com.mojang.brigadier.tree.CommandNode; -import fi.dy.masa.malilib.config.ConfigType; -import fi.dy.masa.malilib.config.IConfigBase; -import fi.dy.masa.malilib.config.options.ConfigBoolean; -import fi.dy.masa.malilib.config.options.ConfigColor; -import fi.dy.masa.malilib.config.options.ConfigDouble; -import fi.dy.masa.malilib.config.options.ConfigInteger; -import fi.dy.masa.malilib.config.options.ConfigString; -import io.github.darkkronicle.advancedchatcore.AdvancedChatCore; -import io.github.darkkronicle.advancedchatcore.util.*; -import io.github.darkkronicle.kommandlib.CommandManager; -import io.github.darkkronicle.kommandlib.command.ClientCommand; -import io.github.darkkronicle.kommandlib.command.CommandInvoker; -import io.github.darkkronicle.kommandlib.invokers.BaseCommandInvoker; -import io.github.darkkronicle.kommandlib.util.CommandUtil; -import io.github.darkkronicle.kommandlib.util.InfoUtil; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; - -import java.util.List; -import java.util.Optional; - -public class CommandsHandler { - - private static final CommandsHandler INSTANCE = new CommandsHandler(); - private static String TEST_REGEX = ""; - - public static CommandsHandler getInstance() { - return INSTANCE; - } - - private CommandsHandler() {} - - public CommandNode getOrCreateSubs(String... keys) { - // Should always exist - CommandInvoker main = CommandManager.getInstance().getInvoker("advancedchat").get(); - CommandNode node = main; - for (String k : keys) { - Optional> optional = CommandUtil.getChild(node, k); - if (optional.isPresent()) { - node = optional.get(); - continue; - } - CommandNode newNode = CommandUtil.literal(k).build(); - node.addChild(newNode); - node = newNode; - } - return node; - } - - public void addOptions(CommandNode subCommand, List> options) { - for (SaveableConfig option : options) { - addOption(subCommand, option); - } - } - - public void addOption(CommandNode parent, SaveableConfig option) { - CommandNode wrapped = getOptionCommandWrapper(option.config); - if (wrapped == null) { - return; - } - parent.addChild(CommandUtil.literal(option.key).executes(wrapped.getCommand()).then(wrapped).build()); - } - - private void sendInvalid(String message) { - InfoUtil.sendChatMessage(message, Formatting.RED); - } - - private CommandNode getOptionCommandWrapper(IConfigBase option) { - if (option.getType() == ConfigType.BOOLEAN) { - ConfigBoolean bool = (ConfigBoolean) option; - return CommandUtil.argument("active", BoolArgumentType.bool()).executes(ClientCommand.of(context -> { - Optional value = CommandUtil.getArgument(context, "active", Boolean.class); - if (value.isEmpty()) { - sendInvalid("Active needs to be specified!"); - return; - } - bool.setBooleanValue(value.get()); - InfoUtil.sendChatMessage("Set!"); - })).build(); - } - if (option.getType() == ConfigType.INTEGER) { - ConfigInteger intOption = (ConfigInteger) option; - return CommandUtil.argument("number", IntegerArgumentType.integer(intOption.getMinIntegerValue(), intOption.getMaxIntegerValue())).executes(ClientCommand.of(context -> { - Optional value = CommandUtil.getArgument(context, "number", Integer.class); - if (value.isEmpty()) { - sendInvalid("Number needs to be specified!"); - return; - } - intOption.setIntegerValue(value.get()); - InfoUtil.sendChatMessage("Set!"); - })).build(); - } - if (option.getType() == ConfigType.DOUBLE) { - ConfigDouble doubleOption = (ConfigDouble) option; - return CommandUtil.argument("number", DoubleArgumentType.doubleArg(doubleOption.getMinDoubleValue(), doubleOption.getMaxDoubleValue())).executes(ClientCommand.of(context -> { - Optional value = CommandUtil.getArgument(context, "number", Double.class); - if (value.isEmpty()) { - sendInvalid("Number needs to be specified!"); - return; - } - doubleOption.setDoubleValue(value.get()); - InfoUtil.sendChatMessage("Set!"); - })).build(); - } - if (option.getType() == ConfigType.STRING) { - ConfigString stringOption = (ConfigString) option; - return CommandUtil.argument("text", StringArgumentType.greedyString()).executes(ClientCommand.of(context -> { - Optional value = CommandUtil.getArgument(context, "text", String.class); - stringOption.setValueFromString(value.orElse("")); - InfoUtil.sendChatMessage("Set!"); - })).build(); - } - if (option.getType() == ConfigType.COLOR) { - ConfigColor colorOption = (ConfigColor) option; - return CommandUtil.argument("color", StringArgumentType.string()).executes(ClientCommand.of(context -> { - Optional value = CommandUtil.getArgument(context, "color", String.class); - if (value.isEmpty()) { - sendInvalid("Color needs to be specified!"); - return; - } - colorOption.setValueFromString(value.orElse("")); - InfoUtil.sendChatMessage("Set!"); - })).build(); - } - return null; - } - - public void setup() { - CommandManager.getInstance().unregister(invoker -> invoker.getModId().equals(AdvancedChatCore.MOD_ID)); - CommandInvoker command = new BaseCommandInvoker( - AdvancedChatCore.MOD_ID, - "advancedchat", - CommandUtil.literal("advancedchat").executes(ClientCommand.of(context -> InfoUtil.sendChatMessage("AdvancedChatCore by DarkKronicle"))).build() - ); - command.addChild(CommandUtil.literal("setTestRegex").then( - CommandUtil.argument( - "value", StringArgumentType.greedyString() - ).executes(ClientCommand.of(context -> { - Optional value = CommandUtil.getArgument(context, "value", String.class); - if (value.isPresent()) { - InfoUtil.sendChatMessage("Set!"); - TEST_REGEX = value.get(); - } else { - InfoUtil.sendChatMessage("Not set!"); - } - })).build()).build()); - command.addChild(CommandUtil.literal("testRegex").then( - CommandUtil.argument( - "value", StringArgumentType.greedyString() - ).executes(ClientCommand.of(context -> { - Optional value = CommandUtil.getArgument(context, "value", String.class); - if (value.isPresent()) { - String val = value.get(); - val = val.replace('&', '§'); - Text text = StyleFormatter.formatText(Text.literal(val)); - Optional> matches = SearchUtils.findMatches(text, TEST_REGEX, FindType.REGEX); - InfoUtil.sendChatMessage(text); - if (matches.isEmpty()) { - InfoUtil.sendChatMessage("None!"); - return; - } - InfoUtil.sendChatMessage(String.join(", ", matches.get().stream().map(match -> match.match).toList())); - } else { - InfoUtil.sendChatMessage("Not there!"); - } - })).build()).build()); - command.addChild(CommandUtil.literal("reloadColors").executes(ClientCommand.of((context) -> { - InfoUtil.sendChatMessage("Reloading colors..."); - Colors.getInstance().load(); - InfoUtil.sendChatMessage("Reloaded!", Formatting.GREEN); - })).build()); - CommandManager.getInstance().addCommand(command); - addOptions(getOrCreateSubs("coreconfig", "general"), ConfigStorage.General.OPTIONS); - addOptions(getOrCreateSubs("coreconfig", "chatScreen"), ConfigStorage.ChatScreen.OPTIONS); - } - -} diff --git a/src/main/java/io/github/darkkronicle/advancedchatcore/config/ConfigStorage.java b/src/main/java/io/github/darkkronicle/advancedchatcore/config/ConfigStorage.java index ec6bc61..554cf26 100644 --- a/src/main/java/io/github/darkkronicle/advancedchatcore/config/ConfigStorage.java +++ b/src/main/java/io/github/darkkronicle/advancedchatcore/config/ConfigStorage.java @@ -26,6 +26,7 @@ import io.github.darkkronicle.advancedchatcore.config.options.ConfigColor; import io.github.darkkronicle.advancedchatcore.interfaces.ConfigRegistryOption; import io.github.darkkronicle.advancedchatcore.util.AbstractRegistry; +import io.github.darkkronicle.advancedchatcore.util.Color; import io.github.darkkronicle.advancedchatcore.util.Colors; import io.github.darkkronicle.advancedchatcore.util.EasingMethod; import java.io.File; @@ -185,8 +186,39 @@ public static String translate(String key) { new ConfigBoolean( translate("moretext"), false, translate("info.moretext"))); + public static final SaveableConfig SHOW_CHAT_ICONS = + SaveableConfig.fromConfig( + "showChatIcons", + new ConfigBoolean( + translate("showchaticons"), true, translate("info.showchaticons"))); + + public static final SaveableConfig MODIFIED = + SaveableConfig.fromConfig( + "modified", + new ConfigColor( + translate("modified"), new Color(15386724), translate("info.modified"))); + + public static final SaveableConfig SYSTEM = + SaveableConfig.fromConfig( + "system", + new ConfigColor( + translate("system"), new Color(10526880), translate("info.system"))); + + public static final SaveableConfig FILTERED = + SaveableConfig.fromConfig( + "filtered", + new ConfigColor( + translate("filtered"), new Color(15386724), translate("info.filtered"))); + + public static final SaveableConfig NOT_SECURE = + SaveableConfig.fromConfig( + "notSecure", + new ConfigColor( + translate("notsecure"), new Color(15224664), translate("info.notsecure"))); + + public static final ImmutableList> OPTIONS = - ImmutableList.of(PERSISTENT_TEXT, COLOR, MORE_TEXT); + ImmutableList.of(PERSISTENT_TEXT, COLOR, MORE_TEXT, SHOW_CHAT_ICONS, MODIFIED, SYSTEM, FILTERED, NOT_SECURE); } public static class Hotkeys { diff --git a/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IMessageProcessor.java b/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IMessageProcessor.java index b929799..cb2b992 100644 --- a/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IMessageProcessor.java +++ b/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IMessageProcessor.java @@ -7,6 +7,8 @@ */ package io.github.darkkronicle.advancedchatcore.interfaces; +import net.minecraft.client.gui.hud.MessageIndicator; +import net.minecraft.network.message.MessageSignatureData; import net.minecraft.text.Text; import java.util.Optional; import org.jetbrains.annotations.Nullable; @@ -37,4 +39,8 @@ default Optional filter(Text text) { * @return If the processing was a success */ boolean process(Text text, @Nullable Text unfiltered); + + default boolean process(Text text, @Nullable Text unfilterered, @Nullable MessageSignatureData signature, @Nullable MessageIndicator indicator) { + return process(text, unfilterered); + } } diff --git a/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinChatHud.java b/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinChatHud.java index fe323a2..e74d9a3 100644 --- a/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinChatHud.java +++ b/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinChatHud.java @@ -14,7 +14,10 @@ import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.hud.ChatHud; +import net.minecraft.client.gui.hud.MessageIndicator; +import net.minecraft.network.message.MessageSignatureData; import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -30,12 +33,12 @@ public class MixinChatHud { @Shadow @Final private MinecraftClient client; @Inject( - method = "addMessage(Lnet/minecraft/text/Text;I)V", + method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/client/gui/hud/MessageIndicator;)V", at = @At("HEAD"), cancellable = true) - private void addMessage(Text text, int id, CallbackInfo ci) { + private void addMessage(Text message, @Nullable MessageSignatureData signature, @Nullable MessageIndicator indicator, CallbackInfo ci) { // Pass forward messages to dispatcher - MessageDispatcher.getInstance().handleText(text); + MessageDispatcher.getInstance().handleText(message, signature, indicator); ci.cancel(); } diff --git a/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinChatHudInvoker.java b/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinChatHudInvoker.java index 4914e17..a6702a1 100644 --- a/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinChatHudInvoker.java +++ b/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinChatHudInvoker.java @@ -8,12 +8,15 @@ package io.github.darkkronicle.advancedchatcore.mixin; import net.minecraft.client.gui.hud.ChatHud; +import net.minecraft.client.gui.hud.MessageIndicator; +import net.minecraft.network.message.MessageSignatureData; import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; @Mixin(ChatHud.class) public interface MixinChatHudInvoker { @Invoker - void invokeAddMessage(Text message, int messageId, int timestamp, boolean refresh); + void invokeAddMessage(Text message, @Nullable MessageSignatureData signature, int ticks, @Nullable MessageIndicator indicator, boolean refresh); } diff --git a/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinMessageIndicator.java b/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinMessageIndicator.java new file mode 100644 index 0000000..728ca22 --- /dev/null +++ b/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinMessageIndicator.java @@ -0,0 +1,34 @@ +package io.github.darkkronicle.advancedchatcore.mixin; + +import io.github.darkkronicle.advancedchatcore.config.ConfigStorage; +import net.minecraft.client.gui.hud.MessageIndicator; +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.callback.CallbackInfoReturnable; + +@Mixin(MessageIndicator.class) +public class MixinMessageIndicator { + + @Inject(method = "indicatorColor", at = @At("HEAD"), cancellable = true) + private void getColor(CallbackInfoReturnable ci) { + MessageIndicator indicator = ((MessageIndicator) (Object) this); + String name = indicator.loggedName(); + ci.setReturnValue(switch (name) { + case "Modified" -> ConfigStorage.ChatScreen.MODIFIED.config.getColor().intValue; + case "Filtered" -> ConfigStorage.ChatScreen.FILTERED.config.getColor().intValue; + case "Not Secure" -> ConfigStorage.ChatScreen.NOT_SECURE.config.getColor().intValue; + default -> // And "System" + ConfigStorage.ChatScreen.SYSTEM.config.getColor().intValue; + }); + + } + + @Inject(method = "icon", at = @At("HEAD"), cancellable = true) + private void getIcon(CallbackInfoReturnable ci) { + if (!ConfigStorage.ChatScreen.SHOW_CHAT_ICONS.config.getBooleanValue()) { + ci.setReturnValue(null); + } + } + +} diff --git a/src/main/resources/advancedchatcore.mixins.json b/src/main/resources/advancedchatcore.mixins.json index f946940..b79d5f6 100644 --- a/src/main/resources/advancedchatcore.mixins.json +++ b/src/main/resources/advancedchatcore.mixins.json @@ -11,7 +11,8 @@ "MixinChatScreen", "MixinKeyboard", "MixinMinecraftClient", - "MixinSleepingChatScreen" + "MixinSleepingChatScreen", + "MixinMessageIndicator" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/assets/advancedchatcore/lang/en_us.json b/src/main/resources/assets/advancedchatcore/lang/en_us.json index 2559b17..590ee43 100644 --- a/src/main/resources/assets/advancedchatcore/lang/en_us.json +++ b/src/main/resources/assets/advancedchatcore/lang/en_us.json @@ -53,6 +53,16 @@ "advancedchat.config.chatscreen.info.moretext": "Whether or not messages that are §6over the 256 character limit§r are broken into multiple chat messages", "advancedchat.config.chatscreen.color": "Chat Color", "advancedchat.config.chatscreen.info.color": "Changes color of the §6chat box§r and buttons nearby.", + "advancedchat.config.chatscreen.showchaticons": "Show Chat Icons", + "advancedchat.config.chatscreen.info.showchaticons": "Show chat icons that provide info on message signature type", + "advancedchat.config.chatscreen.modified": "Modified Color", + "advancedchat.config.chatscreen.info.modified": "The color that modified signed messages will be", + "advancedchat.config.chatscreen.filtered": "Filtered Color", + "advancedchat.config.chatscreen.info.filtered": "The color that filtered signed messages will be", + "advancedchat.config.chatscreen.system": "System Color", + "advancedchat.config.chatscreen.info.system": "The color that system signed messages will be", + "advancedchat.config.chatscreen.notsecure": "Not Secure Color", + "advancedchat.config.chatscreen.info.notsecure": "The color that not secure signed messages will be", "advancedchat.config.button.configure": "§bConfigure", "advancedchat.config.button.active": "%s", diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index a896bdf..66ad16c 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -31,8 +31,7 @@ "fabricloader": ">=0.13.0", "fabric": "*", "minecraft": ">=1.19", - "malilib": ">=0.13.0", - "kommandlib": "*" + "malilib": ">=0.13.0" }, "custom": { "modmenu": {