# Update（热更新包）

本节说明 `update.dc` 的字段、用途、取值规则与执行行为。

`dc` 格式请先阅读：
- [开始使用](../Getting_Started)
自动生成热更新包工作流请阅读：
- [自动生成热更新包教程](./Update_Pack) （仅支持DLC管理器`3.6.4`及以上版本）

## 目录与包结构
- 目录：`DLC/update/`
- 更新包格式：`.zip`
- 清单文件：`update.dc`（建议放在 ZIP 根目录，也支持子目录）
- `update.dc` 所在目录即更新内容根目录
- 临时目录：`DLC/tmp/_staging/`
- 备份/回滚元数据：`DLC/tmp/<dlc_new>/meta.dc`
- 运行时版本文件：`DLC/info/version.dc`

## 完整示例
```dc
isHidden = false

[version]
platform = "universal"   # client / server / universal
base = "1.0.0"
base_new = "1.0.1"       # 可选
dlc = "1.0.0"            # 旧键 dlc_old 仍可读取
dlc_new = "1.0.2"        # 可选

[changelog]
en_us = """Update notes line 1
line 2"""
zh_cn = """更新说明第1行
第2行"""

[file]
  [del]
    "mods/old-mod.jar"
    "config/old.toml"

  [add]
    "mods/new-mod.jar":
      appliedTarget = "mods/new-mod.jar"
      override = true

    "config/":
      appliedTarget = "config/"
      override = "all"

  [move]
  "config/a.toml" = "config/legacy/a.toml"

  [modify]
    "config/example.toml":
      find = "old_value"
      replace = "new_value"
      which = "all"

[update]
  [info]
    "mod0":
      basic.RedirectUrl = "https://example.com/new-page"
      DisplayName.en_us = "New Name"

  [remote]
    "mod1":
      curseforge = "1234567"
      modrinth = "AbCdEf12"
      directUrl = ["https://example.com/mod1.jar"]
      basic.RedirectUrl = "https://example.com/project-page"

  [required]
    "mod2":
      curseforge = "7654321"
      modrinth = "ZyXwVu98"
      directUrl = ["https://example.com/mod2.zip"]
      basic.RedirectUrl = "https://example.com/required-resource-guide"
```

## 字段说明

#### `isHidden`
- **用途**：在更新管理器中隐藏该更新包。
- **可填**：布尔。

#### `UpdateDLCM`
- **用途**：更新 DLC 管理器。
- **可填**：布尔或版本号字符串。
- **默认**：不填写时为 `false`

#### `[version]`
- `platform`：`client` / `server` / `universal`（默认 `universal`）
- `base`：原底包版本（必填）
- `base_new`：新底包版本（可选）
- `dlc`：原 DLC 版本（用于匹配）
- `dlc_new`：新 DLC 版本（可选）

> `base` 和 `dlc` 必填。`base_new` 与 `dlc_new` 至少需要填写一项，否则该更新包无效。

#### `[changelog]`
- **用途**：更新日志。
- **可填**：
  - 多语言表（`en_us`、`zh_cn` 等）
  - 单字符串

#### `[file].del`
- **用途**：删除文件/目录。
- **可填**：字符串数组。

#### `[file].add`
- **用途**：从更新包内容根目录添加文件/目录。
- **结构**：`"<source>": { appliedTarget, override }`
- `appliedTarget`：目标路径（必填）
- `override`：`true` / `false` / `all` / `none`
  - `true`：覆盖；若为文件夹，则替换文件夹内的每一个文件。
  - `false`：不覆盖；若为文件夹，则跳过同名文件。
  - `all`：替换整个文件夹。
  - `none`：存在同名文件夹时跳过。

#### `[file].move`
- **用途**：移动/重命名文件。
- **结构**：`"<from>" = "<to>"`

#### `[file].modify`
- **用途**：文本内替换。
- **键**：
  - `find`
  - `replace`
  - `which`（`all`、`last`、`-1`、索引、索引数组）

#### `[update].remote`
- **用途**：按 identifier 更新 remote 配置中的平台 ID。
- **键**：条目 identifier。
- **值键**：
  - `curseforge`
  - `modrinth`
  - `directUrl`
  - `basic.RedirectUrl`

#### `[update].info`
- **用途**：按 identifier 更新已有 info 条目。
- **键**：条目 identifier。
- **值键**：
  - `basic.RedirectUrl`
  - `DisplayName.en_us`
  - `tip.en_us`
  - 其他直接 info 字段路径

#### `[update].required`
- **用途**：按 identifier 更新 required 配置中的平台 ID。
- **键**：条目 identifier。
- **值键**：
  - `curseforge`
  - `modrinth`
  - `directUrl`
  - `basic.RedirectUrl`

## 执行规则
- 执行顺序：
  1. `[file].del`
  2. `[file].move`
  3. `[file].add`
  4. `[file].modify`
  5. `[update].remote` 和 `[update].required`
  6. `[update].info`
- 版本匹配基于 `DLC/info/version.dc`。
- 若更新包包含 `remote/` 或 `required/`，且未在 `[file].add` 显式映射，会按默认规则隐式复制。
- 添加 required 资源时会清理 `DLC/required/SKIP`。

## 仓库 Release 更新模式
仓库模式由 `[ui].updateGithubRepo` / `[server].updateGithubRepo` 配置驱动，通过 Release 元数据匹配热更新包并下载。

### 仓库输入与回退
- 支持逗号分隔多个仓库 URL。
- 按从左到右顺序依次检测，直到找到可用更新链。
- 支持平台：
  - GitHub
  - GitLab（含自建实例）
  - Gitee （国内最佳平台）
  - 其他带 API 回退探测的通用 Git 平台

### Release Tag 规则
- 必须满足：`<oldBase><sep><oldDlc>/<newBase><sep><newDlc>`
- 示例：`1.0.0+1.0.0/1.0.1+1.0.1`
- `base` 与 `dlc` 之间支持分隔符：
  - `+`、`_`、`@`、`~`、`-`、空格

### 资产文件名匹配
- 客户端候选：
  - `Universal_<newBase><sep><newDlc>.zip`
  - `Client_<newBase><sep><newDlc>.zip`
- 服务端候选：
  - `Universal_<newBase><sep><newDlc>.zip`
  - `Server_<newBase><sep><newDlc>.zip`
- `<sep>` 与 Tag 解析使用同一组分隔符。
- 若同时存在 `Universal_*` 与端侧包，优先选择 `Universal_*`。

### 多步链式更新
- 检测器会从当前版本对开始构建链：
  - `<currentBase>|<currentDlc>` -> 下一步 -> 下一步 ...
- 当存在多段可升级路径时，会按链顺序依次更新，而不是跨版本直接跳转。

### 更新日志来源
- `Release Notes` （没有语言区分）
