Skip to content

Commit

Permalink
feat: chat responser
Browse files Browse the repository at this point in the history
- move sendPlayerChat method from MacroChat.java to ChatTools.java
  • Loading branch information
70CentsApple committed Sep 9, 2023
1 parent 9c682d5 commit 99906ad
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 29 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ loader_version=0.14.21
fabric_version=0.83.0+1.20

# Mod Properties
mod_version = 1.3.4
mod_version = 1.4.0
maven_group = net.apple70cents
archives_base_name = chattools
35 changes: 35 additions & 0 deletions src/main/java/net/apple70cents/chattools/ChatTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.apple70cents.chattools.config.ModClothConfig;
import net.apple70cents.chattools.config.ModConfigFallback;
import net.apple70cents.chattools.features.chatnotifier.ChatNotifier;
import net.apple70cents.chattools.features.chatnotifier.SystemToast;
import net.apple70cents.chattools.features.quickchat.MacroChat;
import net.apple70cents.chattools.features.quickchat.QuickRepeat;
Expand All @@ -18,12 +19,15 @@
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.util.InputUtil;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Pair;
import net.minecraft.util.StringHelper;
import net.minecraft.util.Util;
import org.apache.commons.lang3.StringUtils;
import org.lwjgl.glfw.GLFW;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -259,6 +263,37 @@ public static String wash_message(String str) {
return Pattern.compile("§.").matcher(str).replaceAll("");
}

public static void sendPlayerChat(String chatText, boolean forceDisableInjector) {
boolean oldStatus = config.injectorEnabled;
// 临时关闭
if (forceDisableInjector) {
config.injectorEnabled = false;
}
ChatNotifier.setJustSentMessage(true);
chatText = StringHelper.truncateChat(StringUtils.normalizeSpace(chatText.trim()));
if (!chatText.isEmpty()) {
MinecraftClient.getInstance().inGameHud.getChatHud().addToMessageHistory(chatText);
ClientPlayerEntity player = MinecraftClient.getInstance().player;
if (chatText.startsWith("/")) {
if (player != null) {
player.networkHandler.sendChatCommand(chatText.substring(1));
}
} else {
if (player != null) {
player.networkHandler.sendChatMessage(chatText);
}
}
}
// 重新开启
if (forceDisableInjector) {
config.injectorEnabled = oldStatus;
}
}

public static void sendPlayerChat(String chatText) {
sendPlayerChat(chatText, false);
}

