Ratty123/CDMW-Full

GitHub: Ratty123/CDMW-Full

一款专为《Crimson Desert》游戏提供完整归档浏览、网格编辑、纹理重建与材质替换能力的 Windows 桌面 Mod 制作工作台。

Stars: 10 | Forks: 1

# Crimson Desert Mod Workbench [![Windows 构建](https://img.shields.io/github/actions/workflow/status/Ratty123/CDMW-Full/windows-build.yml?branch=main&style=flat-square&logo=github&label=Windows%20build)](https://github.com/Ratty123/CDMW-Full/actions/workflows/windows-build.yml) ![版本](https://img.shields.io/badge/version-0.11.0--alpha.2-1f6feb?style=flat-square) ![平台](https://img.shields.io/badge/platform-Windows%2011%20x64-555555?style=flat-square) ![Python](https://img.shields.io/badge/Python-3.11%20%7C%203.14-3776AB?style=flat-square&logo=python&logoColor=white) ![.NET](https://img.shields.io/badge/.NET-10-512BD4?style=flat-square&logo=dotnet&logoColor=white) ![渲染器](https://img.shields.io/badge/renderer-D3D11-brightgreen?style=flat-square) ![归档](https://img.shields.io/badge/archives-explicit%20mutation-orange?style=flat-square) [![许可证](https://img.shields.io/badge/license-MIT-brightgreen?style=flat-square)](LICENSE) 一个用于为 **Crimson Desert** 制作 mod 的 Windows 桌面工作台:浏览和提取 游戏归档,在原生 D3D11 渲染器上预览和编辑网格,重建和 制作 DDS 纹理,组装材质和网格替换包,并读取 必须从发布的版本中逆向工程的格式。 这是完整的工作台。如果你只需要查看归档的内部内容,只读的 配套应用 [**CDMW Lite**](https://github.com/Ratty123/CDMW-Lite) 体积更小,交给不制作 mod 的人使用也更安全。 | | | |---|---| | **下载** | [版本发布](https://github.com/Ratty123/CDMW-Full/releases) | | **更新日志** | [CHANGELOG.md](CHANGELOG.md) | | **架构** | [docs/architecture.md](docs/architecture.md) | | **格式状态** | [docs/features/format-decode-progress.md](docs/features/format-decode-progress.md) | | **贡献指南** | [CONTRIBUTING.md](CONTRIBUTING.md) · [SECURITY.md](SECURITY.md) | ## 目录 - [功能介绍](#what-it-does) - [文件格式解码状态](#file-format-decoding-status) - [架构](#architecture) - [安装说明](#install) - [从源码构建](#build-from-source) - [项目结构](#project-layout) - [安全模型](#safety-model) - [隐私](#privacy) - [已知限制](#known-limitations) - [许可证](#license) ## 功能介绍 | 工作区 | 你可以做什么 | |---|---| | **归档浏览器** | 以平面或树状视图浏览 `.pamt` / `.paz` 归档,支持过滤、搜索、缓存重用、提取、文本和媒体预览,以及显式的修补/恢复流程。 | | **网格预览与编辑器** | 在原生 D3D11 路径上预览 `.pam`、`.pamlod` 和 `.pac` 网格,检查引用的纹理,通过原生编辑核心编辑驻留网格,并导出 OBJ/FBX 或导入 OBJ/DAE/glTF/GLB 进行比较。 | | **纹理工作流** | 使用内置的 `cd-texture-dx.exe` DirectXTex 助手重建 DDS,通过 Real-ESRGAN NCNN 或 chaiNNer 进行放大,规划纹理策略,比较前后效果,并导出 mod 包。 | | **纹理替换器** | 使用原始游戏 DDS 作为重建依据来替换已编辑的 PNG/DDS 纹理,生成带包前缀的松散输出文件和管理器元数据。 | | **图像编辑器** | 在应用内编辑可见纹理:图层项目、选区、蒙版、调整图层、通道锁定、画笔工具、仿制/修复、涂抹、锐化、柔化,以及扁平化 PNG 导出。 | | **材质权限** | 构建和审计具有源所属材质路由的材质/网格替换包,保留运行时 XML,提供诊断和最终包预览。 | | **放置与动画工作室** | 移动武器或盔甲的位置,从视口中将其重新路由到不同的 socket,重定向拔出/收起动画,并为 CDUMM、DMM 或 JMM 封装结果。 | | **格式探索器** | 了解每种游戏文件格式能做什么和不能做什么,以及由哪个工具执行 —— 从下方 [解码状态](#file-format-decoding-status) 生成所用的同一功能清单中读取,因此不会偏离代码实际支持的功能。 | | **辅助工具** | 模型库、图标创建器、重新着色变体、纹理研究、文本搜索、改造/重新封装、设置/配置导出、诊断包、可分离选项卡。 | ### 放置与动画工作室 武器悬挂的位置、路由到的 socket 以及拔出时播放的剪辑都是可以编辑的,而且所有这些都不需要解码 Havok tagfile。四种机制涵盖了所有手工构建、经游戏验证的 mod 所需的操作:XML 中的 socket 变换编辑和描述符路由编辑、`.paac` 内同等长度的 socket 名称重定向,以及对游戏其他位置已有的 `.paa` 和 `.motionblending` 负载的整体文件替换。 安全模型基于操作词汇表,而不是事后拼凑的验证过程 —— 不安全的操作根本无法表达。该编辑器在配置的范围内生成 socket 平移/旋转,将更改路由到已存在的 socket,生成必须保持字节一致的描述符别名对,保持长度的 `.paac` 重定向,以及经过验证的负载替换。对于任何会更改文件长度的二进制写入、PAAC 图结构编辑、`ItemInfo`/`EquipSlot`/prefab 树编辑、目标 socket 集中不存在的 socket 名称以及创作新的 `.paa` 关键帧数据,它都会拒绝并给出解释,绝不进行静默回退。 这个范围不是断言的,而是测量出来的。一个基准测试工具从每个已知良好的 mod 中提取操作列表,并在锁定的原版基准上重放:20 个 mod 中的 20 个表示为 6,416 次操作,15 个基于原版的 mod 中的 15 个实现了逐字节重现,并且组合 1H 和 2H 操作列表会产生组合 mod。`.paac` 字符串以长度为前缀 (``),在整个语料库中验证了 30 个中的 30 个,这就是让同等长度的重定向可证明安全而非臆想的原因。 从 **工具 → 放置与动画工作室** 打开,或使用 `python scripts/placement_studio.py` 独立运行。163 个单元测试涵盖了它,并且都不需要安装游戏。 ## 文件格式解码状态 Crimson Desert 发布了 141 种不同的文件扩展名。其中 89 种是引擎格式 —— Pearl Abyss 自有或授权的中间件 —— 并且 **其中 77 种实际出现在 发布的版本中**。最后一个数字是真实的分母:游戏不包含的格式 无法进行 mod 制作,也不应计入进度。 | 范围 | 格式 | 读取覆盖率 | 写入覆盖率 | |---|---:|---:|---:| | **版本发布的引擎格式** | 77 | **41.7%** | **26.0%** | | 按归档文件数加权 | 1,383,187 个文件 | 65.9% | 53.8% | | 引擎格式(专有 + 中间件) | 89 | 41.9% | 27.5% | | 仅 Pearl Abyss 格式 | 82 | 42.6% | 28.0% | | 所有格式,包括开源格式 | 141 | 54.3% | 33.0% | 覆盖率是加权平均值,而不是文件计数。读取:`full` = 1.0, `partial` = 0.6,`surface` = 0.3,`none` = 0.0。写入:`full` = 1.0, `constrained` = 0.5,`none` = 0.0。 ### 按区域划分 | 区域 | 格式 | 读取 | 写入 | |---|---:|---|---| | `user_interface_text` | 15 | `██████████████████░░` 88.7% | `████████████████░░░░` 80.0% | | `texture_image` | 12 | `████████████████░░░░` 80.0% | `███░░░░░░░░░░░░░░░░░` 16.7% | | `model_mesh_physics` | 19 | `███████████░░░░░░░░░` 54.2% | `███████░░░░░░░░░░░░░` 36.8% | | `audio_video` | 18 | `█████████░░░░░░░░░░░` 47.2% | `██░░░░░░░░░░░░░░░░░░` 8.3% | | `material_metadata` | 62 | `█████████░░░░░░░░░░░` 46.0% | `███████░░░░░░░░░░░░░` 33.1% | | `animation_scene` | 15 | `████████░░░░░░░░░░░░` 42.0% | `█████░░░░░░░░░░░░░░░` 23.3% | ### 已完成的内容 这些格式可以完全读取和写入,是构建 mod 制作工作流的基础: `.pac` · `.pam` · `.pamlod` · `.pami` · `.paa` · `.paloc` · `.papr` · `.paprojdesc` · `.pac_xml` · `.pam_xml` · `.pamlod_xml` · `.prefabdata_xml` · `.material` · `.mi` · `.pas` · `.pma` · `.spline` · `.spline2d` · `.app_xml` 网格、骨骼动画、纹理、材质和游戏中每一行本地化 文本都能逐字节往返。`.papr` 最近才完成关闭:所有 二十个发布的物理布料绑定现在都平铺到它们声明的条目数,并且 在 2,737 个配置块中完全重建。 ### 已部分解码的内容 | 格式 | 文件数 | 读取 | 写入 | 剩余工作 | |---|---:|---|---|---| | `.prefab` | 47,343 | partial | constrained | 40% 的归档 prefab 未能遍历完成。在失败位置未标明组件身份,并且在 87% 的位置,集合标头宽度规则不明确。值编辑仅限于文件已声明类型的对象。 | | `.hkx` | 58,031 | partial | constrained | 结构编辑 —— 拓扑、计数、引用、字符串、数组 —— 在提供语义重建证明之前被阻止。无法创建新的碰撞形状或布娃娃身体。 | | `.paac` | 520 | partial | constrained | 字符串周围的图表节点结构尚未解析,因此仅允许同等长度的动画重定向。 | | `.wem` | 375,762 | partial | constrained | 仅未压缩的 PCM 被重新编码;Vorbis/Opus 流无法创作。 | | `.pat` | 1,397 | partial | none | 没有构建器,且 LOD1+ 以及无法识别的顶点布局仍未解码 —— 静态世界几何体仅供查看。 | | `.parg` `.pasg` `.pcg` | 882 | partial | none | 指针地址寻址的堆遍历在指针尾部停止,因此无法读取嵌套值。关闭 `.parg` 可开启 VFX mod 制作;关闭 `.pcg` 允许创建自定义碰撞轮廓。 | | `.pab` | 257 | partial | none | 未知和截断的变体回退到尽力而为的扫描,并且没有写入器 —— 无法添加、删除或重命名骨骼。 | ### 尚未解密的内容 最高价值的缺口,按其产生回报的顺序排列: - **`.palevel` / `.levelinfo`**(35,597 个文件) —— 放置记录尚未解析, 因此无法编辑关卡布局。 - **`.paseq` / `.paseqc` / `.pastage`**(10,947 个文件) —— 轨道和事件布局尚未 解析,因此过场动画创作已关闭。 - **`.pae` / `.paem`**(6,669 个文件) —— 参数表尚未解析,因此 VFX 创作已关闭。 - **`.meshinfo`**(35, 个文件) —— 计数/偏移表尚未验证,这就是为什么 网格替换将其视为只读的原因;物理边界和 socket 上下文 无法编辑。 - **`.paschedule` / `.paschedulepath`**(7,756 个文件) —— NPC 例行程序 无法重新定时或重新路由。 - **`.bnk`**(3,186 个文件) —— HIRC 事件/动作表尚未解析,因此可以 交换声音,但不能添加声音。 - **`.padxil`**(89,824 个文件) —— 着色器字节码已编目,但未 在此处反汇编,并且没有途径将编辑后的着色器重新编译 回缓存中。 少数条目(`.save`、`.binarystring`、`.paseqh`、`.paasmt`、 `.questgaugecount`、`.linkedsceneobject`)使用项目 没有的密钥进行了加密。在解决此问题之前,那里无法 解码任何内容。 ## 架构 工作台是一个拥有 UI 和领域规则的单一 Python 进程,加上 拥有所有性能关键或平台关键功能的经验证的辅助进程。 没有任何界面会静默回退到不同的渲染器或更慢的路径: 无法完成任务的辅助进程会报告明确的不可用状态。 ``` flowchart LR subgraph host["Python host process"] direction TB APP["cdmw/app
bootstrap · single instance · splash"] SHELL["cdmw/ui/shell
MainWindow · tabs · controllers"] FEAT["cdmw/ui feature packages
archive · texture · mesh · research"] SVC["cdmw/services + cdmw/domain
coordination · rules · policy"] WRK["cdmw/workers
QThread jobs · cancellation"] APP --> SHELL --> FEAT --> SVC --> WRK end subgraph native["Native helpers (C++)"] direction TB PREV["cdmw_preview_core
archive decode · name index · packaging"] MESH["cdmw_mesh_core
resident mesh edit authority"] TEX["cd_texture_dx
DirectXTex encode/decode"] HKX["cd_hkx
Havok container reads"] end subgraph dotnet[".NET 10 helpers"] direction TB EDITOR["Cdmw.MeshEditorExperiment
D3D11 / Vortice presentation + input host"] ARCH["Cdmw.FullArchive.Worker
archive backend service"] end WRK -->|stdio protocol| PREV WRK -->|stdio protocol| ARCH SVC -->|command protocol| MESH WRK --> TEX WRK --> HKX FEAT -->|embedded HWND + scene protocol| EDITOR PREV -->|schema-8 packages| EDITOR ``` ### 分层规则 导入是单向的。上一层可以使用其下面的一层,而不能使用其上面的一层。 ``` flowchart TD UI["cdmw/ui — the only layer that may import PySide6 widgets"] SERVICES["cdmw/services — coordination boundaries"] DOMAIN["cdmw/domain — pure rules, no Qt"] WORKERS["cdmw/workers — protocols, results, cancellation"] CORE["cdmw/core · cdmw/modding · cdmw/rendering"] NATIVE["native/ · tools/dotnet_* — helper processes"] UI --> SERVICES --> DOMAIN SERVICES --> WORKERS --> CORE --> NATIVE UI -.->|via stable descriptors| WORKERS ``` `MainWindow` 仅将 `QMainWindow` 作为直接基类。功能行为 通过绑定到窗口的稳定描述符注册,而不是通过 新的窗口基类,因此当提取实现所有者时,调用点保持 原样。新行为应属于专门的控制器。 ### 网格预览与编辑 一个控制器拥有一个经验证的辅助进程,具有单调的进程和 包生成,因此永远不会显示过时的结果。 ``` sequenceDiagram participant UI as Archive Browser participant SESS as Preview session controller participant PREV as cdmw_preview_core participant NET as .NET D3D11 host UI->>SESS: select entry SESS->>PREV: prepare package (latest wins) PREV-->>SESS: schema-8 package + material report SESS->>NET: replace resident package NET-->>SESS: Ready (consumed once per process) SESS-->>UI: scene visible Note over SESS,NET: A replacement prepares while the accepted scene stays on screen. Note over SESS,PREV: Package/material failure is retryable and never recycles a healthy process. ``` `preview` 配置文件公开只读展示、拾取、覆盖和 捕获。`authoring` 配置文件添加了网格编辑器变异协议,并在 恢复后从权威的 `MeshService` 状态重新水合。`Edit Mesh` 更改变异权限 —— 它不会选择或重启渲染器。 ### 构建系统 两种构建路径,均受支持,由一个 UI 驱动: ``` flowchart LR UIB[".tools/build-ui/cdmw-build.exe"] BZL["bazel build //:CrimsonDesertModWorkbench
fast · skips release gates"] REL["build.bat onefile release
full gates · publishes to dist/"] NATIVE_T["bazel test //native/..."] UIB --> BZL UIB --> REL UIB --> NATIVE_T ``` Bazel 端到端地构建发布的可执行文件 —— 所有五个原生 C++ 助手、 两个独立的 .NET 发布以及 PyInstaller 包 —— 并且是 附加的:PowerShell 发布路径保持不变,并且仍然拥有发布 关卡。Bazel 在本地仓库的 `.tools/bazel/` 中安装;没有 系统范围的安装。请参阅 [docs/bazel-migration.md](docs/bazel-migration.md)。 ## 安装说明 1. 从 [版本发布](https://github.com/Ratty123/CDMW-Full/releases)下载最新的 Windows 便携版 EXE。 2. 运行 `CrimsonDesertModWorkbench--windows-portable.exe`。 3. 在 **纹理工作流 → 设置** 中,初始化工作区并配置根目录。 4. DDS 预览、暂存和重建会自动使用内置的 `cd-texture-dx.exe` 助手。 仅在需要时配置可选的放大工具: - **Real-ESRGAN NCNN** 用于直接放大 - **chaiNNer** 用于现有的 `.chn` 链 便携式配置存储在 EXE 旁边。应用管理的文件夹位于 `workspace/` 下:原始 DDS 文件、暂存、输出、提取、库、工具、 缓存、日志、会话、项目和研究数据。 ## 从源码构建 **要求** —— Windows 11 x64、Python 3.11 或 3.14(两个经过发布测试的 解释器)、PowerShell、.NET 10 SDK,以及用于 原生助手的 CMake/MSVC 工具链。 ``` python -m venv .venv .\.venv\Scripts\python.exe -m pip install "pip==25.3" .\.venv\Scripts\python.exe -m pip install -c constraints-release.txt -r requirements-build.txt .\.venv\Scripts\python.exe -m pip install "pytest==9.0.3" .\.venv\Scripts\python.exe scripts\verify_release_dependencies.py ``` 运行测试(578 个测试模块涵盖行为、协议契约和 源码防护): ``` .\.venv\Scripts\python.exe -m pytest ``` 从源码运行应用: ``` .\.venv\Scripts\python.exe cdmw_app.py ``` 构建可发布的单文件 EXE: ``` powershell -NoProfile -ExecutionPolicy Bypass -File .\build_pyside6_app.ps1 -Mode onefile -BuildProfile release ``` 发布版本需要 `constraints-release.txt` 中的确切版本,将 内置的 .NET 网格编辑器作为独立的 `win-x64` 单文件发布,并运行 离屏启动冒烟测试。仅当原子结果 标记报告 `post_construction` 后才会发布输出: ``` dist\CrimsonDesertModWorkbench--windows-portable.exe ``` 其他入口点: | 命令 | 结果 | |---|---| | `build.bat onefile release` | 与上述相同,通过批处理封装器执行 | | `build.bat onedir release` | 文件夹包,而不是单个文件 | | `build.bat` | 图形化构建选择器 | | `.tools\build-ui\cdmw-build.exe` | 涵盖 Bazel 和发布路径的构建 UI | | `.tools\bazel\bazel.exe build //:CrimsonDesertModWorkbench` | 快速 Bazel 构建,无发布关卡 | | `.tools\bazel\bazel.exe test //native/...` | 原生助手单元测试 | ## 项目结构 ``` cdmw/ application code app/ bootstrap, startup routing, single-instance handling ui/shell/ MainWindow, tabs, controllers, close/diagnostics ui// archive browser, texture workflow, mesh editor, research ui/preview/ shared Qt host and resident preview session controller services/ coordination boundaries, no PySide widget imports domain/ pure rules: archive safety, texture policy, manifests workers/ worker protocols, result types, cancellation core/ modding/ rendering/ archive, DDS, import/export, packaging logic native/ C++ helpers (preview core, mesh core, texture, hkx) tools/dotnet_* .NET 10 helpers (D3D11 host, archive worker, build UI) schemas/ versioned capability and package schemas tests/ behaviour, protocol contract, and source-guard tests docs/ guides, runbooks, and reverse-engineering notes ``` 延伸阅读:[架构](docs/architecture.md) · [文档索引](docs/README.md) · [启动流程](docs/runbooks/startup-flow.md) · [Worker 生命周期](docs/runbooks/worker-lifecycle.md) · [归档安全模型](docs/features/archive-safety-model.md) ## 安全模型 归档变异是显式的。浏览、预览、提取、扫描和 包构建从不会静默重写游戏归档。受支持的归档修补 流程使用确认、预检、备份和还原支持。 将本地游戏归档、提取的资产、DDS 负载、构建输出、崩溃 报告、还原点和语料库数据排除在源码控制之外。 ## 隐私 在正常的离线使用期间,没有遥测、分析、自动更新检查或后台网络调用。崩溃报告和诊断包将保留在本地,直到你 导出并共享它们。外部页面仅在用户明确操作时打开,例如 下载或帮助链接。 ## 已知限制 **放置编辑具有严格的边界。** 在 [放置与动画工作室](#placement--animation-studio) 下列出的操作是整个 词汇表。它之外的任何内容 —— 完整的 PAAC 图交换、`ItemInfo`/`EquipSlot` 编辑、新的关键帧数据、任何更改文件长度的二进制写入 —— 在设计上都是超出范围的,而不是功能差距,并且编辑器会 附上解释予以拒绝。早期的 `Weapon Placement Studio` 使这些操作 可表达,但由于会导致游戏卡死而被撤下;它在归档 浏览器中的菜单项保持禁用且未动,因此没有任何内容继承导致崩溃的功能的名称或代码 路径。 **网格重建仅限 LOD0。** `.pamlod` LOD1+ 可以读取但无法重新创作, 并且 `.meshinfo` 被视为只读,因为其计数/偏移表 尚未验证 —— 无法编辑物理边界和 socket 上下文。 **关卡布局、过场动画和 VFX 是只读的。** 请参阅 [尚未解密的内容](#what-is-still-closed)了解其背后的格式以及 关闭它们的回报顺序。 ## 许可证 [MIT](LICENSE)。第三方组件及其许可证列在 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)中。
标签:D3D11, Python, 云资产清单, 多人体追踪, 无后门, 模型编辑, 游戏Mod, 纹理处理, 逆向工具, 逆向工程