--- title: 房间版本 1 type: docs weight: 10 version: 1 --- {{< boxes/warning >}} 本页面的翻译未经核对,可能存在翻译质量不佳、错翻、漏翻等情况。您可以在 Forgejo 存储库 打开 Issue、提交 Pull Request 或邮件联系我们提出改进建议和参与翻译与核对。 {{< /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" %}}