/**
* 打开 GUI
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import me.shedaniel.clothconfig2.impl.builders.SubCategoryBuilder;
import net.apple70cents.chattools.ChatTools;
import net.apple70cents.chattools.features.chatbubbles.BubbleRenderer;
import net.apple70cents.chattools.features.chatresponser.ChatResponser;
import net.apple70cents.chattools.features.quickchat.MacroChat;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.util.InputUtil;
Expand Down Expand Up @@ -140,6 +141,10 @@ public enum CustomModifier {
add(new BubbleRenderer.BubbleRuleUnit(".*\\.hypixel\\.net", "(?<name>\\S+): (?<message>.*)", false));
add(new BubbleRenderer.BubbleRuleUnit());
}};
public boolean chatResponserEnabled = false;
public List<ChatResponser.ResponserRuleUnit> responserRuleList = new ArrayList<>() {{
add(new ChatResponser.ResponserRuleUnit());
}};

/**
* 保存配置
Expand Down Expand Up @@ -205,15 +210,15 @@ public static ConfigBuilder getConfigBuilder() {
builder.setSavingRunnable(ModClothConfig::save);
ConfigEntryBuilder eb = builder.entryBuilder();
final ModClothConfig config = ModClothConfig.get();
Function<String, Optional<Text>> REGEX_COMPILE_ERROR_SUPPLIER = (v) -> {
final Function<String, Optional<Text>> REGEX_COMPILE_ERROR_SUPPLIER = (v) -> {
try {
Pattern.compile(v);
return Optional.empty();
} catch (PatternSyntaxException e) {
return Optional.of(Text.of(e.getDescription()));
}
};
Function<String, Optional<Text>> REGEX_COMPILE_ERROR_SUPPLIER_ALLOW_STAR = (v) -> {
final Function<String, Optional<Text>> REGEX_COMPILE_ERROR_SUPPLIER_ALLOW_STAR = (v) -> {
if ("*".equals(v)) return Optional.empty();
try {
Pattern.compile(v);
Expand All @@ -222,7 +227,7 @@ public static ConfigBuilder getConfigBuilder() {
return Optional.of(Text.of(e.getDescription()));
}
};
Function<String, Optional<Text>> REGEX_COMPILE_ERROR_SUPPLIER_REQUIRE_GROUPS = (v) -> {
final Function<String, Optional<Text>> REGEX_COMPILE_ERROR_SUPPLIER_REQUIRE_GROUPS = (v) -> {
try {
Pattern.compile(v);
if (v.contains("<name>") && v.contains("<message>")) {
Expand Down Expand Up @@ -448,6 +453,46 @@ public static ConfigBuilder getConfigBuilder() {
}
}));

// ========== Chat Responser Category ==========
ConfigCategory chatResponserCategory = builder.getOrCreateCategory(Text.translatable("key.chattools.category.responser"));
// 启用聊天回应
chatResponserCategory.addEntry(eb.startBooleanToggle(Text.translatable("text.config.chattools.option.responserEnabled"), config.chatResponserEnabled).setDefaultValue(new ModConfigFallback().chatResponserEnabled).setSaveConsumer(v -> config.chatResponserEnabled = v).build());
// 回应规则
if (MinecraftClient.getInstance().getCurrentServerEntry() == null) {
label = Text.translatable("text.config.chattools.option.responserRulesList", "§f-");
} else {
label = Text.translatable("text.config.chattools.option.responserRulesList", "§f" + MinecraftClient.getInstance().getCurrentServerEntry().address);
}
chatResponserCategory.addEntry(new NestedListListEntry<ChatResponser.ResponserRuleUnit, MultiElementListEntry<ChatResponser.ResponserRuleUnit>>(label, config.responserRuleList, true, // 启用默认展开
() -> Optional.of(new net.minecraft.text.MutableText[]{Text.translatable("text.config.chattools.option.responserRulesList.@Tooltip")}), // Tooltip
v -> config.responserRuleList = v, // Save Consumer
() -> new ModConfigFallback().responserRuleList, // 默认值
eb.getResetButtonKey(), // 重置按钮键值
true, // 启用删除键
true, // 在列表前面插入新内容
(responserRuleUnit, __) -> {
AtomicReference<ChatResponser.ResponserRuleUnit> responserUnitRef = new AtomicReference<>(new ChatResponser.ResponserRuleUnit());
if (responserRuleUnit == null) { // 新建
Text displayText = Text.translatable("text.config.chattools.option.responserNew");
ChatResponser.ResponserRuleUnit defaultRule = new ChatResponser.ResponserRuleUnit();
responserUnitRef.set(defaultRule); // 设置初始值
return new MultiElementListEntry<>(displayText, defaultRule, new ArrayList<>() {{
add(eb.startStrField(Text.translatable("text.config.chattools.option.responserAddress"), defaultRule.getAddress()).setTooltip(Text.translatable("text.config.chattools.option.responserAddress.@Tooltip")).setDefaultValue(defaultRule.getAddress()).setSaveConsumer(responserUnitRef.get()::setAddress).setErrorSupplier(REGEX_COMPILE_ERROR_SUPPLIER_ALLOW_STAR).build());
add(eb.startStrField(Text.translatable("text.config.chattools.option.responserMatchPattern"), defaultRule.getPattern()).setTooltip(Text.translatable("text.config.chattools.option.responserMatchPattern.@Tooltip")).setDefaultValue(defaultRule.getPattern()).setSaveConsumer(responserUnitRef.get()::setPattern).setErrorSupplier(REGEX_COMPILE_ERROR_SUPPLIER).build());
add(eb.startStrField(Text.translatable("text.config.chattools.option.responserString"), defaultRule.getMessage()).setTooltip(Text.translatable("text.config.chattools.option.responserString.@Tooltip")).setDefaultValue(defaultRule.getMessage()).setSaveConsumer(responserUnitRef.get()::setMessage).build());
add(eb.startBooleanToggle(Text.translatable("text.config.chattools.option.responserForceDisableInjector"), defaultRule.isForceDisableInjector()).setTooltip(Text.translatable("text.config.chattools.option.responserForceDisableInjector.@Tooltip")).setDefaultValue(defaultRule.isForceDisableInjector()).setSaveConsumer(responserUnitRef.get()::setForceDisableInjector).build());
}}, false);
} else { // 现有
String colorPrefix = ("*".equals(responserRuleUnit.getAddress()) || (MinecraftClient.getInstance().getCurrentServerEntry() != null && Pattern.compile(responserRuleUnit.getAddress()).matcher(MinecraftClient.getInstance().getCurrentServerEntry().address).matches())) ? "§a" : "§6";
Text displayText = Text.translatable("text.config.chattools.option.responserDisplay", colorPrefix + responserRuleUnit.getAddress(), responserRuleUnit.isForceDisableInjector() ? "§a✔" : "§c✘", responserRuleUnit.getPattern(), responserRuleUnit.getMessage());
return new MultiElementListEntry<>(displayText, responserRuleUnit, new ArrayList<>() {{
add(eb.startStrField(Text.translatable("text.config.chattools.option.responserAddress"), responserRuleUnit.getAddress()).setTooltip(Text.translatable("text.config.chattools.option.responserAddress.@Tooltip")).setDefaultValue(new ChatResponser.ResponserRuleUnit().getAddress()).setSaveConsumer(responserRuleUnit::setAddress).setErrorSupplier(REGEX_COMPILE_ERROR_SUPPLIER_ALLOW_STAR).build());
add(eb.startStrField(Text.translatable("text.config.chattools.option.responserMatchPattern"), responserRuleUnit.getPattern()).setTooltip(Text.translatable("text.config.chattools.option.responserMatchPattern.@Tooltip")).setDefaultValue(new ChatResponser.ResponserRuleUnit().getPattern()).setSaveConsumer(responserRuleUnit::setPattern).setErrorSupplier(REGEX_COMPILE_ERROR_SUPPLIER).build());
add(eb.startStrField(Text.translatable("text.config.chattools.option.responserString"), responserRuleUnit.getMessage()).setTooltip(Text.translatable("text.config.chattools.option.responserString.@Tooltip")).setDefaultValue(new ChatResponser.ResponserRuleUnit().getMessage()).setSaveConsumer(responserRuleUnit::setMessage).build());
add(eb.startBooleanToggle(Text.translatable("text.config.chattools.option.responserForceDisableInjector"), responserRuleUnit.isForceDisableInjector()).setTooltip(Text.translatable("text.config.chattools.option.responserString.@Tooltip")).setDefaultValue(new ChatResponser.ResponserRuleUnit().isForceDisableInjector()).setSaveConsumer(responserRuleUnit::setForceDisableInjector).build());
}}, false);
}
}));
return builder;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.apple70cents.chattools.config;

import net.apple70cents.chattools.features.chatbubbles.BubbleRenderer;
import net.apple70cents.chattools.features.chatresponser.ChatResponser;
import net.apple70cents.chattools.features.quickchat.MacroChat;
import net.minecraft.client.util.InputUtil;

Expand Down Expand Up @@ -76,4 +77,8 @@ public static class ToastNotifySettings {
add(new BubbleRenderer.BubbleRuleUnit(".*\\.hypixel\\.net","(?<name>\\S+): (?<message>.*)",false));
add(new BubbleRenderer.BubbleRuleUnit());
}};
public boolean chatResponserEnabled = false;
public List<ChatResponser.ResponserRuleUnit> responserRuleList = new ArrayList<>() {{
add(new ChatResponser.ResponserRuleUnit());
}};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package net.apple70cents.chattools.features.chatresponser;

import net.apple70cents.chattools.ChatTools;
import net.apple70cents.chattools.config.ModClothConfig;
import net.minecraft.client.MinecraftClient;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ChatResponser {
public static class ResponserRuleUnit {
private String address;
private String pattern;

private String message;
private boolean forceDisableInjector;


public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public String getPattern() {
return pattern;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}

public String getMessage() {
return message;
}

public void setMessage(String string) {
this.message = string;
}

public boolean isForceDisableInjector() {
return forceDisableInjector;
}

public void setForceDisableInjector(boolean forceDisableInjector) {
this.forceDisableInjector = forceDisableInjector;
}

public ResponserRuleUnit() {
this.address = "*";
this.pattern = "Repeat my words:(?<word>.*)";
this.message = "You said {word}.";
this.forceDisableInjector = false;
}

public ResponserRuleUnit(String address, String pattern, String message, boolean forceDisableInjector) {
this.address = address;
this.pattern = pattern;
this.message = message;
this.forceDisableInjector = forceDisableInjector;
}
}

static ModClothConfig config = ModClothConfig.get();
static MinecraftClient mc = MinecraftClient.getInstance();

/**
* 把`message`中的{GROUP}格式的组名替换成`rawMessageReceived`中的对应分组
*
* @param rawMessageReceived 收到的原始信息
* @param rawPattern 原始模式串
* @param message 待发消息
* @return 处理后的待发消息
*/
static String replaceAllGroupNames(String rawMessageReceived, String rawPattern, String message) {
// 这个正则表达式能取出花括号中的组名。即能取出`{name}`中的`name`;`{\}\{}`中的`\}\{`;但不能取出`{name\}`或者`\{name}`。
final String groupNamePattern = "(?<!\\\\)\\{(?<group>.*?)(?<!\\\\)}";
Matcher matcher = Pattern.compile(groupNamePattern).matcher(message);
Matcher rawMessageMatcher = Pattern.compile(rawPattern).matcher(rawMessageReceived);
while (matcher.find()) {
String groupName = matcher.group("group");
System.out.println("groupName = " + groupName);
if (rawMessageMatcher.find()) {
String context = rawMessageMatcher.group(groupName);
if (context != null && !context.isBlank()) { // 捕获到的组内容非空
message = message.replace("{" + groupName + "}", context);
}
}
}
return message;
}

