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