PyLibMS 4.3.3__tar.gz → 5.0.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.
- {pylibms-4.3.3 → pylibms-5.0.0}/PKG-INFO +20 -27
- {pylibms-4.3.3 → pylibms-5.0.0}/PyLibMS.egg-info/PKG-INFO +20 -27
- {pylibms-4.3.3 → pylibms-5.0.0}/PyLibMS.egg-info/SOURCES.txt +2 -2
- {pylibms-4.3.3 → pylibms-5.0.0}/README.md +18 -25
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/common/field/io.py +13 -15
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/common/field/lms_datatype.py +35 -42
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/common/field/lms_field.py +34 -30
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/common/lms_constants.py +1 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/common/stream/section.py +9 -13
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/fileio/io.py +62 -63
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/flowchart/definitions/node.py +53 -21
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/flowchart/flw3.py +26 -8
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/flowchart/msbf.py +69 -54
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/flowchart/msbfio.py +22 -15
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/lms_messagetext.py +15 -13
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/msbt.py +39 -21
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/msbtio.py +51 -18
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/tag/io/param_io.py +11 -8
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/tag/io/tag_io.py +12 -12
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/tag/lms_tag.py +19 -20
- pylibms-5.0.0/lms/project/definitions/attribute.py +32 -0
- pylibms-5.0.0/lms/project/definitions/tag.py +137 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/project/msbp.py +12 -12
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/project/msbpread.py +26 -28
- pylibms-5.0.0/lms/project/section/ali2.py +22 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/project/section/ati2.py +5 -6
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/project/section/clr1.py +1 -1
- pylibms-5.0.0/lms/project/section/string.py +16 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/project/section/syl3.py +4 -4
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/project/section/tag2.py +7 -5
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/project/section/tgg2.py +6 -4
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/project/section/tgp2.py +10 -8
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/titleconfig/config.py +38 -110
- pylibms-5.0.0/lms/titleconfig/definitions/__init__.py +0 -0
- pylibms-5.0.0/lms/titleconfig/definitions/attribute.py +28 -0
- pylibms-5.0.0/lms/titleconfig/definitions/field.py +32 -0
- pylibms-5.0.0/lms/titleconfig/definitions/nodes.py +151 -0
- pylibms-5.0.0/lms/titleconfig/definitions/tags.py +90 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/pyproject.toml +2 -2
- pylibms-4.3.3/lms/flowchart/definitions/flowchart.py +0 -100
- pylibms-4.3.3/lms/project/definitions/attribute.py +0 -24
- pylibms-4.3.3/lms/project/definitions/tag.py +0 -93
- pylibms-4.3.3/lms/project/section/ali2.py +0 -19
- pylibms-4.3.3/lms/project/section/string.py +0 -18
- pylibms-4.3.3/lms/titleconfig/definitions/attribute.py +0 -12
- pylibms-4.3.3/lms/titleconfig/definitions/nodes.py +0 -147
- pylibms-4.3.3/lms/titleconfig/definitions/tags.py +0 -93
- pylibms-4.3.3/lms/titleconfig/definitions/value.py +0 -18
- {pylibms-4.3.3 → pylibms-5.0.0}/LICENSE +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/MANIFEST.in +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/PyLibMS.egg-info/dependency_links.txt +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/PyLibMS.egg-info/requires.txt +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/PyLibMS.egg-info/top_level.txt +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/common/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/common/field/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/common/lms_exceptions.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/common/lms_fileinfo.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/common/stream/fileinfo.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/common/stream/hashtable.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/fileio/encoding.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/flowchart/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/flowchart/definitions/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/flowchart/definitions/lms_nodeexceptions.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/flowchart/definitions/node_type.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/definitions/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/definitions/field/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/msbtentry.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/section/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/section/atr1.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/section/nli1.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/section/tsy1.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/section/txt2.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/tag/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/message/tag/lms_tagexceptions.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/project/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/project/definitions/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/project/definitions/color.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/project/definitions/style.py +0 -0
- /pylibms-4.3.3/lms/titleconfig/__init__.py → /pylibms-5.0.0/lms/py.typed +0 -0
- {pylibms-4.3.3/lms/titleconfig/definitions → pylibms-5.0.0/lms/titleconfig}/__init__.py +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/titleconfig/presets/Badge Arcade.yaml +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/titleconfig/presets/Brain Age Concentration Training.yaml +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/titleconfig/presets/Kirby Planet Robobot.yaml +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/titleconfig/presets/Super Mario 3D Land.yaml +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/titleconfig/presets/Super Mario 3D World + Bowsers Fury.yaml +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/titleconfig/presets/Super Mario Odyssey.yaml +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/titleconfig/presets/The Legend of Zelda Echos of Wisdom.yaml +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/titleconfig/presets/The Legend of Zelda a Link Between Worlds.yaml +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/lms/titleconfig/presets/Tomodachi Life Living The Dream.yaml +0 -0
- {pylibms-4.3.3 → pylibms-5.0.0}/setup.cfg +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyLibMS
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0.0
|
|
4
4
|
Summary: Python library built for the libMessageStudio (LMS) proprietary file formats from Nintendo. Supports MSBT, MSBP, and MSBF.
|
|
5
5
|
Author: AbdyyEee
|
|
6
6
|
License-Expression: MIT
|
|
7
|
-
Project-URL: Documentation, https://github.com/AbdyyEee/PylibMS/wiki
|
|
8
7
|
Project-URL: Repository, https://github.com/AbdyyEee/PylibMS
|
|
8
|
+
Project-URL: Documentation, https://github.com/AbdyyEee/PylibMS/wiki
|
|
9
9
|
Keywords: nintendo,msbt,message text,msbp,message project,msbf,message flowchart,flw3,modding,libmessagestudio
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.10
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -30,11 +30,11 @@ formats from Nintendo.
|
|
|
30
30
|
|
|
31
31
|
The following is supported:
|
|
32
32
|
|
|
33
|
-
| Format | Read | Write |
|
|
33
|
+
| Format | Read | Write | Support |
|
|
34
34
|
|--------|------|-------|---------------------------------------------------------------------------------------------------------------------------------------------|
|
|
35
|
-
| `MSBT` | ✅ | ✅ | Support for
|
|
36
|
-
| `MSBF` | ✅ | ✅ | Support for custom node definitions, attaching names and descriptions to nodes. Altering parameter datatypes for flexibility between games. |
|
|
37
|
-
| `MSBP` | ✅ | ❌ |
|
|
35
|
+
| `MSBT` | ✅ | ✅ | 1:1 Reading and writing Support for majority of sections. Full attribute (`ATR1`) decoding with configurations. Tag decoding 1:1 with the official Nintendo `.mstxt` file format. |
|
|
36
|
+
| `MSBF` | ✅ | ✅ | 1:1 Reading and writing flowcharts (`FLW3`). Support for custom node definitions, attaching names and descriptions to nodes. Altering parameter datatypes for flexibility between games. |
|
|
37
|
+
| `MSBP` | ✅ | ❌ | Viewing all MSBP relevant metadata and generating configuration files for use with `MSBT` files. |
|
|
38
38
|
|
|
39
39
|
This library is designed to support LMS revision >=3.0. These include files generated for late **Wii** titles,
|
|
40
40
|
**Nintendo 3DS**, **Wii U**, **Mobile**, **Nintendo Switch** and **Nintendo Switch 2** games.
|
|
@@ -45,46 +45,31 @@ Simple preview of the library is below. See [the wiki](https://github.com/AbdyyE
|
|
|
45
45
|
and examples.
|
|
46
46
|
|
|
47
47
|
## Reading
|
|
48
|
-
|
|
49
|
-
### MSBT
|
|
50
|
-
|
|
51
48
|
```py
|
|
49
|
+
# MSBT
|
|
52
50
|
from lms.message.msbtio import read_msbt_path
|
|
53
51
|
|
|
54
52
|
msbt = read_msbt_path("Text.msbt")
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### MSBP
|
|
58
53
|
|
|
59
|
-
|
|
54
|
+
# MSBP
|
|
60
55
|
from lms.project.msbpread import read_msbp_path
|
|
61
56
|
|
|
62
57
|
msbp = read_msbp_path("Project.msbp")
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### MSBF
|
|
66
58
|
|
|
67
|
-
|
|
59
|
+
# MSBF
|
|
68
60
|
from lms.flowchart.msbfio import read_msbf_path
|
|
69
61
|
|
|
70
62
|
msbf = read_msbf_path("Flowchart.msbf")
|
|
71
63
|
```
|
|
72
64
|
|
|
73
65
|
## Writing
|
|
74
|
-
|
|
75
|
-
There is no writing for `MSBP` files as most of the time it acts as leftover metadata and not actually loaded by games.
|
|
76
|
-
|
|
77
|
-
### MSBT
|
|
78
|
-
|
|
79
66
|
```py
|
|
67
|
+
# MSBT
|
|
80
68
|
from lms.message.msbtio import write_msbt_path
|
|
81
69
|
|
|
82
70
|
write_msbt_path("Out_text.msbt")
|
|
83
|
-
```
|
|
84
71
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
```py
|
|
72
|
+
# MSBF
|
|
88
73
|
from lms.flowchart.msbfio import write_msbf_path
|
|
89
74
|
|
|
90
75
|
write_msbf_path("Out_Flowchart.msbf")
|
|
@@ -114,8 +99,16 @@ cd PyLibMS
|
|
|
114
99
|
pip install -e .
|
|
115
100
|
```
|
|
116
101
|
|
|
117
|
-
#
|
|
102
|
+
# AI Disclaimer
|
|
103
|
+
Code in this library was written by me. AI was utilized occasionally when fit and always reviewed by me.
|
|
104
|
+
|
|
105
|
+
`MSBT`: Only usage of AI was for control tag regex formats and for understanding implementing string importing with `re`.
|
|
106
|
+
|
|
107
|
+
`MSBP`: AI was not utilized anywhere.
|
|
118
108
|
|
|
109
|
+
`MSBF`: AI was only utilized for the `LMS_BaseNode.get_descendents` function and for consultation for ways to improve the API.
|
|
110
|
+
|
|
111
|
+
# Credits & Sources
|
|
119
112
|
* [SS-Decomp](https://github.com/zeldaret/ss): Referenced some parts of their MSBF decomp when adding the format
|
|
120
113
|
to [Nintendo-File-Formats](https://nintendo-formats.com) and this library.
|
|
121
114
|
* [Nintendo-File-Formats](https://nintendo-formats.com) by Kinnay: For existing information on the MSBT and MSBP file
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyLibMS
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0.0
|
|
4
4
|
Summary: Python library built for the libMessageStudio (LMS) proprietary file formats from Nintendo. Supports MSBT, MSBP, and MSBF.
|
|
5
5
|
Author: AbdyyEee
|
|
6
6
|
License-Expression: MIT
|
|
7
|
-
Project-URL: Documentation, https://github.com/AbdyyEee/PylibMS/wiki
|
|
8
7
|
Project-URL: Repository, https://github.com/AbdyyEee/PylibMS
|
|
8
|
+
Project-URL: Documentation, https://github.com/AbdyyEee/PylibMS/wiki
|
|
9
9
|
Keywords: nintendo,msbt,message text,msbp,message project,msbf,message flowchart,flw3,modding,libmessagestudio
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.10
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -30,11 +30,11 @@ formats from Nintendo.
|
|
|
30
30
|
|
|
31
31
|
The following is supported:
|
|
32
32
|
|
|
33
|
-
| Format | Read | Write |
|
|
33
|
+
| Format | Read | Write | Support |
|
|
34
34
|
|--------|------|-------|---------------------------------------------------------------------------------------------------------------------------------------------|
|
|
35
|
-
| `MSBT` | ✅ | ✅ | Support for
|
|
36
|
-
| `MSBF` | ✅ | ✅ | Support for custom node definitions, attaching names and descriptions to nodes. Altering parameter datatypes for flexibility between games. |
|
|
37
|
-
| `MSBP` | ✅ | ❌ |
|
|
35
|
+
| `MSBT` | ✅ | ✅ | 1:1 Reading and writing Support for majority of sections. Full attribute (`ATR1`) decoding with configurations. Tag decoding 1:1 with the official Nintendo `.mstxt` file format. |
|
|
36
|
+
| `MSBF` | ✅ | ✅ | 1:1 Reading and writing flowcharts (`FLW3`). Support for custom node definitions, attaching names and descriptions to nodes. Altering parameter datatypes for flexibility between games. |
|
|
37
|
+
| `MSBP` | ✅ | ❌ | Viewing all MSBP relevant metadata and generating configuration files for use with `MSBT` files. |
|
|
38
38
|
|
|
39
39
|
This library is designed to support LMS revision >=3.0. These include files generated for late **Wii** titles,
|
|
40
40
|
**Nintendo 3DS**, **Wii U**, **Mobile**, **Nintendo Switch** and **Nintendo Switch 2** games.
|
|
@@ -45,46 +45,31 @@ Simple preview of the library is below. See [the wiki](https://github.com/AbdyyE
|
|
|
45
45
|
and examples.
|
|
46
46
|
|
|
47
47
|
## Reading
|
|
48
|
-
|
|
49
|
-
### MSBT
|
|
50
|
-
|
|
51
48
|
```py
|
|
49
|
+
# MSBT
|
|
52
50
|
from lms.message.msbtio import read_msbt_path
|
|
53
51
|
|
|
54
52
|
msbt = read_msbt_path("Text.msbt")
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### MSBP
|
|
58
53
|
|
|
59
|
-
|
|
54
|
+
# MSBP
|
|
60
55
|
from lms.project.msbpread import read_msbp_path
|
|
61
56
|
|
|
62
57
|
msbp = read_msbp_path("Project.msbp")
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### MSBF
|
|
66
58
|
|
|
67
|
-
|
|
59
|
+
# MSBF
|
|
68
60
|
from lms.flowchart.msbfio import read_msbf_path
|
|
69
61
|
|
|
70
62
|
msbf = read_msbf_path("Flowchart.msbf")
|
|
71
63
|
```
|
|
72
64
|
|
|
73
65
|
## Writing
|
|
74
|
-
|
|
75
|
-
There is no writing for `MSBP` files as most of the time it acts as leftover metadata and not actually loaded by games.
|
|
76
|
-
|
|
77
|
-
### MSBT
|
|
78
|
-
|
|
79
66
|
```py
|
|
67
|
+
# MSBT
|
|
80
68
|
from lms.message.msbtio import write_msbt_path
|
|
81
69
|
|
|
82
70
|
write_msbt_path("Out_text.msbt")
|
|
83
|
-
```
|
|
84
71
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
```py
|
|
72
|
+
# MSBF
|
|
88
73
|
from lms.flowchart.msbfio import write_msbf_path
|
|
89
74
|
|
|
90
75
|
write_msbf_path("Out_Flowchart.msbf")
|
|
@@ -114,8 +99,16 @@ cd PyLibMS
|
|
|
114
99
|
pip install -e .
|
|
115
100
|
```
|
|
116
101
|
|
|
117
|
-
#
|
|
102
|
+
# AI Disclaimer
|
|
103
|
+
Code in this library was written by me. AI was utilized occasionally when fit and always reviewed by me.
|
|
104
|
+
|
|
105
|
+
`MSBT`: Only usage of AI was for control tag regex formats and for understanding implementing string importing with `re`.
|
|
106
|
+
|
|
107
|
+
`MSBP`: AI was not utilized anywhere.
|
|
118
108
|
|
|
109
|
+
`MSBF`: AI was only utilized for the `LMS_BaseNode.get_descendents` function and for consultation for ways to improve the API.
|
|
110
|
+
|
|
111
|
+
# Credits & Sources
|
|
119
112
|
* [SS-Decomp](https://github.com/zeldaret/ss): Referenced some parts of their MSBF decomp when adding the format
|
|
120
113
|
to [Nintendo-File-Formats](https://nintendo-formats.com) and this library.
|
|
121
114
|
* [Nintendo-File-Formats](https://nintendo-formats.com) by Kinnay: For existing information on the MSBT and MSBP file
|
|
@@ -8,6 +8,7 @@ PyLibMS.egg-info/dependency_links.txt
|
|
|
8
8
|
PyLibMS.egg-info/requires.txt
|
|
9
9
|
PyLibMS.egg-info/top_level.txt
|
|
10
10
|
lms/__init__.py
|
|
11
|
+
lms/py.typed
|
|
11
12
|
lms/common/__init__.py
|
|
12
13
|
lms/common/lms_constants.py
|
|
13
14
|
lms/common/lms_exceptions.py
|
|
@@ -26,7 +27,6 @@ lms/flowchart/flw3.py
|
|
|
26
27
|
lms/flowchart/msbf.py
|
|
27
28
|
lms/flowchart/msbfio.py
|
|
28
29
|
lms/flowchart/definitions/__init__.py
|
|
29
|
-
lms/flowchart/definitions/flowchart.py
|
|
30
30
|
lms/flowchart/definitions/lms_nodeexceptions.py
|
|
31
31
|
lms/flowchart/definitions/node.py
|
|
32
32
|
lms/flowchart/definitions/node_type.py
|
|
@@ -67,9 +67,9 @@ lms/titleconfig/__init__.py
|
|
|
67
67
|
lms/titleconfig/config.py
|
|
68
68
|
lms/titleconfig/definitions/__init__.py
|
|
69
69
|
lms/titleconfig/definitions/attribute.py
|
|
70
|
+
lms/titleconfig/definitions/field.py
|
|
70
71
|
lms/titleconfig/definitions/nodes.py
|
|
71
72
|
lms/titleconfig/definitions/tags.py
|
|
72
|
-
lms/titleconfig/definitions/value.py
|
|
73
73
|
lms/titleconfig/presets/Badge Arcade.yaml
|
|
74
74
|
lms/titleconfig/presets/Brain Age Concentration Training.yaml
|
|
75
75
|
lms/titleconfig/presets/Kirby Planet Robobot.yaml
|
|
@@ -9,11 +9,11 @@ formats from Nintendo.
|
|
|
9
9
|
|
|
10
10
|
The following is supported:
|
|
11
11
|
|
|
12
|
-
| Format | Read | Write |
|
|
12
|
+
| Format | Read | Write | Support |
|
|
13
13
|
|--------|------|-------|---------------------------------------------------------------------------------------------------------------------------------------------|
|
|
14
|
-
| `MSBT` | ✅ | ✅ | Support for
|
|
15
|
-
| `MSBF` | ✅ | ✅ | Support for custom node definitions, attaching names and descriptions to nodes. Altering parameter datatypes for flexibility between games. |
|
|
16
|
-
| `MSBP` | ✅ | ❌ |
|
|
14
|
+
| `MSBT` | ✅ | ✅ | 1:1 Reading and writing Support for majority of sections. Full attribute (`ATR1`) decoding with configurations. Tag decoding 1:1 with the official Nintendo `.mstxt` file format. |
|
|
15
|
+
| `MSBF` | ✅ | ✅ | 1:1 Reading and writing flowcharts (`FLW3`). Support for custom node definitions, attaching names and descriptions to nodes. Altering parameter datatypes for flexibility between games. |
|
|
16
|
+
| `MSBP` | ✅ | ❌ | Viewing all MSBP relevant metadata and generating configuration files for use with `MSBT` files. |
|
|
17
17
|
|
|
18
18
|
This library is designed to support LMS revision >=3.0. These include files generated for late **Wii** titles,
|
|
19
19
|
**Nintendo 3DS**, **Wii U**, **Mobile**, **Nintendo Switch** and **Nintendo Switch 2** games.
|
|
@@ -24,46 +24,31 @@ Simple preview of the library is below. See [the wiki](https://github.com/AbdyyE
|
|
|
24
24
|
and examples.
|
|
25
25
|
|
|
26
26
|
## Reading
|
|
27
|
-
|
|
28
|
-
### MSBT
|
|
29
|
-
|
|
30
27
|
```py
|
|
28
|
+
# MSBT
|
|
31
29
|
from lms.message.msbtio import read_msbt_path
|
|
32
30
|
|
|
33
31
|
msbt = read_msbt_path("Text.msbt")
|
|
34
|
-
```
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
```py
|
|
33
|
+
# MSBP
|
|
39
34
|
from lms.project.msbpread import read_msbp_path
|
|
40
35
|
|
|
41
36
|
msbp = read_msbp_path("Project.msbp")
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### MSBF
|
|
45
37
|
|
|
46
|
-
|
|
38
|
+
# MSBF
|
|
47
39
|
from lms.flowchart.msbfio import read_msbf_path
|
|
48
40
|
|
|
49
41
|
msbf = read_msbf_path("Flowchart.msbf")
|
|
50
42
|
```
|
|
51
43
|
|
|
52
44
|
## Writing
|
|
53
|
-
|
|
54
|
-
There is no writing for `MSBP` files as most of the time it acts as leftover metadata and not actually loaded by games.
|
|
55
|
-
|
|
56
|
-
### MSBT
|
|
57
|
-
|
|
58
45
|
```py
|
|
46
|
+
# MSBT
|
|
59
47
|
from lms.message.msbtio import write_msbt_path
|
|
60
48
|
|
|
61
49
|
write_msbt_path("Out_text.msbt")
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### MSBF
|
|
65
50
|
|
|
66
|
-
|
|
51
|
+
# MSBF
|
|
67
52
|
from lms.flowchart.msbfio import write_msbf_path
|
|
68
53
|
|
|
69
54
|
write_msbf_path("Out_Flowchart.msbf")
|
|
@@ -93,8 +78,16 @@ cd PyLibMS
|
|
|
93
78
|
pip install -e .
|
|
94
79
|
```
|
|
95
80
|
|
|
96
|
-
#
|
|
81
|
+
# AI Disclaimer
|
|
82
|
+
Code in this library was written by me. AI was utilized occasionally when fit and always reviewed by me.
|
|
97
83
|
|
|
84
|
+
`MSBT`: Only usage of AI was for control tag regex formats and for understanding implementing string importing with `re`.
|
|
85
|
+
|
|
86
|
+
`MSBP`: AI was not utilized anywhere.
|
|
87
|
+
|
|
88
|
+
`MSBF`: AI was only utilized for the `LMS_BaseNode.get_descendents` function and for consultation for ways to improve the API.
|
|
89
|
+
|
|
90
|
+
# Credits & Sources
|
|
98
91
|
* [SS-Decomp](https://github.com/zeldaret/ss): Referenced some parts of their MSBF decomp when adding the format
|
|
99
92
|
to [Nintendo-File-Formats](https://nintendo-formats.com) and this library.
|
|
100
93
|
* [Nintendo-File-Formats](https://nintendo-formats.com) by Kinnay: For existing information on the MSBT and MSBP file
|
|
@@ -4,18 +4,18 @@ from lms.common.field.lms_datatype import (
|
|
|
4
4
|
LMS_DataType,
|
|
5
5
|
is_bool_datatype,
|
|
6
6
|
is_bytes_datatype,
|
|
7
|
-
|
|
7
|
+
is_enum_datatype,
|
|
8
8
|
is_number_datatype,
|
|
9
9
|
)
|
|
10
10
|
from lms.common.field.lms_field import LMS_Field
|
|
11
11
|
from lms.fileio.io import FileReader, FileWriter
|
|
12
|
-
from lms.titleconfig.definitions.
|
|
12
|
+
from lms.titleconfig.definitions.field import FieldDefinition
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def read_field(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
reader: FileReader,
|
|
17
|
+
definition: FieldDefinition,
|
|
18
|
+
read_variable_width_value: Callable | None = None,
|
|
19
19
|
) -> LMS_Field:
|
|
20
20
|
# String is excluded as their reading varies between MSBT/MSBF
|
|
21
21
|
match definition.datatype:
|
|
@@ -33,27 +33,25 @@ def read_field(
|
|
|
33
33
|
value = reader.read_int32()
|
|
34
34
|
case LMS_DataType.FLOAT32:
|
|
35
35
|
value = reader.read_float32()
|
|
36
|
-
case LMS_DataType.
|
|
36
|
+
case LMS_DataType.ENUM:
|
|
37
37
|
if read_variable_width_value is not None:
|
|
38
38
|
index = read_variable_width_value()
|
|
39
39
|
else:
|
|
40
40
|
index = reader.read_uint8()
|
|
41
|
-
value = definition.
|
|
41
|
+
value = definition.enum_members[index]
|
|
42
42
|
case LMS_DataType.BOOL:
|
|
43
43
|
if read_variable_width_value is not None:
|
|
44
44
|
value = bool(read_variable_width_value())
|
|
45
45
|
else:
|
|
46
46
|
value = bool(reader.read_uint8())
|
|
47
|
-
case LMS_DataType.BYTES:
|
|
48
|
-
value = reader.read_bytes(1)
|
|
49
47
|
|
|
50
|
-
return LMS_Field(value, definition)
|
|
48
|
+
return LMS_Field(value, definition)
|
|
51
49
|
|
|
52
50
|
|
|
53
51
|
def write_field(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
writer: FileWriter,
|
|
53
|
+
field: LMS_Field,
|
|
54
|
+
write_variable_width_value: Callable | None = None,
|
|
57
55
|
) -> None:
|
|
58
56
|
if is_number_datatype(field.value, field.datatype):
|
|
59
57
|
write_functions: dict[LMS_DataType, Callable] = {
|
|
@@ -68,8 +66,8 @@ def write_field(
|
|
|
68
66
|
write_functions[field.datatype](field.value)
|
|
69
67
|
return
|
|
70
68
|
|
|
71
|
-
if
|
|
72
|
-
value = field.
|
|
69
|
+
if is_enum_datatype(field.value, field.datatype):
|
|
70
|
+
value = list(field.enum_members.values()).index(field.value)
|
|
73
71
|
if write_variable_width_value is not None:
|
|
74
72
|
write_variable_width_value(value)
|
|
75
73
|
else:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from enum import
|
|
3
|
+
from enum import IntEnum, auto
|
|
4
4
|
from typing import Type, TypeGuard
|
|
5
5
|
|
|
6
6
|
FLOAT32_MIN = -3.4028235e38
|
|
@@ -15,8 +15,9 @@ ALIAS_MAP = {
|
|
|
15
15
|
"i32": "INT32",
|
|
16
16
|
"f32": "FLOAT32",
|
|
17
17
|
"str": "STRING",
|
|
18
|
+
# LIST fallback for ENUM datatype
|
|
19
|
+
"list": "ENUM",
|
|
18
20
|
"bool": "BOOL",
|
|
19
|
-
"byte": "BYTES",
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
|
|
@@ -32,8 +33,8 @@ def is_number_datatype(value: object, datatype: LMS_DataType) -> TypeGuard[int |
|
|
|
32
33
|
) and isinstance(value, int)
|
|
33
34
|
|
|
34
35
|
|
|
35
|
-
def
|
|
36
|
-
return datatype is LMS_DataType.
|
|
36
|
+
def is_enum_datatype(value: object, datatype: LMS_DataType) -> TypeGuard[str]:
|
|
37
|
+
return datatype is LMS_DataType.ENUM and isinstance(value, str)
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
def is_bool_datatype(value: object, datatype: LMS_DataType) -> TypeGuard[bool]:
|
|
@@ -48,7 +49,7 @@ def is_string_datatype(value: object, datatype: LMS_DataType) -> TypeGuard[str]:
|
|
|
48
49
|
return datatype is LMS_DataType.STRING and isinstance(value, str)
|
|
49
50
|
|
|
50
51
|
|
|
51
|
-
class LMS_DataType(
|
|
52
|
+
class LMS_DataType(IntEnum):
|
|
52
53
|
"""Enum that represents a datatype for a value entry in a MSBT/MSBP file."""
|
|
53
54
|
|
|
54
55
|
UINT8 = 0
|
|
@@ -62,64 +63,56 @@ class LMS_DataType(Enum):
|
|
|
62
63
|
FLOAT32 = 6
|
|
63
64
|
|
|
64
65
|
STRING = 8
|
|
65
|
-
|
|
66
|
+
ENUM = 9
|
|
66
67
|
|
|
67
|
-
#
|
|
68
|
-
|
|
69
|
-
# The actual value isn't important since they are not real types, but are instantiated from a config
|
|
70
|
-
BOOL = "bool"
|
|
71
|
-
BYTES = "byte"
|
|
72
|
-
|
|
73
|
-
def to_string(self) -> str:
|
|
74
|
-
return self._name_.lower()
|
|
68
|
+
# Interface type for UINT8
|
|
69
|
+
BOOL = auto()
|
|
75
70
|
|
|
76
71
|
@property
|
|
77
72
|
def signed(self) -> bool:
|
|
78
73
|
"""Property for if the type is signed or not."""
|
|
79
74
|
if self not in [
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
LMS_DataType.BYTES,
|
|
75
|
+
self.STRING,
|
|
76
|
+
self.ENUM,
|
|
77
|
+
self.BOOL,
|
|
84
78
|
]:
|
|
85
|
-
return self in [
|
|
79
|
+
return self in [self.INT8, self.INT16, self.INT32]
|
|
86
80
|
|
|
87
|
-
raise TypeError(f"Signed is not a valid property for '{self.
|
|
81
|
+
raise TypeError(f"Signed is not a valid property for '{self.name.lower()}'!")
|
|
88
82
|
|
|
89
83
|
@property
|
|
90
84
|
def builtin_type(self) -> Type[int | float | str | bool | bytes]:
|
|
91
85
|
"""The enum as the builtin python type."""
|
|
92
86
|
return {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
LMS_DataType.BYTES: bytes,
|
|
87
|
+
self.UINT8: int,
|
|
88
|
+
self.UINT16: int,
|
|
89
|
+
self.UINT32: int,
|
|
90
|
+
self.INT8: int,
|
|
91
|
+
self.INT16: int,
|
|
92
|
+
self.INT32: int,
|
|
93
|
+
self.FLOAT32: float,
|
|
94
|
+
self.STRING: str,
|
|
95
|
+
self.ENUM: str,
|
|
96
|
+
self.BOOL: bool,
|
|
104
97
|
}[self]
|
|
105
98
|
|
|
106
99
|
@property
|
|
107
100
|
def stream_size(self) -> int:
|
|
108
101
|
"""Size of the datatype, only for fixed integers."""
|
|
109
102
|
sizes = {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
103
|
+
self.UINT8: 1,
|
|
104
|
+
self.UINT16: 2,
|
|
105
|
+
self.UINT32: 4,
|
|
106
|
+
self.INT8: 1,
|
|
107
|
+
self.INT16: 2,
|
|
108
|
+
self.INT32: 4,
|
|
109
|
+
self.FLOAT32: 4,
|
|
117
110
|
}
|
|
118
111
|
|
|
119
112
|
try:
|
|
120
113
|
return sizes[self]
|
|
121
114
|
except KeyError:
|
|
122
|
-
raise TypeError(f"Stream size is not defined for '{self.
|
|
115
|
+
raise TypeError(f"Stream size is not defined for '{self.name.lower()}'.")
|
|
123
116
|
|
|
124
117
|
@classmethod
|
|
125
118
|
def from_string(cls, string: str):
|
|
@@ -136,8 +129,8 @@ class LMS_DataType(Enum):
|
|
|
136
129
|
|
|
137
130
|
|
|
138
131
|
def verify_number_from_datatype(
|
|
139
|
-
|
|
140
|
-
|
|
132
|
+
value: int | float,
|
|
133
|
+
datatype: LMS_DataType,
|
|
141
134
|
):
|
|
142
135
|
if datatype is LMS_DataType.FLOAT32:
|
|
143
136
|
max_value = FLOAT32_MAX
|
|
@@ -148,7 +141,7 @@ def verify_number_from_datatype(
|
|
|
148
141
|
max_value = 2 ** (bits - 1)
|
|
149
142
|
min_value = -max_value
|
|
150
143
|
else:
|
|
151
|
-
min_value, max_value = 0, (2**bits) - 1
|
|
144
|
+
min_value, max_value = 0, (2 ** bits) - 1
|
|
152
145
|
|
|
153
146
|
if not min_value <= value <= max_value:
|
|
154
147
|
raise ValueError(
|