Skip to content
This repository has been archived by the owner on Sep 2, 2024. It is now read-only.

Commit

Permalink
make ExpressionHighlighter a class, better CommandSuggestions mixin, …
Browse files Browse the repository at this point in the history
…mixin cleanup, remove MixinCustomField (i was tired!)
  • Loading branch information
homchom committed Oct 27, 2023
1 parent d20f1f8 commit ec5b21e
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ class SideChat(private val mc: Minecraft) : ChatComponent(mc) {
private fun tailWidth(scale: Double) = (12 * scale).toInt()
}

/**
* A duck interface applied to [net.minecraft.client.gui.Gui].
*/
@Suppress("FunctionName")
interface MCGuiWithSideChat {
interface DGuiWithSideChat {
fun `recode$getSideChat`(): SideChat
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ import io.github.homchom.recode.util.map
import io.github.homchom.recode.util.regex.regex
import net.kyori.adventure.text.minimessage.MiniMessage
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack

typealias HighlightedExpression = Computation<Component, String>

object ExpressionHighlighter {
class ExpressionHighlighter {
private val codes = setOf(
"default",
"selected",
Expand Down Expand Up @@ -86,13 +87,8 @@ object ExpressionHighlighter {
or; end
}

private fun leadingArgumentsRegex(highlightIndex: Int) = regex {
start
group {
none(" ").oneOrMore()
space
} * (highlightIndex + 1)
}
private var cachedInput = ""
private var cachedHighlight: HighlightedExpression = Computation.Success(Component.empty())

private val countRegex = regex {
space
Expand All @@ -107,7 +103,25 @@ object ExpressionHighlighter {
space.optional()
}

fun runHighlighting(chatInput: String, mainHandItem: ItemStack): HighlightedExpression? {
private fun leadingArgumentsRegex(highlightIndex: Int) = regex {
start
group {
none(" ").oneOrMore()
space
} * (highlightIndex + 1)
}

fun runHighlighting(chatInput: String, player: Player): HighlightedExpression? {
if (cachedInput == chatInput) return cachedHighlight
val highlight = highlight(chatInput, player.mainHandItem)
if (highlight != null) {
cachedInput = chatInput
cachedHighlight = highlight
}
return highlight
}

private fun highlight(chatInput: String, mainHandItem: ItemStack): HighlightedExpression? {
// highlight commands
if (chatInput.startsWith('/')) {
val splitIndex = chatInput.indexOf(' ') + 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import io.github.homchom.recode.feature.social.MCGuiWithSideChat;
import io.github.homchom.recode.feature.social.DGuiWithSideChat;
import io.github.homchom.recode.feature.social.SideChat;
import io.github.homchom.recode.sys.sidedchat.ChatRule;
import io.github.homchom.recode.sys.util.SoundUtil;
Expand All @@ -17,7 +17,7 @@
import org.spongepowered.asm.mixin.injection.At;

@Mixin(ChatListener.class)
public class MChatListener {
public abstract class MChatListener {
@WrapOperation(method = "showMessageToPlayer", at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/gui/components/ChatComponent;addMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/MessageSignature;Lnet/minecraft/client/GuiMessageTag;)V"
))
Expand Down Expand Up @@ -65,7 +65,7 @@ private ChatRule.ChatSide matchToChatSide(Component message) {

@Unique
private SideChat getSideChat() {
var gui = (MCGuiWithSideChat) Minecraft.getInstance().gui;
var gui = (DGuiWithSideChat) Minecraft.getInstance().gui;
return gui.recode$getSideChat();
}
}
5 changes: 3 additions & 2 deletions src/main/java/io/github/homchom/recode/mixin/render/MGui.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import io.github.homchom.recode.feature.social.MCGuiWithSideChat;
import io.github.homchom.recode.feature.social.DGuiWithSideChat;
import io.github.homchom.recode.feature.social.SideChat;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiGraphics;
Expand All @@ -13,7 +13,7 @@
import org.spongepowered.asm.mixin.injection.At;

@Mixin(Gui.class)
public abstract class MGui implements MCGuiWithSideChat {
public abstract class MGui implements DGuiWithSideChat {
@Unique
private final SideChat sideChat = new SideChat();

Expand All @@ -34,6 +34,7 @@ private void renderSideChat(

@Unique
@NotNull
@Override
public SideChat recode$getSideChat() {
return sideChat;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package io.github.homchom.recode.mixin.render;

import com.mojang.blaze3d.platform.Window;
import io.github.homchom.recode.feature.social.MCGuiWithSideChat;
import io.github.homchom.recode.feature.social.DGuiWithSideChat;
import net.minecraft.client.Minecraft;
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.CallbackInfo;

@Mixin(Window.class)
public class MWindow {
public abstract class MWindow {
@Inject(method = "setGuiScale", at = @At("TAIL"))
private void rescaleSideChat(CallbackInfo ci) {
var gui = (MCGuiWithSideChat) Minecraft.getInstance().gui;
var gui = (DGuiWithSideChat) Minecraft.getInstance().gui;
gui.recode$getSideChat().rescaleChat();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import io.github.homchom.recode.feature.social.MCGuiWithSideChat;
import io.github.homchom.recode.feature.social.DGuiWithSideChat;
import io.github.homchom.recode.feature.social.MessageStacking;
import io.github.homchom.recode.feature.social.SideChat;
import io.github.homchom.recode.mod.config.Config;
import io.github.homchom.recode.ui.ChatUI;
import io.github.homchom.recode.ui.TextFunctions;
import io.github.homchom.recode.util.mixin.MixinCustomField;
import net.minecraft.client.GuiMessage;
import net.minecraft.client.GuiMessageTag;
import net.minecraft.client.Minecraft;
Expand Down Expand Up @@ -73,7 +72,7 @@ private void clearSideChat(boolean refresh, CallbackInfo ci) {

@Unique
private SideChat getSideChat() {
var gui = (MCGuiWithSideChat) Minecraft.getInstance().gui;
var gui = (DGuiWithSideChat) Minecraft.getInstance().gui;
return gui.recode$getSideChat();
}

Expand All @@ -98,14 +97,14 @@ private boolean isSideChat() {
// message stacking

@Unique
private final MixinCustomField<Integer, ChatComponent> trimmedMessageCount = new MixinCustomField<>(() -> 0);
private int trimmedMessageCount = 0;

@Inject(
method = "addMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/MessageSignature;ILnet/minecraft/client/GuiMessageTag;Z)V",
at = @At("HEAD")
)
private void countTrimmedMessagesBeforeMessageStacking(CallbackInfo ci) {
trimmedMessageCount.set(thisChatComponent(), trimmedMessages.size());
trimmedMessageCount = trimmedMessages.size();
}

@Inject(
Expand All @@ -121,13 +120,12 @@ private void stackMessages(
CallbackInfo ci
) {
if (!Config.getBoolean("stackDuplicateMsgs")) return;
int trimmedCount = trimmedMessageCount.get(thisChatComponent());
if (trimmedCount == 0) return;
if (trimmedMessageCount == 0) return;

// trimmedMessages[0] is the most recent message
var lineCount = trimmedMessages.size() - trimmedCount;
if (trimmedCount < lineCount) return;
if (trimmedCount > lineCount) {
var lineCount = trimmedMessages.size() - trimmedMessageCount;
if (trimmedMessageCount < lineCount) return;
if (trimmedMessageCount > lineCount) {
if (!trimmedMessages.get(lineCount * 2).endOfEntry()) return;
}

Expand Down Expand Up @@ -157,9 +155,4 @@ private void stackMessages(
trimmedMessages.set(index, newLine);
}
}

@Unique
private ChatComponent thisChatComponent() {
return (ChatComponent) (Object) this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import io.github.homchom.recode.feature.social.MCGuiWithSideChat;
import io.github.homchom.recode.feature.social.DGuiWithSideChat;
import net.minecraft.client.GuiMessageTag;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.ChatComponent;
Expand All @@ -11,7 +11,7 @@
import org.spongepowered.asm.mixin.injection.At;

@Mixin(ChatScreen.class)
public class MChatScreen {
public abstract class MChatScreen {
@WrapOperation(method = "render", at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/gui/components/ChatComponent;getMessageTagAt(DD)Lnet/minecraft/client/GuiMessageTag;"
))
Expand All @@ -23,7 +23,7 @@ private GuiMessageTag recognizeSideChatTags(
) {
var mainTag = operation.call(mainChat, screenX, screenY);
if (mainTag != null) return mainTag;
var gui = (MCGuiWithSideChat) Minecraft.getInstance().gui;
var gui = (DGuiWithSideChat) Minecraft.getInstance().gui;
return gui.recode$getSideChat().getMessageTagAt(screenX, screenY);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package io.github.homchom.recode.mixin.render.chat;

import io.github.homchom.recode.feature.visual.ExpressionHighlighter;
import io.github.homchom.recode.util.Computation;
import io.github.homchom.recode.util.mixin.MixinCustomField;
import kotlin.Pair;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.CommandSuggestions;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.locale.Language;
import net.minecraft.network.chat.Component;
import net.minecraft.util.FormattedCharSequence;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
Expand All @@ -19,36 +17,26 @@
import java.util.Objects;

@Mixin(CommandSuggestions.class)
public class MCommandSuggestions {
// (input, output)
public abstract class MCommandSuggestions {
@Shadow @Final EditBox input;

@Unique
private final MixinCustomField<@Nullable Pair<String, FormattedCharSequence>, CommandSuggestions> highlight =
new MixinCustomField<>(() -> null);
private final ExpressionHighlighter highlighter = new ExpressionHighlighter();

@Inject(method = "formatChat", at = @At("HEAD"), cancellable = true)
private void formatExpressionHighlighting(
String input,
int displayPos,
private void runHighlighting(
String partialInput,
int position,
CallbackInfoReturnable<FormattedCharSequence> cir
) {
var currentHighlight = highlight.get(thisCommandSuggestions());

if (currentHighlight != null && currentHighlight.getFirst().equals(input)) {
cir.setReturnValue(currentHighlight.getSecond());
return;
}
var player = Objects.requireNonNull(Minecraft.getInstance().player);

var mainHandItem = Objects.requireNonNull(Minecraft.getInstance().player).getMainHandItem();
var comp = ExpressionHighlighter.INSTANCE.runHighlighting(input, mainHandItem);
if (comp instanceof Computation.Success<?> success) {
var formatted = Language.getInstance().getVisualOrder((Component) success.getValue());
highlight.set(thisCommandSuggestions(), new Pair<>(input, formatted));
cir.setReturnValue(formatted);
}
}
var highlighted = highlighter.runHighlighting(partialInput, player);
if (highlighted == null) return;
var success = highlighted.asSuccess();
if (success == null) return;

@Unique
private CommandSuggestions thisCommandSuggestions() {
return (CommandSuggestions) (Object) this;
var formatted = Language.getInstance().getVisualOrder(success.getValue());
cir.setReturnValue(formatted);
}
}
2 changes: 2 additions & 0 deletions src/main/java/io/github/homchom/recode/util/Computations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import io.github.homchom.recode.util.Computation.Success
* [Either](https://docs.rs/either/latest/either/enum.Either.html) type found in many functional languages.
*/
sealed interface Computation<out S, out F> {
fun asSuccess() = this as? Success<S>

class Success<out T>(override val value: T) : Computation<T, Nothing>, InvokableWrapper<T>
class Failure<out T>(override val value: T) : Computation<Nothing, T>, InvokableWrapper<T>
}
Expand Down

This file was deleted.

0 comments on commit ec5b21e

Please sign in to comment.