# Update (Update Packages)

This section documents update package fields, purposes, value rules, and execution behavior for `update.dc`.

For `dc` format conventions, please read:
- [Getting Started](../Getting_Started)
For auto generate update package workflow usage, please read:
- [Auto Generate Update Pack Guide](./Update_Pack) (only support Version `3.6.4` and above of DLC Manager)

## Directory & Package Layout
- Directory: `DLC/update/`
- Update packages are `.zip`.
- Manifest file: `update.dc` (recommended at ZIP root; can be in subdirectories).
- The directory containing `update.dc` is the update content root.
- Temporary staging directory: `DLC/tmp/_staging/`.
- Backup/rollback metadata: `DLC/tmp/<dlc_new>/meta.dc`.
- Runtime version file: `DLC/info/version.dc`.

## Complete Example
```dc
isHidden = false

[version]
platform = "universal"   # client / server / universal
base = "1.0.0"
base_new = "1.0.1"       # optional
dlc = "1.0.0"            # old key dlc_old is still readable
dlc_new = "1.0.2"        # optional

[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"
```

## Field Reference

#### `isHidden`
- **Purpose**: Hide this update package in manager list.
- **Allowed**: Boolean.

#### `UpdateDLCM`
- **Purpose**: Update DLC Manager.
- **Allowed**: Boolean or version string.
- **Default**: Omitted means `false`.

#### `[version]`
- `platform`: `client` / `server` / `universal` (default `universal`)
- `base`: source base-pack version (required)
- `base_new`: target base-pack version (optional)
- `dlc`: source DLC version (required for matching)
- `dlc_new`: target DLC version (optional)

> `base` and `dlc` are required. At least one of `base_new` or `dlc_new` must be set, otherwise the package is invalid.

#### `[changelog]`
- **Purpose**: Update notes.
- **Allowed**:
  - Localized table (`en_us`, `zh_cn`, ...)
  - Single string

#### `[file].del`
- **Purpose**: Delete files/directories.
- **Allowed**: string array.

#### `[file].add`
- **Purpose**: Add files/directories from package content root.
- **Shape**: `"<source>": { appliedTarget, override }`
- `appliedTarget`: target path (required)
- `override`: `true` / `false` / `all` / `none`
  - `true`: overwrite; for directories, replace every file inside the folder.
  - `false`: do not overwrite; for directories, skip files with the same name.
  - `all`: replace the entire folder.
  - `none`: skip when a folder with the same name already exists.

#### `[file].move`
- **Purpose**: Move/rename files.
- **Shape**: `"<from>" = "<to>"`

#### `[file].modify`
- **Purpose**: In-place text replacement.
- **Keys**:
  - `find`
  - `replace`
  - `which` (`all`, `last`, `-1`, index, index list)

#### `[update].remote`
- **Purpose**: Update existing remote entries by identifier.
- **Key**: entry identifier.
- **Value keys**:
  - `curseforge`
  - `modrinth`
  - `directUrl`
  - `basic.RedirectUrl`

#### `[update].info`
- **Purpose**: Update existing info entries by identifier.
- **Key**: entry identifier.
- **Value keys**:
  - `basic.RedirectUrl`
  - `DisplayName.en_us`
  - `tip.en_us`
  - Other direct info field paths

#### `[update].required`
- **Purpose**: Update existing required entries by identifier.
- **Key**: entry identifier.
- **Value keys**:
  - `curseforge`
  - `modrinth`
  - `directUrl`
  - `basic.RedirectUrl`

## Execution Rules
- Execution order:
  1. `[file].del`
  2. `[file].move`
  3. `[file].add`
  4. `[file].modify`
  5. `[update].remote` and `[update].required`
  6. `[update].info`
- Version matching is based on current `DLC/info/version.dc`.
- If update content contains `remote/` or `required/` and they are not explicitly mapped in `[file].add`, they are copied implicitly.
- Adding required resources clears `DLC/required/SKIP`.

## Pack Release Update (Repository Mode)
Repository mode is configured by `[ui].updateGithubRepo` / `[server].updateGithubRepo`. It checks Release metadata and maps Release assets to update package downloads.

### Repository input and fallback
- Multiple repositories are supported via comma-separated URLs.
- Repositories are checked in left-to-right order until a valid update chain is found.
- Supported providers:
  - GitHub
  - GitCode
  - GitLab (including self-hosted instances)
  - Gitee
  - Generic Git hosts with API fallback probing

### Release tag format
- Required format: `<oldBase><sep><oldDlc>/<newBase><sep><newDlc>`
- Example: `1.0.0+1.0.0/1.0.1+1.0.1`
- Supported `<sep>` between base and dlc:
  - `+`, `_`, `@`, `~`, `-`, space

### Asset filename matching
- Client side candidates:
  - `Universal_<newBase><sep><newDlc>.zip`
  - `Client_<newBase><sep><newDlc>.zip`
- Server side candidates:
  - `Universal_<newBase><sep><newDlc>.zip`
  - `Server_<newBase><sep><newDlc>.zip`
- `<sep>` supports the same delimiter set as tag parsing.
- If both `Universal_*` and side-specific assets exist, `Universal_*` is preferred.

### Multi-step chain updates
- The checker builds a state chain from current version pair:
  - `<currentBase>|<currentDlc>` -> next -> next ...
- If multiple releases are available, updates are applied in chain order (old to new), not in one jump.

### Release changelog source
- `Release Notes` (not language-key tables).