public static void work(String messageReceived) {
messageReceived = ChatTools.wash_message(messageReceived);
boolean canResponse = false;
String pattern = "";
String message = "";
boolean forceDisableInjector = false;
for (var unit : config.responserRuleList) {
if (mc.getCurrentServerEntry() == null) {
if ("*".equals(unit.getAddress())) {
if (Pattern.compile(unit.getPattern()).matcher(messageReceived).matches()) {
canResponse = true;
pattern = unit.getPattern();
message = unit.getMessage();
forceDisableInjector = unit.isForceDisableInjector();
break;
}
}
} else if ("*".equals(unit.getAddress()) || Pattern.compile(unit.getAddress()).matcher(mc.getCurrentServerEntry().address).matches()) {
if (Pattern.compile(unit.getPattern()).matcher(messageReceived).matches()) {
canResponse = true;
pattern = unit.getPattern();
forceDisableInjector = unit.isForceDisableInjector();
break;
}
}
}
if (canResponse) {
message = replaceAllGroupNames(messageReceived, pattern, message);
if (mc.player != null) {
message = message.replace("{pos}", String.format("(%d,%d,%d)", (int) mc.player.getX(), (int) mc.player.getY(), (int) mc.player.getZ()));
}
message = message.replace("\\{", "{").replace("\\}", "}");
ChatTools.sendPlayerChat(message,forceDisableInjector);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
import net.apple70cents.chattools.ChatTools;
import net.apple70cents.chattools.config.ModClothConfig;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.util.InputUtil;
import net.minecraft.util.StringHelper;
import org.apache.commons.lang3.StringUtils;

import static net.apple70cents.chattools.ChatTools.config;
import static net.apple70cents.chattools.ChatTools.isKeyPressedOrMouseKeyClicked;
Expand Down Expand Up @@ -89,31 +86,14 @@ public void tick() {
if (!keyWasPressed) {
keyWasPressed = true;
ChatTools.LOGGER.info("[ChatTools] Triggered Macro: " + command);
sendPlayerChat(command);
ChatTools.sendPlayerChat(command);
}
} else {
keyWasPressed = false;
}
}
}

