> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/contributor/contributor-zh/nei-rong/snapshots.md).

# 快照

内容服务器会定期汇总它们所托管的活跃实体，称为 *快照*。它们是常规 [文件](https://github.com/decentraland/docs/blob/main/contributor/filesystem.md) ，并且可以使用其标识符下载。

快照按日、周、月和年生成。每个快照都包含自上一个该时间范围内的快照以来发生变化的活跃实体集合。

快照会包含同一实体的冲突版本（即不同的 [清单文件](https://github.com/decentraland/docs/blob/main/contributor/entities.md#properties) ）并与同一指针关联，因为它们会不断更新。扫描时，客户端应保留最新快照中的版本。由于内容服务器允许删除非活跃文件，过时的实体版本不能保证可供下载。

当一个新的快照 *替换* 旧快照时（例如，一个合并了一系列日快照的周快照），其元数据会指明哪些先前文件被替换，因此客户端无需下载它们。

完整的活跃实体集合可以通过合并所有可用快照来发现（下面会进一步说明），并保留沿途发现的每个 [指针](https://github.com/decentraland/docs/blob/main/contributor/pointers.md) 所引用的最新实体。

你可以在 [练习](https://github.com/decentraland/docs/blob/main/contributor/practice.md) 部分使用可运行的代码来尝试快照。

### 发现快照 <a href="#discover" id="discover"></a>

要定位当前的快照集合，请使用 [`快照` 端点](https://decentraland.github.io/catalyst-api-specs/#tag/Content-Server/operation/getSnapshots)。响应包含一个项目数组，字段如下：

| 字段                        | 值                                                                                   |
| ------------------------- | ----------------------------------------------------------------------------------- |
| `generationTimestamp`     | 创建此快照时的 Unix UTC 时间戳。                                                               |
| `hash`                    | 该快照 [文件](https://github.com/decentraland/docs/blob/main/contributor/filesystem.md). |
| `numberOfEntities`        | 快照文件中的条目数量。                                                                         |
| `replacedSnapshotHashes`  | 一个包含 `hash` 被此快照替换的任何快照哈希值的数组。                                                      |
| `timeRange.initTimestamp` | 快照范围开始时的 Unix UTC 时间戳（毫秒）。                                                          |
| `timerange.endTimestamp`  | 快照范围结束时的 Unix UTC 时间戳（毫秒）。                                                          |

例如：

```json
{
  "generationTimestamp": 1684979298844,
  "hash": "bafybeiflmm46nr4vv2h3wuzbx3pukcz7ju4fhbfzt6yxmoo533uktlgru4",
  "numberOfEntities": 12345,
  "replacedSnapshotHashes": [ "bafybeicw6x75ieaxfwynekbyhpcsgctpjkt6cb4j6oa7s57qjj6e4b5phd" ],
  "timeRange": {
     "initTimestamp": 1684281600000,
     "endTimestamp": 1684886400000
  }
}
```

### 下载快照 <a href="#download" id="download"></a>

使用快照的 `hash` 字段，客户端可以下载在该时间范围内创建或更新的相关包含实体。

快照文件以这一行精确开头：

```
### Decentraland JSON 快照
```

之后，每一行都是一个描述某个 [实体](https://github.com/decentraland/docs/blob/main/contributor/entities.md) 的 JSON 文档，包含以下字段：

| 字段                | 值                                                                                                         |
| ----------------- | --------------------------------------------------------------------------------------------------------- |
| `entityId`        | 此 [实体](https://github.com/decentraland/docs/blob/main/contributor/entities.md).                           |
| `entityType`      | 以下之一： `场景`, `个人资料`, `可穿戴物`, `表情动作`, `商店` 或 `套装`.                                                          |
| `指针`              | 一个包含 [指针](https://github.com/decentraland/docs/blob/main/contributor/pointers.md) 的数组，这些指针解析到（或曾经解析到）该实体。 |
| `entityTimestamp` | 此实体上传时的 Unix UTC 时间戳（毫秒）。                                                                                 |
| `authChain`       | 该 [认证链](https://github.com/decentraland/docs/blob/main/contributor/entities.md#ownership) 用于此实体。          |

典型条目如下：

```json
{
  "entityId": "bafkreigrvaqynmiglpvewwhn2yd63q5dvagrrt5jbhimzvbrn5kimj5zne",
  "entityType": "wearable",
  "pointers": ["urn:decentraland:matic:collections-v2:0x11a6879861f36cbad632a4e7226816a16139fb33:0"],
  "entityTimestamp": 1671117456129,
  "authChain": [
    // ... 认证链载荷和签名
  ]
}
```

{% hint style="info" %}
如果你打算逐行解析快照，请记得跳过（或者更好地说，验证）带有表头的第一行，并准备好处理文件末尾的空行。
{% endhint %}

#### 开始建立实体索引 <a href="#index-start" id="index-start"></a>

希望对整个活跃实体集合进行索引的客户端，应处理当前所有可用的快照，并保留最新的 [实体](https://github.com/decentraland/docs/blob/main/contributor/entities.md) 针对每个 [指针](https://github.com/decentraland/docs/blob/main/contributor/pointers.md).

最简单的策略是按时间倒序处理快照（即最新的先处理），忽略已经发现的指针，以便保留对最新实体的引用。

伪代码如下：

```py
# 下载当前的快照集合，并按从新到旧排序：
snapshots = get_snapshots()
snapshots.sort('timeRange.initTimestamp', DESCENDING)

seen_pointers = set()

# 处理快照，为每个指针保留最新的实体：
for snapshot in snapshots:
    items = get_snapshot_items(snapshot) 

    for item in items:
        if any(pointer in seen_pointers for pointer in item.pointers):
            discard(item)
        else:
            keep(item)
            seen_pointers.update(item.pointers)
```

由于单个实体可以被多个指针引用（这在 [场景](/contributor/contributor-zh/nei-rong/shi-ti-lei-xing/scenes.md)中很常见），因此在决定保留还是丢弃该条目之前，必须检查所有指针。

{% hint style="info" %}
较长时间范围的快照文件可能非常大。对于不需要对整个实体集进行索引的开发和实验，建议使用较小的快照。生成的实体集合将是不完整的，但仍然有效。
{% endhint %}

#### 更新实体索引 <a href="#index-update" id="index-update"></a>

维护最新实体索引的客户端可以定期调用 [`快照`](https://decentraland.github.io/catalyst-api-specs/#tag/Content-Server/operation/getSnapshots) 端点，并通过考虑以下因素来决定是否下载每个文件：

* 由 `hash` 标识的快照是否
* 已经 `hash` 在 `replacedSnapshotHashes` 另一个已下载快照的列表中？
* 该 `timeRange` 是否与当前目的相关？

如果需要处理任何新快照，可以使用与上面相同的策略来更新现有数据集。

### 示例

在 [练习](https://github.com/decentraland/docs/blob/main/contributor/practice.md) 部分，你会找到与快照系统配合使用的代码示例。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/contributor/contributor-zh/nei-rong/snapshots.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
