Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 91e12e4ba1 | |||
| 921a5a3156 | |||
| 2ab32b258c | |||
| 175c1dbaed | |||
| e9bfbfe74f | |||
| 6782cfcd87 | |||
| eaf84ad605 | |||
| 65e3f5b48e | |||
| 9519b92771 | |||
| 6257027a13 | |||
| cde9194ed5 | |||
| 1c8cf13f67 | |||
| 74a8942999 | |||
| 7f8f09a3ac | |||
| 70f93c3d29 | |||
| 4aa2e136b2 | |||
| 3ae30a5263 | |||
| 4da26911fe | |||
| df1daee6ab | |||
| 9d1a26c8e0 | |||
| 8a4970742c | |||
| b50a6a2f95 | |||
| 4646b51459 | |||
| a72b7bc1e1 | |||
| 7aca648396 | |||
| 36129b15d1 | |||
| 97ca95ba16 | |||
| ad129e15d5 | |||
| c8371a3fec | |||
| 321fef2f63 | |||
| eb9ba5eefa | |||
| c0524832d0 | |||
| e78610c702 | |||
| 5c0a44a71e | |||
| c859ddc50c | |||
| 5f3ca9ae0d |
88
ACTIONS.md
Normal file
88
ACTIONS.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# ACTIONS.md
|
||||||
|
|
||||||
|
VERSION: 2
|
||||||
|
MODE: machine-first
|
||||||
|
LANG: ru
|
||||||
|
|
||||||
|
ROUTING:
|
||||||
|
- match_user_request_to_action_id: true
|
||||||
|
- if_match: propose_action
|
||||||
|
- if_no_match: ignore_actions_md
|
||||||
|
- if_no_match_user_message: none
|
||||||
|
|
||||||
|
PROPOSE_RULE:
|
||||||
|
- prompt_template: "Приступить к выполнению '{action_id}'?"
|
||||||
|
- require_user_confirmation: true
|
||||||
|
- execute_without_confirmation: false
|
||||||
|
|
||||||
|
EXECUTION_BASELINE:
|
||||||
|
- enforce_agents_md: true
|
||||||
|
- minimal_non_breaking_changes: true
|
||||||
|
- steps_count_range: [3, 7]
|
||||||
|
- before_commit_push: request_user_approval
|
||||||
|
|
||||||
|
REPORT_FORMAT:
|
||||||
|
- done
|
||||||
|
- changed_files
|
||||||
|
- checks
|
||||||
|
- remaining
|
||||||
|
|
||||||
|
ACTIONS:
|
||||||
|
translation:update:
|
||||||
|
intent: sync_ru_translation_with_upstream
|
||||||
|
inputs:
|
||||||
|
- Mods/DnD 5.5e AIO Russian/Localization/Russian/russian.xml
|
||||||
|
- glossary/glossary.normalized.json
|
||||||
|
- AGENTS.md::Canonical Paths::Upstream English reference
|
||||||
|
plan:
|
||||||
|
- compare_en_vs_ru_by_keys
|
||||||
|
- classify_diff_into_new_changed_stale_candidate
|
||||||
|
- update_ru_for_new_and_changed_using_glossary
|
||||||
|
- validate_xml_structure_and_service_attributes
|
||||||
|
- prepare_delta_summary_counts
|
||||||
|
checks:
|
||||||
|
- xml_valid
|
||||||
|
- glossary_consistency
|
||||||
|
- scope_limited_to_localization_and_allowed_metadata
|
||||||
|
outputs:
|
||||||
|
- Mods/DnD 5.5e AIO Russian/Localization/Russian/russian.xml
|
||||||
|
- optional: Mods/DnD 5.5e AIO Russian/meta.lsx (release-only)
|
||||||
|
after_success:
|
||||||
|
- suggest_action: meta:sync-parent
|
||||||
|
reason: "Обновить версию зависимости из родительского мода (актуальный Version64 и связанные поля зависимости)."
|
||||||
|
|
||||||
|
action:report:
|
||||||
|
intent: unified_task_report
|
||||||
|
inputs:
|
||||||
|
- task_context
|
||||||
|
- modified_files
|
||||||
|
- verification_results
|
||||||
|
plan:
|
||||||
|
- summarize_done
|
||||||
|
- list_changed_files
|
||||||
|
- list_checks
|
||||||
|
- list_remaining
|
||||||
|
checks:
|
||||||
|
- concise
|
||||||
|
- factual
|
||||||
|
- no_unverified_claims
|
||||||
|
outputs:
|
||||||
|
- final_user_report
|
||||||
|
meta:sync-parent:
|
||||||
|
intent: sync_dependency_moduleshortdesc_from_parent_meta
|
||||||
|
inputs:
|
||||||
|
- parent_meta_git_url (optional; defaults to upstream)
|
||||||
|
- Mods/DnD 5.5e AIO Russian/meta.lsx
|
||||||
|
plan:
|
||||||
|
- read_parent_moduleinfo_fields
|
||||||
|
- validate_required_fields_folder_md5_name_publishhandle_uuid_version64
|
||||||
|
- update_target_dependencies_moduleshortdesc_fields
|
||||||
|
- validate_xml_structure
|
||||||
|
- report_changed_fields
|
||||||
|
checks:
|
||||||
|
- xml_valid
|
||||||
|
- required_parent_fields_present
|
||||||
|
- only_dependencies_moduleshortdesc_changed
|
||||||
|
outputs:
|
||||||
|
- Mods/DnD 5.5e AIO Russian/meta.lsx
|
||||||
|
|
||||||
206
AGENTS.md
206
AGENTS.md
@@ -1,153 +1,87 @@
|
|||||||
# AGENTS.md
|
# AGENTS.md
|
||||||
|
|
||||||
## Project Overview
|
## General Rules (MUST)
|
||||||
|
|
||||||
This repository contains a standalone Russian localization mod for **Baldur's Gate 3**:
|
### Git Collaboration Policy (General)
|
||||||
|
- Commit/push only after explicit user approval.
|
||||||
|
- After approval: commit and push immediately.
|
||||||
|
- Branch switch prompt (`fix/*` or `feat/*`): ask once at dialogue start; reuse the explicit user decision for all subsequent fix/feature tasks in the same dialogue.
|
||||||
|
- After finishing work in `fix/*` or `feat/*`: propose either
|
||||||
|
1. creating an MR into `main`, or
|
||||||
|
2. merging to `main` immediately and deleting the `fix/*`/`feat/*` branch.
|
||||||
|
- If push fails: retry up to 2 more times with 3s pause.
|
||||||
|
- Approval prompts for pending actions: short direct phrasing, no soft/opening phrases; response format is mandatory:
|
||||||
|
- binary action: yes/no question.
|
||||||
|
- multiple actions/combinations: numbered options only.
|
||||||
|
|
||||||
- Mod name: `DnD 5.5e All-in-One BEYOND Russian Localization`
|
### Cleanup (General)
|
||||||
- Mod folder: `Mods/DnD 5.5e AIO Russian`
|
- Do not leave temporary/debug artifacts in repo.
|
||||||
- Base/original mod dependency: `DnD 5.5e All-in-One BEYOND`
|
- Remove additional debug/temp dirs unless user asked to keep them.
|
||||||
- Original mod repository: `https://github.com/Yoonmoonsik/dnd55e`
|
|
||||||
- Original dependency UUID: `897914ef-5c96-053c-44af-0be823f895fe`
|
|
||||||
|
|
||||||
This repository is for the localization mod only. It must not gain gameplay logic, Script Extender files, or unrelated assets.
|
### Rules Maintenance (General)
|
||||||
|
- For changes to rules files (`AGENTS.md`, `ACTIONS.md`): prefer optimized, compressed edits for AI-agent execution (machine-readable, unambiguous).
|
||||||
|
- Keep rule updates minimal and non-duplicative: merge overlapping points, remove redundancy, preserve intent.
|
||||||
|
|
||||||
## Repository Rules
|
## Project-Specific Rules (MUST)
|
||||||
|
|
||||||
- Keep the repository source-only.
|
### Scope
|
||||||
- Do not commit `.pak` artifacts.
|
- Repository purpose: standalone Russian localization mod only.
|
||||||
- Do not commit temporary build outputs.
|
- Allowed domain: localization content + packaging/release metadata.
|
||||||
- Do not add gameplay or script content unrelated to localization/release packaging.
|
- Forbidden: gameplay logic, Script Extender content, unrelated assets.
|
||||||
- Keep the localization folder and metadata consistent with the packaged mod.
|
- Keep repository source-only.
|
||||||
|
- Never commit `.pak` or temporary build artifacts.
|
||||||
## Current Important Paths
|
|
||||||
|
|
||||||
|
### Canonical Paths
|
||||||
- Mod sources: `Mods/DnD 5.5e AIO Russian`
|
- Mod sources: `Mods/DnD 5.5e AIO Russian`
|
||||||
- Localization XML: `Mods/DnD 5.5e AIO Russian/Localization/Russian/russian.xml`
|
- Russian localization: `Mods/DnD 5.5e AIO Russian/Localization/Russian/russian.xml`
|
||||||
- Glossary: `glossary/glossary.normalized.json`
|
|
||||||
- Mod metadata: `Mods/DnD 5.5e AIO Russian/meta.lsx`
|
- Mod metadata: `Mods/DnD 5.5e AIO Russian/meta.lsx`
|
||||||
|
- Build script (single source of build truth): `scripts/build.ps1`
|
||||||
- CI workflow: `.gitea/workflows/build.yml`
|
- CI workflow: `.gitea/workflows/build.yml`
|
||||||
- Main build script: `scripts/build.ps1`
|
- Glossary (primary terminology reference): `glossary/glossary.normalized.json`
|
||||||
|
- Action catalog and command playbooks: `ACTIONS.md`
|
||||||
|
- Upstream English reference: `https://github.com/Yoonmoonsik/dnd55e/blob/main/Mods/DnD2024_897914ef-5c96-053c-44af-0be823f895fe/Localization/English/english.xml`
|
||||||
|
|
||||||
## Build And Release Model
|
### Packaging Invariants
|
||||||
|
- `.pak` must contain only BG3 mod structure under `Mods/...`.
|
||||||
|
- Required content in `.pak`:
|
||||||
|
- `Mods/DnD 5.5e AIO Russian/meta.lsx`
|
||||||
|
- `Mods/DnD 5.5e AIO Russian/Localization/Russian/russian.xml`
|
||||||
|
- Must not leak into `.pak`: `.git`, `.gitea`, `scripts`, `tools`, `.tools`, `build`, staging dirs.
|
||||||
|
- Staging for packaging must be in `%TEMP%`, not in dot-prefixed repo dirs.
|
||||||
|
|
||||||
The authoritative build logic lives in:
|
### Build/CI Contract
|
||||||
|
- CI workflow stays thin:
|
||||||
|
1. prepare workspace
|
||||||
|
2. download Divine
|
||||||
|
3. call `scripts/build.ps1`
|
||||||
|
4. publish tag archive
|
||||||
|
- Expected build outputs:
|
||||||
|
- `build/DnD 5.5e AIO Russian.pak`
|
||||||
|
- `build/info.json`
|
||||||
|
- `build/DnD 5.5e AIO Russian <tag>.zip` (for tag builds)
|
||||||
|
- Release ZIP must include only `.pak` + `info.json`.
|
||||||
|
- CI triggers: tag `v*` and manual dispatch; not every push to `main`.
|
||||||
|
|
||||||
- `scripts/build.ps1`
|
### Version/Release Rules
|
||||||
|
- Read release version only from `save/region/node[@id="ModuleSettings"]/children/node[@id="ModuleInfo"]/attribute[@id="Version64"]` via explicit XML parsing.
|
||||||
|
- `PublishVersion` must not be changed during release preparation.
|
||||||
|
- Release tag must match the source-of-truth version.
|
||||||
|
- Decision logic before tagging:
|
||||||
|
1. If `ModuleInfo/Version64` was manually changed (e.g. BG3 Toolkit), use matching tag and release.
|
||||||
|
2. If `ModuleInfo/Version64` equals latest released version, bump version first (e.g. `scripts/set-version.ps1 -VersionTag <tag>`), commit, then create/push tag.
|
||||||
|
- `scripts/build.ps1` derives release `Version64` from tag and writes it to generated `info.json` and staged `meta.lsx`.
|
||||||
|
|
||||||
The Gitea workflow should stay thin and only:
|
### info.json Contract
|
||||||
|
- Top-level keys: `Mods`, `MD5`.
|
||||||
|
- Per-mod keys: `Author`, `Name`, `Folder`, `Version`, `Description`, `UUID`, `Created`, `Dependencies`, `Group`.
|
||||||
|
- `Dependencies` is an array of UUIDs.
|
||||||
|
- Current dependency UUID: `897914ef-5c96-053c-44af-0be823f895fe`.
|
||||||
|
|
||||||
1. prepare the workspace
|
### Git Collaboration Policy (Project-Specific)
|
||||||
2. download `Divine`
|
- Commit messages and comments: Russian.
|
||||||
3. call `scripts/build.ps1`
|
- Commit message content: what was done (not what should be done).
|
||||||
4. publish the release zip for tag builds
|
- If changes affect `.pak` contents or build/release flow: propose releasing next version.
|
||||||
|
- For released versions in user-facing messages: provide direct archive link in Markdown format `[version](url)` when derivable (acceptable immediately after tag push, even before CI finishes).
|
||||||
|
|
||||||
### Current Build Outputs
|
### Cleanup (Project-Specific)
|
||||||
|
- Ignored/temp patterns include: `build/`, `build-stage*`, `.tools/`, `*.pak`.
|
||||||
The build script produces:
|
|
||||||
|
|
||||||
- `build/DnD 5.5e AIO Russian.pak`
|
|
||||||
- `build/info.json`
|
|
||||||
- `build/DnD 5.5e AIO Russian <tag>.zip` for tagged builds
|
|
||||||
|
|
||||||
The release zip is expected to contain:
|
|
||||||
|
|
||||||
- the built `.pak`
|
|
||||||
- `info.json`
|
|
||||||
|
|
||||||
## Packaging Notes
|
|
||||||
|
|
||||||
The package must contain only the BG3 mod structure under `Mods/...`.
|
|
||||||
|
|
||||||
Verified expected extracted `.pak` structure:
|
|
||||||
|
|
||||||
- `Mods/DnD 5.5e AIO Russian/meta.lsx`
|
|
||||||
- `Mods/DnD 5.5e AIO Russian/Localization/Russian/russian.xml`
|
|
||||||
|
|
||||||
Do not allow `.git`, `.gitea`, `scripts`, `tools`, `.tools`, `build`, or staging directories into the `.pak`.
|
|
||||||
|
|
||||||
## Important Packaging Behavior
|
|
||||||
|
|
||||||
There is a runner-specific packaging quirk:
|
|
||||||
|
|
||||||
- `Divine` can produce a broken 48-byte `.pak` on the CI runner depending on the source path.
|
|
||||||
- Current mitigation is implemented in `scripts/build.ps1`.
|
|
||||||
- The script uses staged sources and fallback packaging attempts.
|
|
||||||
- Staging is performed in `%TEMP%`, not in a dot-prefixed directory inside the repo.
|
|
||||||
|
|
||||||
If packaging breaks again, debug the source path and unpack the resulting `.pak` locally to verify actual contents.
|
|
||||||
|
|
||||||
## Versioning
|
|
||||||
|
|
||||||
Version displayed by BG3ModManager should be derived from the release tag.
|
|
||||||
|
|
||||||
Current behavior:
|
|
||||||
|
|
||||||
- `scripts/build.ps1` derives `Version64` from tags like `v0.1.0`
|
|
||||||
- the computed version is written into:
|
|
||||||
- generated `info.json`
|
|
||||||
- staged `meta.lsx` before packaging
|
|
||||||
|
|
||||||
Do not manually hardcode release versions in the committed `meta.lsx` for each release if CI can derive them from tags.
|
|
||||||
|
|
||||||
## info.json Expectations
|
|
||||||
|
|
||||||
`info.json` is generated during build and should remain aligned with BG3/BG3ModManager expectations.
|
|
||||||
|
|
||||||
Current expected shape:
|
|
||||||
|
|
||||||
- top-level `Mods`
|
|
||||||
- top-level `MD5`
|
|
||||||
- per-mod fields:
|
|
||||||
- `Author`
|
|
||||||
- `Name`
|
|
||||||
- `Folder`
|
|
||||||
- `Version`
|
|
||||||
- `Description`
|
|
||||||
- `UUID`
|
|
||||||
- `Created`
|
|
||||||
- `Dependencies`
|
|
||||||
- `Group`
|
|
||||||
|
|
||||||
Current dependency model:
|
|
||||||
|
|
||||||
- `Dependencies` is an array of dependency UUIDs
|
|
||||||
- current dependency UUID:
|
|
||||||
- `897914ef-5c96-053c-44af-0be823f895fe`
|
|
||||||
|
|
||||||
## CI Trigger Policy
|
|
||||||
|
|
||||||
Current workflow policy:
|
|
||||||
|
|
||||||
- run on tags `v*`
|
|
||||||
- run on manual dispatch
|
|
||||||
- do not run on every push to `main`
|
|
||||||
|
|
||||||
## Git / Collaboration Preferences
|
|
||||||
|
|
||||||
User preference:
|
|
||||||
|
|
||||||
- after making changes, ask for permission before committing
|
|
||||||
- if the user approves, commit and push immediately
|
|
||||||
- for significant changes, propose moving work into a separate branch
|
|
||||||
- feature/fix branches must use the prefix `feat/` or `fix/`
|
|
||||||
- after finishing work in a `feat/` or `fix/` branch, propose merging it back into `main`
|
|
||||||
- comments and commit messages should be written in Russian
|
|
||||||
- commit messages should describe what was done, not what should be done
|
|
||||||
- if changes affect files that go into the final `.pak`, or change the build/release process, propose releasing the next version
|
|
||||||
- if push fails, retry up to two more times with a 3-second pause between attempts
|
|
||||||
|
|
||||||
Do not auto-commit or auto-push without explicit user approval.
|
|
||||||
|
|
||||||
## Cleanup Expectations
|
|
||||||
|
|
||||||
Temporary directories and debug artifacts should not remain in the repository.
|
|
||||||
|
|
||||||
Ignored paths currently include:
|
|
||||||
|
|
||||||
- `build/`
|
|
||||||
- `build-stage*`
|
|
||||||
- `.tools/`
|
|
||||||
- `*.pak`
|
|
||||||
|
|
||||||
If local debugging creates additional temporary folders, remove them when done unless the user explicitly wants to keep them.
|
|
||||||
|
|||||||
BIN
Mods/DnD 5.5e AIO Russian/GUI/metadata.lsf
Normal file
BIN
Mods/DnD 5.5e AIO Russian/GUI/metadata.lsf
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,44 +1,77 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<save>
|
<save>
|
||||||
<version major="4" minor="8" revision="0" build="500"/>
|
<version major="4" minor="8" revision="0" build="500"/>
|
||||||
<region id="Config">
|
<region id="Config">
|
||||||
<node id="root">
|
<node id="root">
|
||||||
<children>
|
<children>
|
||||||
<node id="Dependencies">
|
<node id="Conflicts"/>
|
||||||
<children>
|
<node id="Dependencies">
|
||||||
<node id="ModuleShortDesc">
|
<children>
|
||||||
<attribute id="Folder" type="LSString" value=""/>
|
<node id="ModuleShortDesc">
|
||||||
<attribute id="MD5" type="LSString" value=""/>
|
<attribute id="Folder" type="LSString" value="DnD2024_897914ef-5c96-053c-44af-0be823f895fe"/>
|
||||||
<attribute id="Name" type="LSString" value="DnD 5.5e All-in-One BEYOND"/>
|
<attribute id="MD5" type="LSString" value="ac497558b070a635abecd7d23d4a3125"/>
|
||||||
<attribute id="PublishHandle" type="uint64" value="0"/>
|
<attribute id="Name" type="LSString" value="DnD 5.5e All-in-One BEYOND"/>
|
||||||
<attribute id="UUID" type="guid" value="897914ef-5c96-053c-44af-0be823f895fe"/>
|
<attribute id="PublishHandle" type="uint64" value="4419649"/>
|
||||||
<attribute id="Version64" type="int64" value="36028797018963968"/>
|
<attribute id="UUID" type="guid" value="897914ef-5c96-053c-44af-0be823f895fe"/>
|
||||||
</node>
|
<attribute id="Version64" type="int64" value="144396678084952064"/>
|
||||||
</children>
|
</node>
|
||||||
|
</children>
|
||||||
|
</node>
|
||||||
|
<node id="ModuleInfo">
|
||||||
|
<attribute id="Author" type="LSString" value="MikhailRaw"/>
|
||||||
|
<attribute id="CharacterCreationLevelName" type="FixedString" value=""/>
|
||||||
|
<attribute id="Description" type="LSString" value="Русский перевод мода DnD 5.5e All-in-One BEYOND. Перевод ещё в разработке: AI помогает быстро обновлять тексты, а финальные правки и качество мы проверяем вручную."/>
|
||||||
|
<attribute id="FileSize" type="uint64" value="2488095"/>
|
||||||
|
<attribute id="Folder" type="LSString" value="DnD 5.5e AIO Russian"/>
|
||||||
|
<attribute id="LobbyLevelName" type="FixedString" value=""/>
|
||||||
|
<attribute id="MD5" type="LSString" value="c0a8f3412870277331306e0719fc6f77"/>
|
||||||
|
<attribute id="MenuLevelName" type="FixedString" value=""/>
|
||||||
|
<attribute id="Name" type="LSString" value="DnD 5.5e All-in-One BEYOND Russian Localization"/>
|
||||||
|
<attribute id="NumPlayers" type="uint8" value="4"/>
|
||||||
|
<attribute id="PhotoBooth" type="FixedString" value=""/>
|
||||||
|
<attribute id="PublishHandle" type="uint64" value="5965149"/>
|
||||||
|
<attribute id="StartupLevelName" type="FixedString" value=""/>
|
||||||
|
<attribute id="UUID" type="FixedString" value="6401e84d-daf2-416d-adeb-99c03a2487a6"/>
|
||||||
|
<attribute id="Version64" type="int64" value="281481419161600"/>
|
||||||
|
<children>
|
||||||
|
<node id="PublishVersion">
|
||||||
|
<attribute id="Version64" type="int64" value="281477124194304"/>
|
||||||
|
</node>
|
||||||
|
<node id="Scripts">
|
||||||
|
<children>
|
||||||
|
<node id="Script">
|
||||||
|
<attribute id="UUID" type="FixedString" value="1953f77d-a201-45d7-a194-9b84c34b8461"/>
|
||||||
|
<children>
|
||||||
|
<node id="Parameters">
|
||||||
|
<children>
|
||||||
|
<node id="Parameter">
|
||||||
|
<attribute id="MapKey" type="FixedString" value="HardcoreOnly"/>
|
||||||
|
<attribute id="Type" type="int32" value="1"/>
|
||||||
|
<attribute id="Value" type="LSString" value="0"/>
|
||||||
|
</node>
|
||||||
|
</children>
|
||||||
|
</node>
|
||||||
|
</children>
|
||||||
|
</node>
|
||||||
|
<node id="Script">
|
||||||
|
<attribute id="UUID" type="FixedString" value="0d6510f5-50a3-4ecd-83d8-134c9a640324"/>
|
||||||
|
<children>
|
||||||
|
<node id="Parameters">
|
||||||
|
<children>
|
||||||
|
<node id="Parameter">
|
||||||
|
<attribute id="MapKey" type="FixedString" value="HardcoreOnly"/>
|
||||||
|
<attribute id="Type" type="int32" value="1"/>
|
||||||
|
<attribute id="Value" type="LSString" value="0"/>
|
||||||
|
</node>
|
||||||
|
</children>
|
||||||
|
</node>
|
||||||
|
</children>
|
||||||
|
</node>
|
||||||
|
</children>
|
||||||
|
</node>
|
||||||
|
</children>
|
||||||
|
</node>
|
||||||
|
</children>
|
||||||
</node>
|
</node>
|
||||||
<node id="ModuleInfo">
|
</region>
|
||||||
<attribute id="Author" type="LSString" value="MikhailRaw"/>
|
|
||||||
<attribute id="CharacterCreationLevelName" type="FixedString" value=""/>
|
|
||||||
<attribute id="Description" type="LSString" value="Русская локализация мода, который добавляет и обновляет контент в соответствии с правилами DnD 5.5e и другими источниками, включая предыстории, классы, таланты, расы, заклинания и многое другое. Это отдельный мод локализации и он требует установленный оригинальный мод."/>
|
|
||||||
<attribute id="FileSize" type="uint64" value="0"/>
|
|
||||||
<attribute id="Folder" type="LSString" value="DnD 5.5e AIO Russian"/>
|
|
||||||
<attribute id="LobbyLevelName" type="FixedString" value=""/>
|
|
||||||
<attribute id="MD5" type="LSString" value=""/>
|
|
||||||
<attribute id="MenuLevelName" type="FixedString" value=""/>
|
|
||||||
<attribute id="Name" type="LSString" value="DnD 5.5e All-in-One BEYOND Russian Localization"/>
|
|
||||||
<attribute id="NumPlayers" type="uint8" value="4"/>
|
|
||||||
<attribute id="PhotoBooth" type="FixedString" value=""/>
|
|
||||||
<attribute id="PublishHandle" type="uint64" value="0"/>
|
|
||||||
<attribute id="StartupLevelName" type="FixedString" value=""/>
|
|
||||||
<attribute id="UUID" type="FixedString" value="6401e84d-daf2-416d-adeb-99c03a2487a6"/>
|
|
||||||
<attribute id="Version64" type="int64" value="36028797018963968"/>
|
|
||||||
<children>
|
|
||||||
<node id="PublishVersion">
|
|
||||||
<attribute id="Version64" type="int64" value="36028797018963968"/>
|
|
||||||
</node>
|
|
||||||
</children>
|
|
||||||
</node>
|
|
||||||
</children>
|
|
||||||
</node>
|
|
||||||
</region>
|
|
||||||
</save>
|
</save>
|
||||||
|
|||||||
BIN
Mods/DnD 5.5e AIO Russian/mod_publish_logo.png
Normal file
BIN
Mods/DnD 5.5e AIO Russian/mod_publish_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 MiB |
@@ -556,6 +556,10 @@
|
|||||||
"Origin Feat: Alert": "Черта происхождения: Бдительный",
|
"Origin Feat: Alert": "Черта происхождения: Бдительный",
|
||||||
"Origin Feat: Magic Initiate (Cleric)": "Черта происхождения: Посвященный в магию (Жрец)",
|
"Origin Feat: Magic Initiate (Cleric)": "Черта происхождения: Посвященный в магию (Жрец)",
|
||||||
"Origin Feat: Magic Initiate (Wizard)": "Черта происхождения: Посвященный в магию (Волшебник)",
|
"Origin Feat: Magic Initiate (Wizard)": "Черта происхождения: Посвященный в магию (Волшебник)",
|
||||||
|
"Origin Feat: Magic Initiate (Druid)": "Черта происхождения: Посвященный в магию (Друид)",
|
||||||
|
"Origin Feat: Healer": "Черта происхождения: Лекарь",
|
||||||
|
"Origin Feat: Lucky": "Черта происхождения: Везунчик",
|
||||||
|
"Origin Feat: Tavern Brawler": "Черта происхождения: Драчун",
|
||||||
"Origin Feat: Musician": "Черта происхождения: Музыкант",
|
"Origin Feat: Musician": "Черта происхождения: Музыкант",
|
||||||
"Origin Feat: Savage Attacker": "Черта происхождения: Дикий атакующий",
|
"Origin Feat: Savage Attacker": "Черта происхождения: Дикий атакующий",
|
||||||
"Origin Feat: Skilled": "Черта происхождения: Одаренный",
|
"Origin Feat: Skilled": "Черта происхождения: Одаренный",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ param(
|
|||||||
[string]$ModName = "DnD 5.5e All-in-One BEYOND Russian Localization",
|
[string]$ModName = "DnD 5.5e All-in-One BEYOND Russian Localization",
|
||||||
[string]$ModUuid = "6401e84d-daf2-416d-adeb-99c03a2487a6",
|
[string]$ModUuid = "6401e84d-daf2-416d-adeb-99c03a2487a6",
|
||||||
[string]$ModAuthor = "MikhailRaw",
|
[string]$ModAuthor = "MikhailRaw",
|
||||||
[string]$ModDescription = "Russian Localization",
|
[string]$ModDescription = "Русская локализация мода, который добавляет и обновляет контент в соответствии с правилами DnD 5.5e и другими источниками, включая предыстории, классы, таланты, расы, заклинания и многое другое. Это отдельный мод локализации и он требует установленный оригинальный мод.",
|
||||||
[string]$ModVersion64 = "36028797018963968",
|
[string]$ModVersion64 = "36028797018963968",
|
||||||
[string]$ModGroup = "6401e84d-daf2-416d-adeb-99c03a2487a6",
|
[string]$ModGroup = "6401e84d-daf2-416d-adeb-99c03a2487a6",
|
||||||
[string]$DependencyUuid = "897914ef-5c96-053c-44af-0be823f895fe",
|
[string]$DependencyUuid = "897914ef-5c96-053c-44af-0be823f895fe",
|
||||||
@@ -103,7 +103,8 @@ if (-not (Test-Path -LiteralPath $stagedMetaPath)) {
|
|||||||
|
|
||||||
$stagedMetaContent = Get-Content -LiteralPath $stagedMetaPath -Raw
|
$stagedMetaContent = Get-Content -LiteralPath $stagedMetaPath -Raw
|
||||||
$stagedMetaContent = $stagedMetaContent -replace '(<attribute id="Version64" type="int64" value=")\d+("/>)', "`${1}$resolvedVersion64`${2}"
|
$stagedMetaContent = $stagedMetaContent -replace '(<attribute id="Version64" type="int64" value=")\d+("/>)', "`${1}$resolvedVersion64`${2}"
|
||||||
Set-Content -LiteralPath $stagedMetaPath -Value $stagedMetaContent -Encoding utf8
|
$utf8Bom = New-Object System.Text.UTF8Encoding($true)
|
||||||
|
[System.IO.File]::WriteAllText($stagedMetaPath, $stagedMetaContent, $utf8Bom)
|
||||||
|
|
||||||
Write-Host "[build.ps1] Staged source tree:"
|
Write-Host "[build.ps1] Staged source tree:"
|
||||||
Get-ChildItem -Recurse $stagingPath | Select-Object FullName, Length | Format-Table -AutoSize
|
Get-ChildItem -Recurse $stagingPath | Select-Object FullName, Length | Format-Table -AutoSize
|
||||||
@@ -112,6 +113,8 @@ if (Test-Path -LiteralPath $tempPackagePath) {
|
|||||||
Remove-Item -LiteralPath $tempPackagePath -Force
|
Remove-Item -LiteralPath $tempPackagePath -Force
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# CI quirk: Divine can occasionally emit a broken ~48-byte package for some source roots.
|
||||||
|
# Mitigation: try staged/mods/workspace sources and accept only outputs that look valid by size.
|
||||||
$packageAttempts = @(
|
$packageAttempts = @(
|
||||||
[ordered]@{ Name = "staging-root"; Source = $stagingPath },
|
[ordered]@{ Name = "staging-root"; Source = $stagingPath },
|
||||||
[ordered]@{ Name = "mods-root"; Source = $modsPath },
|
[ordered]@{ Name = "mods-root"; Source = $modsPath },
|
||||||
|
|||||||
63
scripts/set-version.ps1
Normal file
63
scripts/set-version.ps1
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$VersionTag,
|
||||||
|
[string]$MetaPath = "Mods/DnD 5.5e AIO Russian/meta.lsx"
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
function Convert-VersionTagToVersion64 {
|
||||||
|
param(
|
||||||
|
[string]$Tag
|
||||||
|
)
|
||||||
|
|
||||||
|
$normalized = $Tag
|
||||||
|
if ($normalized.StartsWith("v")) {
|
||||||
|
$normalized = $normalized.Substring(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($normalized -notmatch '^\d+(\.\d+){0,3}$') {
|
||||||
|
throw "Version tag '$Tag' is invalid. Expected format: vX.Y.Z or X.Y.Z"
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = $normalized.Split(".")
|
||||||
|
$numbers = @(0, 0, 0, 0)
|
||||||
|
for ($i = 0; $i -lt $parts.Length; $i++) {
|
||||||
|
$numbers[$i] = [int]$parts[$i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return ([int64]$numbers[0] -shl 55) -bor ([int64]$numbers[1] -shl 47) -bor ([int64]$numbers[2] -shl 31) -bor [int64]$numbers[3]
|
||||||
|
}
|
||||||
|
|
||||||
|
$resolvedMetaPath = [System.IO.Path]::GetFullPath($MetaPath)
|
||||||
|
if (-not (Test-Path -LiteralPath $resolvedMetaPath)) {
|
||||||
|
throw "meta.lsx was not found: '$resolvedMetaPath'."
|
||||||
|
}
|
||||||
|
|
||||||
|
$resolvedVersion64 = Convert-VersionTagToVersion64 -Tag $VersionTag
|
||||||
|
$metaContent = Get-Content -LiteralPath $resolvedMetaPath -Raw
|
||||||
|
[xml]$metaXml = $metaContent
|
||||||
|
|
||||||
|
# Explicitly target ModuleInfo/Version64 via XML path to avoid touching Dependencies/PublishVersion.
|
||||||
|
$moduleInfoVersionNode = $metaXml.SelectSingleNode('/save/region/node/children/node[@id="ModuleInfo"]/attribute[@id="Version64" and @type="int64"]')
|
||||||
|
if ($null -eq $moduleInfoVersionNode) {
|
||||||
|
throw "ModuleInfo/Version64 attribute was not found in '$resolvedMetaPath'."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Replace only the Version64 attribute that appears inside ModuleInfo before its <children> block.
|
||||||
|
$moduleInfoVersionPattern = '(?s)(<node id="ModuleInfo">\s*(?:(?!<children>).)*?<attribute id="Version64" type="int64" value=")\d+("/>)'
|
||||||
|
if ($metaContent -notmatch $moduleInfoVersionPattern) {
|
||||||
|
throw "ModuleInfo/Version64 attribute was not found in '$resolvedMetaPath'."
|
||||||
|
}
|
||||||
|
|
||||||
|
$updatedMeta = [regex]::Replace(
|
||||||
|
$metaContent,
|
||||||
|
$moduleInfoVersionPattern,
|
||||||
|
"`${1}$resolvedVersion64`${2}",
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
$utf8Bom = New-Object System.Text.UTF8Encoding($true)
|
||||||
|
[System.IO.File]::WriteAllText($resolvedMetaPath, $updatedMeta, $utf8Bom)
|
||||||
|
|
||||||
|
Write-Host "[set-version.ps1] Updated '$resolvedMetaPath' to Version64=$resolvedVersion64 (from tag '$VersionTag')."
|
||||||
91
scripts/sync-parent-meta.ps1
Normal file
91
scripts/sync-parent-meta.ps1
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
param(
|
||||||
|
[string]$ParentMetaUrl = "https://raw.githubusercontent.com/Yoonmoonsik/dnd55e/main/Mods/DnD2024_897914ef-5c96-053c-44af-0be823f895fe/meta.lsx",
|
||||||
|
[string]$TargetMetaPath = "Mods/DnD 5.5e AIO Russian/meta.lsx"
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$resolvedTargetMetaPath = [System.IO.Path]::GetFullPath($TargetMetaPath)
|
||||||
|
|
||||||
|
if (-not (Test-Path -LiteralPath $resolvedTargetMetaPath)) {
|
||||||
|
throw "Target meta.lsx was not found: '$resolvedTargetMetaPath'."
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([string]::IsNullOrWhiteSpace($ParentMetaUrl)) {
|
||||||
|
throw "ParentMetaUrl must not be empty."
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$parentResponse = Invoke-WebRequest -Uri $ParentMetaUrl -UseBasicParsing -TimeoutSec 60
|
||||||
|
} catch {
|
||||||
|
throw "Failed to download parent meta.lsx from '$ParentMetaUrl': $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
|
||||||
|
$parentRaw = $parentResponse.Content
|
||||||
|
$targetRaw = Get-Content -LiteralPath $resolvedTargetMetaPath -Raw
|
||||||
|
|
||||||
|
[xml]$parentXml = $parentRaw
|
||||||
|
[xml]$targetXml = $targetRaw
|
||||||
|
|
||||||
|
$parentModuleInfo = $parentXml.SelectSingleNode('/save/region/node/children/node[@id="ModuleInfo"]')
|
||||||
|
if ($null -eq $parentModuleInfo) {
|
||||||
|
throw "ModuleInfo node was not found in parent meta downloaded from '$ParentMetaUrl'."
|
||||||
|
}
|
||||||
|
|
||||||
|
$requiredFields = @("Folder", "MD5", "Name", "PublishHandle", "UUID", "Version64")
|
||||||
|
$sourceValues = @{}
|
||||||
|
|
||||||
|
foreach ($field in $requiredFields) {
|
||||||
|
$node = $parentModuleInfo.SelectSingleNode("attribute[@id='$field']")
|
||||||
|
if ($null -eq $node) {
|
||||||
|
throw "Required parent ModuleInfo attribute '$field' is missing in meta downloaded from '$ParentMetaUrl'."
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = $node.GetAttribute("value")
|
||||||
|
if ([string]::IsNullOrWhiteSpace($value)) {
|
||||||
|
throw "Required parent ModuleInfo attribute '$field' has empty value in meta downloaded from '$ParentMetaUrl'."
|
||||||
|
}
|
||||||
|
|
||||||
|
$sourceValues[$field] = $value
|
||||||
|
}
|
||||||
|
|
||||||
|
$targetDependencyNode = $targetXml.SelectSingleNode('/save/region/node/children/node[@id="Dependencies"]/children/node[@id="ModuleShortDesc"]')
|
||||||
|
if ($null -eq $targetDependencyNode) {
|
||||||
|
throw "Dependencies/ModuleShortDesc node was not found in target meta: '$resolvedTargetMetaPath'."
|
||||||
|
}
|
||||||
|
|
||||||
|
$changedFields = @()
|
||||||
|
foreach ($field in $requiredFields) {
|
||||||
|
$targetAttr = $targetDependencyNode.SelectSingleNode("attribute[@id='$field']")
|
||||||
|
if ($null -eq $targetAttr) {
|
||||||
|
throw "Target Dependencies/ModuleShortDesc attribute '$field' is missing in '$resolvedTargetMetaPath'."
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentValue = $targetAttr.GetAttribute("value")
|
||||||
|
$newValue = [string]$sourceValues[$field]
|
||||||
|
if ($currentValue -ne $newValue) {
|
||||||
|
$targetAttr.SetAttribute("value", $newValue)
|
||||||
|
$changedFields += $field
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($changedFields.Count -eq 0) {
|
||||||
|
Write-Host "[sync-parent-meta.ps1] No changes needed. Target dependency data is already up to date."
|
||||||
|
} else {
|
||||||
|
$utf8Bom = New-Object System.Text.UTF8Encoding($true)
|
||||||
|
$settings = New-Object System.Xml.XmlWriterSettings
|
||||||
|
$settings.Encoding = $utf8Bom
|
||||||
|
$settings.Indent = $true
|
||||||
|
$settings.IndentChars = " "
|
||||||
|
$settings.NewLineChars = "`n"
|
||||||
|
$settings.NewLineHandling = [System.Xml.NewLineHandling]::Replace
|
||||||
|
|
||||||
|
$writer = [System.Xml.XmlWriter]::Create($resolvedTargetMetaPath, $settings)
|
||||||
|
try {
|
||||||
|
$targetXml.WriteTo($writer)
|
||||||
|
} finally {
|
||||||
|
$writer.Dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ("[sync-parent-meta.ps1] Updated fields: " + ($changedFields -join ", "))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user