Repository: sealdice/sealdice-core (language: go)

Issue:
[Bug]: 使用海豹码嵌入相对路径发送文件名带逗号的文件失败
### 在提问之前...

- [X] 我理解 Issue 是用于反馈和解决问题的，而非吐槽评论区，将尽可能提供更多信息帮助问题解决
- [X] 我填写了简短且清晰明确的标题，以便开发者在翻阅 issue 列表时能快速确定大致问题。而不是“一个建议”、“卡住了”等
- [X] 我已查看master branch或最新测试版的更新内容，并未提及该 bug 已被修复的情况
- [X] 已有issue中并没有看见其他人与我反馈相同的问题

### 问题描述

在海豹码中使用相对路径时，若文件名带有`,`，似乎会产生截断

[dice\platform_adapter_gocq_actions.go:638 textAssetsConvert](https://github.com/sealdice/sealdice-core/blob/789f7ae243822734e2688b8ff4360ec10b072181/dice/platform_adapter_gocq_actions.go#L638)

在海豹码中手动转义`,`
海豹提示找不到文件

### 如何复现

1. 自定义回复中嵌入海豹码，且待发送的文件名带`,`
`"[语音:data/music/乐正绫,COP - 世末歌者.mp3]"`
 -> NapCat报错仅收到`*/data/music/乐正绫`，文件名被截断
`"[语音:data/music/乐正绫&#44;COP - 世末歌者.mp3]"`
 -> 海豹提示找不到文件

2. 代码中调用`ReplyToSender`发送
`"[语音:data/music/乐正绫,COP - 世末歌者.mp3]"`
 -> NapCat报错仅收到`*/data/music/乐正绫`，文件名被截断
`"[语音:data/music/乐正绫&#44;COP - 世末歌者.mp3]"`
 -> 海豹提示找不到文件

3. 使用完整url路径发送
`"[语音:file:///D:/sealdice/data/music/乐正绫,COP - 世末歌者.mp3]"`
 -> 成功发送

### 你期望发生的

成功使用相对路径的海豹码发送文件名带`,`的语音

### 实际上发生的

使用相对路径的海豹码发送文件名带`,`的语音失败

### 日志文件

sealdice日志：
dice/im_session.go:724  收到群(####)内<樂>(QQ:####)的消息: 小奥测试
dice/ext_reply.go:233   自定义回复[reply.yaml]: 条件满足
dice/im_helpers.go:192  发给(####): [voice:"D:/Programs/sealdice/data/music/乐正绫,COP - 世末歌者.mp3"]
Received message {"status":"failed","retcode":1200,"data":null,"message":"语音转换失败, 请检查语音文件是否正常","wording":"语音转换失败, 请检查语音文件是否正常","echo":""}

NapCat日志：
[INFO] 奥尔菲·亚德里安(####) | 接收 <- 群聊 (群 #### 的 ####) 小奥测试
[ERROR] 奥尔菲·亚德里安(####) | convert silk failed Error: ENOENT: no such file or directory, open 'D:\Programs\sealdice\data\music\乐正绫'

### 截图

_No response_

### 海豹核心版本

1.5.0-dev

### 操作系统

Windows 11 Pro

### 帐号类型

QQ
仅搭载了一个QQ，通过LLOneBot连接到NapCat

### 使用协议

_No response_

### 附加内容

_No response_


Discussion / hints:
~上游问题吧，海豹应该不负责这个~
~Napcat日志信息量太少，把日志等级调高，然后再抓一次日志~
~海豹问题，等待修复吧~
问题解决啦！把文件名里的逗号删了就不会报错啦！

Fix patch:
diff --git a/dice/platform_adapter_gocq_actions.go b/dice/platform_adapter_gocq_actions.go
index 82cf5d91..0963a629 100644
--- a/dice/platform_adapter_gocq_actions.go
+++ b/dice/platform_adapter_gocq_actions.go
@@ -656,7 +656,7 @@ func textAssetsConvert(s string) string {
 				}
 				cq := CQCommand{
 					Type: cqType,
-					Args: map[string]string{"file": u.String(), "cache": "0"},
+					Args: map[string]string{"file": EscapeComma(u.String()), "cache": "0"},
 				}
 				return cq.Compile()
 			}
@@ -683,7 +683,7 @@ func textAssetsConvert(s string) string {
 			}
 			cq := CQCommand{
 				Type: cqType,
-				Args: map[string]string{"file": u.String()},
+				Args: map[string]string{"file": EscapeComma(u.String())},
 			}
 			return cq.Compile()
 		}
@@ -702,6 +702,7 @@ func textAssetsConvert(s string) string {
 				return
 			}
 			if strings.HasPrefix(fn, "file://") || strings.HasPrefix(fn, "http://") || strings.HasPrefix(fn, "https://") || strings.HasPrefix(fn, "base64://") {
+				cq.Args["file"] = EscapeComma(cq.Args["file"])
 				return
 			}
 			if strings.HasSuffix(fn, ".image") && len(fn) == 32+6 {
@@ -728,7 +729,7 @@ func textAssetsConvert(s string) string {
 						Scheme: "file",
 						Path:   filepath.ToSlash(afn),
 					}
-					cq.Args["file"] = u.String()
+					cq.Args["file"] = EscapeComma(u.String())
 				}
 			} else {
 				cq.Overwrite = "[CQ码读取的不是当前目录文件或临时文件，可能是恶意行为，已禁止]"
@@ -741,3 +742,11 @@ func textAssetsConvert(s string) string {
 	text = ImageRewrite(text, solve2)
 	return CQRewrite(text, solve)
 }
+
+func EscapeComma(text string) string {
+	// 逗号属于URL合法字符，故只对file协议格式进行处理
+	if strings.HasPrefix(text, "file://") {
+		return strings.ReplaceAll(text, ",", "%2C")
+	}
+	return text
+}


Test patch: