chronocat/packages/docs/blog/why-not-onebot/index.mdx.tmp
2024-03-06 12:32:45 +08:00

79 lines
3.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 为什么不是 OneBot
---
样的问题——「Chronocat 推荐使用 Satori。为什么不是 OneBot
实际上,这个问题可以拆分成两个问题:
1. **为什么 Chronocat 只提供了 Satori没有提供 OneBot**
1. **为什么 Chronocat 推荐使用 Satori而不是 OneBot**
第一个问题很好解答:我和我认识的人主要使用 Satori。我个人的 Bot 从很久以前开始就基于 Satori。
所以Chronocat 不支持 OneBot 只是因为目前我没有使用 OneBot 的需求,也就没有提供 OneBot
的实现。未来如果我有用到 OneBot 的地方,那么也会提供 OneBot 实现的。
但是为什么 Chronocat 推荐使用 Satori 而非 OneBot 呢?让我们先从几个经常遇到的场景开始说起。
---
111111111111111111111111111111111111111111111111
# 为什么 Satori 数据包中消息使用 string
如果你还不了解 Satori 或 Satori 消息元素,那么请前往 [Satori 官网]
列举一下各协议传递消息内容的方式,在 Satori 出现以前应当只有这两种:
- 使用 String 传递,并定义一种特殊元素
- 使用 JSON 传递
## 为什么使用 XML 而不是 JSON
```cs
var 消息;
// 遍历消息
foreach (var 消息段 in 消息) {
// 要判断的是文字消息
if (消息段.类型 == "text") {
// 判断内容有无「我超」
if (消息段.内容.包含("我超")) {
发送("原!");
}
}
}
```
```cs
if (消息.包含("我超")) 发送("原!")
```
不过,具体到这个问题的话,`alt_message` 呢?一些协议的
## 既然使用 String那么表达消息的能力会不会遇到问题
```html
你好! <b>我是</b> <i>Chronocat</i> 。
```
这是一段 HTML 文本。把它保存成 `.html` 格式的文件后用浏览器打开你会发现上面的粗体b和斜体i都正确得到了渲染是的你不需要添加 `<html>` 和 `<body>` 等标签。很显然HTML 是 String并且它的表达能力没有任何问题因为我们每天都会使用的各个网站全都使用 Web 技术构建。
那么,为什么在机器人开发中,我们就会开始担心 String 的表达能力问题呢?确切地来说,为什么我们会开始担心 **String 相较 JSON 的表达能力问题呢**
显然,是 OneBot 的 String 形式消息的表达能力出现了问题。这一问题实际上是由 CQ 码带来的。CQ 码只有一个最核心的问题:
**CQ 码不支持嵌套。**
不支持嵌套是 CQ 码表达能力出现缺失的根本原因CQ 码无力表达类似合并转发(`<message forward>`)这样的数据结构。使用 OneBot
的情况下,需要发送合并转发消息时,用户只能使用 JSON 来发送消息,这就使大多数用户都认为「使用 String 的话,表达消息的能力会出现问题」。但这其实是由 CQ 码导致的。
然而,并不是所有时候都可以临时使用 JSON 来解决需要嵌套的问题。OneBot 的 API 支持以两种格式发送消息,而事件推送则同样支持以两种格式推送消息事件。这却给 OneBot
实现侧的开发造成了很大的困难:如果用户配置「希望使用 String 格式接收消息」(在 OneBot 早期,为了方便 Bot 开发,大多数 Bot 开发者都使用 String 格式go-cqhttp 也将 String 作为默认值),那么
OneBot 实现就必须找到一种方法,将 JSON 之类的复杂数据结构装入 CQ 码里。
**解析 CQ 码时会遇到严重的转义问题。**
当然,也有很多其他的方法绕过这个问题,比如在 CQ 码内只放一个消息 ID然后另起一个 API 端点用于获取该消息的具体信息;然而这样的做法却会同时增加 Bot 侧和实现侧开发者的工作量,并增加实现和实现之间的分裂。