public static void sendPlayerChat(String chatText) {
chatText = StringHelper.truncateChat(StringUtils.normalizeSpace(chatText.trim()));
if (!chatText.isEmpty()) {
MinecraftClient.getInstance().inGameHud.getChatHud().addToMessageHistory(chatText);
ClientPlayerEntity player = MinecraftClient.getInstance().player;
if (chatText.startsWith("/")) {
if (player != null) {
player.networkHandler.sendChatCommand(chatText.substring(1));
}
} else {
if (player != null) {
player.networkHandler.sendChatMessage(chatText);
}
}
}
}

/**
* 聊天宏的主要逻辑
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public static void checkQuickRepeat() {
mc.player.sendMessage(Text.translatable("text.config.chattools.option.quickRepeatFailure"), true);
}
} else {
MacroChat.sendPlayerChat(history.get(history.size() - 1));
ChatTools.sendPlayerChat(history.get(history.size() - 1));
}
}
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.apple70cents.chattools.mixin;

import net.apple70cents.chattools.features.chatnotifier.ChatNotifier;
import net.apple70cents.chattools.features.chatresponser.ChatResponser;
import net.minecraft.client.gui.hud.ChatHud;
import net.minecraft.client.gui.hud.MessageIndicator;
import net.minecraft.text.Text;
Expand Down Expand Up @@ -32,6 +33,9 @@ public void dealWithMessage(Args args) {
}
Text message = args.get(0);
MessageIndicator indicator = args.get(3);
if(config.chatResponserEnabled && !ChatNotifier.isJustSentMessage()){
ChatResponser.work(message.getString());
}
args.set(0, ChatNotifier.deal(message, indicator));
}
}
Loading

0 comments on commit 99906ad

Please sign in to comment.