mcpywrap 0.2.2__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcpywrap-0.3.0/CHANGELOG.md +15 -0
- mcpywrap-0.3.0/LICENSE +21 -0
- mcpywrap-0.3.0/MANIFEST.in +6 -0
- mcpywrap-0.3.0/PKG-INFO +232 -0
- mcpywrap-0.3.0/README.md +206 -0
- mcpywrap-0.3.0/docs/releasing.md +23 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/__init__.py +1 -1
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/builders/AddonsPack.py +12 -23
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/builders/MapPack.py +4 -6
- mcpywrap-0.3.0/mcpywrap/builders/assembly.py +85 -0
- mcpywrap-0.3.0/mcpywrap/builders/dependency_manager.py +158 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/builders/file_merge.py +2 -4
- mcpywrap-0.3.0/mcpywrap/builders/project_builder.py +97 -0
- mcpywrap-0.3.0/mcpywrap/builders/watcher.py +136 -0
- mcpywrap-0.3.0/mcpywrap/commands/add_cmd.py +34 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/commands/build_cmd.py +9 -4
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/commands/default_cmd.py +4 -1
- mcpywrap-0.3.0/mcpywrap/commands/dependency_prompt.py +21 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/commands/dev_cmd.py +8 -5
- mcpywrap-0.3.0/mcpywrap/commands/edit_cmd.py +86 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/commands/init_cmd.py +49 -43
- mcpywrap-0.3.0/mcpywrap/commands/remove_cmd.py +46 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/commands/run_cmd.py +47 -73
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/commands/ui_cmd.py +1 -2
- mcpywrap-0.3.0/mcpywrap/config.py +281 -0
- mcpywrap-0.3.0/mcpywrap/dependencies.py +222 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/mcstudio/game.py +8 -7
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/mcstudio/mcs.py +3 -3
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/mcstudio/symlinks.py +66 -242
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/ui/project_ui.py +184 -119
- mcpywrap-0.3.0/mcpywrap/utils/pip_error_parser.py +184 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/utils/project_setup.py +36 -4
- mcpywrap-0.3.0/mcpywrap.egg-info/PKG-INFO +232 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap.egg-info/SOURCES.txt +11 -2
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap.egg-info/requires.txt +2 -1
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/pyproject.toml +10 -6
- mcpywrap-0.3.0/tests/manual_integration.py +278 -0
- mcpywrap-0.3.0/tests/test_local_dependencies.py +485 -0
- mcpywrap-0.2.2/PKG-INFO +0 -145
- mcpywrap-0.2.2/README.md +0 -121
- mcpywrap-0.2.2/mcpywrap/builders/dependency_manager.py +0 -209
- mcpywrap-0.2.2/mcpywrap/builders/project_builder.py +0 -346
- mcpywrap-0.2.2/mcpywrap/builders/watcher.py +0 -314
- mcpywrap-0.2.2/mcpywrap/commands/add_cmd.py +0 -39
- mcpywrap-0.2.2/mcpywrap/commands/edit_cmd.py +0 -130
- mcpywrap-0.2.2/mcpywrap/commands/remove_cmd.py +0 -42
- mcpywrap-0.2.2/mcpywrap/config.py +0 -143
- mcpywrap-0.2.2/mcpywrap/utils/py3to2_util.py +0 -53
- mcpywrap-0.2.2/mcpywrap.egg-info/PKG-INFO +0 -145
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/__main__.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/builders/__init__.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/cli.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/commands/__init__.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/commands/mod_cmd.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/commands/modsdk_cmd.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/commands/publish_cmd.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/custom_packaging.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/mcstudio/SimpleMonitor.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/mcstudio/__init__.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/mcstudio/editor.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/mcstudio/runtime_cppconfig.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/mcstudio/studio_server.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/mcstudio/studio_server_ui.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/mcstudio/symlink_helper_global.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/mcstudio/symlink_helper_map.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/minecraft/__init__.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/minecraft/addons.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/minecraft/level_dat.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/minecraft/map.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/minecraft/netease_modsdk.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/minecraft/template/generate_mod_files.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/minecraft/template/mod_template.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/ui/__init__.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/utils/__init__.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/utils/print_guide.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap/utils/utils.py +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap.egg-info/dependency_links.txt +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap.egg-info/entry_points.txt +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/mcpywrap.egg-info/top_level.txt +0 -0
- {mcpywrap-0.2.2 → mcpywrap-0.3.0}/setup.cfg +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 更新记录
|
|
2
|
+
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
- 新增本地 Addon 目录依赖:CLI、初始化向导和 GUI 支持直接添加、预检和移除目录引用,无需初始化或安装被引用项目。
|
|
6
|
+
- Python 包和本地目录共用依赖图,支持相对路径、真实路径去重、循环检测及标准 requirement 版本和环境标记校验。
|
|
7
|
+
- `build/run/edit/dev` 接入本地依赖;运行前重新校验,避免缓存过期的依赖集合。
|
|
8
|
+
- **构建行为变更**:主项目优先,完整与增量构建统一依赖顺序;删除高优先级文件后恢复低优先级来源。
|
|
9
|
+
- 构建前拒绝输出与源目录重叠;无效依赖不清空已有输出。
|
|
10
|
+
- Windows 链接保留其他项目内容,支持无符号链接权限时使用目录 junction;游戏启动使用实际进程句柄。
|
|
11
|
+
- 修正最低 Python 版本为 3.9,与现有运行代码要求一致。
|
|
12
|
+
- 显式依赖 pip,确保通过 uv 安装的隔离工具环境也能执行 Python 包的添加和初始化安装。
|
|
13
|
+
- 新增自动化测试、打包校验和 GitHub Actions → PyPI Trusted Publishing 流程。
|
|
14
|
+
|
|
15
|
+
本机已通过 33 项自动化测试及 MCS 3.10.0.420447 的四组实际游戏加载测试。
|
mcpywrap-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 EaseCation®️
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
mcpywrap-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcpywrap
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: A wrapper for Minecraft China Edition Addons management
|
|
5
|
+
Author-email: boybook <boybook@easecation.net>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/EaseCation/mcpywrap
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/EaseCation/mcpywrap/issues
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: pip>=21
|
|
15
|
+
Requires-Dist: click>=8.0.0
|
|
16
|
+
Requires-Dist: watchdog>=2.0.0
|
|
17
|
+
Requires-Dist: twine>=3.4.0
|
|
18
|
+
Requires-Dist: tomli
|
|
19
|
+
Requires-Dist: tomli-w
|
|
20
|
+
Requires-Dist: setuptools
|
|
21
|
+
Requires-Dist: packaging>=21
|
|
22
|
+
Requires-Dist: PyQt5>=5.15.0
|
|
23
|
+
Requires-Dist: psutil>=5.8.0
|
|
24
|
+
Requires-Dist: rich>=10.0.0
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# 🧰 mcpywrap
|
|
28
|
+
|
|
29
|
+
**《我的世界》中国版 ModSDK 与资源包的全周期管理工具**
|
|
30
|
+
|
|
31
|
+
[](https://pypi.org/project/mcpywrap/)
|
|
32
|
+
[](LICENSE)
|
|
33
|
+
|
|
34
|
+
mcpywrap 是基于 Python 生态的《我的世界》中国版 ModSDK/资源包全周期管理工具,支持依赖管理、语法转换和自动化构建,助力开发者实现高效协作与代码复用。
|
|
35
|
+
|
|
36
|
+
## 🌟 核心特性
|
|
37
|
+
|
|
38
|
+
- 🧩 **模块化开发** - 基于 Addons 维度的依赖管理(基于包管理和依赖的开发与测试流程)
|
|
39
|
+
- 🔄 **现代语法** - 支持 Python3 现代语法特性,提升开发体验
|
|
40
|
+
- 📦 **生态兼容** - 无缝对接 PyPI 生态,支持标准 `pyproject.toml` 配置
|
|
41
|
+
- 🚀 **智能构建** - 一键打包符合 MCStudio 规范的成品 Addons
|
|
42
|
+
- 🔥 **热重载开发** - 实时监控代码变更,支持 MCStudio 热更新
|
|
43
|
+
|
|
44
|
+
## 📖 为何选择此工具?
|
|
45
|
+
|
|
46
|
+
### 传统开发痛点
|
|
47
|
+
- 📜 **代码复用困难** - 通过 **文件拷贝** 导致版本管理混乱
|
|
48
|
+
- 🚧 **协作效率低下** - 多项目 **重复代码** 维护成本高
|
|
49
|
+
- ⚠️ **代码质量** - 缺乏现代开发工具和语法支持
|
|
50
|
+
|
|
51
|
+
### mcpywrap 解决方案
|
|
52
|
+
1. **标准化开发**
|
|
53
|
+
通过 `pyproject.toml` 声明项目元数据和依赖关系,实现真正的模块化开发
|
|
54
|
+
|
|
55
|
+
2. **直接启动测试和编辑**
|
|
56
|
+
- 直接通过 `mcpy run` 启动游戏实例,支持热重载和实时构建,提升开发效率
|
|
57
|
+
- 通过 `mcpy edit` 命令,使用 MC Studio Editor 编辑器进行编辑
|
|
58
|
+
|
|
59
|
+
3. **生态集成**
|
|
60
|
+
依托 pip 包管理体系,支持依赖的版本锁定和自动解析
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
## 🚀 快速开始
|
|
64
|
+
|
|
65
|
+
### 前置要求
|
|
66
|
+
- Python ≥ 3.9(游戏与编辑器启动需要 Windows 和 MC Studio)
|
|
67
|
+
- pip ≥ 21.0
|
|
68
|
+
|
|
69
|
+
### 安装
|
|
70
|
+
```bash
|
|
71
|
+
pip install mcpywrap
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 初始化项目
|
|
75
|
+
```bash
|
|
76
|
+
# 首先进入项目目录
|
|
77
|
+
mcpy init
|
|
78
|
+
```
|
|
79
|
+
交互式创建项目结构,自动生成标准的 Mod 框架。
|
|
80
|
+
|
|
81
|
+
### 运行测试
|
|
82
|
+
```bash
|
|
83
|
+
mcpy run
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 🛠 工作流指南
|
|
87
|
+
|
|
88
|
+
### 依赖管理
|
|
89
|
+
| 命令 | 说明 |
|
|
90
|
+
|-------------------------------|---------------------|
|
|
91
|
+
| `mcpy` | 维护项目,将项目安装到系统 site-package 环境 |
|
|
92
|
+
| `mcpy add "package>=1.0"` | 安装并声明 Python 包依赖 |
|
|
93
|
+
| `mcpy add --path ../common` | 直接引用本地 Addon 目录 |
|
|
94
|
+
| `mcpy remove <package>` | 移除依赖 |
|
|
95
|
+
|
|
96
|
+
### 完整命令参考
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
mcpy --help
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### 依赖管理
|
|
103
|
+
| 命令 | 说明 |
|
|
104
|
+
|-------------------------------|---------------------|
|
|
105
|
+
| `mcpy add "package>=1.0"` | 安装成功后保存 Python 包声明 |
|
|
106
|
+
| `mcpy add --path ../common` | 添加本地 Addon 目录,无需初始化或安装该目录 |
|
|
107
|
+
| `mcpy remove <package>` | 从项目配置中删除依赖并可选择卸载 |
|
|
108
|
+
| `mcpy remove --path ../common` | 仅移除本地引用,保留源目录 |
|
|
109
|
+
|
|
110
|
+
### 本地目录依赖
|
|
111
|
+
|
|
112
|
+
主项目仍使用 `pyproject.toml` 管理项目;引用的 Addon 可以是直接从 MCS 导出的目录,**无需 `mcpy init`、无需 `pyproject.toml`,也无需 pip 安装**。
|
|
113
|
+
|
|
114
|
+
```toml
|
|
115
|
+
[project]
|
|
116
|
+
name = "my-addon"
|
|
117
|
+
version = "0.1.0"
|
|
118
|
+
dependencies = ["published-addon>=1.0"]
|
|
119
|
+
|
|
120
|
+
[tool.mcpywrap]
|
|
121
|
+
project_type = "addon"
|
|
122
|
+
target_dir = "./build"
|
|
123
|
+
local_dependencies = [
|
|
124
|
+
"../shared-addon",
|
|
125
|
+
"D:/Minecraft/common-resources",
|
|
126
|
+
]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
有效目录至少包含一个行为包或资源包及其 `manifest.json` 或 `pack_manifest.json`,例如:
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
shared-addon/
|
|
133
|
+
behavior_pack/ # 也支持 behavior_pack_*、BehaviorPack*
|
|
134
|
+
manifest.json
|
|
135
|
+
sharedScript/
|
|
136
|
+
resource_pack/ # 也支持 resource_pack_*、ResourcePack*
|
|
137
|
+
manifest.json
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
第一版不支持把单独的行为包/资源包、地图根目录、普通源码目录作为本地依赖,也不支持同一 Addon 中多个同类型包。不必同时具备行为包和资源包。
|
|
141
|
+
|
|
142
|
+
相对路径相对于**声明它的项目目录**解析,与执行命令前的其他工作目录无关。目标目录存在 `[tool.mcpywrap]` 时,继续读取该项目的 Python 和本地依赖;否则视为叶节点。读取不会初始化、安装或修改目标目录。重复引用按真实路径去重(包含 Windows 大小写和目录链接);循环引用会报告引用链。同名目录使用不同内部标识,避免链接覆盖。
|
|
143
|
+
|
|
144
|
+
```powershell
|
|
145
|
+
mcpy add --path "../共享 Addon"
|
|
146
|
+
mcpy add --path "D:/Minecraft/common-resources"
|
|
147
|
+
mcpy remove --path "../共享 Addon"
|
|
148
|
+
|
|
149
|
+
# 不带参数进入来源选择/直接依赖选择向导
|
|
150
|
+
mcpy add
|
|
151
|
+
mcpy remove
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
CLI 保留传入的相对或绝对写法,不根据包参数猜测路径。`--path` 不能与包参数同时使用;本地移除不接受 `--uninstall`。目录失效后仍可移除声明。非交互环境必须传入参数,否则返回非零退出码。`mcpy init` 的依赖收集也支持两种来源。
|
|
155
|
+
|
|
156
|
+
添加目录时会先验证结构和依赖图,无效或循环引用不会写入配置。其 Python 依赖未安装或版本不满足时,会显示警告及可复制的 `mcpy add "requirement"` 命令,允许保存本地引用,但**不会自动安装**。构建、运行、编辑器启动前会重新完整校验。Python 包仍通过当前工具环境的 pip 安装,安装失败不保存新增声明;环境标记为假的 requirement 不参与当前平台的依赖图,普通 Python 库也不会当成 Addon 加载。
|
|
157
|
+
|
|
158
|
+
### GUI 添加与移除
|
|
159
|
+
|
|
160
|
+
运行 `mcpy ui`,在“添加新依赖”选择“Python 包”或“本地目录”。包模式支持可编辑下拉框及补全,安装在后台执行,完成前禁用冲突操作;失败会保留输入并显示原因。
|
|
161
|
+
|
|
162
|
+
本地模式可输入路径或“浏览目录”,预览解析后的目录、包结构和将保存的路径。默认保存相对路径;跨盘保存绝对路径,也可勾选“保存为绝对路径”。**选择目录本身不保存,点击“添加依赖”才写入配置**。错误输入保留供修改。
|
|
163
|
+
|
|
164
|
+
依赖列表显示来源、声明和不可用状态,详细原因显示在提示中。移除本地依赖的确认框会说明仅移除引用,源目录保留。每次修改后刷新运行包集合,每次启动前重新校验;失效依赖可继续移除。配置更新只影响后续启动,不自动更改正在运行的游戏。
|
|
165
|
+
|
|
166
|
+
### 构建顺序与迁移
|
|
167
|
+
|
|
168
|
+
旧配置无需迁移,省略 `local_dependencies` 等同于空数组。只有本地依赖、没有 Python 包依赖的项目同样支持 `build/run/edit/dev`(地图项目仍不支持 `dev`)。本地引用只用于此工具,**不会自动成为可通过 pip 分发、安装或锁定的依赖**;分发时需自行安排资源和路径。
|
|
169
|
+
|
|
170
|
+
**行为变更:完整构建和增量构建现在都以主项目为最高优先级。** 顺序为子依赖先于引用者;同级先 Python 包列表、再本地列表,各列表按声明顺序处理,后处理者覆盖重复文件/合并键;主项目最后。共享子依赖只处理一次,采用稳定的依赖优先遍历。保留已有 JSON/语言文件合并规则及主项目 manifest。删除高优先级来源文件后,增量构建会恢复低优先级来源内容。
|
|
171
|
+
|
|
172
|
+
构建在清空输出前校验依赖及路径,拒绝输出覆盖源项目/源包或与依赖目录重叠。`dev` 监控主项目和解析到的所有依赖目录,修改依赖声明后需要重启监控。
|
|
173
|
+
|
|
174
|
+
`run/edit` 仍将依赖作为独立包链接/编辑器包路径传递,以上构建覆盖规则不代表游戏引擎自身的资源包加载优先级。Windows 优先使用符号链接,无符号链接权限时可使用目录 junction;复用已有同目标链接,保留其他项目链接,同名冲突明确报错。
|
|
175
|
+
|
|
176
|
+
### 开发验证
|
|
177
|
+
|
|
178
|
+
```powershell
|
|
179
|
+
python -m unittest discover -s tests -v
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
自动化测试使用临时目录、Click、Qt 离屏及安装/启动替身。本机多项目验收脚本另行执行真实 CLI、pip、watchdog,可加 `--game` 启动已安装的 MCS 引擎。请先关闭已有游戏,使用独立环境和一个尚不存在的输出目录:
|
|
183
|
+
|
|
184
|
+
```powershell
|
|
185
|
+
uv venv test/acceptance-venv
|
|
186
|
+
uv pip install --python test/acceptance-venv/Scripts/python.exe -e . pip
|
|
187
|
+
test/acceptance-venv/Scripts/python.exe tests/manual_integration.py --workspace test/my-acceptance --game
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
脚本保留测试项目、构建结果、CLI/pip 日志和 `report.json`;实际游戏验证检查各 Mod 的服务端/客户端加载标记及游戏生成的包 UUID 列表,并清理本次创建的全局链接。测试存档和 `.runtime` 配置保留供复查。游戏验收仅替换日志窗口为 TCP 文件收集器,真实引擎、目录链接和运行配置均使用产品实现。
|
|
191
|
+
|
|
192
|
+
#### 项目初始化与开发
|
|
193
|
+
| 命令 | 说明 |
|
|
194
|
+
|-------------------------------|---------------------|
|
|
195
|
+
| `mcpy init` | 交互式初始化项目,创建基础的包信息及配置 |
|
|
196
|
+
| `mcpy mod` | 向导式创建 Python Mod 基础框架 |
|
|
197
|
+
| `mcpy build` | 构建为 MCStudio 工程 |
|
|
198
|
+
| `mcpy dev` | 使用watch模式,实时构建与热重载 |
|
|
199
|
+
| `mcpy edit` | 使用 MC Studio Editor 编辑器进行编辑 |
|
|
200
|
+
|
|
201
|
+
#### ModSDK与游戏实例
|
|
202
|
+
| 命令 | 说明 |
|
|
203
|
+
|-------------------------------|---------------------|
|
|
204
|
+
| `mcpy modsdk` | 管理网易我的世界ModSDK |
|
|
205
|
+
| `mcpy run` | 游戏实例运行与管理 |
|
|
206
|
+
|
|
207
|
+
#### 发布项目
|
|
208
|
+
| 命令 | 说明 |
|
|
209
|
+
|-------------------------------|---------------------|
|
|
210
|
+
| `mcpy publish` | 发布项目到 PyPI |
|
|
211
|
+
|
|
212
|
+
#### 游戏实例管理详解
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# 启动最新游戏实例
|
|
216
|
+
mcpy run
|
|
217
|
+
|
|
218
|
+
# 创建新的游戏实例
|
|
219
|
+
mcpy run -n
|
|
220
|
+
|
|
221
|
+
# 列出所有可用的游戏实例
|
|
222
|
+
mcpy run -l
|
|
223
|
+
|
|
224
|
+
# 删除指定的游戏实例
|
|
225
|
+
mcpy run -d <实例ID前缀>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## 🤝 参与贡献
|
|
229
|
+
欢迎提交 Issue 和 PR!请先阅读 [贡献指南](CONTRIBUTING.md)。
|
|
230
|
+
|
|
231
|
+
## 开源协议
|
|
232
|
+
[MIT License](LICENSE) © 2025 EaseCation
|
mcpywrap-0.3.0/README.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# 🧰 mcpywrap
|
|
2
|
+
|
|
3
|
+
**《我的世界》中国版 ModSDK 与资源包的全周期管理工具**
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/mcpywrap/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
mcpywrap 是基于 Python 生态的《我的世界》中国版 ModSDK/资源包全周期管理工具,支持依赖管理、语法转换和自动化构建,助力开发者实现高效协作与代码复用。
|
|
9
|
+
|
|
10
|
+
## 🌟 核心特性
|
|
11
|
+
|
|
12
|
+
- 🧩 **模块化开发** - 基于 Addons 维度的依赖管理(基于包管理和依赖的开发与测试流程)
|
|
13
|
+
- 🔄 **现代语法** - 支持 Python3 现代语法特性,提升开发体验
|
|
14
|
+
- 📦 **生态兼容** - 无缝对接 PyPI 生态,支持标准 `pyproject.toml` 配置
|
|
15
|
+
- 🚀 **智能构建** - 一键打包符合 MCStudio 规范的成品 Addons
|
|
16
|
+
- 🔥 **热重载开发** - 实时监控代码变更,支持 MCStudio 热更新
|
|
17
|
+
|
|
18
|
+
## 📖 为何选择此工具?
|
|
19
|
+
|
|
20
|
+
### 传统开发痛点
|
|
21
|
+
- 📜 **代码复用困难** - 通过 **文件拷贝** 导致版本管理混乱
|
|
22
|
+
- 🚧 **协作效率低下** - 多项目 **重复代码** 维护成本高
|
|
23
|
+
- ⚠️ **代码质量** - 缺乏现代开发工具和语法支持
|
|
24
|
+
|
|
25
|
+
### mcpywrap 解决方案
|
|
26
|
+
1. **标准化开发**
|
|
27
|
+
通过 `pyproject.toml` 声明项目元数据和依赖关系,实现真正的模块化开发
|
|
28
|
+
|
|
29
|
+
2. **直接启动测试和编辑**
|
|
30
|
+
- 直接通过 `mcpy run` 启动游戏实例,支持热重载和实时构建,提升开发效率
|
|
31
|
+
- 通过 `mcpy edit` 命令,使用 MC Studio Editor 编辑器进行编辑
|
|
32
|
+
|
|
33
|
+
3. **生态集成**
|
|
34
|
+
依托 pip 包管理体系,支持依赖的版本锁定和自动解析
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
## 🚀 快速开始
|
|
38
|
+
|
|
39
|
+
### 前置要求
|
|
40
|
+
- Python ≥ 3.9(游戏与编辑器启动需要 Windows 和 MC Studio)
|
|
41
|
+
- pip ≥ 21.0
|
|
42
|
+
|
|
43
|
+
### 安装
|
|
44
|
+
```bash
|
|
45
|
+
pip install mcpywrap
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 初始化项目
|
|
49
|
+
```bash
|
|
50
|
+
# 首先进入项目目录
|
|
51
|
+
mcpy init
|
|
52
|
+
```
|
|
53
|
+
交互式创建项目结构,自动生成标准的 Mod 框架。
|
|
54
|
+
|
|
55
|
+
### 运行测试
|
|
56
|
+
```bash
|
|
57
|
+
mcpy run
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 🛠 工作流指南
|
|
61
|
+
|
|
62
|
+
### 依赖管理
|
|
63
|
+
| 命令 | 说明 |
|
|
64
|
+
|-------------------------------|---------------------|
|
|
65
|
+
| `mcpy` | 维护项目,将项目安装到系统 site-package 环境 |
|
|
66
|
+
| `mcpy add "package>=1.0"` | 安装并声明 Python 包依赖 |
|
|
67
|
+
| `mcpy add --path ../common` | 直接引用本地 Addon 目录 |
|
|
68
|
+
| `mcpy remove <package>` | 移除依赖 |
|
|
69
|
+
|
|
70
|
+
### 完整命令参考
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
mcpy --help
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### 依赖管理
|
|
77
|
+
| 命令 | 说明 |
|
|
78
|
+
|-------------------------------|---------------------|
|
|
79
|
+
| `mcpy add "package>=1.0"` | 安装成功后保存 Python 包声明 |
|
|
80
|
+
| `mcpy add --path ../common` | 添加本地 Addon 目录,无需初始化或安装该目录 |
|
|
81
|
+
| `mcpy remove <package>` | 从项目配置中删除依赖并可选择卸载 |
|
|
82
|
+
| `mcpy remove --path ../common` | 仅移除本地引用,保留源目录 |
|
|
83
|
+
|
|
84
|
+
### 本地目录依赖
|
|
85
|
+
|
|
86
|
+
主项目仍使用 `pyproject.toml` 管理项目;引用的 Addon 可以是直接从 MCS 导出的目录,**无需 `mcpy init`、无需 `pyproject.toml`,也无需 pip 安装**。
|
|
87
|
+
|
|
88
|
+
```toml
|
|
89
|
+
[project]
|
|
90
|
+
name = "my-addon"
|
|
91
|
+
version = "0.1.0"
|
|
92
|
+
dependencies = ["published-addon>=1.0"]
|
|
93
|
+
|
|
94
|
+
[tool.mcpywrap]
|
|
95
|
+
project_type = "addon"
|
|
96
|
+
target_dir = "./build"
|
|
97
|
+
local_dependencies = [
|
|
98
|
+
"../shared-addon",
|
|
99
|
+
"D:/Minecraft/common-resources",
|
|
100
|
+
]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
有效目录至少包含一个行为包或资源包及其 `manifest.json` 或 `pack_manifest.json`,例如:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
shared-addon/
|
|
107
|
+
behavior_pack/ # 也支持 behavior_pack_*、BehaviorPack*
|
|
108
|
+
manifest.json
|
|
109
|
+
sharedScript/
|
|
110
|
+
resource_pack/ # 也支持 resource_pack_*、ResourcePack*
|
|
111
|
+
manifest.json
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
第一版不支持把单独的行为包/资源包、地图根目录、普通源码目录作为本地依赖,也不支持同一 Addon 中多个同类型包。不必同时具备行为包和资源包。
|
|
115
|
+
|
|
116
|
+
相对路径相对于**声明它的项目目录**解析,与执行命令前的其他工作目录无关。目标目录存在 `[tool.mcpywrap]` 时,继续读取该项目的 Python 和本地依赖;否则视为叶节点。读取不会初始化、安装或修改目标目录。重复引用按真实路径去重(包含 Windows 大小写和目录链接);循环引用会报告引用链。同名目录使用不同内部标识,避免链接覆盖。
|
|
117
|
+
|
|
118
|
+
```powershell
|
|
119
|
+
mcpy add --path "../共享 Addon"
|
|
120
|
+
mcpy add --path "D:/Minecraft/common-resources"
|
|
121
|
+
mcpy remove --path "../共享 Addon"
|
|
122
|
+
|
|
123
|
+
# 不带参数进入来源选择/直接依赖选择向导
|
|
124
|
+
mcpy add
|
|
125
|
+
mcpy remove
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
CLI 保留传入的相对或绝对写法,不根据包参数猜测路径。`--path` 不能与包参数同时使用;本地移除不接受 `--uninstall`。目录失效后仍可移除声明。非交互环境必须传入参数,否则返回非零退出码。`mcpy init` 的依赖收集也支持两种来源。
|
|
129
|
+
|
|
130
|
+
添加目录时会先验证结构和依赖图,无效或循环引用不会写入配置。其 Python 依赖未安装或版本不满足时,会显示警告及可复制的 `mcpy add "requirement"` 命令,允许保存本地引用,但**不会自动安装**。构建、运行、编辑器启动前会重新完整校验。Python 包仍通过当前工具环境的 pip 安装,安装失败不保存新增声明;环境标记为假的 requirement 不参与当前平台的依赖图,普通 Python 库也不会当成 Addon 加载。
|
|
131
|
+
|
|
132
|
+
### GUI 添加与移除
|
|
133
|
+
|
|
134
|
+
运行 `mcpy ui`,在“添加新依赖”选择“Python 包”或“本地目录”。包模式支持可编辑下拉框及补全,安装在后台执行,完成前禁用冲突操作;失败会保留输入并显示原因。
|
|
135
|
+
|
|
136
|
+
本地模式可输入路径或“浏览目录”,预览解析后的目录、包结构和将保存的路径。默认保存相对路径;跨盘保存绝对路径,也可勾选“保存为绝对路径”。**选择目录本身不保存,点击“添加依赖”才写入配置**。错误输入保留供修改。
|
|
137
|
+
|
|
138
|
+
依赖列表显示来源、声明和不可用状态,详细原因显示在提示中。移除本地依赖的确认框会说明仅移除引用,源目录保留。每次修改后刷新运行包集合,每次启动前重新校验;失效依赖可继续移除。配置更新只影响后续启动,不自动更改正在运行的游戏。
|
|
139
|
+
|
|
140
|
+
### 构建顺序与迁移
|
|
141
|
+
|
|
142
|
+
旧配置无需迁移,省略 `local_dependencies` 等同于空数组。只有本地依赖、没有 Python 包依赖的项目同样支持 `build/run/edit/dev`(地图项目仍不支持 `dev`)。本地引用只用于此工具,**不会自动成为可通过 pip 分发、安装或锁定的依赖**;分发时需自行安排资源和路径。
|
|
143
|
+
|
|
144
|
+
**行为变更:完整构建和增量构建现在都以主项目为最高优先级。** 顺序为子依赖先于引用者;同级先 Python 包列表、再本地列表,各列表按声明顺序处理,后处理者覆盖重复文件/合并键;主项目最后。共享子依赖只处理一次,采用稳定的依赖优先遍历。保留已有 JSON/语言文件合并规则及主项目 manifest。删除高优先级来源文件后,增量构建会恢复低优先级来源内容。
|
|
145
|
+
|
|
146
|
+
构建在清空输出前校验依赖及路径,拒绝输出覆盖源项目/源包或与依赖目录重叠。`dev` 监控主项目和解析到的所有依赖目录,修改依赖声明后需要重启监控。
|
|
147
|
+
|
|
148
|
+
`run/edit` 仍将依赖作为独立包链接/编辑器包路径传递,以上构建覆盖规则不代表游戏引擎自身的资源包加载优先级。Windows 优先使用符号链接,无符号链接权限时可使用目录 junction;复用已有同目标链接,保留其他项目链接,同名冲突明确报错。
|
|
149
|
+
|
|
150
|
+
### 开发验证
|
|
151
|
+
|
|
152
|
+
```powershell
|
|
153
|
+
python -m unittest discover -s tests -v
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
自动化测试使用临时目录、Click、Qt 离屏及安装/启动替身。本机多项目验收脚本另行执行真实 CLI、pip、watchdog,可加 `--game` 启动已安装的 MCS 引擎。请先关闭已有游戏,使用独立环境和一个尚不存在的输出目录:
|
|
157
|
+
|
|
158
|
+
```powershell
|
|
159
|
+
uv venv test/acceptance-venv
|
|
160
|
+
uv pip install --python test/acceptance-venv/Scripts/python.exe -e . pip
|
|
161
|
+
test/acceptance-venv/Scripts/python.exe tests/manual_integration.py --workspace test/my-acceptance --game
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
脚本保留测试项目、构建结果、CLI/pip 日志和 `report.json`;实际游戏验证检查各 Mod 的服务端/客户端加载标记及游戏生成的包 UUID 列表,并清理本次创建的全局链接。测试存档和 `.runtime` 配置保留供复查。游戏验收仅替换日志窗口为 TCP 文件收集器,真实引擎、目录链接和运行配置均使用产品实现。
|
|
165
|
+
|
|
166
|
+
#### 项目初始化与开发
|
|
167
|
+
| 命令 | 说明 |
|
|
168
|
+
|-------------------------------|---------------------|
|
|
169
|
+
| `mcpy init` | 交互式初始化项目,创建基础的包信息及配置 |
|
|
170
|
+
| `mcpy mod` | 向导式创建 Python Mod 基础框架 |
|
|
171
|
+
| `mcpy build` | 构建为 MCStudio 工程 |
|
|
172
|
+
| `mcpy dev` | 使用watch模式,实时构建与热重载 |
|
|
173
|
+
| `mcpy edit` | 使用 MC Studio Editor 编辑器进行编辑 |
|
|
174
|
+
|
|
175
|
+
#### ModSDK与游戏实例
|
|
176
|
+
| 命令 | 说明 |
|
|
177
|
+
|-------------------------------|---------------------|
|
|
178
|
+
| `mcpy modsdk` | 管理网易我的世界ModSDK |
|
|
179
|
+
| `mcpy run` | 游戏实例运行与管理 |
|
|
180
|
+
|
|
181
|
+
#### 发布项目
|
|
182
|
+
| 命令 | 说明 |
|
|
183
|
+
|-------------------------------|---------------------|
|
|
184
|
+
| `mcpy publish` | 发布项目到 PyPI |
|
|
185
|
+
|
|
186
|
+
#### 游戏实例管理详解
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
# 启动最新游戏实例
|
|
190
|
+
mcpy run
|
|
191
|
+
|
|
192
|
+
# 创建新的游戏实例
|
|
193
|
+
mcpy run -n
|
|
194
|
+
|
|
195
|
+
# 列出所有可用的游戏实例
|
|
196
|
+
mcpy run -l
|
|
197
|
+
|
|
198
|
+
# 删除指定的游戏实例
|
|
199
|
+
mcpy run -d <实例ID前缀>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## 🤝 参与贡献
|
|
203
|
+
欢迎提交 Issue 和 PR!请先阅读 [贡献指南](CONTRIBUTING.md)。
|
|
204
|
+
|
|
205
|
+
## 开源协议
|
|
206
|
+
[MIT License](LICENSE) © 2025 EaseCation
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# 发布流程
|
|
2
|
+
|
|
3
|
+
主分支和 PR 运行 Windows Python 3.9、3.12、3.14 的自动化测试。通过后构建 wheel/sdist、运行严格元数据检查、检查产物内容,并在独立环境安装 wheel 验证 CLI 和模块导入。
|
|
4
|
+
|
|
5
|
+
发布凭据使用 PyPI Trusted Publishing,不在仓库或工作流中保存长期 API token。在 PyPI 项目 `mcpywrap` 的 Publishing 设置添加 GitHub publisher:
|
|
6
|
+
|
|
7
|
+
| 字段 | 值 |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Owner | `EaseCation` |
|
|
10
|
+
| Repository | `mcpywrap` |
|
|
11
|
+
| Workflow filename | `release.yml` |
|
|
12
|
+
| Environment | `pypi` |
|
|
13
|
+
|
|
14
|
+
每次发布:
|
|
15
|
+
|
|
16
|
+
1. 同步修改 `pyproject.toml` 和 `mcpywrap/__init__.py` 中的版本,更新 CHANGELOG。
|
|
17
|
+
2. 将通过本地验证的提交推送到 `main`,等待 CI 全部通过。
|
|
18
|
+
3. 在该提交创建匹配版本的 `vX.Y.Z` 标签并推送,触发 CI 再次检查及发布。标签版本必须匹配元数据,且提交必须位于 `main` 历史上。
|
|
19
|
+
4. 检查 Actions 的 publish job 和 PyPI 新版本文件。发布失败时先排除原因;若是首次配置 publisher 尚未完成,可完成 PyPI 配置后重跑失败任务。
|
|
20
|
+
|
|
21
|
+
也可手动运行 `release.yml`:选择 `main` 并设置 `publish=true`。默认手动运行只验证,不发布。发布只允许标签推送或显式开启发布的 main 手动运行,PR 和普通 main 推送均不会上传 PyPI。
|
|
22
|
+
|
|
23
|
+
不要覆盖已有 PyPI 版本。发布动作开启 PyPI provenance attestations;各第三方 Action 固定到已核实的提交。GitHub `pypi` environment 与 PyPI publisher 的 environment 必须一致。
|
|
@@ -49,12 +49,11 @@ class AddonsPack(object):
|
|
|
49
49
|
|
|
50
50
|
def __init__(self, pkg_name, path, is_origin=False):
|
|
51
51
|
self.pkg_name = pkg_name
|
|
52
|
-
self.path = path
|
|
52
|
+
self.path = os.path.abspath(path)
|
|
53
53
|
self.is_origin = is_origin
|
|
54
54
|
self.behavior_pack_dir = None
|
|
55
55
|
self.resource_pack_dir = None
|
|
56
56
|
# 进入此目录,查找内部的行为包和资源包的路径
|
|
57
|
-
os.chdir(self.path)
|
|
58
57
|
for item in os.listdir(self.path):
|
|
59
58
|
item_path = os.path.join(self.path, item)
|
|
60
59
|
if os.path.isdir(item_path):
|
|
@@ -280,25 +279,15 @@ class AddonsPack(object):
|
|
|
280
279
|
包类型: "behavior" 或 "resource"
|
|
281
280
|
相对路径: 在包中的相对路径,如果不在包中则为None
|
|
282
281
|
"""
|
|
283
|
-
#
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
parts = file_path.split(os.sep)
|
|
295
|
-
for i, part in enumerate(parts):
|
|
296
|
-
if (is_behavior and ("behavior_pack" in part.lower() or "behaviorpack" in part.lower())) or \
|
|
297
|
-
(is_resource and ("resource_pack" in part.lower() or "resourcepack" in part.lower())):
|
|
298
|
-
if i + 1 < len(parts):
|
|
299
|
-
rel_path = os.path.join(*parts[i+1:])
|
|
300
|
-
return True, pack_type, rel_path
|
|
301
|
-
else:
|
|
302
|
-
return True, pack_type, ""
|
|
303
|
-
|
|
282
|
+
# Watchdog 可能返回短路径或目录链接路径;保留相对文件名大小写。
|
|
283
|
+
absolute = os.path.realpath(file_path)
|
|
284
|
+
for kind, folder in (("behavior", self.behavior_pack_dir), ("resource", self.resource_pack_dir)):
|
|
285
|
+
if not folder:
|
|
286
|
+
continue
|
|
287
|
+
folder = os.path.realpath(folder)
|
|
288
|
+
try:
|
|
289
|
+
if os.path.commonpath([os.path.normcase(absolute), os.path.normcase(folder)]) == os.path.normcase(folder):
|
|
290
|
+
return True, kind, os.path.relpath(absolute, folder)
|
|
291
|
+
except ValueError:
|
|
292
|
+
continue
|
|
304
293
|
return False, None, None
|
|
@@ -21,25 +21,23 @@ class MapPack(object):
|
|
|
21
21
|
def __init__(self, pkg_name: str, path: str):
|
|
22
22
|
self.pkg_name = pkg_name
|
|
23
23
|
self.path = path
|
|
24
|
+
self.behavior_packs = []
|
|
25
|
+
self.resource_packs = []
|
|
24
26
|
|
|
25
27
|
# 读取配置文件
|
|
26
28
|
self.behavior_packs_dir = os.path.join(self.path, "behavior_packs")
|
|
27
29
|
self.resource_packs_dir = os.path.join(self.path, "resource_packs")
|
|
28
30
|
|
|
29
|
-
if not os.path.exists(self.behavior_packs_dir):
|
|
30
|
-
os.makedirs(self.behavior_packs_dir)
|
|
31
31
|
|
|
32
32
|
# 遍历行为包目录
|
|
33
|
-
for pack in os.listdir(self.behavior_packs_dir):
|
|
33
|
+
for pack in sorted(os.listdir(self.behavior_packs_dir)) if os.path.isdir(self.behavior_packs_dir) else []:
|
|
34
34
|
pack_path = os.path.join(self.behavior_packs_dir, pack)
|
|
35
35
|
if os.path.isdir(pack_path):
|
|
36
36
|
self.behavior_packs.append(pack_path)
|
|
37
37
|
|
|
38
|
-
if not os.path.exists(self.resource_packs_dir):
|
|
39
|
-
os.makedirs(self.resource_packs_dir)
|
|
40
38
|
|
|
41
39
|
# 遍历资源包目录
|
|
42
|
-
for pack in os.listdir(self.resource_packs_dir):
|
|
40
|
+
for pack in sorted(os.listdir(self.resource_packs_dir)) if os.path.isdir(self.resource_packs_dir) else []:
|
|
43
41
|
pack_path = os.path.join(self.resource_packs_dir, pack)
|
|
44
42
|
if os.path.isdir(pack_path):
|
|
45
43
|
self.resource_packs.append(pack_path)
|