90 lines
4.2 KiB
Markdown
90 lines
4.2 KiB
Markdown
---
|
||
title: 房间版本 1
|
||
type: docs
|
||
weight: 10
|
||
version: 1
|
||
---
|
||
|
||
{{< boxes/warning >}}
|
||
本页面的翻译未经核对,可能存在翻译质量不佳、错翻、漏翻等情况。您可以在 <a href="https://codeberg.org/wholetrans/docs-matrix-spec">Forgejo 存储库</a> 打开 Issue、提交 Pull Request 或<a href="mailto:errata@wholetrans.org">邮件联系</a>我们提出改进建议和参与翻译与核对。
|
||
{{< /boxes/warning >}}
|
||
|
||
|
||
此房间版本是房间的第一个版本,包含了其他房间版本的构建基础。
|
||
|
||
## 客户端注意事项
|
||
|
||
本地实现删除算法的客户端应参考下方的[删除](#redactions)部分。
|
||
|
||
### 删除
|
||
|
||
{{% rver-fragment name="v1-redactions" %}}
|
||
|
||
## 服务器实现组成部分
|
||
|
||
{{% boxes/warning %}}
|
||
本节信息仅供服务器实现者参考。使用客户端-服务器 API 的应用通常不受此处细节的影响。针对客户端注意事项的上一节才是客户端-服务器 API 相关用例应参考的资源。
|
||
{{% /boxes/warning %}}
|
||
|
||
此处定义的算法仅适用于版本 1 的房间。其他房间版本可能会采用其他算法,因此服务器在执行相关算法前应先确认所处理的是哪一版本的房间。
|
||
|
||
{{% boxes/warning %}}
|
||
尽管目前有许多房间在使用房间版本 1,但已知其会出现一些不理想的效果。支持房间版本 1 的服务器应注意,其限制通常应当更为宽松,同时可能会出现不一致的情况。
|
||
{{% /boxes/warning %}}
|
||
|
||
### 删除
|
||
|
||
[见上文](#redactions)。
|
||
|
||
### 事件 ID
|
||
|
||
{{% rver-fragment name="v1-event-ids" %}}
|
||
|
||
### 事件格式
|
||
|
||
版本 1 房间中的事件结构如下:
|
||
|
||
{{% definition path="api/server-server/definitions/pdu_v1" %}}
|
||
|
||
#### 已弃用的事件内容 schema
|
||
|
||
{{% rver-fragment name="v1-deprecated-formatting-off-spec" %}}
|
||
|
||
{{% rver-fragment name="v1-stringy-power-levels" %}}
|
||
|
||
### 授权规则
|
||
|
||
{{% rver-fragment name="v1-auth-rules" %}}
|
||
|
||
### 状态解析
|
||
|
||
{{% boxes/warning %}}
|
||
已知房间版本 1 存在一些 bug 可能导致房间状态回滚到之前的旧版本。例如,这可能导致已加入房间的用户被移除,管理员和版主丢失其权限,甚至被封禁的用户能够重新加入。其它状态事件,如房间名称或主题,也可能会回滚到之前的版本。
|
||
|
||
这些问题在房间版本 2 引入的状态解析算法中已被修复。
|
||
{{% /boxes/warning %}}
|
||
|
||
事件 *E* 之后的房间状态 *S′*(*E*),以 *E* 之前的房间状态 *S*(*E*) 为基础定义,并且取决于 *E* 是状态事件还是消息事件:
|
||
|
||
- 如果 *E* 是消息事件,则 *S′(E)* = *S(E)*。
|
||
- 如果 *E* 是状态事件,则 *S′(E)* 等于 *S(E)*,但将对应于 *E* 的 `event_type` 和 `state_key` 的条目替换为 *E* 的 `event_id`。
|
||
|
||
事件 *E* 之前的房间状态 *S(E)*,等于 *E* 的所有 `prev_events` {*E′*, *E″*, …} 之后生成的状态集 {*S′(E′)*, *S′(E″)*, …} 的*解析*结果。
|
||
|
||
多状态的*解析*规则如下。最终解析出的状态通过多轮遍历构建;我们以 *R* 表示当前已解析的中间结果。
|
||
|
||
- 首先,将 *R* 设为所有需要解析的状态的并集,排除任何*冲突*事件。
|
||
- 第一步先解决 `m.room.power_levels` 相关事件的冲突。如果没有冲突,则跳过此步骤;否则:
|
||
- 把要解析的状态中的所有 `m.room.power_levels` 事件收集成一个列表。
|
||
- 按照 `depth` 升序、`sha1(event_id)` 降序排序。
|
||
- 将列表中的第一个事件加入 *R*。
|
||
- 对于列表后续每个事件,检查该事件是否被授权在状态 *R* 的房间中触发。如果允许,则用该事件更新 *R*,继续处理下一个事件;如不允许,则终止,跳过到下一步解决 `m.room.join_rules` 事件。
|
||
- 针对 `m.room.join_rules` 事件的冲突,重复上述过程。
|
||
- 针对 `m.room.member` 事件的冲突,也同样重复上述过程。
|
||
- 其余事件对授权规则没有影响,因此对于其它所有冲突,只需选择通过 *R* 中的身份验证、且拥有最大 depth 和最小 `sha1(event_id)` 的事件,将其加入 *R*。
|
||
|
||
*冲突*指的是两个状态针对同一 `(event_type, state_key)` 拥有不同 `event_id`。因此受影响的事件被称为*冲突*事件。
|
||
|
||
### 标准 JSON
|
||
|
||
{{% rver-fragment name="v1-canonical-json" %}}
|