From e68ebaa5fa0ded07531b57f40f8bfeeda60a077d Mon Sep 17 00:00:00 2001 From: hypherionmc Date: Wed, 1 May 2024 23:41:14 +0200 Subject: [PATCH] [CHORE] Update orion and add chat suggestions for SDLink --- .../client/mentions/MentionCondition.java | 13 +++ .../client/mentions/MentionsController.java | 47 +++++++++++ .../mixin/ChatInputSuggestorMixin.java | 84 +++++++++++++++++++ .../src/main/resources/craterlib.mixins.json | 1 + Fabric/build.gradle | 1 - build.gradle | 4 +- 6 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionCondition.java create mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionsController.java create mode 100644 Common/src/main/java/com/hypherionmc/craterlib/mixin/ChatInputSuggestorMixin.java diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionCondition.java b/Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionCondition.java new file mode 100644 index 0000000..e8bffde --- /dev/null +++ b/Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionCondition.java @@ -0,0 +1,13 @@ +package com.hypherionmc.craterlib.client.mentions; + +/** + * Based on ... + */ +@FunctionalInterface +public interface MentionCondition { + + boolean shouldAddMention(String currentWord); + + MentionCondition ALWAYS = currentWord -> true; + +} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionsController.java b/Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionsController.java new file mode 100644 index 0000000..bad3b43 --- /dev/null +++ b/Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionsController.java @@ -0,0 +1,47 @@ +package com.hypherionmc.craterlib.client.mentions; + +import com.hypherionmc.craterlib.nojang.resources.ResourceIdentifier; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Based on ... + */ +public class MentionsController { + + private static final Map> mentions = new LinkedHashMap<>(); + private static final Map mentionConditions = new LinkedHashMap<>(); + @Getter + private static boolean lastMentionConditional = true; + + public static void registerMention(ResourceIdentifier mentionClass, Collection suggestions, MentionCondition condition) { + mentions.put(mentionClass, suggestions); + mentionConditions.put(mentionClass, condition); + } + + public static Collection getMentions(String currentWord) { + ArrayList applicableMentions = new ArrayList<>(); + lastMentionConditional = false; + + mentionConditions.forEach((mention, condition) -> { + boolean shouldSuggest = condition.shouldAddMention(currentWord); + if (!shouldSuggest) return; + + if (!lastMentionConditional && condition != MentionCondition.ALWAYS) { + lastMentionConditional = true; + } + + applicableMentions.addAll(mentions.get(mention)); + }); + + return applicableMentions; + } + + public static boolean hasMentions() { + return !mentions.isEmpty(); + } +} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/mixin/ChatInputSuggestorMixin.java b/Common/src/main/java/com/hypherionmc/craterlib/mixin/ChatInputSuggestorMixin.java new file mode 100644 index 0000000..c48dfbc --- /dev/null +++ b/Common/src/main/java/com/hypherionmc/craterlib/mixin/ChatInputSuggestorMixin.java @@ -0,0 +1,84 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.client.mentions.MentionsController; +import net.minecraft.client.gui.components.CommandSuggestions; +import net.minecraft.client.gui.components.EditBox; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.Slice; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * @author HypherionSA + * Allow Users, Roles and Channels to be pingable from MC chat (Client Side) + */ +@Mixin(CommandSuggestions.class) +public abstract class ChatInputSuggestorMixin { + + @Shadow + public abstract void showSuggestions(boolean p_93931_); + + @Shadow @Final + EditBox input; + + @Shadow + private static int getLastWordIndex(String p_93913_) { + return 0; + } + + @Inject( + method = "updateCommandInfo", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/client/gui/components/CommandSuggestions;pendingSuggestions:Ljava/util/concurrent/CompletableFuture;", + opcode = Opcodes.PUTFIELD, + shift = At.Shift.AFTER, + ordinal = 0 + ), + slice = @Slice( + from = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/components/CommandSuggestions;getLastWordIndex(Ljava/lang/String;)I" + ) + ) + ) + private void injectSuggestions(CallbackInfo ci) { + if (MentionsController.hasMentions() && MentionsController.isLastMentionConditional()) { + this.showSuggestions(true); + } + } + + @SuppressWarnings("InvalidInjectorMethodSignature") + @ModifyVariable(method = "updateCommandInfo", at = @At(value = "STORE"), ordinal = 0, name = "collection") + private Collection injectMentions(Collection vanilla) { + if (!MentionsController.hasMentions()) + return vanilla; + + ArrayList newSuggest = new ArrayList<>(vanilla); + + String currentInput = this.input.getValue(); + int currentCursorPosition = this.input.getCursorPosition(); + + String textBeforeCursor = currentInput.substring(0, currentCursorPosition); + int startOfCurrentWord = getLastWordIndex(textBeforeCursor); + + String currentWord = textBeforeCursor.substring(startOfCurrentWord); + String finalWord = currentWord.replace("[", "").replace("]", ""); + + Collection mentions = MentionsController.getMentions(finalWord); + + if (!mentions.isEmpty()) { + mentions.forEach(m -> newSuggest.add("[" + m + "]")); + } + + return newSuggest; + } +} \ No newline at end of file diff --git a/Common/src/main/resources/craterlib.mixins.json b/Common/src/main/resources/craterlib.mixins.json index 108b07b..1a739db 100644 --- a/Common/src/main/resources/craterlib.mixins.json +++ b/Common/src/main/resources/craterlib.mixins.json @@ -6,6 +6,7 @@ "mixins": [ ], "client": [ + "ChatInputSuggestorMixin", "events.PlayerMixin", "events.client.ClientLevelMixin", "events.client.MinecraftMixin", diff --git a/Fabric/build.gradle b/Fabric/build.gradle index 557c74d..3aeee20 100644 --- a/Fabric/build.gradle +++ b/Fabric/build.gradle @@ -56,7 +56,6 @@ jar { processResources { from project(":Common").sourceSets.main.resources def buildProps = project.properties.clone() - println(project.version) filesMatching(['fabric.mod.json']) { expand buildProps diff --git a/build.gradle b/build.gradle index 11c5bf6..a00cece 100644 --- a/build.gradle +++ b/build.gradle @@ -3,11 +3,11 @@ plugins { id 'com.github.johnrengelman.shadow' version '8.1.1' apply false id "xyz.wagyourtail.unimined" version "1.1.0-SNAPSHOT" apply false id "me.hypherionmc.modutils.modpublisher" version "1.0.23+" - id "com.hypherionmc.modutils.orion" version "1.0.7" + id "com.hypherionmc.modutils.orion" version "1.0.9" id 'maven-publish' } -orion { +orion.setup { multiProject = true enableMirrorMaven = true enableReleasesMaven = true