Skip to content

Commit

Permalink
CQ码错误转义修复 (#145)
Browse files Browse the repository at this point in the history
* 临时的崩溃修复

* 问题修复和代码格式化

现在发送消息不会导致服务器暂停
调整一些对象的作用域

* 现在游戏内聊天中的"[""]"不会被错误转义。

孩子们我回来了

* 异步游戏->QQ的CQ转义

反卡服

* 移除多余的代码

忘删了

* 添加一个替选的旧方法

把上一个提交删的加回来了
  • Loading branch information
xia-mc authored Mar 15, 2024
1 parent 6f8bfa8 commit 0cd0055
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 74 deletions.
11 changes: 11 additions & 0 deletions fabric/src/main/java/cn/evole/mods/mcbot/Const.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import cn.evole.mods.mcbot.util.onebot.MessageThread;
import net.fabricmc.loader.api.FabricLoader;
import java.nio.file.Path;
import java.util.concurrent.Callable;
//#if MC >= 11700
//$$ import org.slf4j.Logger;
//$$ import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -40,10 +41,20 @@ public static void sendAllGroupMsg(String message){
}
}

public static void sendAllGroupMsg(Callable<String> message){
for (long id : ModConfig.INSTANCE.getCommon().getGroupIdList()){
sendGroupMsg(id, message);
}
}

public static void sendGroupMsg(long id, String message){
messageThread.submit(id, message, false);
}

public static void sendGroupMsg(long id, Callable<String> message){
messageThread.submit(id, message, false);
}

public static void shutdown() {
messageThread.stop();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void onGroup(GroupMessageEvent event){
&& ModConfig.INSTANCE.getStatus().isREnable()//总接受开关
&& event.getUserId() != ModConfig.INSTANCE.getBotConfig().getBotId()//过滤机器人
){
String send = CQUtils.replace(event);//暂时匹配仅符合字符串聊天内容与图片
String send = CQUtils.replace(event, 3000);//暂时匹配仅符合字符串聊天内容与图片
if (!send.startsWith(ModConfig.INSTANCE.getCmd().getCmdStart())//过滤命令前缀
) {
if (ModConfig.INSTANCE.getStatus().isRChatEnable())/*接受聊天开关*/ onGroupMessage(event, send);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import cn.evole.mods.mcbot.Const;
import cn.evole.mods.mcbot.config.ModConfig;
import cn.evole.mods.mcbot.util.onebot.CQUtils;
import cn.evole.onebot.sdk.util.MsgUtils;
import lombok.val;
import net.minecraft.server.level.ServerPlayer;
Expand Down Expand Up @@ -31,7 +32,7 @@ public static void register(ServerPlayer player, String message) {
ModConfig.INSTANCE.getCmd().isMcChatPrefixOn()
&& ModConfig.INSTANCE.getCmd().getMcChatPrefix().equals(split[0]) ? split[1] : message);

Const.sendAllGroupMsg(MsgUtils.builder().text(msg).build());
Const.sendAllGroupMsg(() -> MsgUtils.builder().text(CQUtils.replace(msg)).build());

}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package cn.evole.mods.mcbot.util.onebot;

import cn.evole.mods.mcbot.McBot;
import cn.evole.mods.mcbot.cmds.CustomCmd;
import cn.evole.mods.mcbot.config.ModConfig;
import cn.evole.mods.mcbot.init.handler.CustomCmdHandler;
import cn.evole.onebot.sdk.event.message.GroupMessageEvent;
import cn.evole.onebot.sdk.util.NetUtils;
import lombok.val;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.atomic.AtomicBoolean;

Expand Down Expand Up @@ -86,8 +89,8 @@ public static String cmdParse(String command) {


/**
* 获取群头像
*
* 获取群头像(弃用)
* TODO 过时的API,无法使用
* @param groupId 群号
* @param size 头像尺寸
* @return 头像链接 (size为0返回真实大小, 40(40*40), 100(100*100), 640(640*640))
Expand All @@ -97,8 +100,8 @@ public static String getGroupAvatar(long groupId, int size) {
}

/**
* 获取用户昵称
*
* 获取用户昵称(弃用)
* TODO 过时的API,无法使用
* @param userId QQ号
* @return 用户昵称
*/
Expand All @@ -113,8 +116,8 @@ public static String getNickname(long userId) {
}

/**
* 获取用户头像
*
* 获取用户头像(弃用)
* TODO 过时的API,无法使用
* @param userId QQ号
* @param size 头像尺寸
* @return 头像链接 (size为0返回真实大小, 40(40*40), 100(100*100), 640(640*640))
Expand Down
156 changes: 90 additions & 66 deletions fabric/src/main/java/cn/evole/mods/mcbot/util/onebot/CQUtils.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package cn.evole.mods.mcbot.util.onebot;

import cn.evole.mods.mcbot.Const;
import cn.evole.mods.mcbot.McBot;
import cn.evole.mods.mcbot.config.ModConfig;
import cn.evole.onebot.sdk.event.message.MessageEvent;
import io.netty.util.concurrent.SingleThreadEventExecutor;
import lombok.val;
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.concurrent.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -32,80 +34,102 @@ public static boolean hasImg(String msg) {
return m.find();
}

public static String replace(MessageEvent event) {
/**
* @param timeout 超时时间(毫秒),超时后返回空字符串。
*/
public static @NotNull String replace(@NotNull MessageEvent event, long timeout) {
String back = "";
val task = new FutureTask<>(() -> replace(event));
try {
Executor.execute(task);
back = task.get(timeout, TimeUnit.MILLISECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException | IllegalStateException e) {
task.cancel(true);
Const.LOGGER.error(e.getLocalizedMessage());
}
return back;
}

public static String replace(@NotNull MessageEvent event) {
return replace(event.getRawMessage());
}

public static String replace(String msg) {
String back;
StringBuffer message = new StringBuffer();
Pattern pattern = Pattern.compile(CQ_CODE_REGEX);
Matcher matcher = pattern.matcher(event.getRawMessage());
val call = new FutureTask<>(() -> {
while (matcher.find()) {//全局匹配
val type = matcher.group(1);
val data = matcher.group(2);
switch (type) {
case "image":
if (ModConfig.INSTANCE.getCommon().isImageOn() && Const.isLoad("chatimage")) {
val url = Arrays.stream(data.split(","))//具体数据分割
.filter(it -> it.startsWith("url"))//非空判断
.map(it -> it.substring(it.indexOf('=') + 1))
.findFirst();
if (url.isPresent()) {
matcher.appendReplacement(message, String.format("[[CICode,url=%s,name=来自QQ的图片]]", url.get()));
} else {
matcher.appendReplacement(message, "[图片]");
}
} else {
matcher.appendReplacement(message, "[图片]");
}
break;
case "at":
val id = Arrays.stream(data.split(","))//具体数据分割
.filter(it -> it.startsWith("qq"))//非空判断
Matcher matcher = pattern.matcher(msg);
try {
back = doReplace(matcher, message);
} catch (Exception e) {
back = msg;
Const.LOGGER.error(e.getLocalizedMessage());
}
return back;
}

private static @NotNull String doReplace(@NotNull Matcher matcher, StringBuffer message) {
while (matcher.find()) {//全局匹配
val type = matcher.group(1);
val data = matcher.group(2);
switch (type) {
case "image":
if (ModConfig.INSTANCE.getCommon().isImageOn() && Const.isLoad("chatimage")) {
val url = Arrays.stream(data.split(","))//具体数据分割
.filter(it -> it.startsWith("url"))//非空判断
.map(it -> it.substring(it.indexOf('=') + 1))
.findFirst();
if (id.isPresent()) {
matcher.appendReplacement(message, String.format("[@%s]", BotUtils.getNickname(Long.parseLong(id.get()))));
if (url.isPresent()) {
matcher.appendReplacement(message, String.format("[[CICode,url=%s,name=来自QQ的图片]]", url.get()));
} else {
matcher.appendReplacement(message, "[@]");
matcher.appendReplacement(message, "[图片]");
}
break;
case "record":
matcher.appendReplacement(message, "[语音]");
break;
case "forward":
matcher.appendReplacement(message, "[合并转发]");
break;
case "video":
matcher.appendReplacement(message, "[视频]");
break;
case "music":
matcher.appendReplacement(message, "[音乐]");
break;
case "redbag":
matcher.appendReplacement(message, "[红包]");
break;
case "face":
matcher.appendReplacement(message, "[表情]");
break;
case "reply":
matcher.appendReplacement(message, "[回复]");
break;
default:
matcher.appendReplacement(message, "[?]");
break;
}
} else {
matcher.appendReplacement(message, "[图片]");
}
break;
case "at":
/* TODO @cnlimiter need to fix it.
val id = data.split("=");
if (id.length == 2) {
if (id[0].equals("qq"))
try {
matcher.appendReplacement(message, String.format("[@%s]", BotUtils.getNickname(Long.parseLong(id[1]))));
break;
} catch (NumberFormatException ignored) {}
}
*/
matcher.appendReplacement(message, "[@]");
break;
case "record":
matcher.appendReplacement(message, "[语音]");
break;
case "forward":
matcher.appendReplacement(message, "[合并转发]");
break;
case "video":
matcher.appendReplacement(message, "[视频]");
break;
case "music":
matcher.appendReplacement(message, "[音乐]");
break;
case "redbag":
matcher.appendReplacement(message, "[红包]");
break;
case "face":
matcher.appendReplacement(message, "[表情]");
break;
case "reply":
matcher.appendReplacement(message, "[回复]");
break;
default:
matcher.appendReplacement(message, "[?]");
break;
}
matcher.appendTail(message);
return message.toString();
});
try {
Executor.execute(call);
back = call.get(1000 * 3, TimeUnit.MILLISECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException | IllegalStateException e) {
back = event.getRawMessage();
call.cancel(true);
Const.LOGGER.error(e.getLocalizedMessage());
}
return back;
matcher.appendTail(message);
return message.toString();

}

public static void shutdown() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import cn.evole.mods.mcbot.Const;
import cn.evole.mods.mcbot.McBot;
import com.google.gson.JsonArray;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

Expand Down Expand Up @@ -38,6 +40,15 @@ public void submit(String guildID, String channelID, JsonArray message) {
executor.submit(() -> McBot.onebot.getBot().sendGuildMsg(guildID, channelID, message));
}

public void submit(long groupId, Callable<String> msg, boolean autoEscape) {
executor.submit(() -> {
try {
submit(groupId, msg.call(), autoEscape);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
public void stop() {
executor.shutdownNow();
}
Expand Down

0 comments on commit 0cd0055

Please sign in to comment.